string Required. Dialog script handler name used in AJAX and enqueue hooks. * - 'plugin_slug' => string Required. Main plugin file path relative to wp-content/plugins, e.g. updraftplus/updraftplus.php * - 'dialog_title' => string Optional. Title for the confirmation dialog. Default 'Deactivation Confirmation'. * - 'deactivate_label' => string Optional. Label for the "Deactivate" button. Default 'Deactivate'. * - 'cancel_label' => string Optional. Label for the "Cancel" button. Default 'Cancel'. * - 'dialog_type' => string Optional. Type of dialog to display ('jqueryui' or 'thickbox'). Default 'jqueryui'. * - 'template_file' => string Optional. Path to the HTML template for the dialog content. Default 'templates/dialog.php'. * * @throws InvalidArgumentException If required options 'script_handler' or 'plugin_slug' are missing. */ public function __construct($options) { if (!isset($options['script_handler'], $options['plugin_slug'])) throw new InvalidArgumentException('Missing required options.'); if (isset($options['dialog_type']) && !in_array($options['dialog_type'], array('jqueryui', 'thickbox'))) unset($options['dialog_type']); // Set default options and merge with any passed options. $defaults = array( 'dialog_title' => 'Deactivation Confirmation', 'deactivate_label' => 'Deactivate', 'cancel_label' => 'Cancel', 'dialog_type' => 'jqueryui', 'template_file' => plugin_dir_path(__FILE__).'templates/dialog.php', 'show_on_network_admin' => true, 'show_on_subsites' => true, ); $this->options = array_merge($defaults, $options); add_action('admin_enqueue_scripts', array($this, 'enqueue_dialog_assets')); add_filter('plugin_action_links', array($this, 'modify_deactivate_link'), 10, 2); add_filter('network_admin_plugin_action_links', array($this, 'modify_deactivate_link'), 10, 2); add_action('wp_ajax_'.$this->options['script_handler'].'_deinstall_confirm', array($this, 'handle_deinstall_confirm')); } /** * Enqueue dialog assets (JS) based on the specified dialog type. * * Only enqueues on the plugins page and localizes dialog data for use in JavaScript. */ public function enqueue_dialog_assets() { global $pagenow; if ('plugins.php' !== $pagenow) return; if ($this->options['dialog_type'] === 'thickbox') { wp_enqueue_script('thickbox'); wp_enqueue_style('thickbox'); if (version_compare($GLOBALS['wp_version'], '3.9', '<')) { wp_enqueue_style('deinstall-dialog-thickbox-css', plugins_url('assets/css/deinstall-dialog-thickbox.css', __FILE__), array('thickbox'), self::VERSION); } $file = plugins_url('assets/js/deinstall-dialog-thickbox.js', __FILE__); $dependencies = array('jquery', 'thickbox'); } else { $file = plugins_url('assets/js/deinstall-dialog-jqueryui.js', __FILE__); $dependencies = array('jquery', 'jquery-ui-dialog'); } $script_handler = 'updraft-deinstall-dialog-'.$this->options['script_handler'].'-'.$this->options['dialog_type'].'-'.self::VERSION; wp_register_script($script_handler, $file, $dependencies, self::VERSION, true); $data = array( 'nonce' => wp_create_nonce($this->options['script_handler'].'_deinstall_nonce'), 'dialog_html' => $this->load_dialog_template($this->options['template_file']), 'dialog_title' => $this->options['dialog_title'], 'deactivate_label' => $this->options['deactivate_label'], 'cancel_label' => $this->options['cancel_label'], ); wp_localize_script( $script_handler, 'updraft_deinstall_data_'.$this->options['script_handler'], $data ); wp_enqueue_script($script_handler); } /** * Load the HTML template for the dialog. * * @param string $file Path to the dialog template file. * @return string HTML content of the dialog. */ public function load_dialog_template($file) { $form = '
'; ob_start(); include $file; $form .= ob_get_clean(); $form .= '
'; return $form; } /** * Handle AJAX request to confirm de-installation. * * Verifies nonce and triggers the main deinstallation action for the plugin. */ public function handle_deinstall_confirm() { if (!current_user_can('activate_plugins') || !isset($_POST['_nonce']) || !wp_verify_nonce($_POST['_nonce'], $this->options['script_handler'].'_deinstall_nonce')) { wp_send_json_error(array('message' => 'Nonce and/or capability verification failed.'), 403); } do_action($this->options['script_handler'].'_deinstall'); wp_send_json_success(); } /** * Modify the plugin action links to attach deinstallation data attribute. * * @param array $links Array of action links for the plugin. * @param string $file Current plugin file. * @return array Modified array of action links. */ public function modify_deactivate_link($links, $file) { if (!is_array($links) || $this->options['plugin_slug'] !== $file) return $links; if (is_multisite()) { if (!is_network_admin() && empty($this->options['show_on_subsites'])) { return $links; } if (is_network_admin() && empty($this->options['show_on_network_admin'])) { return $links; } } foreach ($links as $key => $value) { if ($key != 'deactivate') continue; $links[$key] = preg_replace( '//i', '', $value ); } return $links; } } }