/class.jetpack.php
PHP | 4426 lines | 3109 code | 626 blank | 691 comment | 571 complexity | 42ae87d59d543ef7935317c6f065841b MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- <?php
- /*
- Options:
- jetpack_options (array)
- An array of options.
- @see Jetpack_Options::get_option_names()
- jetpack_register (string)
- Temporary verification secrets.
- jetpack_activated (int)
- 1: the plugin was activated normally
- 2: the plugin was activated on this site because of a network-wide activation
- 3: the plugin was auto-installed
- 4: the plugin was manually disconnected (but is still installed)
- jetpack_active_modules (array)
- Array of active module slugs.
- jetpack_do_activate (bool)
- Flag for "activating" the plugin on sites where the activation hook never fired (auto-installs)
- */
- class Jetpack {
- var $xmlrpc_server = null;
- private $xmlrpc_verification = null;
- var $HTTP_RAW_POST_DATA = null; // copy of $GLOBALS['HTTP_RAW_POST_DATA']
- var $plugins_to_deactivate = array(
- 'stats' => array( 'stats/stats.php', 'WordPress.com Stats' ),
- 'shortlinks' => array( 'stats/stats.php', 'WordPress.com Stats' ),
- 'sharedaddy' => array( 'sharedaddy/sharedaddy.php', 'Sharedaddy' ),
- 'twitter-widget' => array( 'wickett-twitter-widget/wickett-twitter-widget.php', 'Wickett Twitter Widget' ),
- 'after-the-deadline' => array( 'after-the-deadline/after-the-deadline.php', 'After The Deadline' ),
- 'contact-form' => array( 'grunion-contact-form/grunion-contact-form.php', 'Grunion Contact Form' ),
- 'custom-css' => array( 'safecss/safecss.php', 'WordPress.com Custom CSS' ),
- 'random-redirect' => array( 'random-redirect/random-redirect.php', 'Random Redirect' ),
- 'videopress' => array( 'video/video.php', 'VideoPress' ),
- 'widget-visibility' => array( 'jetpack-widget-visibility/widget-visibility.php', 'Jetpack Widget Visibility' ),
- 'widget-visibility' => array( 'widget-visibility-without-jetpack/widget-visibility-without-jetpack.php', 'Widget Visibility Without Jetpack' ),
- 'sharedaddy' => array( 'jetpack-sharing/sharedaddy.php', 'Jetpack Sharing' ),
- 'omnisearch' => array( 'jetpack-omnisearch/omnisearch.php', 'Jetpack Omnisearch' ),
- 'gravatar-hovercards' => array( 'jetpack-gravatar-hovercards/gravatar-hovercards.php', 'Jetpack Gravatar Hovercards' ),
- 'latex' => array( 'wp-latex/wp-latex.php', 'WP LaTeX' ),
- );
- var $capability_translations = array(
- 'administrator' => 'manage_options',
- 'editor' => 'edit_others_posts',
- 'author' => 'publish_posts',
- 'contributor' => 'edit_posts',
- 'subscriber' => 'read',
- );
- /**
- * Map of modules that have conflicts with plugins and should not be auto-activated
- * if the plugins are active. Used by filter_default_modules
- *
- * Plugin Authors: If you'd like to prevent a single module from auto-activating,
- * change `module-slug` and add this to your plugin:
- *
- * add_filter( 'jetpack_get_default_modules', 'my_jetpack_get_default_modules' );
- * function my_jetpack_get_default_modules( $modules ) {
- * return array_diff( $modules, array( 'module-slug' ) );
- * }
- *
- * @var array
- */
- private $conflicting_plugins = array(
- 'comments' => array(
- 'Intense Debate' => 'intensedebate/intensedebate.php',
- 'Disqus' => 'disqus-comment-system/disqus.php',
- 'Livefyre' => 'livefyre-comments/livefyre.php',
- 'Comments Evolved for WordPress' => 'gplus-comments/comments-evolved.php',
- 'Google+ Comments' => 'google-plus-comments/google-plus-comments.php',
- ),
- 'contact-form' => array(
- 'Contact Form 7' => 'contact-form-7/wp-contact-form-7.php',
- 'Gravity Forms' => 'gravityforms/gravityforms.php',
- 'Contact Form Plugin' => 'contact-form-plugin/contact_form.php',
- 'Easy Contact Forms' => 'easy-contact-forms/easy-contact-forms.php',
- 'Fast Secure Contact Form' => 'si-contact-form/si-contact-form.php',
- ),
- 'gplus-authorship' => array(
- 'WP SEO by Yoast' => 'wordpress-seo/wp-seo.php',
- ),
- 'minileven' => array(
- 'WPtouch' => 'wptouch/wptouch.php',
- ),
- 'latex' => array(
- 'LaTeX for WordPress' => 'latex/latex.php',
- 'Youngwhans Simple Latex' => 'youngwhans-simple-latex/yw-latex.php',
- 'Easy WP LaTeX' => 'easy-wp-latex-lite/easy-wp-latex-lite.php',
- 'MathJax-LaTeX' => 'mathjax-latex/mathjax-latex.php',
- 'Enable Latex' => 'enable-latex/enable-latex.php',
- 'WP QuickLaTeX' => 'wp-quicklatex/wp-quicklatex.php',
- ),
- 'random-redirect' => array(
- 'Random Redirect 2' => 'random-redirect-2/random-redirect.php',
- ),
- 'related-posts' => array(
- 'YARPP' => 'yet-another-related-posts-plugin/yarpp.php',
- 'WordPress Related Posts' => 'wordpress-23-related-posts-plugin/wp_related_posts.php',
- 'nrelate Related Content' => 'nrelate-related-content/nrelate-related.php',
- 'Contextual Related Posts' => 'contextual-related-posts/contextual-related-posts.php',
- 'Related Posts for WordPress' => 'microkids-related-posts/microkids-related-posts.php',
- 'outbrain' => 'outbrain/outbrain.php',
- 'Shareaholic' => 'shareaholic/shareaholic.php',
- 'Sexybookmarks' => 'sexybookmarks/shareaholic.php',
- ),
- 'sharedaddy' => array(
- 'AddThis' => 'addthis/addthis_social_widget.php',
- 'Add To Any' => 'add-to-any/add-to-any.php',
- 'ShareThis' => 'share-this/sharethis.php',
- 'Shareaholic' => 'shareaholic/shareaholic.php',
- ),
- 'verification-tools' => array(
- 'WordPress SEO by Yoast' => 'wordpress-seo/wp-seo.php',
- 'WordPress SEO Premium by Yoast' => 'wordpress-seo-premium/wp-seo-premium.php',
- 'All in One SEO Pack' => 'all-in-one-seo-pack/all_in_one_seo_pack.php',
- ),
- 'widget-visibility' => array(
- 'Widget Logic' => 'widget-logic/widget_logic.php',
- 'Dynamic Widgets' => 'dynamic-widgets/dynamic-widgets.php',
- ),
- );
- /**
- * Plugins for which we turn off our Facebook OG Tags implementation.
- */
- private $open_graph_conflicting_plugins = array(
- 'facebook/facebook.php', // Official Facebook plugin
- 'wordpress-seo/wp-seo.php', // WordPress SEO by Yoast
- 'add-link-to-facebook/add-link-to-facebook.php', // Add Link to Facebook
- 'facebook-awd/AWD_facebook.php', // Facebook AWD All in one
- 'header-footer/plugin.php', // Header and Footer
- 'nextgen-facebook/nextgen-facebook.php', // NextGEN Facebook OG
- 'seo-facebook-comments/seofacebook.php', // SEO Facebook Comments
- 'seo-ultimate/seo-ultimate.php', // SEO Ultimate
- 'sexybookmarks/sexy-bookmarks.php', // Shareaholic
- 'shareaholic/sexy-bookmarks.php', // Shareaholic
- 'social-discussions/social-discussions.php', // Social Discussions
- 'social-networks-auto-poster-facebook-twitter-g/NextScripts_SNAP.php',
- // NextScripts SNAP
- 'wordbooker/wordbooker.php', // Wordbooker
- 'socialize/socialize.php', // Socialize
- 'simple-facebook-connect/sfc.php', // Simple Facebook Connect
- 'social-sharing-toolkit/social_sharing_toolkit.php', // Social Sharing Toolkit
- 'wp-facebook-open-graph-protocol/wp-facebook-ogp.php', // WP Facebook Open Graph protocol
- 'opengraph/opengraph.php', // Open Graph
- 'sharepress/sharepress.php', // SharePress
- 'wp-facebook-like-send-open-graph-meta/wp-facebook-like-send-open-graph-meta.php',
- // WP Facebook Like Send & Open Graph Meta
- 'network-publisher/networkpub.php', // Network Publisher
- 'wp-ogp/wp-ogp.php', // WP-OGP
- 'open-graph-protocol-framework/open-graph-protocol-framework.php',
- // Open Graph Protocol Framework
- 'all-in-one-seo-pack/all_in_one_seo_pack.php', // All in One SEO Pack
- 'facebook-featured-image-and-open-graph-meta-tags/fb-featured-image.php',
- // Facebook Featured Image & OG Meta Tags
- 'add-meta-tags/add-meta-tags.php', // Add Meta Tags
- 'only-tweet-like-share-and-google-1/tweet-like-plusone.php',
- // Tweet, Like, Google +1 and Share
- 'easy-facebook-share-thumbnails/esft.php', // Easy Facebook Share Thumbnail
- '2-click-socialmedia-buttons/2-click-socialmedia-buttons.php',
- // 2 Click Social Media Buttons
- 'facebook-thumb-fixer/_facebook-thumb-fixer.php', // Facebook Thumb Fixer
- 'zoltonorg-social-plugin/zosp.php', // Zolton.org Social Plugin
- 'wp-caregiver/wp-caregiver.php', // WP Caregiver
- 'facebook-revised-open-graph-meta-tag/index.php', // Facebook Revised Open Graph Meta Tag
- 'facebook-and-digg-thumbnail-generator/facebook-and-digg-thumbnail-generator.php',
- // Fedmich's Facebook Open Graph Meta
- 'facebook-meta-tags/facebook-metatags.php', // Facebook Meta Tags
- 'wordpress-seo-premium/wp-seo-premium.php', // WordPress SEO Premium by Yoast
- );
- /**
- * Plugins for which we turn off our Twitter Cards Tags implementation.
- */
- private $twitter_cards_conflicting_plugins = array(
- 'twitter-cards/twitter-cards.php', // Twitter Cards
- 'twitter-cards-meta/twitter-cards-meta.php', // Twitter Cards Meta
- 'ig-twitter-cards/ig-twitter-cards.php', // IG:Twitter Cards
- 'jm-twitter-cards/jm-twitter-cards.php', // JM Twitter Cards
- 'wp-twitter-cards/twitter_cards.php', // WP Twitter Cards
- 'eewee-twitter-card/index.php', // Eewee Twitter Card
- 'kevinjohn-gallagher-pure-web-brilliants-social-graph-twitter-cards-extention/kevinjohn_gallagher___social_graph_twitter_output.php',
- // Pure Web Brilliant's Social Graph Twitter Cards Extension
- );
- /**
- * Message to display in admin_notice
- * @var string
- */
- var $message = '';
- /**
- * Error to display in admin_notice
- * @var string
- */
- var $error = '';
- /**
- * Modules that need more privacy description.
- * @var string
- */
- var $privacy_checks = '';
- /**
- * Stats to record once the page loads
- *
- * @var array
- */
- var $stats = array();
- /**
- * Jetpack_Sync object
- */
- var $sync;
- /**
- * Verified data for JSON authorization request
- */
- var $json_api_authorization_request = array();
- /**
- * Holds the singleton instance of this class
- * @since 2.3.3
- * @var Jetpack
- */
- static $instance = false;
- /**
- * Singleton
- * @static
- */
- public static function init() {
- if ( ! self::$instance ) {
- if ( did_action( 'plugins_loaded' ) )
- self::plugin_textdomain();
- else
- add_action( 'plugins_loaded', array( __CLASS__, 'plugin_textdomain' ) );
- self::$instance = new Jetpack;
- self::$instance->plugin_upgrade();
- }
- return self::$instance;
- }
- /**
- * Must never be called statically
- */
- function plugin_upgrade() {
- // Upgrade: 1.1 -> 1.2
- if ( get_option( 'jetpack_id' ) ) {
- // Move individual jetpack options to single array of options
- $options = array();
- foreach ( Jetpack_Options::get_option_names() as $option ) {
- if ( false !== $value = get_option( "jetpack_$option" ) ) {
- $options[$option] = $value;
- }
- }
- if ( $options ) {
- Jetpack_Options::update_options( $options );
- foreach ( array_keys( $options ) as $option ) {
- delete_option( "jetpack_$option" );
- }
- }
- // Add missing version and old_version options
- if ( ! $version = Jetpack_Options::get_option( 'version' ) ) {
- $version = $old_version = '1.1:' . time();
- Jetpack_Options::update_options( compact( 'version', 'old_version' ) );
- }
- }
- // Upgrade from a single user token to a user_id-indexed array and a master_user ID
- if ( ! Jetpack_Options::get_option( 'user_tokens' ) ) {
- if ( $user_token = Jetpack_Options::get_option( 'user_token' ) ) {
- $token_parts = explode( '.', $user_token );
- if ( isset( $token_parts[2] ) ) {
- $master_user = $token_parts[2];
- $user_tokens = array( $master_user => $user_token );
- Jetpack_Options::update_options( compact( 'master_user', 'user_tokens' ) );
- Jetpack_Options::delete_option( 'user_token' );
- } else {
- // @todo: is this even possible?
- trigger_error( sprintf( 'Jetpack::plugin_upgrade found no user_id in user_token "%s"', $user_token ), E_USER_WARNING );
- }
- }
- }
- }
- /**
- * Constructor. Initializes WordPress hooks
- */
- private function Jetpack() {
- /**
- * Do things that should run even in the network admin
- * here, before we potentially fail out.
- */
- add_filter( 'jetpack_require_lib_dir', array( $this, 'require_lib_dir' ) );
- /*
- * Load things that should only be in Network Admin.
- *
- * For now blow away everything else until a more full
- * understanding of what is needed at the network level is
- * available
- */
- if( is_multisite() ) {
- Jetpack_Network::init();
- if( is_network_admin() )
- return; // End here to prevent single site actions from firing
- }
- $this->sync = new Jetpack_Sync;
- // Modules should do Jetpack_Sync::sync_options( __FILE__, $option, ... ); instead
- // We access the "internal" method here only because the Jetpack object isn't instantiated yet
- $this->sync->options(
- JETPACK__PLUGIN_DIR . 'jetpack.php',
- 'home',
- 'siteurl',
- 'blogname',
- 'gmt_offset',
- 'timezone_string'
- );
- if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST && isset( $_GET['for'] ) && 'jetpack' == $_GET['for'] ) {
- @ini_set( 'display_errors', false ); // Display errors can cause the XML to be not well formed.
- require_once JETPACK__PLUGIN_DIR . 'class.jetpack-xmlrpc-server.php';
- $this->xmlrpc_server = new Jetpack_XMLRPC_Server();
- $this->require_jetpack_authentication();
- if ( Jetpack::is_active() ) {
- // Hack to preserve $HTTP_RAW_POST_DATA
- add_filter( 'xmlrpc_methods', array( $this, 'xmlrpc_methods' ) );
- $signed = $this->verify_xml_rpc_signature();
- if ( $signed && ! is_wp_error( $signed ) ) {
- // The actual API methods.
- add_filter( 'xmlrpc_methods', array( $this->xmlrpc_server, 'xmlrpc_methods' ) );
- } else {
- add_filter( 'xmlrpc_methods', '__return_empty_array' );
- }
- } else {
- // The bootstrap API methods.
- add_filter( 'xmlrpc_methods', array( $this->xmlrpc_server, 'bootstrap_xmlrpc_methods' ) );
- }
- // Now that no one can authenticate, and we're whitelisting all XML-RPC methods, force enable_xmlrpc on.
- add_filter( 'pre_option_enable_xmlrpc', '__return_true' );
- } elseif ( is_admin() && isset( $_POST['action'] ) && 'jetpack_upload_file' == $_POST['action'] ) {
- $this->require_jetpack_authentication();
- $this->add_remote_request_handlers();
- } else {
- if ( Jetpack::is_active() ) {
- add_action( 'login_form_jetpack_json_api_authorization', array( &$this, 'login_form_json_api_authorization' ) );
- }
- }
- if ( Jetpack::is_active() ) {
- Jetpack_Heartbeat::init();
- }
- add_action( 'jetpack_clean_nonces', array( 'Jetpack', 'clean_nonces' ) );
- if ( ! wp_next_scheduled( 'jetpack_clean_nonces' ) ) {
- wp_schedule_event( time(), 'hourly', 'jetpack_clean_nonces' );
- }
- add_filter( 'xmlrpc_blog_options', array( $this, 'xmlrpc_options' ) );
- add_action( 'admin_menu', array( $this, 'admin_menu' ), 999 ); // run late so that other plugins hooking into this menu don't get left out
- add_action( 'admin_init', array( $this, 'admin_init' ) );
- add_action( 'admin_init', array( $this, 'dismiss_jetpack_notice' ) );
- add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
- add_action( 'wp_ajax_jetpack-check-news-subscription', array( $this, 'check_news_subscription' ) );
- add_action( 'wp_ajax_jetpack-subscribe-to-news', array( $this, 'subscribe_to_news' ) );
- add_action( 'wp_ajax_jetpack-sync-reindex-trigger', array( $this, 'sync_reindex_trigger' ) );
- add_action( 'wp_ajax_jetpack-sync-reindex-status', array( $this, 'sync_reindex_status' ) );
- add_action( 'wp_loaded', array( $this, 'register_assets' ) );
- add_action( 'wp_enqueue_scripts', array( $this, 'devicepx' ) );
- add_action( 'customize_controls_enqueue_scripts', array( $this, 'devicepx' ) );
- add_action( 'admin_enqueue_scripts', array( $this, 'devicepx' ) );
- // add_action( 'jetpack_admin_menu', array( $this, 'admin_menu_modules' ) );
- add_action( 'jetpack_activate_module', array( $this, 'activate_module_actions' ) );
- add_action( 'plugins_loaded', array( $this, 'extra_oembed_providers' ) );
- /**
- * These actions run checks to load additional files.
- * They check for external files or plugins, so they need to run as late as possible.
- */
- add_action( 'wp_head', array( $this, 'check_open_graph' ), 1 );
- add_action( 'plugins_loaded', array( $this, 'check_twitter_tags' ), 999 );
- add_action( 'plugins_loaded', array( $this, 'check_rest_api_compat' ), 1000 );
- add_filter( 'map_meta_cap', array( $this, 'jetpack_custom_caps' ), 1, 4 );
- add_filter( 'jetpack_get_default_modules', array( $this, 'filter_default_modules' ) );
- add_filter( 'jetpack_get_default_modules', array( $this, 'handle_deprecated_modules' ), 99 );
- }
- /**
- * If there are any stats that need to be pushed, but haven't been, push them now.
- */
- function __destruct() {
- if ( ! empty( $this->stats ) ) {
- $this->do_stats( 'server_side' );
- }
- }
- function jetpack_custom_caps( $caps, $cap, $user_id, $args ) {
- switch( $cap ) {
- case 'jetpack_connect' :
- case 'jetpack_reconnect' :
- if ( Jetpack::is_development_mode() ) {
- $caps = array( 'do_not_allow' );
- break;
- }
- /**
- * Pass through. If it's not development mode, these should match disconnect.
- * Let users disconnect if it's development mode, just in case things glitch.
- */
- case 'jetpack_disconnect' :
- /**
- * In multisite, can individual site admins manage their own connection?
- *
- * Ideally, this should be extracted out to a separate filter in the Jetpack_Network class.
- */
- if ( is_multisite() && ! is_super_admin() && is_plugin_active_for_network( 'jetpack/jetpack.php' ) ) {
- if ( ! Jetpack_Network::init()->get_option( 'sub-site-connection-override' ) ) {
- /**
- * We need to update the option name -- it's terribly unclear which
- * direction the override goes.
- *
- * @todo: Update the option name to `sub-sites-can-manage-own-connections`
- */
- $caps = array( 'do_not_allow' );
- break;
- }
- }
- $caps = array( 'manage_options' );
- break;
- case 'jetpack_manage_modules' :
- case 'jetpack_activate_modules' :
- case 'jetpack_deactivate_modules' :
- $caps = array( 'manage_options' );
- break;
- case 'jetpack_configure_modules' :
- $caps = array( 'manage_options' );
- break;
- case 'jetpack_admin_page' :
- if ( Jetpack::is_development_mode() ) {
- $caps = array( 'manage_options' );
- break;
- }
- /**
- * Pass through. If it's not development mode, these should match the admin page.
- * Let users disconnect if it's development mode, just in case things glitch.
- */
- case 'jetpack_connect_user' :
- if ( Jetpack::is_development_mode() ) {
- $caps = array( 'do_not_allow' );
- break;
- }
- $caps = array( 'read' );
- break;
- }
- return $caps;
- }
- function require_jetpack_authentication() {
- // Don't let anyone authenticate
- $_COOKIE = array();
- remove_all_filters( 'authenticate' );
- /**
- * For the moment, remove Limit Login Attempts if its xmlrpc for Jetpack.
- * If Limit Login Attempts is installed as a mu-plugin, it can occasionally
- * generate false-positives.
- */
- remove_filter( 'wp_login_failed', 'limit_login_failed' );
- if ( Jetpack::is_active() ) {
- // Allow Jetpack authentication
- add_filter( 'authenticate', array( $this, 'authenticate_jetpack' ), 10, 3 );
- }
- }
- /**
- * Load language files
- */
- public static function plugin_textdomain() {
- load_plugin_textdomain( 'jetpack', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
- }
- /**
- * Register assets for use in various modules and the Jetpack admin page.
- *
- * @uses wp_script_is, wp_register_script, plugins_url
- * @action wp_loaded
- * @return null
- */
- public function register_assets() {
- if ( ! wp_script_is( 'spin', 'registered' ) )
- wp_register_script( 'spin', plugins_url( '_inc/spin.js', __FILE__ ), false, '1.3' );
- if ( ! wp_script_is( 'jquery.spin', 'registered' ) )
- wp_register_script( 'jquery.spin', plugins_url( '_inc/jquery.spin.js', __FILE__ ) , array( 'jquery', 'spin' ), '1.3' );
- if ( ! wp_script_is( 'jetpack-gallery-settings', 'registered' ) )
- wp_register_script( 'jetpack-gallery-settings', plugins_url( '_inc/gallery-settings.js', __FILE__ ), array( 'media-views' ), '20121225' );
- /**
- * As jetpack_register_genericons is by default fired off a hook,
- * the hook may have already fired by this point.
- * So, let's just trigger it manually.
- */
- require_once( JETPACK__PLUGIN_DIR . '_inc/genericons.php' );
- jetpack_register_genericons();
- if ( ! wp_style_is( 'jetpack-icons', 'registered' ) )
- wp_register_style( 'jetpack-icons', plugins_url( '_inc/jetpack-icons/jetpack-icons.css', __FILE__ ), false, JETPACK__VERSION );
- }
- /**
- * Device Pixels support
- * This improves the resolution of gravatars and wordpress.com uploads on hi-res and zoomed browsers.
- */
- function devicepx() {
- if ( Jetpack::is_active() ) {
- wp_enqueue_script( 'devicepx', set_url_scheme( 'http://s0.wp.com/wp-content/js/devicepx-jetpack.js' ), array(), gmdate( 'oW' ), true );
- }
- }
- /*
- * Returns the location of Jetpack's lib directory. This filter is applied
- * in require_lib().
- *
- * @filter require_lib_dir
- */
- function require_lib_dir( $lib_dir ) {
- return JETPACK__PLUGIN_DIR . '_inc/lib';
- }
- /**
- * Is Jetpack active?
- */
- public static function is_active() {
- return (bool) Jetpack_Data::get_access_token( JETPACK_MASTER_USER );
- }
- /**
- * Is Jetpack in development (offline) mode?
- */
- public static function is_development_mode() {
- $development_mode = false;
- if ( defined( 'JETPACK_DEV_DEBUG' ) ) {
- $development_mode = JETPACK_DEV_DEBUG;
- }
- elseif ( site_url() && false === strpos( site_url(), '.' ) ) {
- $development_mode = true;
- }
- return apply_filters( 'jetpack_development_mode', $development_mode );
- }
- /**
- * Is a given user (or the current user if none is specified) linked to a WordPress.com user?
- */
- public static function is_user_connected( $user_id = false ) {
- $user_id = false === $user_id ? get_current_user_id() : absint( $user_id );
- if ( ! $user_id ) {
- return false;
- }
- return (bool) Jetpack_Data::get_access_token( $user_id );
- }
- /**
- * Get the wpcom email of the current connected user.
- */
- public static function get_connected_user_email() {
- Jetpack::load_xml_rpc_client();
- $xml = new Jetpack_IXR_Client( array(
- 'user_id' => get_current_user_id()
- ) );
- $xml->query( 'wpcom.getUserEmail' );
- if ( ! $xml->isError() ) {
- return $xml->getResponse();
- }
- return false;
- }
- function current_user_is_connection_owner() {
- $user_token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER );
- return $user_token && is_object( $user_token ) && isset( $user_token->external_user_id ) && get_current_user_id() === $user_token->external_user_id;
- }
- /**
- * Add any extra oEmbed providers that we know about and use on wpcom for feature parity.
- */
- function extra_oembed_providers() {
- // Cloudup: https://dev.cloudup.com/#oembed
- wp_oembed_add_provider( 'https://cloudup.com/*' , 'https://cloudup.com/oembed' );
- }
- /**
- * Synchronize connected user role changes
- */
- function user_role_change( $user_id ) {
- if ( Jetpack::is_active() && Jetpack::is_user_connected( $user_id ) ) {
- $current_user_id = get_current_user_id();
- wp_set_current_user( $user_id );
- $role = $this->translate_current_user_to_role();
- $signed_role = $this->sign_role( $role );
- wp_set_current_user( $current_user_id );
- $master_token = Jetpack_Data::get_access_token( JETPACK_MASTER_USER );
- $master_user_id = absint( $master_token->external_user_id );
- if ( ! $master_user_id )
- return; // this shouldn't happen
- Jetpack::xmlrpc_async_call( 'jetpack.updateRole', $user_id, $signed_role );
- //@todo retry on failure
- //try to choose a new master if we're demoting the current one
- if ( $user_id == $master_user_id && 'administrator' != $role ) {
- $query = new WP_User_Query(
- array(
- 'fields' => array( 'id' ),
- 'role' => 'administrator',
- 'orderby' => 'id',
- 'exclude' => array( $master_user_id ),
- )
- );
- $new_master = false;
- foreach ( $query->results as $result ) {
- $uid = absint( $result->id );
- if ( $uid && Jetpack::is_user_connected( $uid ) ) {
- $new_master = $uid;
- break;
- }
- }
- if ( $new_master ) {
- Jetpack_Options::update_option( 'master_user', $new_master );
- }
- // else disconnect..?
- }
- }
- }
- /**
- * Loads the currently active modules.
- */
- public static function load_modules() {
- /*
- if ( ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) {
- return;
- }
- */
- $version = Jetpack_Options::get_option( 'version' );
- if ( ! $version ) {
- $version = $old_version = JETPACK__VERSION . ':' . time();
- Jetpack_Options::update_options( compact( 'version', 'old_version' ) );
- }
- list( $version ) = explode( ':', $version );
- $modules = array_filter( Jetpack::get_active_modules(), array( 'Jetpack', 'is_module' ) );
- $modules_data = array();
- // Don't load modules that have had "Major" changes since the stored version until they have been deactivated/reactivated through the lint check.
- if ( version_compare( $version, JETPACK__VERSION, '<' ) ) {
- $updated_modules = array();
- foreach ( $modules as $module ) {
- $modules_data[ $module ] = Jetpack::get_module( $module );
- if ( ! isset( $modules_data[ $module ]['changed'] ) ) {
- continue;
- }
- if ( version_compare( $modules_data[ $module ]['changed'], $version, '<=' ) ) {
- continue;
- }
- $updated_modules[] = $module;
- }
- $modules = array_diff( $modules, $updated_modules );
- }
- foreach ( $modules as $module ) {
- // If not connected and we're in dev mode, disable modules requiring a connection
- if ( ! Jetpack::is_active() ) {
- if ( empty( $modules_data[ $module ] ) ) {
- $modules_data[ $module ] = Jetpack::get_module( $module );
- }
- if ( $modules_data[ $module ]['requires_connection'] || ! Jetpack::is_development_mode() ) {
- continue;
- }
- }
- if ( did_action( 'jetpack_module_loaded_' . $module ) ) {
- continue;
- }
- require Jetpack::get_module_path( $module );
- do_action( 'jetpack_module_loaded_' . $module );
- }
- do_action( 'jetpack_modules_loaded' );
- // Load module-specific code that is needed even when a module isn't active. Loaded here because code contained therein may need actions such as setup_theme.
- if ( Jetpack::is_active() || Jetpack::is_development_mode() )
- require_once( JETPACK__PLUGIN_DIR . 'modules/module-extras.php' );
- }
- /**
- * Check if Jetpack's REST API compat file should be included
- * @action plugins_loaded
- * @return null
- */
- public function check_rest_api_compat() {
- $_jetpack_rest_api_compat_includes = apply_filters( 'jetpack_rest_api_compat', array() );
- if ( function_exists( 'bbpress' ) )
- $_jetpack_rest_api_compat_includes[] = JETPACK__PLUGIN_DIR . 'class.jetpack-bbpress-json-api-compat.php';
- foreach ( $_jetpack_rest_api_compat_includes as $_jetpack_rest_api_compat_include )
- require_once $_jetpack_rest_api_compat_include;
- }
- /**
- * Gets all plugins currently active in values, regardless of whether they're
- * traditionally activated or network activated.
- *
- * @todo Store the result in core's object cache maybe?
- */
- public static function get_active_plugins() {
- $active_plugins = (array) get_option( 'active_plugins', array() );
- if ( is_multisite() ) {
- // Due to legacy code, active_sitewide_plugins stores them in the keys,
- // whereas active_plugins stores them in the values.
- $network_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
- if ( $network_plugins ) {
- $active_plugins = array_merge( $active_plugins, $network_plugins );
- }
- }
- sort( $active_plugins );
- return $active_plugins;
- }
- /**
- * Checks whether a specific plugin is active.
- *
- * We don't want to store these in a static variable, in case
- * there are switch_to_blog() calls involved.
- */
- public static function is_plugin_active( $plugin = 'jetpack/jetpack.php' ) {
- return in_array( $plugin, self::get_active_plugins() );
- }
- /**
- * Check if Jetpack's Open Graph tags should be used.
- * If certain plugins are active, Jetpack's og tags are suppressed.
- *
- * @uses Jetpack::get_active_modules, add_filter, get_option, apply_filters
- * @action plugins_loaded
- * @return null
- */
- public function check_open_graph() {
- if ( in_array( 'publicize', Jetpack::get_active_modules() ) || in_array( 'sharedaddy', Jetpack::get_active_modules() ) ) {
- add_filter( 'jetpack_enable_open_graph', '__return_true', 0 );
- }
- $active_plugins = self::get_active_plugins();
- if ( ! empty( $active_plugins ) ) {
- foreach ( $this->open_graph_conflicting_plugins as $plugin ) {
- if ( in_array( $plugin, $active_plugins ) ) {
- add_filter( 'jetpack_enable_open_graph', '__return_false', 99 );
- break;
- }
- }
- }
- if ( apply_filters( 'jetpack_enable_open_graph', false ) ) {
- require_once JETPACK__PLUGIN_DIR . 'functions.opengraph.php';
- }
- }
- /**
- * Check if Jetpack's Twitter tags should be used.
- * If certain plugins are active, Jetpack's twitter tags are suppressed.
- *
- * @uses Jetpack::get_active_modules, add_filter, get_option, apply_filters
- * @action plugins_loaded
- * @return null
- */
- public function check_twitter_tags() {
- $active_plugins = self::get_active_plugins();
- if ( ! empty( $active_plugins ) ) {
- foreach ( $this->twitter_cards_conflicting_plugins as $plugin ) {
- if ( in_array( $plugin, $active_plugins ) ) {
- add_filter( 'jetpack_disable_twitter_cards', '__return_true', 99 );
- break;
- }
- }
- }
- if ( apply_filters( 'jetpack_disable_twitter_cards', true ) ) {
- require_once JETPACK__PLUGIN_DIR . 'class.jetpack-twitter-cards.php';
- }
- }
- /* Jetpack Options API */
- public static function get_option_names( $type = 'compact' ) {
- return Jetpack_Options::get_option_names( $type );
- }
- /**
- * Returns the requested option. Looks in jetpack_options or jetpack_$name as appropriate.
- *
- * @param string $name Option name
- * @param mixed $default (optional)
- */
- public static function get_option( $name, $default = false ) {
- return Jetpack_Options::get_option( $name, $default );
- }
- /**
- * Stores two secrets and a timestamp so WordPress.com can make a request back and verify an action
- * Does some extra verification so urls (such as those to public-api, register, etc) can't just be crafted
- * $name must be a registered option name.
- */
- public static function create_nonce( $name ) {
- $secret = wp_generate_password( 32, false ) . ':' . wp_generate_password( 32, false ) . ':' . ( time() + 600 );
- Jetpack_Options::update_option( $name, $secret );
- @list( $secret_1, $secret_2, $eol ) = explode( ':', Jetpack_Options::get_option( $name ) );
- if ( empty( $secret_1 ) || empty( $secret_2 ) || $eol < time() )
- return new Jetpack_Error( 'missing_secrets' );
- return array(
- 'secret_1' => $secret_1,
- 'secret_2' => $secret_2,
- 'eol' => $eol,
- );
- }
- /**
- * Updates the single given option. Updates jetpack_options or jetpack_$name as appropriate.
- *
- * @param string $name Option name
- * @param mixed $value Option value
- */
- public static function update_option( $name, $value ) {
- return Jetpack_Options::update_option( $name, $value );
- }
- /**
- * Updates the multiple given options. Updates jetpack_options and/or jetpack_$name as appropriate.
- *
- * @param array $array array( option name => option value, ... )
- */
- public static function update_options( $array ) {
- return Jetpack_Options::update_options( $array );
- }
- /**
- * Deletes the given option. May be passed multiple option names as an array.
- * Updates jetpack_options and/or deletes jetpack_$name as appropriate.
- *
- * @param string|array $names
- */
- public static function delete_option( $names ) {
- return Jetpack_Options::delete_option( $names );
- }
- /**
- * Enters a user token into the user_tokens option
- *
- * @param int $user_id
- * @param string $token
- * return bool
- */
- public static function update_user_token( $user_id, $token, $is_master_user ) {
- // not designed for concurrent updates
- $user_tokens = Jetpack_Options::get_option( 'user_tokens' );
- if ( ! is_array( $user_tokens ) )
- $user_tokens = array();
- $user_tokens[$user_id] = $token;
- if ( $is_master_user ) {
- $master_user = $user_id;
- $options = compact( 'user_tokens', 'master_user' );
- } else {
- $options = compact( 'user_tokens' );
- }
- return Jetpack_Options::update_options( $options );
- }
- /**
- * Returns an array of all PHP files in the specified absolute path.
- * Equivalent to glob( "$absolute_path/*.php" ).
- *
- * @param string $absolute_path The absolute path of the directory to search.
- * @return array Array of absolute paths to the PHP files.
- */
- public static function glob_php( $absolute_path ) {
- $absolute_path = untrailingslashit( $absolute_path );
- $files = array();
- if ( ! $dir = @opendir( $absolute_path ) ) {
- return $files;
- }
- while ( false !== $file = readdir( $dir ) ) {
- if ( '.' == substr( $file, 0, 1 ) || '.php' != substr( $file, -4 ) ) {
- continue;
- }
- $file = "$absolute_path/$file";
- if ( ! is_file( $file ) ) {
- continue;
- }
- $files[] = $file;
- }
- closedir( $dir );
- return $files;
- }
- public function activate_new_modules() {
- if ( ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) {
- return;
- }
- $jetpack_old_version = Jetpack_Options::get_option( 'version' ); // [sic]
- if ( ! $jetpack_old_version ) {
- $jetpack_old_version = $version = $old_version = '1.1:' . time();
- Jetpack_Options::update_options( compact( 'version', 'old_version' ) );
- }
- list( $jetpack_version ) = explode( ':', $jetpack_old_version ); // [sic]
- if ( version_compare( JETPACK__VERSION, $jetpack_version, '<=' ) ) {
- return;
- }
- $active_modules = Jetpack::get_active_modules();
- $reactivate_modules = array();
- foreach ( $active_modules as $active_module ) {
- $module = Jetpack::get_module( $active_module );
- if ( ! isset( $module['changed'] ) ) {
- continue;
- }
- if ( version_compare( $module['changed'], $jetpack_version, '<=' ) ) {
- continue;
- }
- $reactivate_modules[] = $active_module;
- Jetpack::deactivate_module( $active_module );
- }
- if ( version_compare( $jetpack_version, '1.9.2', '<' ) && version_compare( '1.9-something', JETPACK__VERSION, '<' ) ) {
- add_action( 'jetpack_activate_default_modules', array( $this->sync, 'sync_all_registered_options' ), 1000 );
- }
- Jetpack_Options::update_options(
- array(
- 'version' => JETPACK__VERSION . ':' . time(),
- 'old_version' => $jetpack_old_version,
- )
- );
- Jetpack::state( 'message', 'modules_activated' );
- Jetpack::activate_default_modules( $jetpack_version, JETPACK__VERSION, $reactivate_modules );
- wp_safe_redirect( Jetpack::admin_url( 'page=jetpack' ) );
- exit;
- }
- /**
- * List available Jetpack modules. Simply lists .php files in /modules/.
- * Make sure to tuck away module "library" files in a sub-directory.
- */
- public static function get_available_modules( $min_version = false, $max_version = false ) {
- static $modules = null;
- if ( ! isset( $modules ) ) {
- $files = Jetpack::glob_php( JETPACK__PLUGIN_DIR . 'modules' );
- $modules = array();
- foreach ( $files as $file ) {
- if ( ! $headers = Jetpack::get_module( $file ) ) {
- continue;
- }
- $modules[ Jetpack::get_module_slug( $file ) ] = $headers['introduced'];
- }
- }
- $modules = apply_filters( 'jetpack_get_available_modules', $modules, $min_version, $max_version );
- if ( ! $min_version && ! $max_version ) {
- return array_keys( $modules );
- }
- $r = array();
- foreach ( $modules as $slug => $introduced ) {
- if ( $min_version && version_compare( $min_version, $introduced, '>=' ) ) {
- continue;
- }
- if ( $max_version && version_compare( $max_version, $introduced, '<' ) ) {
- continue;
- }
- $r[] = $slug;
- }
- return $r;
- }
- /**
- * Default modules loaded on activation.
- */
- public static function get_default_modules( $min_version = false, $max_version = false ) {
- $return = array();
- foreach ( Jetpack::get_available_modules( $min_version, $max_version ) as $module ) {
- $module_data = Jetpack::get_module( $module );
- switch ( strtolower( $module_data['auto_activate'] ) ) {
- case 'yes' :
- $return[] = $module;
- break;
- case 'public' :
- if ( Jetpack_Options::get_option( 'public' ) ) {
- $return[] = $module;
- }
- break;
- case 'no' :
- default :
- break;
- }
- }
- return apply_filters( 'jetpack_get_default_modules', $return, $min_version, $max_version );
- }
- /**
- * Checks activated modules during auto-activation to determine
- * if any of those modules are being deprecated. If so, close
- * them out, and add any replacement modules.
- *
- * Runs at priority 99 by default.
- *
- * This is run late, so that it can still activate a module if
- * the new module is a replacement for another that the user
- * currently has active, even if something at the normal priority
- * would kibosh everything.
- *
- * @since 2.6
- * @uses jetpack_get_default_modules filter
- * @param array $modules
- * @return array
- */
- function handle_deprecated_modules( $modules ) {
- $deprecated_modules = array(
- 'debug' => null, // Closed out and moved to ./class.jetpack-debugger.php
- 'wpcc' => 'sso', // Closed out in 2.6 -- SSO provides the same functionality.
- );
- // Don't activate SSO if they never completed activating WPCC.
- if ( Jetpack::is_module_active( 'wpcc' ) ) {
- $wpcc_options = Jetpack_Options::get_option( 'wpcc_options' );
- if ( empty( $wpcc_options ) || empty( $wpcc_options['client_id'] ) || empty( $wpcc_options['client_id'] ) ) {
- $deprecated_modules['wpcc'] = null;
- }
- }
- foreach ( $deprecated_modules as $module => $replacement ) {
- if ( Jetpack::is_module_active( $module ) ) {
- self::deactivate_module( $module );
- if ( $replacement ) {
- $modules[] = $replacement;
- }
- }
- }
- return array_unique( $modules );
- }
- /**
- * Checks activated plugins during auto-activation to determine
- * if any of those plugins are in the list with a corresponding module
- * that is not compatible with the plugin. The module will not be allowed
- * to auto-activate.
- *
- * @since 2.6
- * @uses jetpack_get_default_modules filter
- * @param array $modules
- * @return array
- */
- function filter_default_modules( $modules ) {
- $active_plugins = self::get_active_plugins();
- if ( ! empty( $active_plugins ) ) {
- // For each module we'd like to auto-activate...
- foreach ( $modules as $key => $module ) {
- // If there are potential conflicts for it...
- if ( ! empty( $this->conflicting_plugins[ $module ] ) ) {
- // For each potential conflict...
- foreach ( $this->conflicting_plugins[ $module ] as $title => $plugin ) {
- // If that conflicting plugin is active...
- if ( in_array( $plugin, $active_plugins ) ) {
- // Remove that item from being auto-activated.
- unset( $modules[ $key ] );
- }
- }
- }
- }
- }
- return $modules;
- }
- /**
- * Extract a module's slug from its full path.
- */
- public static function get_module_slug( $file ) {
- return str_replace( '.php', '', basename( $file ) );
- }
- /**
- * Generate a module's path from its slug.
- */
- public static function get_module_path( $slug ) {
- return JETPACK__PLUGIN_DIR . "modules/$slug.php";
- }
- /**
- * 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',
- 'sort' => 'Sort Order',
- 'introduced' => 'First Introduced',
- 'changed' => 'Major Changes In',
- 'deactivate' => 'Deactivate',
- 'free' => 'Free',
- 'requires_connection' => 'Requires Connection',
- 'auto_activate' => 'Auto Activate',
- 'module_tags' => 'Module Tags',
- );
- $file = Jetpack::get_module_path( Jetpack::get_module_slug( $module ) );
- if ( ! file_exists( $file ) )
- return false;
- $mod = get_file_data( $file, $headers );
- if ( empty( $mod['name'] ) )
- return false;
- $mod['name'] = translate( $mod['name'], 'jetpack' );
- $mod['description'] = translate( $mod['description'], 'jetpack' );
- $mod['sort'] = empty( $mod['sort'] ) ? 10 : (int) $mod['sort'];
- $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' ) );
- }
- return $mod;
- }
- public static function translate_module_tag( $untranslated_tag ) {
- return _x( $untranslated_tag, 'Module Tag', 'jetpack' );
- // Calls here are to populate translation files.
- _x( 'Photos and Videos', 'Module Tag', 'jetpack' );
- _x( 'Social', 'Module Tag', 'jetpack' );
- _x( 'WordPress.com Stats', 'Module Tag', 'jetpack' );
- _x( 'Writing', 'Module Tag', 'jetpack' );
- _x( 'Appearance', 'Module Tag', 'jetpack' );
- _x( 'Developers', 'Module Tag', 'jetpack' );
- _x( 'Mobile', 'Module Tag', 'jetpack' );
- _x( 'Other', 'Module Tag', 'jetpack' );
- }
- /**
- * Get a list of activated modules as an array of module slugs.
- */
- public static function get_active_modules() {
- $active = Jetpack_Options::get_option( 'active_modules' );
- if ( ! is_array( $active ) )
- $active = array();
- if ( is_admin() ) {
- $active[] = 'vaultpress';
- } else {
- $active = array_diff( $active, array( 'vaultpress' ) );
- }
- return array_unique( $active );
- }
- /**
- * Check whether or not a Jetpack module is active.
- *
- * @param string $module The slug of a Jetpack module.
- * @return bool
- *
- * @static
- */
- public static function is_module_active( $module ) {
- return in_array( $module, self::get_active_modules() );
- }
- public static function is_module( $module ) {
- return ! empty( $module ) && ! validate_file( $module, Jetpack::get_available_modules() );
- }
- /**
- * Catches PHP errors. Must be used in conjunction with output buffering.
- *
- * @param bool $catch True to start catching, False to stop.
- *
- * @static
- */
- public static function catch_errors( $catch ) {
- static $display_errors, $error_reporting;
- if ( $catch ) {
- $display_errors = @ini_set( 'display_errors', 1 );
- $error_reporting = @error_reporting( E_ALL );
- add_action( 'shutdown', array( 'Jetpack', 'catch_errors_on_shutdown' ), 0 );
- } else {
- @ini_set( 'display_errors', $display_errors );
- @error_reporting( $error_reporting );
- remove_action( 'shutdown', array( 'Jetpack', 'catch_errors_on_shutdown' ), 1 );
- }
- }
- /**
- * Saves any generated PHP errors in ::state( 'php_errors', {errors} )
- */
- public static function catch_errors_on_shutdown() {
- Jetpack::state( 'php_errors', ob_get_clean() );
- }
- public static function activate_default_modules( $min_version = false, $max_version = false, $other_modules = array() ) {
- $jetpack = Jetpack::init();
- $modules = Jetpack::get_default_modules( $min_version, $max_version );
- $modules = array_merge( $other_modules, $modules );
- // Look for standalone plugins and disable if active.
- $to_deactivate = array();
- foreach ( $modules as $module ) {
- if ( isset( $jetpack->plugins_to_deactivate[$module] ) ) {
- $to_deactivate[$module] = $jetpack->plugins_to_deactivate[$module];
- }
- }
- $deactivated = array();
- foreach ( $to_deactivate as $module => $deactivate_me ) {
- list( $probable_file, $probable_title ) = $deactivate_me;
- if ( Jetpack_Client_Server::deactivate_plugin( $probable_file, $probable_title ) ) {
- $deactivated[] = $module;
- }
- }
- if ( $deactivated ) {
- Jetpack::state( 'deactivated_plugins', join( ',', $deactivated ) );
- $url = add_query_arg(
- array(
- 'action' => 'activate_default_modules',
- '_wpnonce' => wp_create_nonce( 'activate_default_modules' ),
- ),
- add_query_arg( compact( 'min_version', 'max_version', 'other_modules' ), Jetpack::admin_url( 'page=jetpack' ) )
- );
- wp_safe_redirect( $url );
- exit;
- }
- do_action( 'jetpack_before_activate_default_modules', $min_version, $max_version, $other_modules );
- // Check each module for fatal errors, a la wp-admin/plugins.php::activate before activating
- Jetpack::restate();
- Jetpack::catch_errors( true );
- foreach ( $modules as $module ) {
- if ( did_action( "jetpack_module_loaded_$module" ) ) {
- $active[] = $module;
- Jetpack_Options::update_option( 'active_modules', array_unique( $active ) );
- continue;
- }
- $active = Jetpack::get_active_modules();
- if ( in_array( $module, $active ) ) {
- $module_info = Jetpack::get_module( $module );
- if ( ! $module_info['deactivate'] ) {
- $state = in_array( $module, $other_modules ) ? 'reactivated_modules' : 'activated_modules';
- if ( $active_state = Jetpack::state( $state ) ) {
- $active_state = explode( ',', $active_state );
- } else {
- $active_state = array();
- }
- $active_state[] = $module;
- Jetpack::state( $state, implode( ',', $active_state ) );
- }
- continue;
- }
- $file = Jetpack::get_module_path( $module );
- if ( ! file_exists( $file ) ) {
- continue;
- }
- // we'll override this later if the plugin can be included without fatal error
- wp_safe_redirect( Jetpack::admin_url( 'page=jetpack' ) );
- Jetpack::state( 'error', 'module_activation_failed' );
- Jetpack::state( 'module', $module );
- ob_start();
- require $file;
- do_action( 'jetpack_activate_module', $module );
- $active[] = $module;
- $state = in_array( $module, $other_modules ) ? 'reactivated_modules' : 'activated_modules';
- if ( $active_state = Jetpack::state( $state ) ) {
- $active_state = explode( ',', $active_state );
- } else {
- $active_state = array();
- }
- $active_state[] = $module;
- Jetpack::state( $state, implode( ',', $active_state ) );
- Jetpack_Options::update_option( 'active_modules', array_unique( $active ) );
- ob_end_clean();
- }
- Jetpack::state( 'error', false );
- Jetpack::state( 'module', false );
- Jetpack::catch_errors( false );
- do_action( 'jetpack_activate_default_modules', $min_version, $max_version, $other_modules );
- }
- public static function activate_module( $module, $exit = 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',…
Large files files are truncated, but you can click here to view the full file