mirror of
https://github.com/Heretek-AI/heretek-control-core.git
synced 2026-10-12 02:03:55 +00:00
Sweeps shipped copy clean of em dashes: readme.txt, README.md, CHANGELOG.md, the bundled sample prompts, and user-facing PHP strings (tool descriptions, admin labels). PHP was swept on non-comment lines only, so developer docblocks and inline comments are untouched. Internal dev docs (CLAUDE.md, docs/) were deliberately left alone. Replacements are contextual: colons for label/definition patterns, commas for asides, en dashes for numeric ranges. The .mcpb bundle display_name now reads "EMCP Tools - <host>" with a plain hyphen; its test is updated to match. Fixing CHANGELOG.md also clears the em dashes from the website's generated changelog on the next site build, since that file is its source. Verified: php -l clean on every touched file, pro suite 1559 pass, public suite 102 pass. Bumps the pro submodule for the Pro-side sweep.
495 lines
21 KiB
PHP
495 lines
21 KiB
PHP
<?php
|
|
/**
|
|
* WordPress Plugin lifecycle MCP abilities.
|
|
*
|
|
* Seven tools to discover, install (wordpress.org only), activate, deactivate,
|
|
* update, and delete plugins. Built on WP core's plugin + upgrader APIs and
|
|
* guarded by EMCP_Tools_Package_Guard (protected list, active checks, direct
|
|
* filesystem). Reads ship enabled; the five mutation tools ship disabled-by-
|
|
* default (admin opts in on the Tools tab).
|
|
*
|
|
* @package EMCP_Tools
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Registers and implements the plugin lifecycle abilities.
|
|
*
|
|
* @since 3.0.0
|
|
*/
|
|
class EMCP_Tools_Plugin_Abilities {
|
|
|
|
/** @since 3.0.0 @var string[] */
|
|
private $ability_names = array();
|
|
|
|
/** @since 3.0.0 @return string[] */
|
|
public function get_ability_names(): array {
|
|
return $this->ability_names;
|
|
}
|
|
|
|
/** @since 3.0.0 */
|
|
public function register(): void {
|
|
$this->register_list_plugins();
|
|
$this->register_search_plugins();
|
|
$this->register_install_plugin();
|
|
$this->register_activate_plugin();
|
|
$this->register_deactivate_plugin();
|
|
$this->register_update_plugin();
|
|
$this->register_delete_plugin();
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// Permission callbacks (per-op capability)
|
|
// -------------------------------------------------------------------
|
|
|
|
public function can_list(): bool { return current_user_can( 'activate_plugins' ); }
|
|
public function can_install(): bool { return current_user_can( 'install_plugins' ); }
|
|
public function can_activate(): bool { return current_user_can( 'activate_plugins' ); }
|
|
public function can_update(): bool { return current_user_can( 'update_plugins' ); }
|
|
public function can_delete(): bool { return current_user_can( 'delete_plugins' ); }
|
|
|
|
// -------------------------------------------------------------------
|
|
// list-plugins
|
|
// -------------------------------------------------------------------
|
|
|
|
private function register_list_plugins(): void {
|
|
$this->ability_names[] = 'emcp-tools/list-plugins';
|
|
emcp_tools_register_ability(
|
|
'emcp-tools/list-plugins',
|
|
array(
|
|
'label' => __( 'List Plugins', 'emcp-tools' ),
|
|
'description' => __( 'Lists installed WordPress plugins with status (active/inactive/network), version, whether an update is available, and whether the plugin is protected (EMCP Tools / Elementor can never be disabled via MCP). Optional "status" filter.', 'emcp-tools' ),
|
|
'category' => 'emcp-tools',
|
|
'execute_callback' => array( $this, 'execute_list_plugins' ),
|
|
'permission_callback' => array( $this, 'can_list' ),
|
|
'input_schema' => array(
|
|
'type' => 'object',
|
|
'properties' => array(
|
|
'status' => array( 'type' => 'string', 'enum' => array( 'all', 'active', 'inactive' ), 'description' => __( 'Filter by status. Default: all.', 'emcp-tools' ) ),
|
|
),
|
|
),
|
|
'output_schema' => array( 'type' => 'object', 'properties' => array( 'plugins' => array( 'type' => 'array', 'items' => array( 'type' => 'object' ) ) ) ),
|
|
'meta' => array( 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ), 'show_in_rest' => true ),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @return array
|
|
*/
|
|
public function execute_list_plugins( $input ): array {
|
|
EMCP_Tools_Package_Guard::load_upgrader_deps();
|
|
$filter = in_array( $input['status'] ?? 'all', array( 'all', 'active', 'inactive' ), true ) ? ( $input['status'] ?? 'all' ) : 'all';
|
|
$all = function_exists( 'get_plugins' ) ? get_plugins() : array();
|
|
$updates = get_site_transient( 'update_plugins' );
|
|
$resp = ( is_object( $updates ) && isset( $updates->response ) && is_array( $updates->response ) ) ? $updates->response : array();
|
|
|
|
$rows = array();
|
|
foreach ( $all as $file => $data ) {
|
|
$active = EMCP_Tools_Package_Guard::is_active_plugin( (string) $file );
|
|
if ( 'active' === $filter && ! $active ) { continue; }
|
|
if ( 'inactive' === $filter && $active ) { continue; }
|
|
$rows[] = array(
|
|
'file' => (string) $file,
|
|
'slug' => dirname( (string) $file ),
|
|
'name' => (string) ( $data['Name'] ?? $file ),
|
|
'version' => (string) ( $data['Version'] ?? '' ),
|
|
'author' => wp_strip_all_tags( (string) ( $data['Author'] ?? '' ) ),
|
|
'active' => $active,
|
|
'is_protected' => EMCP_Tools_Package_Guard::is_protected_plugin( (string) $file ),
|
|
'update_available' => isset( $resp[ $file ] ),
|
|
'new_version' => isset( $resp[ $file ]->new_version ) ? (string) $resp[ $file ]->new_version : '',
|
|
);
|
|
}
|
|
return array( 'plugins' => $rows );
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// search-plugins
|
|
// -------------------------------------------------------------------
|
|
|
|
private function register_search_plugins(): void {
|
|
$this->ability_names[] = 'emcp-tools/search-plugins';
|
|
emcp_tools_register_ability(
|
|
'emcp-tools/search-plugins',
|
|
array(
|
|
'label' => __( 'Search Plugins', 'emcp-tools' ),
|
|
'description' => __( 'Searches the wordpress.org plugin directory by keyword so you can find a slug to install. Returns slug, name, version, rating, and requirements. Read-only.', 'emcp-tools' ),
|
|
'category' => 'emcp-tools',
|
|
'execute_callback' => array( $this, 'execute_search_plugins' ),
|
|
'permission_callback' => array( $this, 'can_install' ),
|
|
'input_schema' => array(
|
|
'type' => 'object',
|
|
'properties' => array(
|
|
'search' => array( 'type' => 'string', 'description' => __( 'Keyword(s) to search the .org directory.', 'emcp-tools' ) ),
|
|
'per_page' => array( 'type' => 'integer', 'description' => __( '1-50. Default: 10.', 'emcp-tools' ) ),
|
|
),
|
|
'required' => array( 'search' ),
|
|
),
|
|
'output_schema' => array( 'type' => 'object', 'properties' => array( 'results' => array( 'type' => 'array', 'items' => array( 'type' => 'object' ) ) ) ),
|
|
'meta' => array( 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ), 'show_in_rest' => true ),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @return array|\WP_Error
|
|
*/
|
|
public function execute_search_plugins( $input ) {
|
|
$search = sanitize_text_field( $input['search'] ?? '' );
|
|
if ( '' === $search ) {
|
|
return new \WP_Error( 'missing_params', __( 'A "search" keyword is required.', 'emcp-tools' ) );
|
|
}
|
|
EMCP_Tools_Package_Guard::load_upgrader_deps();
|
|
$per_page = max( 1, min( 50, absint( $input['per_page'] ?? 10 ) ) );
|
|
$api = plugins_api( 'query_plugins', array( 'search' => $search, 'per_page' => $per_page, 'fields' => array( 'short_description' => true, 'icons' => false ) ) );
|
|
if ( is_wp_error( $api ) ) {
|
|
return $api;
|
|
}
|
|
$rows = array();
|
|
foreach ( (array) ( $api->plugins ?? array() ) as $p ) {
|
|
$p = (object) $p;
|
|
$rows[] = array(
|
|
'slug' => (string) ( $p->slug ?? '' ),
|
|
'name' => wp_strip_all_tags( (string) ( $p->name ?? '' ) ),
|
|
'version' => (string) ( $p->version ?? '' ),
|
|
'rating' => (int) ( $p->rating ?? 0 ),
|
|
'num_ratings' => (int) ( $p->num_ratings ?? 0 ),
|
|
'requires' => (string) ( $p->requires ?? '' ),
|
|
'tested' => (string) ( $p->tested ?? '' ),
|
|
'short_description' => wp_strip_all_tags( (string) ( $p->short_description ?? '' ) ),
|
|
);
|
|
}
|
|
return array( 'results' => $rows );
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// install-plugin
|
|
// -------------------------------------------------------------------
|
|
|
|
private function register_install_plugin(): void {
|
|
$this->ability_names[] = 'emcp-tools/install-plugin';
|
|
emcp_tools_register_ability(
|
|
'emcp-tools/install-plugin',
|
|
array(
|
|
'label' => __( 'Install Plugin', 'emcp-tools' ),
|
|
'description' => __( 'Installs a plugin from the wordpress.org directory by slug (e.g. "contact-form-7"). Optionally activates it. Source is always wordpress.org, arbitrary URLs are not accepted.', 'emcp-tools' ),
|
|
'category' => 'emcp-tools',
|
|
'execute_callback' => array( $this, 'execute_install_plugin' ),
|
|
'permission_callback' => array( $this, 'can_install' ),
|
|
'input_schema' => array(
|
|
'type' => 'object',
|
|
'properties' => array(
|
|
'slug' => array( 'type' => 'string', 'description' => __( 'wordpress.org plugin slug.', 'emcp-tools' ) ),
|
|
'activate' => array( 'type' => 'boolean', 'description' => __( 'Activate after install. Default: false.', 'emcp-tools' ) ),
|
|
),
|
|
'required' => array( 'slug' ),
|
|
),
|
|
'output_schema' => array( 'type' => 'object', 'properties' => array(
|
|
'installed' => array( 'type' => 'boolean' ), 'activated' => array( 'type' => 'boolean' ),
|
|
'file' => array( 'type' => 'string' ), 'slug' => array( 'type' => 'string' ),
|
|
'messages' => array( 'type' => 'array', 'items' => array( 'type' => 'string' ) ),
|
|
) ),
|
|
'meta' => array( 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ), 'show_in_rest' => true ),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @return array|\WP_Error
|
|
*/
|
|
public function execute_install_plugin( $input ) {
|
|
$slug = sanitize_key( $input['slug'] ?? '' );
|
|
if ( '' === $slug ) {
|
|
return new \WP_Error( 'missing_params', __( 'A plugin "slug" is required.', 'emcp-tools' ) );
|
|
}
|
|
$activate = ! empty( $input['activate'] );
|
|
if ( $activate && ! current_user_can( 'activate_plugins' ) ) {
|
|
return new \WP_Error( 'cannot_activate', __( 'You cannot activate plugins.', 'emcp-tools' ) );
|
|
}
|
|
$ready = EMCP_Tools_Package_Guard::filesystem_ready();
|
|
if ( is_wp_error( $ready ) ) {
|
|
return $ready;
|
|
}
|
|
$api = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false ) ) );
|
|
if ( is_wp_error( $api ) ) {
|
|
return $api;
|
|
}
|
|
$skin = EMCP_Tools_Package_Guard::make_skin();
|
|
$upgrader = new \Plugin_Upgrader( $skin );
|
|
$result = $upgrader->install( $api->download_link );
|
|
if ( is_wp_error( $result ) ) {
|
|
return $result;
|
|
}
|
|
if ( false === $result || null === $result ) {
|
|
return new \WP_Error( 'install_failed', __( 'Plugin installation failed.', 'emcp-tools' ) );
|
|
}
|
|
$file = (string) $upgrader->plugin_info();
|
|
$activated = false;
|
|
if ( $activate && '' !== $file ) {
|
|
$act = activate_plugin( $file );
|
|
$activated = ! is_wp_error( $act );
|
|
}
|
|
return array(
|
|
'installed' => true,
|
|
'activated' => $activated,
|
|
'file' => $file,
|
|
'slug' => $slug,
|
|
'messages' => EMCP_Tools_Package_Guard::skin_messages( $skin ),
|
|
);
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// activate-plugin
|
|
// -------------------------------------------------------------------
|
|
|
|
private function register_activate_plugin(): void {
|
|
$this->ability_names[] = 'emcp-tools/activate-plugin';
|
|
emcp_tools_register_ability(
|
|
'emcp-tools/activate-plugin',
|
|
array(
|
|
'label' => __( 'Activate Plugin', 'emcp-tools' ),
|
|
'description' => __( 'Activates an installed plugin by its file path (e.g. "akismet/akismet.php") or folder slug.', 'emcp-tools' ),
|
|
'category' => 'emcp-tools',
|
|
'execute_callback' => array( $this, 'execute_activate_plugin' ),
|
|
'permission_callback' => array( $this, 'can_activate' ),
|
|
'input_schema' => array(
|
|
'type' => 'object',
|
|
'properties' => array( 'plugin' => array( 'type' => 'string', 'description' => __( 'Plugin file (folder/file.php) or folder slug.', 'emcp-tools' ) ) ),
|
|
'required' => array( 'plugin' ),
|
|
),
|
|
'output_schema' => array( 'type' => 'object', 'properties' => array( 'success' => array( 'type' => 'boolean' ), 'plugin' => array( 'type' => 'string' ), 'active' => array( 'type' => 'boolean' ) ) ),
|
|
'meta' => array( 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => true ), 'show_in_rest' => true ),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @return array|\WP_Error
|
|
*/
|
|
public function execute_activate_plugin( $input ) {
|
|
$file = $this->resolve_plugin_file( $input['plugin'] ?? '' );
|
|
if ( is_wp_error( $file ) ) {
|
|
return $file;
|
|
}
|
|
$res = activate_plugin( $file );
|
|
if ( is_wp_error( $res ) ) {
|
|
return $res;
|
|
}
|
|
return array( 'success' => true, 'plugin' => $file, 'active' => EMCP_Tools_Package_Guard::is_active_plugin( $file ) );
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// deactivate-plugin
|
|
// -------------------------------------------------------------------
|
|
|
|
private function register_deactivate_plugin(): void {
|
|
$this->ability_names[] = 'emcp-tools/deactivate-plugin';
|
|
emcp_tools_register_ability(
|
|
'emcp-tools/deactivate-plugin',
|
|
array(
|
|
'label' => __( 'Deactivate Plugin', 'emcp-tools' ),
|
|
'description' => __( 'Deactivates an active plugin. Refuses to deactivate EMCP Tools itself or Elementor (its hard dependency).', 'emcp-tools' ),
|
|
'category' => 'emcp-tools',
|
|
'execute_callback' => array( $this, 'execute_deactivate_plugin' ),
|
|
'permission_callback' => array( $this, 'can_activate' ),
|
|
'input_schema' => array(
|
|
'type' => 'object',
|
|
'properties' => array( 'plugin' => array( 'type' => 'string', 'description' => __( 'Plugin file or folder slug.', 'emcp-tools' ) ) ),
|
|
'required' => array( 'plugin' ),
|
|
),
|
|
'output_schema' => array( 'type' => 'object', 'properties' => array( 'success' => array( 'type' => 'boolean' ), 'plugin' => array( 'type' => 'string' ), 'active' => array( 'type' => 'boolean' ) ) ),
|
|
'meta' => array( 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => true ), 'show_in_rest' => true ),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @return array|\WP_Error
|
|
*/
|
|
public function execute_deactivate_plugin( $input ) {
|
|
$file = $this->resolve_plugin_file( $input['plugin'] ?? '' );
|
|
if ( is_wp_error( $file ) ) {
|
|
return $file;
|
|
}
|
|
if ( EMCP_Tools_Package_Guard::is_protected_plugin( $file ) ) {
|
|
return new \WP_Error( 'protected_plugin', sprintf( /* translators: %s: plugin file */ __( '"%s" is protected and cannot be deactivated via MCP (it would break EMCP Tools or Elementor).', 'emcp-tools' ), $file ) );
|
|
}
|
|
deactivate_plugins( array( $file ) );
|
|
return array( 'success' => true, 'plugin' => $file, 'active' => EMCP_Tools_Package_Guard::is_active_plugin( $file ) );
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// update-plugin
|
|
// -------------------------------------------------------------------
|
|
|
|
private function register_update_plugin(): void {
|
|
$this->ability_names[] = 'emcp-tools/update-plugin';
|
|
emcp_tools_register_ability(
|
|
'emcp-tools/update-plugin',
|
|
array(
|
|
'label' => __( 'Update Plugin', 'emcp-tools' ),
|
|
'description' => __( 'Updates an installed plugin to the latest wordpress.org version. Reports up_to_date when no update is pending.', 'emcp-tools' ),
|
|
'category' => 'emcp-tools',
|
|
'execute_callback' => array( $this, 'execute_update_plugin' ),
|
|
'permission_callback' => array( $this, 'can_update' ),
|
|
'input_schema' => array(
|
|
'type' => 'object',
|
|
'properties' => array( 'plugin' => array( 'type' => 'string', 'description' => __( 'Plugin file or folder slug.', 'emcp-tools' ) ) ),
|
|
'required' => array( 'plugin' ),
|
|
),
|
|
'output_schema' => array( 'type' => 'object', 'properties' => array(
|
|
'success' => array( 'type' => 'boolean' ), 'up_to_date' => array( 'type' => 'boolean' ),
|
|
'plugin' => array( 'type' => 'string' ), 'old_version' => array( 'type' => 'string' ),
|
|
'new_version' => array( 'type' => 'string' ), 'messages' => array( 'type' => 'array', 'items' => array( 'type' => 'string' ) ),
|
|
) ),
|
|
'meta' => array( 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ), 'show_in_rest' => true ),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @return array|\WP_Error
|
|
*/
|
|
public function execute_update_plugin( $input ) {
|
|
$file = $this->resolve_plugin_file( $input['plugin'] ?? '' );
|
|
if ( is_wp_error( $file ) ) {
|
|
return $file;
|
|
}
|
|
// Protected packages (EMCP Tools, Elementor, Elementor Pro) are never
|
|
// mutated via MCP — including updates — matching deactivate/delete.
|
|
if ( EMCP_Tools_Package_Guard::is_protected_plugin( $file ) ) {
|
|
return new \WP_Error(
|
|
'protected_plugin',
|
|
/* translators: %s: plugin file */
|
|
sprintf( __( '"%s" is protected and cannot be updated via MCP.', 'emcp-tools' ), $file )
|
|
);
|
|
}
|
|
$ready = EMCP_Tools_Package_Guard::filesystem_ready();
|
|
if ( is_wp_error( $ready ) ) {
|
|
return $ready;
|
|
}
|
|
if ( function_exists( 'wp_update_plugins' ) ) {
|
|
wp_update_plugins();
|
|
}
|
|
$updates = get_site_transient( 'update_plugins' );
|
|
$resp = ( is_object( $updates ) && isset( $updates->response ) && is_array( $updates->response ) ) ? $updates->response : array();
|
|
$all = function_exists( 'get_plugins' ) ? get_plugins() : array();
|
|
$old = (string) ( $all[ $file ]['Version'] ?? '' );
|
|
if ( ! isset( $resp[ $file ] ) ) {
|
|
return array( 'success' => true, 'up_to_date' => true, 'plugin' => $file, 'old_version' => $old, 'new_version' => $old, 'messages' => array() );
|
|
}
|
|
$skin = EMCP_Tools_Package_Guard::make_skin();
|
|
$upgrader = new \Plugin_Upgrader( $skin );
|
|
$result = $upgrader->upgrade( $file );
|
|
if ( is_wp_error( $result ) ) {
|
|
return $result;
|
|
}
|
|
if ( false === $result ) {
|
|
return new \WP_Error( 'update_failed', __( 'Plugin update failed.', 'emcp-tools' ) );
|
|
}
|
|
return array(
|
|
'success' => true,
|
|
'up_to_date' => false,
|
|
'plugin' => $file,
|
|
'old_version' => $old,
|
|
'new_version' => (string) ( $resp[ $file ]->new_version ?? '' ),
|
|
'messages' => EMCP_Tools_Package_Guard::skin_messages( $skin ),
|
|
);
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// delete-plugin
|
|
// -------------------------------------------------------------------
|
|
|
|
private function register_delete_plugin(): void {
|
|
$this->ability_names[] = 'emcp-tools/delete-plugin';
|
|
emcp_tools_register_ability(
|
|
'emcp-tools/delete-plugin',
|
|
array(
|
|
'label' => __( 'Delete Plugin', 'emcp-tools' ),
|
|
'description' => __( 'Permanently deletes an installed plugin. Destructive. Refuses protected plugins (EMCP Tools / Elementor) and any active plugin (deactivate it first).', 'emcp-tools' ),
|
|
'category' => 'emcp-tools',
|
|
'execute_callback' => array( $this, 'execute_delete_plugin' ),
|
|
'permission_callback' => array( $this, 'can_delete' ),
|
|
'input_schema' => array(
|
|
'type' => 'object',
|
|
'properties' => array( 'plugin' => array( 'type' => 'string', 'description' => __( 'Plugin file or folder slug.', 'emcp-tools' ) ) ),
|
|
'required' => array( 'plugin' ),
|
|
),
|
|
'output_schema' => array( 'type' => 'object', 'properties' => array( 'deleted' => array( 'type' => 'boolean' ), 'plugin' => array( 'type' => 'string' ) ) ),
|
|
'meta' => array( 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false ), 'show_in_rest' => true ),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array $input
|
|
* @return array|\WP_Error
|
|
*/
|
|
public function execute_delete_plugin( $input ) {
|
|
$file = $this->resolve_plugin_file( $input['plugin'] ?? '' );
|
|
if ( is_wp_error( $file ) ) {
|
|
return $file;
|
|
}
|
|
if ( EMCP_Tools_Package_Guard::is_protected_plugin( $file ) ) {
|
|
return new \WP_Error( 'protected_plugin', sprintf( /* translators: %s: plugin file */ __( '"%s" is protected and cannot be deleted via MCP.', 'emcp-tools' ), $file ) );
|
|
}
|
|
if ( EMCP_Tools_Package_Guard::is_active_plugin( $file ) ) {
|
|
return new \WP_Error( 'plugin_active', __( 'Deactivate the plugin before deleting it.', 'emcp-tools' ) );
|
|
}
|
|
$ready = EMCP_Tools_Package_Guard::filesystem_ready();
|
|
if ( is_wp_error( $ready ) ) {
|
|
return $ready;
|
|
}
|
|
$res = delete_plugins( array( $file ) );
|
|
if ( is_wp_error( $res ) ) {
|
|
return $res;
|
|
}
|
|
if ( ! $res ) {
|
|
return new \WP_Error( 'delete_failed', __( 'Plugin deletion failed.', 'emcp-tools' ) );
|
|
}
|
|
return array( 'deleted' => true, 'plugin' => $file );
|
|
}
|
|
|
|
// -------------------------------------------------------------------
|
|
// helper
|
|
// -------------------------------------------------------------------
|
|
|
|
/**
|
|
* Resolve a user-supplied plugin reference (file path or folder slug) to an
|
|
* installed plugin file. Returns WP_Error('plugin_not_found') if unknown.
|
|
*
|
|
* @param string $ref
|
|
* @return string|\WP_Error
|
|
*/
|
|
private function resolve_plugin_file( $ref ) {
|
|
$ref = (string) $ref;
|
|
if ( '' === $ref ) {
|
|
return new \WP_Error( 'missing_params', __( 'A "plugin" reference is required.', 'emcp-tools' ) );
|
|
}
|
|
EMCP_Tools_Package_Guard::load_upgrader_deps();
|
|
$all = function_exists( 'get_plugins' ) ? get_plugins() : array();
|
|
if ( isset( $all[ $ref ] ) ) {
|
|
return $ref;
|
|
}
|
|
// Treat $ref as a folder slug and match the first file in that folder.
|
|
foreach ( array_keys( $all ) as $file ) {
|
|
if ( dirname( (string) $file ) === $ref ) {
|
|
return (string) $file;
|
|
}
|
|
}
|
|
return new \WP_Error( 'plugin_not_found', sprintf( /* translators: %s: plugin reference */ __( 'No installed plugin matches "%s".', 'emcp-tools' ), $ref ) );
|
|
}
|
|
}
|