public static function activate_module($module, $exit = true, $redirect = true) { do_action('jetpack_pre_activate_module', $module, $exit); $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); do_action('jetpack_activate_module', $module); $active[] = $module; Jetpack_Options::update_option('active_modules', array_unique($active)); Jetpack::state('error', false); // the override Jetpack::state('message', 'module_activated'); Jetpack::state('module', $module); ob_end_clean(); Jetpack::catch_errors(false); if ($redirect) { wp_safe_redirect(Jetpack::admin_url('page=jetpack')); } if ($exit) { exit; } }
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_Options::update_option('active_modules', array_unique($active)); Jetpack::state('error', false); // the override Jetpack::state('message', 'module_activated'); Jetpack::state('module', $module); 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; }
/** * Get a value not saved locally. * * @since 4.3.0 * * @param string $module Module slug. * @param string $option Option name. * * @return bool Whether user is receiving notifications or not. */ public static function get_remote_value($module, $option) { if (in_array($module, array('post-by-email'), true)) { $option .= get_current_user_id(); } // If option doesn't exist, 'does_not_exist' will be returned. $value = get_option($option, 'does_not_exist'); // If option exists, just return it. if ('does_not_exist' !== $value) { return $value; } // Only check a remote option if Jetpack is connected. if (!Jetpack::is_active()) { return false; } // If the module is inactive, load the class to use the method. if (!did_action('jetpack_module_loaded_' . $module)) { // Class can't be found so do nothing. if (!@(include Jetpack::get_module_path($module))) { return false; } } // Do what is necessary for each module. switch ($module) { case 'monitor': $monitor = new Jetpack_Monitor(); $value = $monitor->user_receives_notifications(false); break; case 'post-by-email': $post_by_email = new Jetpack_Post_By_Email(); $value = $post_by_email->get_post_by_email_address(); if ($value === null) { $value = 'NULL'; // sentinel value so it actually gets set } break; } // Normalize value to boolean. if (is_wp_error($value) || is_null($value)) { $value = false; } // Save option to use it next time. update_option($option, $value); return $value; }
function admin_screen_list_modules() { require_once dirname(__FILE__) . '/modules/module-info.php'; $jetpack_connected = true; if (!Jetpack::is_active()) { $jetpack_connected = false; } ?> <div class="module-container"> <?php $avail_raw = Jetpack::get_available_modules(); $available = array(); $active = Jetpack::get_active_modules(); $counter = 0; foreach ((array) $avail_raw as $module) { if ($plugin = Jetpack::get_module($module)) { $plugin['module'] = $module; $available[] = $plugin; } } unset($avail_raw); usort($available, array('Jetpack', 'sort_modules')); $jetpack_version = Jetpack::get_option('version'); if ($jetpack_version) { list($jetpack_version, $jetpack_version_time) = explode(':', $jetpack_version); } else { $jetpack_version = 0; $jetpack_version_time = 0; } $jetpack_old_version = Jetpack::get_option('old_version'); if ($jetpack_old_version) { list($jetpack_old_version) = explode(':', $jetpack_old_version); } else { $jetpack_old_version = 0; } $now = time(); foreach ((array) $available as $module_data) { $module = $module_data['module']; $activated = in_array($module, $active); if ($activated) { $css = 'active'; $toggle = __('Deactivate', 'jetpack'); $toggle_url = wp_nonce_url(Jetpack::admin_url(array('action' => 'deactivate', 'module' => $module)), "jetpack_deactivate-{$module}"); } else { $css = 'inactive'; $toggle = __('Activate', 'jetpack'); $toggle_url = wp_nonce_url(Jetpack::admin_url(array('action' => 'activate', 'module' => $module)), "jetpack_activate-{$module}"); } $file = Jetpack::get_module_path($module); $png = str_replace('.php', '.png', $file); if (is_readable(dirname(__FILE__) . '/_inc/images/icons/' . basename($png))) { $module_img = plugins_url(basename(dirname(__FILE__)) . '/_inc/images/icons/' . basename($png)); } else { $module_img = plugins_url(basename(dirname(__FILE__)) . '/_inc/images/module-blank.png'); } if ($counter % 4 == 0) { $classes = $css . ' jetpack-newline'; $counter = 0; } else { $classes = $css; } $free_text = esc_html($module_data['free'] ? __('Free', 'jetpack') : __('Purchase', 'jetpack')); $free_text = apply_filters('jetpack_module_free_text_' . $module, $free_text); $badge_text = $free_text; if (!$jetpack_connected) { $classes = 'x disabled'; } else { if ($jetpack_version_time + 604800 > $now) { // 1 week if (version_compare($module_data['introduced'], $jetpack_old_version, '>')) { $badge_text = esc_html__('New', 'jetpack'); $classes .= ' jetpack-new-module'; } elseif (isset($module_data['changed']) && version_compare($module_data['changed'], $jetpack_old_version, '>')) { $badge_text = esc_html__('Updated', 'jetpack'); $classes .= ' jetpack-updated-module'; } else { $badge_text = $free_text; } } } ?> <div class="jetpack-module jetpack-<?php echo $classes; ?> " id="<?php echo $module; ?> "> <h3><?php echo $module_data['name']; ?> </h3> <div class="jetpack-module-description"> <div class="module-image"> <img src="<?php echo esc_url($module_img); ?> " align="right" width="71" height="45" /> <p><span class="module-image-badge"><?php echo $badge_text; ?> </span><span class="module-image-free" style="display: none"><?php echo $free_text; ?> </span></p> </div> <p><?php echo apply_filters('jetpack_short_module_description', $module_data['description'], $module); ?> </p> </div> <div class="jetpack-module-actions"> <?php if ($jetpack_connected) { ?> <?php if (!$activated) { ?> <a href="<?php echo esc_url($toggle_url); ?> " class="jetpack-toggle-button<?php echo 'inactive' == $css ? ' button-primary' : ' button'; ?> "><?php echo $toggle; ?> </a> <?php } ?> <?php do_action('jetpack_learn_more_button_' . $module); ?> <?php if (apply_filters('jetpack_module_configurable_' . $module, false)) { echo '<a href="' . esc_attr(Jetpack::module_configuration_url($module)) . '" class="jetpack-configure-button button">' . __('Configure', 'jetpack') . '</a>'; } if ($activated && $module_data['deactivate']) { ?> <a style="display: none;" href="<?php echo esc_url($toggle_url); ?> " class="jetpack-deactivate-button button"><?php echo $toggle; ?> </a> <?php } ?> <?php } else { ?> <?php do_action('jetpack_learn_more_button_' . $module); ?> <?php } ?> </div> </div> <?php if ('inactive' == $css && $jetpack_connected) { ?> <script type="text/javascript"> jQuery( '#<?php echo esc_js($module); ?> ' ).bind( 'click', function(e){ if ( !jQuery(e.target).hasClass('more-info-link') ) document.location.href = '<?php echo str_replace('&', '&', esc_js(esc_url($toggle_url))); ?> '; } ); </script> <?php } ?> <div id="jp-more-info-<?php echo esc_attr($module); ?> " style="display:none;"> <?php if ($jetpack_connected && has_action('jetpack_module_more_info_connected_' . $module)) { do_action('jetpack_module_more_info_connected_' . $module); } else { do_action('jetpack_module_more_info_' . $module); } ?> </div> <?php $counter++; } // Add in some "Coming soon..." placeholders to fill up the current row and one more for ($i = 0; $i < 3; $i++) { ?> <div class="jetpack-module placeholder"<?php if ($i > 8 - $counter) { echo ' style="display: none;"'; } ?> > <h3><?php _e('Coming soon…', 'jetpack'); ?> </h3> </div> <?php } echo '</div><!-- .module-container -->'; }
/** * Load module data from module file. Headers differ from WordPress * plugin headers to avoid them being identified as standalone * plugins on the WordPress plugins page. */ public static function get_module($module) { $headers = array('name' => 'Module Name', 'description' => 'Module Description', 'jumpstart_desc' => 'Jumpstart Description', 'sort' => 'Sort Order', 'recommendation_order' => 'Recommendation Order', 'introduced' => 'First Introduced', 'changed' => 'Major Changes In', 'deactivate' => 'Deactivate', 'free' => 'Free', 'requires_connection' => 'Requires Connection', 'auto_activate' => 'Auto Activate', 'module_tags' => 'Module Tags', 'feature' => 'Feature'); $file = Jetpack::get_module_path(Jetpack::get_module_slug($module)); $mod = Jetpack::get_file_data($file, $headers); if (empty($mod['name'])) { return false; } $mod['jumpstart_desc'] = _x($mod['jumpstart_desc'], 'Jumpstart Description', 'jetpack'); $mod['name'] = _x($mod['name'], 'Module Name', 'jetpack'); $mod['description'] = _x($mod['description'], 'Module Description', 'jetpack'); $mod['sort'] = empty($mod['sort']) ? 10 : (int) $mod['sort']; $mod['recommendation_order'] = empty($mod['recommendation_order']) ? 20 : (int) $mod['recommendation_order']; $mod['deactivate'] = empty($mod['deactivate']); $mod['free'] = empty($mod['free']); $mod['requires_connection'] = !empty($mod['requires_connection']) && 'No' == $mod['requires_connection'] ? false : true; if (empty($mod['auto_activate']) || !in_array(strtolower($mod['auto_activate']), array('yes', 'no', 'public'))) { $mod['auto_activate'] = 'No'; } else { $mod['auto_activate'] = (string) $mod['auto_activate']; } if ($mod['module_tags']) { $mod['module_tags'] = explode(',', $mod['module_tags']); $mod['module_tags'] = array_map('trim', $mod['module_tags']); $mod['module_tags'] = array_map(array(__CLASS__, 'translate_module_tag'), $mod['module_tags']); } else { $mod['module_tags'] = array(self::translate_module_tag('Other')); } if ($mod['feature']) { $mod['feature'] = explode(',', $mod['feature']); $mod['feature'] = array_map('trim', $mod['feature']); } else { $mod['feature'] = array(self::translate_module_tag('Other')); } /** * Filter the feature array on a module * * This filter allows you to control where each module is filtered: Recommended, * Jumpstart, and the default "Other" listing. * * @since 3.5 * * @param array $mod['feature'] The areas to feature this module: * 'Jumpstart' adds to the "Jumpstart" option to activate many modules at once * 'Recommended' shows on the main Jetpack admin screen * 'Other' should be the default if no other value is in the array * @param string $module The slug of the module, e.g. sharedaddy * @param array $mod All the currently assembled module data */ $mod['feature'] = apply_filters('jetpack_module_feature', $mod['feature'], $module, $mod); /** * Filter the returned data about a module. * * This filter allows overriding any info about Jetpack modules. It is dangerous, * so please be careful. * * @since 3.6 * * @param array $mod The details of the requested module. * @param string $module The slug of the module, e.g. sharedaddy * @param string $file The path to the module source file. */ return apply_filters('jetpack_get_module', $mod, $module, $file); }