/** * Manage Jetpack Modules * * ## OPTIONS * * list : View all available modules, and their status. * activate all : Activate all modules * deactivate all: Deactivate all modules * * activate <module_slug> : Activate a module. * deactivate <module_slug> : Deactivate a module. * toggle <module_slug> : Toggle a module on or off. * * ## EXAMPLES * * wp jetpack module list * wp jetpack module activate stats * wp jetpack module deactivate stats * wp jetpack module toggle stats * * wp jetpack module activate all * wp jetpack module deactivate all * * @synopsis <list|activate|deactivate|toggle> [<module_name>] */ public function module($args, $assoc_args) { $action = isset($args[0]) ? $args[0] : 'list'; if (!in_array($action, array('list', 'activate', 'deactivate', 'toggle'))) { WP_CLI::error(sprintf(__('%s is not a valid command.', 'jetpack'), $action)); } if (in_array($action, array('activate', 'deactivate', 'toggle'))) { if (isset($args[1])) { $module_slug = $args[1]; if ('all' !== $module_slug && !Jetpack::is_module($module_slug)) { WP_CLI::error(sprintf(__('%s is not a valid module.', 'jetpack'), $module_slug)); } if ('toggle' == $action) { $action = Jetpack::is_module_active($module_slug) ? 'deactivate' : 'activate'; } // Bulk actions if ('all' == $args[1]) { $action = 'deactivate' == $action ? 'deactivate_all' : 'activate_all'; } // VaultPress needs to be handled elsewhere. if (in_array($action, array('activate', 'deactivate', 'toggle')) && 'vaultpress' == $args[1]) { WP_CLI::error(sprintf(_x('Please visit %s to configure your VaultPress subscription.', '%s is a website', 'jetpack'), esc_url('https://vaultpress.com/jetpack/'))); } } else { WP_CLI::line(__('Please specify a valid module.', 'jetpack')); $action = 'list'; } } switch ($action) { case 'list': WP_CLI::line(__('Available Modules:', 'jetpack')); $modules = Jetpack::get_available_modules(); sort($modules); foreach ($modules as $module_slug) { if ('vaultpress' == $module_slug) { continue; } $active = Jetpack::is_module_active($module_slug) ? __('Active', 'jetpack') : __('Inactive', 'jetpack'); WP_CLI::line("\t" . str_pad($module_slug, 24) . $active); } break; case 'activate': $module = Jetpack::get_module($module_slug); Jetpack::log('activate', $module_slug); Jetpack::activate_module($module_slug, false, false); WP_CLI::success(sprintf(__('%s has been activated.', 'jetpack'), $module['name'])); break; case 'activate_all': $modules = Jetpack::get_available_modules(); Jetpack::update_active_modules($modules); WP_CLI::success(__('All modules activated!', 'jetpack')); break; case 'deactivate': $module = Jetpack::get_module($module_slug); Jetpack::log('deactivate', $module_slug); Jetpack::deactivate_module($module_slug); WP_CLI::success(sprintf(__('%s has been deactivated.', 'jetpack'), $module['name'])); break; case 'deactivate_all': Jetpack::delete_active_modules(); WP_CLI::success(__('All modules deactivated!', 'jetpack')); break; case 'toggle': // Will never happen, should have been handled above and changed to activate or deactivate. break; } }
/** * Reset Jetpack options * * @since 4.3.0 * * @param WP_REST_Request $data { * Array of parameters received by request. * * @type string $options Available options to reset are options|modules * } * * @return bool|WP_Error True if options were reset. Otherwise, a WP_Error instance with the corresponding error. */ public static function reset_jetpack_options($data) { $param = $data->get_json_params(); if (!isset($param['reset']) || $param['reset'] !== true) { return new WP_Error('invalid_param', esc_html__('Invalid Parameter', 'jetpack'), array('status' => 404)); } if (isset($data['options'])) { $data = $data['options']; switch ($data) { case 'options': $options_to_reset = Jetpack::get_jetpack_options_for_reset(); // Reset the Jetpack options foreach ($options_to_reset['jp_options'] as $option_to_reset) { Jetpack_Options::delete_option($option_to_reset); } foreach ($options_to_reset['wp_options'] as $option_to_reset) { delete_option($option_to_reset); } // Reset to default modules $default_modules = Jetpack::get_default_modules(); Jetpack::update_active_modules($default_modules); // Jumpstart option is special Jetpack_Options::update_option('jumpstart', 'new_connection'); return rest_ensure_response(array('code' => 'success', 'message' => esc_html__('Jetpack options reset.', 'jetpack'))); break; case 'modules': $default_modules = Jetpack::get_default_modules(); Jetpack::update_active_modules($default_modules); return rest_ensure_response(array('code' => 'success', 'message' => esc_html__('Modules reset to default.', 'jetpack'))); break; default: return new WP_Error('invalid_param', esc_html__('Invalid Parameter', 'jetpack'), array('status' => 404)); } } return new WP_Error('required_param', esc_html__('Missing parameter "type".', 'jetpack'), array('status' => 404)); }
public static function activate_module($module, $exit = true, $redirect = true) { /** * Fires before a module is activated. * * @since 2.6.0 * * @param string $module Module slug. * @param bool $exit Should we exit after the module has been activated. Default to true. * @param bool $redirect Should the user be redirected after module activation? Default to true. */ do_action('jetpack_pre_activate_module', $module, $exit, $redirect); $jetpack = Jetpack::init(); if (!strlen($module)) { return false; } if (!Jetpack::is_module($module)) { return false; } // If it's already active, then don't do it again $active = Jetpack::get_active_modules(); foreach ($active as $act) { if ($act == $module) { return true; } } $module_data = Jetpack::get_module($module); if (!Jetpack::is_active()) { if (!Jetpack::is_development_mode()) { return false; } // If we're not connected but in development mode, make sure the module doesn't require a connection if (Jetpack::is_development_mode() && $module_data['requires_connection']) { return false; } } // Check and see if the old plugin is active if (isset($jetpack->plugins_to_deactivate[$module])) { // Deactivate the old plugin if (Jetpack_Client_Server::deactivate_plugin($jetpack->plugins_to_deactivate[$module][0], $jetpack->plugins_to_deactivate[$module][1])) { // If we deactivated the old plugin, remembere that with ::state() and redirect back to this page to activate the module // We can't activate the module on this page load since the newly deactivated old plugin is still loaded on this page load. Jetpack::state('deactivated_plugins', $module); wp_safe_redirect(add_query_arg('jetpack_restate', 1)); exit; } } // Check the file for fatal errors, a la wp-admin/plugins.php::activate Jetpack::state('module', $module); Jetpack::state('error', 'module_activation_failed'); // we'll override this later if the plugin can be included without fatal error Jetpack::catch_errors(true); ob_start(); require Jetpack::get_module_path($module); /** This action is documented in class.jetpack.php */ do_action('jetpack_activate_module', $module); $active[] = $module; Jetpack::update_active_modules($active); Jetpack::state('error', false); // the override ob_end_clean(); Jetpack::catch_errors(false); // A flag for Jump Start so it's not shown again. Only set if it hasn't been yet. if ('new_connection' === Jetpack_Options::get_option('jumpstart')) { Jetpack_Options::update_option('jumpstart', 'jetpack_action_taken'); //Jump start is being dismissed send data to MC Stats $jetpack->stat('jumpstart', 'manual,' . $module); $jetpack->do_stats('server_side'); } if ($redirect) { wp_safe_redirect(Jetpack::admin_url('page=jetpack')); } if ($exit) { exit; } return true; }
function test_sync_always_sync_changes_to_modules_right_away() { Jetpack::update_active_modules(array('stats')); $this->sender->do_sync(); $synced_value = $this->server_replica_storage->get_callable('active_modules'); $this->assertEquals(array('stats'), $synced_value); $this->server_replica_storage->reset(); Jetpack::update_active_modules(array('json-api')); $this->sender->do_sync(); $synced_value = $this->server_replica_storage->get_callable('active_modules'); $this->assertEquals(array('json-api'), $synced_value); }
/** * Checks the site plan and deactivates modules that were active but are no longer included in the plan. * * @since 4.4.0 * * @param $page * * @return bool|array */ function check_plan_deactivate_modules($page) { if (Jetpack::is_development_mode() || !in_array($page->base, array('toplevel_page_jetpack', 'admin_page_jetpack_modules', 'jetpack_page_vaultpress', 'jetpack_page_stats', 'jetpack_page_akismet-key-config')) || true === self::$plan_checked) { return false; } self::$plan_checked = true; $previous = get_option('jetpack_active_plan', ''); $response = rest_do_request(new WP_REST_Request('GET', '/jetpack/v4/site')); if (!is_object($response) || $response->is_error()) { // If we can't get information about the current plan we don't do anything self::$plan_checked = true; return; } $current = $response->get_data(); $current = json_decode($current['data']); $to_deactivate = array(); if (isset($current->plan->product_slug)) { if (empty($previous) || !isset($previous['product_slug']) || $previous['product_slug'] !== $current->plan->product_slug) { $active = Jetpack::get_active_modules(); switch ($current->plan->product_slug) { case 'jetpack_free': $to_deactivate = array('seo-tools', 'videopress'); break; case 'jetpack_personal': case 'jetpack_personal_monthly': $to_deactivate = array('seo-tools', 'videopress'); break; case 'jetpack_premium': case 'jetpack_premium_monthly': $to_deactivate = array('seo-tools'); break; } $to_deactivate = array_intersect($active, $to_deactivate); if (!empty($to_deactivate)) { Jetpack::update_active_modules(array_filter(array_diff($active, $to_deactivate))); } } } return array('previous' => $previous, 'current' => $current, 'deactivate' => $to_deactivate); }
/** * Test that an arg with array type can be saved. * * @since 4.4.0 */ public function test_setting_array_type() { // Create a user and set it up as current. $user = $this->create_and_get_user('administrator'); $user->add_cap('jetpack_activate_modules'); wp_set_current_user($user->ID); Jetpack::update_active_modules(array('sharedaddy')); // Verify that saving another thing fails $response = $this->create_and_get_request('settings', array('show' => 'post'), 'POST'); $this->assertResponseStatus(400, $response); $response = $this->create_and_get_request('settings', array('show' => array('post', 'page')), 'POST'); $this->assertResponseStatus(200, $response); }
function test_sync_always_sync_changes_to_modules_right_away() { delete_transient(Jetpack_Sync_Module_Callables::CALLABLES_AWAIT_TRANSIENT_NAME); delete_option(Jetpack_Sync_Module_Callables::CALLABLES_CHECKSUM_OPTION_NAME); $this->setSyncClientDefaults(); Jetpack::update_active_modules(array('stats')); $this->sender->do_sync(); $synced_value = $this->server_replica_storage->get_callable('active_modules'); $this->assertEquals(array('stats'), $synced_value); $this->server_replica_storage->reset(); Jetpack::update_active_modules(array('json-api')); $this->sender->do_sync(); $synced_value = $this->server_replica_storage->get_callable('active_modules'); $this->assertEquals(array('json-api'), $synced_value); }
public function test_activating_deactivating_modules_fires_specific_actions() { self::reset_tracking_of_module_activation(); add_action('jetpack_activate_module_stats', array(__CLASS__, 'track_activated_modules')); add_action('jetpack_deactivate_module_stats', array(__CLASS__, 'track_deactivated_modules')); Jetpack::update_active_modules(array('stats')); Jetpack::update_active_modules(array('stats')); Jetpack::update_active_modules(array('json-api')); Jetpack::update_active_modules(array('json-api')); $this->assertEquals(self::$activated_modules, array('stats')); $this->assertEquals(self::$deactivated_modules, array('stats')); remove_action('jetpack_activate_module_stats', array(__CLASS__, 'track_activated_modules')); remove_action('jetpack_deactivate_module_stats', array(__CLASS__, 'track_deactivated_modules')); }