summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/_inc/lib')
-rw-r--r--plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php71
-rw-r--r--plugins/jetpack/_inc/lib/admin-pages/class.jetpack-react-page.php18
-rw-r--r--plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php130
-rw-r--r--plugins/jetpack/_inc/lib/class.media-summary.php40
-rw-r--r--plugins/jetpack/_inc/lib/markdown/extra.php2
5 files changed, 158 insertions, 103 deletions
diff --git a/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php b/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php
index b4a86c16..ba2fefe8 100644
--- a/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php
+++ b/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php
@@ -21,15 +21,6 @@ abstract class Jetpack_Admin_Page {
static $block_page_rendering_for_idc;
/**
- * Flag to know if we already checked the plan.
- *
- * @since 4.4.0
- *
- * @var bool
- */
- static $plan_checked = false;
-
- /**
* Function called after admin_styles to load any additional needed styles.
*
* @since 4.3.0
@@ -172,7 +163,7 @@ abstract class Jetpack_Admin_Page {
*
* @param $page
*
- * @return bool|array
+ * @return array
*/
function check_plan_deactivate_modules( $page ) {
if (
@@ -187,49 +178,43 @@ abstract class Jetpack_Admin_Page {
'jetpack_page_akismet-key-config'
)
)
- || true === self::$plan_checked
) {
return false;
}
- self::$plan_checked = true;
- $previous = get_option( 'jetpack_active_plan', '' );
- $current = Jetpack_Core_Json_Api_Endpoints::site_data();
- if ( ! $current || is_wp_error( $current ) ) {
- // If we can't get information about the current plan we don't do anything
- self::$plan_checked = true;
- return;
- }
+ $current = Jetpack::get_active_plan();
$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', 'google-analytics', 'wordads', 'search' );
- break;
- case 'jetpack_personal':
- case 'jetpack_personal_monthly':
- $to_deactivate = array( 'seo-tools', 'videopress', 'google-analytics', 'wordads', 'search' );
- break;
- case 'jetpack_premium':
- case 'jetpack_premium_monthly':
- $to_deactivate = array( 'seo-tools', 'google-analytics', 'search' );
- break;
- }
- $to_deactivate = array_intersect( $active, $to_deactivate );
- if ( ! empty( $to_deactivate ) ) {
- Jetpack::update_active_modules( array_filter( array_diff( $active, $to_deactivate ) ) );
+ if ( isset( $current['product_slug'] ) ) {
+ $active = Jetpack::get_active_modules();
+ switch ( $current['product_slug'] ) {
+ case 'jetpack_free':
+ $to_deactivate = array( 'seo-tools', 'videopress', 'google-analytics', 'wordads', 'search' );
+ break;
+ case 'jetpack_personal':
+ case 'jetpack_personal_monthly':
+ $to_deactivate = array( 'seo-tools', 'videopress', 'google-analytics', 'wordads', 'search' );
+ break;
+ case 'jetpack_premium':
+ case 'jetpack_premium_monthly':
+ $to_deactivate = array( 'seo-tools', 'google-analytics', 'search' );
+ break;
+ }
+ $to_deactivate = array_intersect( $active, $to_deactivate );
+
+ $to_leave_enabled = array();
+ foreach ( $to_deactivate as $feature ) {
+ if ( Jetpack::active_plan_supports( $feature ) ) {
+ $to_leave_enabled []= $feature;
}
}
+ $to_deactivate = array_diff( $to_deactivate, $to_leave_enabled );
+
+ if ( ! empty( $to_deactivate ) ) {
+ Jetpack::update_active_modules( array_filter( array_diff( $active, $to_deactivate ) ) );
+ }
}
return array(
- 'previous' => $previous,
'current' => $current,
'deactivate' => $to_deactivate
);
diff --git a/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-react-page.php b/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-react-page.php
index 4047cfbc..6cd6b94c 100644
--- a/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-react-page.php
+++ b/plugins/jetpack/_inc/lib/admin-pages/class.jetpack-react-page.php
@@ -147,21 +147,6 @@ class Jetpack_React_Page extends Jetpack_Admin_Page {
}
}
- function get_i18n_data() {
-
- $i18n_json = JETPACK__PLUGIN_DIR . 'languages/json/jetpack-' . jetpack_get_user_locale() . '.json';
-
- if ( is_file( $i18n_json ) && is_readable( $i18n_json ) ) {
- $locale_data = @file_get_contents( $i18n_json );
- if ( $locale_data ) {
- return $locale_data;
- }
- }
-
- // Return empty if we have nothing to return so it doesn't fail when parsed in JS
- return '{}';
- }
-
/**
* Gets array of any Jetpack notices that have been dismissed.
*
@@ -303,6 +288,7 @@ class Jetpack_React_Page extends Jetpack_Admin_Page {
*/
'showPromotions' => apply_filters( 'jetpack_show_promotions', true ),
'isAtomicSite' => jetpack_is_atomic_site(),
+ 'plan' => Jetpack::get_active_plan(),
),
'themeData' => array(
'name' => $current_theme->get( 'Name' ),
@@ -311,7 +297,7 @@ class Jetpack_React_Page extends Jetpack_Admin_Page {
'infinite-scroll' => current_theme_supports( 'infinite-scroll' ) || in_array( $current_theme->get_stylesheet(), $inf_scr_support_themes ),
),
),
- 'locale' => $this->get_i18n_data(),
+ 'locale' => Jetpack::get_i18n_data_json(),
'localeSlug' => join( '-', explode( '_', jetpack_get_user_locale() ) ),
'jetpackStateNotices' => array(
'messageCode' => Jetpack::state( 'message' ),
diff --git a/plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php b/plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php
index 71bccc4c..8653d88b 100644
--- a/plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php
+++ b/plugins/jetpack/_inc/lib/class.core-rest-api-endpoints.php
@@ -122,6 +122,13 @@ class Jetpack_Core_Json_Api_Endpoints {
'permission_callback' => __CLASS__ . '::get_user_connection_data_permission_callback',
) );
+ // Set the connection owner
+ register_rest_route( 'jetpack/v4', '/connection/owner', array(
+ 'methods' => WP_REST_Server::EDITABLE,
+ 'callback' => __CLASS__ . '::set_connection_owner',
+ 'permission_callback' => __CLASS__ . '::set_connection_owner_permission_callback',
+ ) );
+
// Current user: get or set tracking settings.
register_rest_route( 'jetpack/v4', '/tracking/settings', array(
array(
@@ -374,39 +381,23 @@ class Jetpack_Core_Json_Api_Endpoints {
}
public static function get_plans( $request ) {
- /**
- * Filter to turn off caching of Jetpack plans
- *
- * @since 5.9.0
- *
- * @param bool true Whether to cache Jetpack plans locally
- */
- $use_cache = apply_filters( 'jetpack_cache_plans', true );
-
- $data = $use_cache ? get_transient( 'jetpack_plans' ) : false;
-
- if ( false === $data ) {
- $path = '/plans';
- // passing along from client to help geolocate currency
- $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; // if we already have an list of forwarded ips, then just use that
- if ( empty( $ip ) ) {
- $ip = $_SERVER['HTTP_CLIENT_IP']; // another popular one for proxy servers
- }
- if ( empty( $ip ) ) {
- $ip = $_SERVER['REMOTE_ADDR']; // if we don't have an ip by now, take the closest node's ip (likely directly connected client)
- }
- $request = Jetpack_Client::wpcom_json_api_request_as_blog( $path, '2', array( 'headers' => array( 'X-Forwarded-For' => $ip ) ), null, 'wpcom' );
- $body = wp_remote_retrieve_body( $request );
- if ( 200 === wp_remote_retrieve_response_code( $request ) ) {
- $data = $body;
- } else {
- // something went wrong so we'll just return the response without caching
- return $body;
- }
+ $request = Jetpack_Client::wpcom_json_api_request_as_user(
+ '/plans?_locale=' . get_user_locale(),
+ '2',
+ array(
+ 'method' => 'GET',
+ 'headers' => array(
+ 'X-Forwarded-For' => Jetpack::current_user_ip( true ),
+ ),
+ )
+ );
- if ( true === $use_cache ) {
- set_transient( 'jetpack_plans', $data, DAY_IN_SECONDS );
- }
+ $body = wp_remote_retrieve_body( $request );
+ if ( 200 === wp_remote_retrieve_response_code( $request ) ) {
+ $data = $body;
+ } else {
+ // something went wrong so we'll just return the response without caching
+ return $body;
}
return $data;
@@ -575,6 +566,21 @@ class Jetpack_Core_Json_Api_Endpoints {
}
/**
+ * Check that user has permission to change the master user.
+ *
+ * @since 6.2.0
+ *
+ * @return bool|WP_Error True if user is able to change master user.
+ */
+ public static function set_connection_owner_permission_callback() {
+ if ( get_current_user_id() === Jetpack_Options::get_option( 'master_user' ) ) {
+ return true;
+ }
+
+ return new WP_Error( 'invalid_user_permission_set_connection_owner', self::$user_permissions_error_msg, array( 'status' => self::rest_authorization_required_code() ) );
+ }
+
+ /**
* Verify that a user can use the /connection/user endpoint. Has to be a registered user and be currently linked.
*
* @since 4.3.0
@@ -833,6 +839,64 @@ class Jetpack_Core_Json_Api_Endpoints {
}
/**
+ * Change the master user.
+ *
+ * @since 6.2.0
+ *
+ * @param WP_REST_Request $request The request sent to the WP REST API.
+ *
+ * @return bool|WP_Error True if owner successfully changed.
+ */
+ public static function set_connection_owner( $request ) {
+ if ( ! isset( $request['owner'] ) ) {
+ return new WP_Error(
+ 'invalid_param',
+ esc_html__( 'Invalid Parameter', 'jetpack' ),
+ array( 'status' => 400 )
+ );
+ }
+
+ $new_owner_id = $request['owner'];
+ if ( ! user_can( $new_owner_id, 'administrator' ) ) {
+ return new WP_Error(
+ 'new_owner_not_admin',
+ esc_html__( 'New owner is not admin', 'jetpack' ),
+ array( 'status' => 400 )
+ );
+ }
+
+ if ( $new_owner_id === get_current_user_id() ) {
+ return new WP_Error(
+ 'new_owner_is_current_user',
+ esc_html__( 'New owner is same as current user', 'jetpack' ),
+ array( 'status' => 400 )
+ );
+ }
+
+ if ( ! Jetpack::is_user_connected( $new_owner_id ) ) {
+ return new WP_Error(
+ 'new_owner_not_connected',
+ esc_html__( 'New owner is not connected', 'jetpack' ),
+ array( 'status' => 400 )
+ );
+ }
+
+ $updated = Jetpack_Options::update_option( 'master_user', $new_owner_id );
+ if ( $updated ) {
+ return rest_ensure_response(
+ array(
+ 'code' => 'success'
+ )
+ );
+ }
+ return new WP_Error(
+ 'error_setting_new_owner',
+ esc_html__( 'Could not confirm new owner.', 'jetpack' ),
+ array( 'status' => 500 )
+ );
+ }
+
+ /**
* Unlinks current user from the WordPress.com Servers.
*
* @since 4.3.0
@@ -1660,7 +1724,7 @@ class Jetpack_Core_Json_Api_Endpoints {
'jp_group' => 'related-posts',
),
'show_thumbnails' => array(
- 'description' => esc_html__( 'Use a large and visually striking layout', 'jetpack' ),
+ 'description' => esc_html__( 'Show a thumbnail image where available', 'jetpack' ),
'type' => 'boolean',
'default' => 0,
'validate_callback' => __CLASS__ . '::validate_boolean',
diff --git a/plugins/jetpack/_inc/lib/class.media-summary.php b/plugins/jetpack/_inc/lib/class.media-summary.php
index d129f5e6..cf1bc050 100644
--- a/plugins/jetpack/_inc/lib/class.media-summary.php
+++ b/plugins/jetpack/_inc/lib/class.media-summary.php
@@ -54,7 +54,7 @@ class Jetpack_Media_Summary {
);
if ( empty( $post->post_password ) ) {
- $return['excerpt'] = self::get_excerpt( $post->post_content, $post->post_excerpt, $args['max_words'], $args['max_chars'] );
+ $return['excerpt'] = self::get_excerpt( $post->post_content, $post->post_excerpt, $args['max_words'], $args['max_chars'] , $post);
$return['count']['word'] = self::get_word_count( $post->post_content );
$return['count']['word_remaining'] = self::get_word_remaining_count( $post->post_content, $return['excerpt'] );
$return['count']['link'] = self::get_link_count( $post->post_content );
@@ -298,22 +298,42 @@ class Jetpack_Media_Summary {
);
}
- static function get_excerpt( $post_content, $post_excerpt, $max_words = 16, $max_chars = 256 ) {
+ /**
+ * Retrieve an excerpt for the post summary.
+ *
+ * This function works around a suspected problem with Core. If resolved, this function should be simplified.
+ * @link https://github.com/Automattic/jetpack/pull/8510
+ * @link https://core.trac.wordpress.org/ticket/42814
+ *
+ * @param string $post_content The post's content.
+ * @param string $post_excerpt The post's excerpt. Empty if none was explicitly set.
+ * @param int $max_words Maximum number of words for the excerpt. Used on wp.com. Default 16.
+ * @param int $max_chars Maximum characters in the excerpt. Used on wp.com. Default 256.
+ * @param WP_Post $requested_post The post object.
+ * @return string Post excerpt.
+ **/
+ static function get_excerpt( $post_content, $post_excerpt, $max_words = 16, $max_chars = 256, $requested_post = null ) {
+ global $post;
+ $original_post = $post; // Saving the global for later use.
if ( function_exists( 'wpcom_enhanced_excerpt_extract_excerpt' ) ) {
return self::clean_text( wpcom_enhanced_excerpt_extract_excerpt( array(
- 'text' => $post_content,
- 'excerpt_only' => true,
- 'show_read_more' => false,
- 'max_words' => $max_words,
- 'max_chars' => $max_chars,
+ 'text' => $post_content,
+ 'excerpt_only' => true,
+ 'show_read_more' => false,
+ 'max_words' => $max_words,
+ 'max_chars' => $max_chars,
'read_more_threshold' => 25,
) ) );
- } else {
-
+ } elseif ( $requested_post instanceof WP_Post ) {
+ $post = $requested_post; // setup_postdata does not set the global.
+ setup_postdata( $post );
/** This filter is documented in core/src/wp-includes/post-template.php */
- $post_excerpt = apply_filters( 'get_the_excerpt', $post_excerpt );
+ $post_excerpt = apply_filters( 'get_the_excerpt', $post_excerpt, $post );
+ $post = $original_post; // wp_reset_postdata uses the $post global.
+ wp_reset_postdata();
return self::clean_text( $post_excerpt );
}
+ return '';
}
static function get_word_count( $post_content ) {
diff --git a/plugins/jetpack/_inc/lib/markdown/extra.php b/plugins/jetpack/_inc/lib/markdown/extra.php
index e54b4ab1..86778d2f 100644
--- a/plugins/jetpack/_inc/lib/markdown/extra.php
+++ b/plugins/jetpack/_inc/lib/markdown/extra.php
@@ -73,7 +73,7 @@ function Markdown($text) {
*
*/
function jetpack_utf8_strlen( $text ) {
- return preg_match_all( "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", $text, $m );
+ return preg_match_all( "/[\\x00-\\xBF]|[\\xC0-\\xFF][\\x80-\\xBF]*/", $text, $m );
}
#