diff options
Diffstat (limited to 'plugins/jetpack/class.jetpack.php')
-rw-r--r-- | plugins/jetpack/class.jetpack.php | 443 |
1 files changed, 255 insertions, 188 deletions
diff --git a/plugins/jetpack/class.jetpack.php b/plugins/jetpack/class.jetpack.php index 8e790dd8..0bebf2c4 100644 --- a/plugins/jetpack/class.jetpack.php +++ b/plugins/jetpack/class.jetpack.php @@ -294,6 +294,7 @@ class Jetpack { // Pure Web Brilliant's Social Graph Twitter Cards Extension 'twitter-cards/twitter-cards.php', // Twitter Cards 'twitter-cards-meta/twitter-cards-meta.php', // Twitter Cards Meta + 'wp-to-twitter/wp-to-twitter.php', // WP to Twitter 'wp-twitter-cards/twitter_cards.php', // WP Twitter Cards ); @@ -529,7 +530,7 @@ class Jetpack { * understanding of what is needed at the network level is * available */ - if( is_multisite() ) { + if ( is_multisite() ) { Jetpack_Network::init(); } @@ -537,9 +538,9 @@ class Jetpack { * Prepare Gutenberg Editor functionality */ require_once JETPACK__PLUGIN_DIR . 'class.jetpack-gutenberg.php'; - add_action( 'init', array( 'Jetpack_Gutenberg', 'load_blocks' ) ); // Registers all the Jetpack blocks . + Jetpack_Gutenberg::init(); + Jetpack_Gutenberg::load_independent_blocks(); add_action( 'enqueue_block_editor_assets', array( 'Jetpack_Gutenberg', 'enqueue_block_editor_assets' ) ); - add_filter( 'jetpack_set_available_blocks', array( 'Jetpack_Gutenberg', 'jetpack_set_available_blocks' ) ); add_action( 'set_user_role', array( $this, 'maybe_clear_other_linked_admins_transient' ), 10, 3 ); @@ -547,6 +548,17 @@ class Jetpack { add_action( 'deleted_user', array( $this, 'unlink_user' ), 10, 1 ); add_action( 'remove_user_from_blog', array( $this, 'unlink_user' ), 10, 1 ); + // Alternate XML-RPC, via ?for=jetpack&jetpack=comms + if ( isset( $_GET['jetpack'] ) && 'comms' == $_GET['jetpack'] && isset( $_GET['for'] ) && 'jetpack' == $_GET['for'] ) { + if ( ! defined( 'XMLRPC_REQUEST' ) ) { + define( 'XMLRPC_REQUEST', true ); + } + + add_action( 'template_redirect', array( $this, 'alternate_xmlrpc' ) ); + + add_filter( 'xmlrpc_methods', array( $this, 'remove_non_jetpack_xmlrpc_methods' ), 1000 ); + } + 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. @@ -677,7 +689,7 @@ class Jetpack { } // Update the Jetpack plan from API on heartbeats - add_action( 'jetpack_heartbeat', array( $this, 'refresh_active_plan_from_wpcom' ) ); + add_action( 'jetpack_heartbeat', array( 'Jetpack_Plan', 'refresh_from_wpcom' ) ); /** * This is the hack to concatenate all css files into one. @@ -773,6 +785,74 @@ class Jetpack { wp_die(); } + /** + * Removes all XML-RPC methods that are not `jetpack.*`. + * Only used in our alternate XML-RPC endpoint, where we want to + * ensure that Core and other plugins' methods are not exposed. + * + * @param array $methods + * @return array filtered $methods + */ + function remove_non_jetpack_xmlrpc_methods( $methods ) { + $jetpack_methods = array(); + + foreach ( $methods as $method => $callback ) { + if ( 0 === strpos( $method, 'jetpack.' ) ) { + $jetpack_methods[ $method ] = $callback; + } + } + + return $jetpack_methods; + } + + /** + * Since a lot of hosts use a hammer approach to "protecting" WordPress sites, + * and just blanket block all requests to /xmlrpc.php, or apply other overly-sensitive + * security/firewall policies, we provide our own alternate XML RPC API endpoint + * which is accessible via a different URI. Most of the below is copied directly + * from /xmlrpc.php so that we're replicating it as closely as possible. + */ + function alternate_xmlrpc() { + // phpcs:disable PHPCompatibility.PHP.RemovedGlobalVariables.http_raw_post_dataDeprecatedRemoved + global $HTTP_RAW_POST_DATA; + + // Some browser-embedded clients send cookies. We don't want them. + $_COOKIE = array(); + + // A bug in PHP < 5.2.2 makes $HTTP_RAW_POST_DATA not set by default, + // but we can do it ourself. + if ( ! isset( $HTTP_RAW_POST_DATA ) ) { + $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); + } + + // fix for mozBlog and other cases where '<?xml' isn't on the very first line + if ( isset( $HTTP_RAW_POST_DATA ) ) { + $HTTP_RAW_POST_DATA = trim( $HTTP_RAW_POST_DATA ); + } + + // phpcs:enable + + include_once( ABSPATH . 'wp-admin/includes/admin.php' ); + include_once( ABSPATH . WPINC . '/class-IXR.php' ); + include_once( ABSPATH . WPINC . '/class-wp-xmlrpc-server.php' ); + + /** + * Filters the class used for handling XML-RPC requests. + * + * @since 3.1.0 + * + * @param string $class The name of the XML-RPC server class. + */ + $wp_xmlrpc_server_class = apply_filters( 'wp_xmlrpc_server_class', 'wp_xmlrpc_server' ); + $wp_xmlrpc_server = new $wp_xmlrpc_server_class; + + // Fire off the request + nocache_headers(); + $wp_xmlrpc_server->serve_request(); + + exit; + } + function jetpack_admin_ajax_tracks_callback() { // Check for nonce if ( ! isset( $_REQUEST['tracksNonce'] ) || ! wp_verify_nonce( $_REQUEST['tracksNonce'], 'jp-tracks-ajax-nonce' ) ) { @@ -1441,167 +1521,35 @@ class Jetpack { /** * Make an API call to WordPress.com for plan status * - * @uses Jetpack_Options::get_option() - * @uses Jetpack_Client::wpcom_json_api_request_as_blog() - * @uses update_option() - * - * @access public - * @static + * @deprecated 7.2.0 Use Jetpack_Plan::refresh_from_wpcom. * * @return bool True if plan is updated, false if no update */ public static function refresh_active_plan_from_wpcom() { - // Make the API request - $request = sprintf( '/sites/%d', Jetpack_Options::get_option( 'id' ) ); - $response = Jetpack_Client::wpcom_json_api_request_as_blog( $request, '1.1' ); - - // Bail if there was an error or malformed response - if ( is_wp_error( $response ) || ! is_array( $response ) || ! isset( $response['body'] ) ) { - return false; - } - - // Decode the results - $results = json_decode( $response['body'], true ); - - // Bail if there were no results or plan details returned - if ( ! is_array( $results ) || ! isset( $results['plan'] ) ) { - return false; - } - - // Store the option and return true if updated - return update_option( 'jetpack_active_plan', $results['plan'] ); + _deprecated_function( __METHOD__, 'jetpack-7.2.0', 'Jetpack_Plan::refresh_from_wpcom' ); + return Jetpack_Plan::refresh_from_wpcom(); } /** * Get the plan that this Jetpack site is currently using * - * @uses get_option() - * - * @access public - * @static - * - * @return array Active Jetpack plan details + * @deprecated 7.2.0 Use Jetpack_Plan::get. + * @return array Active Jetpack plan details. */ public static function get_active_plan() { - global $active_plan_cache; - - // this can be expensive to compute so we cache for the duration of a request - if ( is_array( $active_plan_cache ) && ! empty( $active_plan_cache ) ) { - return $active_plan_cache; - } - - $plan = get_option( 'jetpack_active_plan', array() ); - - // Set the default options - $plan = wp_parse_args( $plan, array( - 'product_slug' => 'jetpack_free', - 'class' => 'free', - 'features' => array( - 'active' => array() - ), - ) ); - - $supports = array(); - - // Define what paid modules are supported by personal plans - $personal_plans = array( - 'jetpack_personal', - 'jetpack_personal_monthly', - 'personal-bundle', - 'personal-bundle-2y', - ); - - if ( in_array( $plan['product_slug'], $personal_plans ) ) { - // special support value, not a module but a separate plugin - $supports[] = 'akismet'; - $plan['class'] = 'personal'; - } - - // Define what paid modules are supported by premium plans - $premium_plans = array( - 'jetpack_premium', - 'jetpack_premium_monthly', - 'value_bundle', - 'value_bundle-2y', - ); - - if ( in_array( $plan['product_slug'], $premium_plans ) ) { - $supports[] = 'akismet'; - $supports[] = 'simple-payments'; - $supports[] = 'vaultpress'; - $supports[] = 'videopress'; - $plan['class'] = 'premium'; - } - - // Define what paid modules are supported by professional plans - $business_plans = array( - 'jetpack_business', - 'jetpack_business_monthly', - 'business-bundle', - 'business-bundle-2y', - 'vip', - ); - - if ( in_array( $plan['product_slug'], $business_plans ) ) { - $supports[] = 'akismet'; - $supports[] = 'simple-payments'; - $supports[] = 'vaultpress'; - $supports[] = 'videopress'; - $plan['class'] = 'business'; - } - - // get available features - foreach ( self::get_available_modules() as $module_slug ) { - $module = self::get_module( $module_slug ); - if ( ! isset( $module ) || ! is_array( $module ) ) { - continue; - } - if ( in_array( 'free', $module['plan_classes'] ) || in_array( $plan['class'], $module['plan_classes'] ) ) { - $supports[] = $module_slug; - } - } - - $plan['supports'] = $supports; - - $active_plan_cache = $plan; - - return $plan; + _deprecated_function( __METHOD__, 'jetpack-7.2.0', 'Jetpack_Plan::get' ); + return Jetpack_Plan::get(); } /** * Determine whether the active plan supports a particular feature * - * @uses Jetpack::get_active_plan() - * - * @access public - * @static - * - * @return bool True if plan supports feature, false if not + * @deprecated 7.2.0 Use Jetpack_Plan::supports. + * @return bool True if plan supports feature, false if not. */ public static function active_plan_supports( $feature ) { - $plan = Jetpack::get_active_plan(); - - // Manually mapping WordPress.com features to Jetpack module slugs - foreach ( $plan['features']['active'] as $wpcom_feature ) { - switch ( $wpcom_feature ) { - case 'wordads-jetpack'; - - // WordAds are supported for this site - if ( 'wordads' === $feature ) { - return true; - } - break; - } - } - - if ( - in_array( $feature, $plan['supports'] ) - || in_array( $feature, $plan['features']['active'] ) - ) { - return true; - } - - return false; + _deprecated_function( __METHOD__, 'jetpack-7.2.0', 'Jetpack_Plan::supports' ); + return Jetpack_Plan::supports( $feature ); } /** @@ -1645,6 +1593,25 @@ class Jetpack { } /** + * Determines reason for Jetpack development mode. + */ + public static function development_mode_trigger_text() { + if ( ! Jetpack::is_development_mode() ) { + return __( 'Jetpack is not in Development Mode.', 'jetpack' ); + } + + if ( defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG ) { + $notice = __( 'The JETPACK_DEV_DEBUG constant is defined in wp-config.php or elsewhere.', 'jetpack' ); + } elseif ( site_url() && false === strpos( site_url(), '.' ) ) { + $notice = __( 'The site URL lacking a dot (e.g. http://localhost).', 'jetpack' ); + } else { + $notice = __( 'The jetpack_development_mode filter is set to true.', 'jetpack' ); + } + + return $notice; + + } + /** * Get Jetpack development mode notice text and notice class. * * Mirrors the checks made in Jetpack::is_development_mode @@ -1652,25 +1619,13 @@ class Jetpack { */ public static function show_development_mode_notice() { if ( Jetpack::is_development_mode() ) { - if ( defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG ) { - $notice = sprintf( - /* translators: %s is a URL */ - __( 'In <a href="%s" target="_blank">Development Mode</a>, via the JETPACK_DEV_DEBUG constant being defined in wp-config.php or elsewhere.', 'jetpack' ), - 'https://jetpack.com/support/development-mode/' - ); - } elseif ( site_url() && false === strpos( site_url(), '.' ) ) { - $notice = sprintf( - /* translators: %s is a URL */ - __( 'In <a href="%s" target="_blank">Development Mode</a>, via site URL lacking a dot (e.g. http://localhost).', 'jetpack' ), - 'https://jetpack.com/support/development-mode/' - ); - } else { - $notice = sprintf( - /* translators: %s is a URL */ - __( 'In <a href="%s" target="_blank">Development Mode</a>, via the jetpack_development_mode filter.', 'jetpack' ), - 'https://jetpack.com/support/development-mode/' - ); - } + $notice = sprintf( + /* translators: %s is a URL */ + __( 'In <a href="%s" target="_blank">Development Mode</a>:', 'jetpack' ), + 'https://jetpack.com/support/development-mode/' + ); + + $notice .= ' ' . Jetpack::development_mode_trigger_text(); echo '<div class="updated" style="border-color: #f0821e;"><p>' . $notice . '</p></div>'; } @@ -2405,7 +2360,7 @@ class Jetpack { */ function handle_deprecated_modules( $modules ) { $deprecated_modules = array( - 'debug' => null, // Closed out and moved to ./class.jetpack-debugger.php + 'debug' => null, // Closed out and moved to the debugger library. 'wpcc' => 'sso', // Closed out in 2.6 -- SSO provides the same functionality. 'gplus-authorship' => null, // Closed out in 3.2 -- Google dropped support. ); @@ -2627,7 +2582,19 @@ class Jetpack { * @return string The locale as JSON */ public static function get_i18n_data_json() { - $i18n_json = JETPACK__PLUGIN_DIR . 'languages/json/jetpack-' . get_user_locale() . '.json'; + + // WordPress 5.0 uses md5 hashes of file paths to associate translation + // JSON files with the file they should be included for. This is an md5 + // of '_inc/build/admin.js'. + $path_md5 = '1bac79e646a8bf4081a5011ab72d5807'; + + $i18n_json = + JETPACK__PLUGIN_DIR + . 'languages/json/jetpack-' + . get_user_locale() + . '-' + . $path_md5 + . '.json'; if ( is_file( $i18n_json ) && is_readable( $i18n_json ) ) { $locale_data = @file_get_contents( $i18n_json ); @@ -2637,12 +2604,7 @@ class Jetpack { } // Return valid empty Jed locale - return json_encode( array( - '' => array( - 'domain' => 'jetpack', - 'lang' => is_admin() ? get_user_locale() : get_locale(), - ), - ) ); + return '{ "locale_data": { "messages": { "": {} } } }'; } /** @@ -2990,7 +2952,7 @@ class Jetpack { } } - if ( ! Jetpack::active_plan_supports( $module ) ) { + if ( ! Jetpack_Plan::supports( $module ) ) { return false; } @@ -3066,9 +3028,26 @@ class Jetpack { add_filter( 'jetpack_module_configurable_' . $module, '__return_true' ); } + /** + * Composes a module configure URL. It uses Jetpack settings search as default value + * It is possible to redefine resulting URL by using "jetpack_module_configuration_url_$module" filter + * + * @param string $module Module slug + * @return string $url module configuration URL + */ public static function module_configuration_url( $module ) { $module = Jetpack::get_module_slug( $module ); - return Jetpack::admin_url( array( 'page' => 'jetpack', 'configure' => $module ) ); + $default_url = Jetpack::admin_url() . "#/settings?term=$module"; + /** + * Allows to modify configure_url of specific module to be able to redirect to some custom location. + * + * @since 6.9.0 + * + * @param string $default_url Default url, which redirects to jetpack settings page. + */ + $url = apply_filters( 'jetpack_module_configuration_url_' . $module, $default_url ); + + return $url; } public static function module_configuration_load( $module, $method ) { @@ -4655,10 +4634,6 @@ p { $secrets = Jetpack::generate_secrets( 'authorize', false, 2 * HOUR_IN_SECONDS ); - $site_icon = ( function_exists( 'has_site_icon') && has_site_icon() ) - ? get_site_icon_url() - : false; - /** * Filter the type of authorization. * 'calypso' completes authorization on wordpress.com/jetpack/connect @@ -4696,10 +4671,11 @@ p { 'blogname' => get_option( 'blogname' ), 'site_url' => site_url(), 'home_url' => home_url(), - 'site_icon' => $site_icon, + 'site_icon' => get_site_icon_url(), 'site_lang' => get_locale(), '_ui' => $tracks_identity['_ui'], - '_ut' => $tracks_identity['_ut'] + '_ut' => $tracks_identity['_ut'], + 'site_created' => Jetpack::get_assumed_site_creation_date(), ) ); @@ -4712,6 +4688,12 @@ p { $url = add_query_arg( 'from', $from, $url ); } + // Ensure that class to get the affiliate code is loaded + if ( ! class_exists( 'Jetpack_Affiliate' ) ) { + require_once JETPACK__PLUGIN_DIR . 'class.jetpack-affiliate.php'; + } + // Get affiliate code and add it to the URL + $url = Jetpack_Affiliate::init()->add_code_as_query_arg( $url ); if ( isset( $_GET['calypso_env'] ) ) { $url = add_query_arg( 'calypso_env', sanitize_key( $_GET['calypso_env'] ), $url ); @@ -4720,6 +4702,44 @@ p { return $raw ? $url : esc_url( $url ); } + /** + * Get our assumed site creation date. + * Calculated based on the earlier date of either: + * - Earliest admin user registration date. + * - Earliest date of post of any post type. + * + * @since 7.2.0 + * + * @return string Assumed site creation date and time. + */ + public static function get_assumed_site_creation_date() { + $earliest_registered_users = get_users( array( + 'role' => 'administrator', + 'orderby' => 'user_registered', + 'order' => 'ASC', + 'fields' => array( 'user_registered' ), + 'number' => 1, + ) ); + $earliest_registration_date = $earliest_registered_users[0]->user_registered; + + $earliest_posts = get_posts( array( + 'posts_per_page' => 1, + 'post_type' => 'any', + 'post_status' => 'any', + 'orderby' => 'date', + 'order' => 'ASC', + ) ); + + // If there are no posts at all, we'll count only on user registration date. + if ( $earliest_posts ) { + $earliest_post_date = $earliest_posts[0]->post_date; + } else { + $earliest_post_date = PHP_INT_MAX; + } + + return min( $earliest_registration_date, $earliest_post_date ); + } + public static function apply_activation_source_to_args( &$args ) { list( $activation_source_name, $activation_source_keyword ) = get_option( 'jetpack_activation_source' ); @@ -4801,7 +4821,7 @@ p { remove_action( 'jetpack_pre_activate_module', array( Jetpack_Admin::init(), 'fix_redirect' ) ); // Don't redirect form the Jetpack Setting Page - $referer_parsed = parse_url ( wp_get_referer() ); + $referer_parsed = wp_parse_url ( wp_get_referer() ); // check that we do have a wp_get_referer and the query paramater is set orderwise go to the Jetpack Home if ( isset( $referer_parsed['query'] ) && false !== strpos( $referer_parsed['query'], 'page=jetpack_modules' ) ) { // Take the user to Jetpack home except when on the setting page @@ -5339,6 +5359,7 @@ p { 'state' => get_current_user_id(), '_ui' => $tracks_identity['_ui'], '_ut' => $tracks_identity['_ut'], + 'site_created' => Jetpack::get_assumed_site_creation_date(), 'jetpack_version' => JETPACK__VERSION ), 'headers' => array( @@ -5840,7 +5861,7 @@ p { if ( ! isset( $path ) ) { require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); $admin_url = Jetpack::admin_url(); - $bits = parse_url( $admin_url ); + $bits = wp_parse_url( $admin_url ); if ( is_array( $bits ) ) { $path = ( isset( $bits['path'] ) ) ? dirname( $bits['path'] ) : null; @@ -6057,6 +6078,10 @@ p { return $domains; } + static function is_redirect_encoded( $redirect_url ) { + return preg_match( '/https?%3A%2F%2F/i', $redirect_url ) > 0; + } + // Add all wordpress.com environments to the safe redirect whitelist function allow_wpcom_environments( $domains ) { $domains[] = 'wordpress.com'; @@ -6104,6 +6129,17 @@ p { $die_error = __( 'Someone may be trying to trick you into giving them access to your site. Or it could be you just encountered a bug :). Either way, please close this window.', 'jetpack' ); + // Host has encoded the request URL, probably as a result of a bad http => https redirect + if ( Jetpack::is_redirect_encoded( $_GET['redirect_to'] ) ) { + JetpackTracking::record_user_event( 'error_double_encode' ); + + $die_error = sprintf( + /* translators: %s is a URL */ + __( 'Your site is incorrectly double-encoding redirects from http to https. This is preventing Jetpack from authenticating your connection. Please visit our <a href="%s">support page</a> for details about how to resolve this.', 'jetpack' ), + 'https://jetpack.com/support/double-encoding/' + ); + } + $jetpack_signature = new Jetpack_Signature( $token->secret, (int) Jetpack_Options::get_option( 'time_diff' ) ); if ( isset( $environment['jetpack_json_api_original_query'] ) ) { @@ -6771,6 +6807,11 @@ p { $do_implode = false; } + // Do not implode CSS when the page loads via the AMP plugin. + if ( Jetpack_AMP_Support::is_amp_request() ) { + $do_implode = false; + } + /** * Allow CSS to be concatenated into a single jetpack.css file. * @@ -6780,7 +6821,7 @@ p { */ $do_implode = apply_filters( 'jetpack_implode_frontend_css', $do_implode ); - // Do not use the imploded file when default behaviour was altered through the filter + // Do not use the imploded file when default behavior was altered through the filter if ( ! $do_implode ) { return; } @@ -6986,9 +7027,18 @@ p { } if ( has_action( 'jetpack_dashboard_widget' ) ) { + $widget_title = sprintf( + wp_kses( + /* translators: Placeholder is a Jetpack logo. */ + __( 'Stats <span>by %s</span>', 'jetpack' ), + array( 'span' => array() ) + ), + Jetpack::get_jp_emblem( true ) + ); + wp_add_dashboard_widget( 'jetpack_summary_widget', - esc_html__( 'Site Stats', 'jetpack' ), + $widget_title, array( __CLASS__, 'dashboard_widget' ) ); wp_enqueue_style( 'jetpack-dashboard-widget', plugins_url( 'css/dashboard-widget.css', JETPACK__PLUGIN_FILE ), array(), JETPACK__VERSION ); @@ -7083,10 +7133,27 @@ p { * * @since 3.9.0 * + * @param bool $logotype Should we use the full logotype (logo + text). Default to false. + * * @return string */ - public static function get_jp_emblem() { - return '<svg id="jetpack-logo__icon" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 32 32"><path fill="#00BE28" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16c8.8,0,16-7.2,16-16S24.8,0,16,0z M15.2,18.7h-8l8-15.5V18.7z M16.8,28.8 V13.3h8L16.8,28.8z"/></svg>'; + public static function get_jp_emblem( $logotype = false ) { + $logo = '<path fill="#00BE28" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16c8.8,0,16-7.2,16-16S24.8,0,16,0z M15.2,18.7h-8l8-15.5V18.7z M16.8,28.8 V13.3h8L16.8,28.8z"/>'; + $text = ' +<path d="M41.3,26.6c-0.5-0.7-0.9-1.4-1.3-2.1c2.3-1.4,3-2.5,3-4.6V8h-3V6h6v13.4C46,22.8,45,24.8,41.3,26.6z" /> +<path d="M65,18.4c0,1.1,0.8,1.3,1.4,1.3c0.5,0,2-0.2,2.6-0.4v2.1c-0.9,0.3-2.5,0.5-3.7,0.5c-1.5,0-3.2-0.5-3.2-3.1V12H60v-2h2.1V7.1 H65V10h4v2h-4V18.4z" /> +<path d="M71,10h3v1.3c1.1-0.8,1.9-1.3,3.3-1.3c2.5,0,4.5,1.8,4.5,5.6s-2.2,6.3-5.8,6.3c-0.9,0-1.3-0.1-2-0.3V28h-3V10z M76.5,12.3 c-0.8,0-1.6,0.4-2.5,1.2v5.9c0.6,0.1,0.9,0.2,1.8,0.2c2,0,3.2-1.3,3.2-3.9C79,13.4,78.1,12.3,76.5,12.3z" /> +<path d="M93,22h-3v-1.5c-0.9,0.7-1.9,1.5-3.5,1.5c-1.5,0-3.1-1.1-3.1-3.2c0-2.9,2.5-3.4,4.2-3.7l2.4-0.3v-0.3c0-1.5-0.5-2.3-2-2.3 c-0.7,0-2.3,0.5-3.7,1.1L84,11c1.2-0.4,3-1,4.4-1c2.7,0,4.6,1.4,4.6,4.7L93,22z M90,16.4l-2.2,0.4c-0.7,0.1-1.4,0.5-1.4,1.6 c0,0.9,0.5,1.4,1.3,1.4s1.5-0.5,2.3-1V16.4z" /> +<path d="M104.5,21.3c-1.1,0.4-2.2,0.6-3.5,0.6c-4.2,0-5.9-2.4-5.9-5.9c0-3.7,2.3-6,6.1-6c1.4,0,2.3,0.2,3.2,0.5V13 c-0.8-0.3-2-0.6-3.2-0.6c-1.7,0-3.2,0.9-3.2,3.6c0,2.9,1.5,3.8,3.3,3.8c0.9,0,1.9-0.2,3.2-0.7V21.3z" /> +<path d="M110,15.2c0.2-0.3,0.2-0.8,3.8-5.2h3.7l-4.6,5.7l5,6.3h-3.7l-4.2-5.8V22h-3V6h3V15.2z" /> +<path d="M58.5,21.3c-1.5,0.5-2.7,0.6-4.2,0.6c-3.6,0-5.8-1.8-5.8-6c0-3.1,1.9-5.9,5.5-5.9s4.9,2.5,4.9,4.9c0,0.8,0,1.5-0.1,2h-7.3 c0.1,2.5,1.5,2.8,3.6,2.8c1.1,0,2.2-0.3,3.4-0.7C58.5,19,58.5,21.3,58.5,21.3z M56,15c0-1.4-0.5-2.9-2-2.9c-1.4,0-2.3,1.3-2.4,2.9 C51.6,15,56,15,56,15z" /> + '; + + return sprintf( + '<svg id="jetpack-logo__icon" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 %1$s 32">%2$s</svg>', + ( true === $logotype ? '118' : '32' ), + ( true === $logotype ? $logo . $text : $logo ) + ); } /* |