From 210e75345653abee7954a11d3669cd56175b9ea5 Mon Sep 17 00:00:00 2001 From: Sergey Mitroshin Date: Wed, 15 Feb 2023 16:15:48 -0500 Subject: [PATCH 01/51] Connection: move the notice for deleting connection owner (#28516) Move the "Delete Connection Owner" notice from JITM to Connection package. --- ...update-move-delete-connection-owner-notice | 4 + projects/packages/connection/composer.json | 2 +- .../src/class-connection-notice.php | 223 ++++++++++++++++++ .../packages/connection/src/class-manager.php | 3 + .../connection/src/class-package-version.php | 2 +- .../php/test-class-connection-notice.php | 168 +++++++++++++ ...update-move-delete-connection-owner-notice | 4 + projects/packages/jitm/composer.json | 2 +- projects/packages/jitm/src/class-jitm.php | 2 +- .../jitm/src/class-post-connection-jitm.php | 191 --------------- ...update-move-delete-connection-owner-notice | 4 + ...update-move-delete-connection-owner-notice | 4 + ...update-move-delete-connection-owner-notice | 5 + ...date-move-delete-connection-owner-notice#2 | 5 + projects/plugins/backup/composer.lock | 8 +- ...update-move-delete-connection-owner-notice | 5 + ...date-move-delete-connection-owner-notice#2 | 5 + projects/plugins/boost/composer.lock | 8 +- ...update-move-delete-connection-owner-notice | 5 + ...date-move-delete-connection-owner-notice#2 | 5 + projects/plugins/jetpack/composer.lock | 8 +- ...update-move-delete-connection-owner-notice | 5 + ...date-move-delete-connection-owner-notice#2 | 5 + projects/plugins/migration/composer.lock | 8 +- ...update-move-delete-connection-owner-notice | 5 + ...date-move-delete-connection-owner-notice#2 | 5 + projects/plugins/protect/composer.lock | 8 +- ...update-move-delete-connection-owner-notice | 5 + ...date-move-delete-connection-owner-notice#2 | 5 + projects/plugins/search/composer.lock | 8 +- ...update-move-delete-connection-owner-notice | 5 + ...date-move-delete-connection-owner-notice#2 | 5 + projects/plugins/social/composer.lock | 8 +- ...update-move-delete-connection-owner-notice | 5 + ...date-move-delete-connection-owner-notice#2 | 5 + projects/plugins/starter-plugin/composer.lock | 8 +- ...update-move-delete-connection-owner-notice | 5 + ...date-move-delete-connection-owner-notice#2 | 5 + projects/plugins/videopress/composer.lock | 8 +- 39 files changed, 540 insertions(+), 231 deletions(-) create mode 100644 projects/packages/connection/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/packages/connection/src/class-connection-notice.php create mode 100644 projects/packages/connection/tests/php/test-class-connection-notice.php create mode 100644 projects/packages/jitm/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/packages/videopress/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/packages/wp-js-data-sync/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/plugins/backup/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/plugins/backup/changelog/update-move-delete-connection-owner-notice#2 create mode 100644 projects/plugins/boost/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/plugins/boost/changelog/update-move-delete-connection-owner-notice#2 create mode 100644 projects/plugins/jetpack/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/plugins/jetpack/changelog/update-move-delete-connection-owner-notice#2 create mode 100644 projects/plugins/migration/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/plugins/migration/changelog/update-move-delete-connection-owner-notice#2 create mode 100644 projects/plugins/protect/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/plugins/protect/changelog/update-move-delete-connection-owner-notice#2 create mode 100644 projects/plugins/search/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/plugins/search/changelog/update-move-delete-connection-owner-notice#2 create mode 100644 projects/plugins/social/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/plugins/social/changelog/update-move-delete-connection-owner-notice#2 create mode 100644 projects/plugins/starter-plugin/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/plugins/starter-plugin/changelog/update-move-delete-connection-owner-notice#2 create mode 100644 projects/plugins/videopress/changelog/update-move-delete-connection-owner-notice create mode 100644 projects/plugins/videopress/changelog/update-move-delete-connection-owner-notice#2 diff --git a/projects/packages/connection/changelog/update-move-delete-connection-owner-notice b/projects/packages/connection/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..819bafa1a1ee8 --- /dev/null +++ b/projects/packages/connection/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,4 @@ +Significance: minor +Type: changed + +Moving deleting connection owner notice from JITM to Connection package. diff --git a/projects/packages/connection/composer.json b/projects/packages/connection/composer.json index aae4136995cba..bd9979837e76f 100644 --- a/projects/packages/connection/composer.json +++ b/projects/packages/connection/composer.json @@ -65,7 +65,7 @@ "link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.50.x-dev" + "dev-trunk": "1.51.x-dev" } }, "config": { diff --git a/projects/packages/connection/src/class-connection-notice.php b/projects/packages/connection/src/class-connection-notice.php new file mode 100644 index 0000000000000..45f51a8232294 --- /dev/null +++ b/projects/packages/connection/src/class-connection-notice.php @@ -0,0 +1,223 @@ +id, + array( + 'jetpack_page_akismet-key-config', + 'admin_page_jetpack_modules', + ), + true + ) ) { + add_action( 'admin_notices', array( $this, 'delete_user_update_connection_owner_notice' ) ); + } + } + + /** + * This is an entire admin notice dedicated to messaging and handling of the case where a user is trying to delete + * the connection owner. + */ + public function delete_user_update_connection_owner_notice() { + global $current_screen; + + /* + * phpcs:disable WordPress.Security.NonceVerification.Recommended + * + * This function is firing within wp-admin and checks (below) if it is in the midst of a deletion on the users + * page. Nonce will be already checked by WordPress, so we do not need to check ourselves. + */ + + if ( ! isset( $current_screen->base ) || 'users' !== $current_screen->base ) { + return; + } + + if ( ! isset( $_REQUEST['action'] ) || 'delete' !== $_REQUEST['action'] ) { + return; + } + + // Get connection owner or bail. + $connection_manager = new Manager(); + $connection_owner_id = $connection_manager->get_connection_owner_id(); + if ( ! $connection_owner_id ) { + return; + } + $connection_owner_userdata = get_userdata( $connection_owner_id ); + + // Bail if we're not trying to delete connection owner. + $user_ids_to_delete = array(); + if ( isset( $_REQUEST['users'] ) ) { + $user_ids_to_delete = array_map( 'sanitize_text_field', wp_unslash( $_REQUEST['users'] ) ); + } elseif ( isset( $_REQUEST['user'] ) ) { + $user_ids_to_delete[] = sanitize_text_field( wp_unslash( $_REQUEST['user'] ) ); + } + + // phpcs:enable + $user_ids_to_delete = array_map( 'absint', $user_ids_to_delete ); + $deleting_connection_owner = in_array( $connection_owner_id, (array) $user_ids_to_delete, true ); + if ( ! $deleting_connection_owner ) { + return; + } + + // Bail if they're trying to delete themselves to avoid confusion. + if ( get_current_user_id() === $connection_owner_id ) { + return; + } + + $tracking = new Tracking(); + + // Track it! + if ( method_exists( $tracking, 'record_user_event' ) ) { + $tracking->record_user_event( 'delete_connection_owner_notice_view' ); + } + + $connected_admins = $connection_manager->get_connected_users( 'jetpack_disconnect' ); + $user = is_a( $connection_owner_userdata, 'WP_User' ) ? esc_html( $connection_owner_userdata->data->user_login ) : ''; + + echo "
"; + echo '

' . esc_html__( 'Important notice about your Jetpack connection:', 'jetpack-connection' ) . '

'; + echo '

' . sprintf( + /* translators: WordPress User, if available. */ + esc_html__( 'Warning! You are about to delete the Jetpack connection owner (%s) for this site, which may cause some of your Jetpack features to stop working.', 'jetpack-connection' ), + esc_html( $user ) + ) . '

'; + + if ( ! empty( $connected_admins ) && count( $connected_admins ) > 1 ) { + echo '
'; + echo "'; + + $connected_admin_ids = array_map( + function ( $connected_admin ) { + return $connected_admin->ID; + }, + $connected_admins + ); + + wp_dropdown_users( + array( + 'name' => 'owner', + 'include' => array_diff( $connected_admin_ids, array( $connection_owner_id ) ), + 'show' => 'display_name_with_login', + ) + ); + + echo '

'; + submit_button( esc_html__( 'Set new connection owner', 'jetpack-connection' ), 'primary', 'jp-switch-connection-owner-submit', false ); + echo '

'; + + echo "
"; + echo '
'; + ?> + + ' . esc_html__( 'Every Jetpack site needs at least one connected admin for the features to work properly. Please connect to your WordPress.com account via the button below. Once you connect, you may refresh this page to see an option to change the connection owner.', 'jetpack-connection' ) . '

'; + $connect_url = $connection_manager->get_authorization_url(); + $connect_url = add_query_arg( 'from', 'delete_connection_owner_notice', $connect_url ); + echo "" . esc_html__( 'Connect to WordPress.com', 'jetpack-connection' ) . ''; + } + + echo '

'; + printf( + wp_kses( + /* translators: URL to Jetpack support doc regarding the primary user. */ + __( "Learn more about the connection owner and what will break if you do not have one.", 'jetpack-connection' ), + array( + 'a' => array( + 'href' => true, + 'target' => true, + 'rel' => true, + ), + ) + ), + esc_url( Redirect::get_url( 'jetpack-support-primary-user' ) ) + ); + echo '

'; + echo '

'; + printf( + wp_kses( + /* translators: URL to contact Jetpack support. */ + __( 'As always, feel free to contact our support team if you have any questions.', 'jetpack-connection' ), + array( + 'a' => array( + 'href' => true, + 'target' => true, + 'rel' => true, + ), + ) + ), + esc_url( Redirect::get_url( 'jetpack-contact-support' ) ) + ); + echo '

'; + echo '
'; + } + +} diff --git a/projects/packages/connection/src/class-manager.php b/projects/packages/connection/src/class-manager.php index 4cb6b2e83512f..9254dc43a9713 100644 --- a/projects/packages/connection/src/class-manager.php +++ b/projects/packages/connection/src/class-manager.php @@ -131,6 +131,9 @@ public static function configure() { if ( defined( 'JETPACK__SANDBOX_DOMAIN' ) && JETPACK__SANDBOX_DOMAIN ) { ( new Server_Sandbox() )->init(); } + + // Initialize connection notices. + new Connection_Notice(); } /** diff --git a/projects/packages/connection/src/class-package-version.php b/projects/packages/connection/src/class-package-version.php index ffab5cfc318dc..27a338e319998 100644 --- a/projects/packages/connection/src/class-package-version.php +++ b/projects/packages/connection/src/class-package-version.php @@ -12,7 +12,7 @@ */ class Package_Version { - const PACKAGE_VERSION = '1.50.2-alpha'; + const PACKAGE_VERSION = '1.51.0-alpha'; const PACKAGE_SLUG = 'connection'; diff --git a/projects/packages/connection/tests/php/test-class-connection-notice.php b/projects/packages/connection/tests/php/test-class-connection-notice.php new file mode 100644 index 0000000000000..2c829ce7bd202 --- /dev/null +++ b/projects/packages/connection/tests/php/test-class-connection-notice.php @@ -0,0 +1,168 @@ +expectOutputRegex( '#Connect to WordPress.com#i' ); + $this->expectOutputRegex( '#https://jetpack\.wordpress\.com/jetpack\.authorize/1/\?response_type=code#i' ); + + $notice->delete_user_update_connection_owner_notice(); + + \Jetpack_Options::update_option( 'user_tokens', $tokens ); + } + + /** + * Testing the "choose new owner" notice. + */ + public function test_delete_user_change_owner_notice() { + $notice = new Connection_Notice(); + + $this->expectOutputRegex( '#Set new connection owner#i' ); + $this->expectOutputRegex( '#http://example\.org/index\.php\?rest_route=/jetpack/v4/connection/owner#i' ); + + $notice->delete_user_update_connection_owner_notice(); + } + + /** + * Set up the environment. + * + * @before + * + * @return void + */ + protected function set_up() { + global $current_screen; + + \Jetpack_Options::update_option( 'blog_token', 'asdasd.123123' ); + \Jetpack_Options::update_option( 'id', '12345' ); + + $id_admin = wp_insert_user( + array( + 'user_login' => 'admin', + 'user_pass' => 'pass', + 'role' => 'administrator', + ) + ); + $this->fake_users[] = $id_admin; + + $id_admin2 = wp_insert_user( + array( + 'user_login' => 'admin2', + 'user_pass' => 'pass2', + 'role' => 'administrator', + ) + ); + $this->fake_users[] = $id_admin2; + wp_set_current_user( $id_admin2 ); + + set_transient( 'jetpack_connected_user_data_' . $id_admin2, array( 'ID' => '12345' ) ); + + // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + $current_screen = \WP_Screen::get(); + $current_screen->base = 'users'; + + $_REQUEST['action'] = 'delete'; + $_REQUEST['user'] = $id_admin; + + $admin_role = get_role( 'administrator' ); + $admin_role->add_cap( 'jetpack_disconnect', true ); + + Constants::set_constant( 'JETPACK__API_BASE', 'https://jetpack.wordpress.com/jetpack.' ); + Constants::set_constant( 'JETPACK__API_VERSION', '1' ); + + \Jetpack_Options::update_option( + 'user_tokens', + array( + $id_admin => 'asd123.asd123.' . $id_admin, + $id_admin2 => 'asd123.asd123.' . $id_admin2, + ) + ); + \Jetpack_Options::update_option( 'master_user', $id_admin ); + + $this->users_query_filter = function ( $result, $query ) { + if ( 0 === strpos( trim( $query ), 'SELECT wp_users.user_registered' ) + && preg_match( '#wp_usermeta\.meta_value LIKE \'\{.*?\}"administrator"\{.*?\}\'#i', $query ) + ) { + return array( (object) array( 'user_registered' => '2012-03-19 00:00:00' ) ); + } + + return $result; + }; + + add_filter( 'wordbless_wpdb_query_results', $this->users_query_filter, 10, 2 ); + } + + /** + * Clean up. + * + * @after + * + * @return void + */ + protected function tear_down() { + global $current_screen; + + delete_transient( 'jetpack_connected_user_data_' . get_current_user_id() ); + + unset( $current_screen ); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + unset( $_REQUEST['action'] ); + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + unset( $_REQUEST['user'] ); + + \Jetpack_Options::delete_option( 'blog_token' ); + \Jetpack_Options::delete_option( 'user_tokens' ); + \Jetpack_Options::delete_option( 'id' ); + \Jetpack_Options::delete_option( 'master_user' ); + + remove_filter( 'wordbless_wpdb_query_results', $this->users_query_filter, 10 ); + + Constants::clear_constants(); + + wp_destroy_current_session(); + + foreach ( $this->fake_users as $user_id ) { + wp_delete_user( $user_id ); + } + + $admin_role = get_role( 'administrator' ); + $admin_role->remove_cap( 'jetpack_disconnect' ); + } +} diff --git a/projects/packages/jitm/changelog/update-move-delete-connection-owner-notice b/projects/packages/jitm/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..819bafa1a1ee8 --- /dev/null +++ b/projects/packages/jitm/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,4 @@ +Significance: minor +Type: changed + +Moving deleting connection owner notice from JITM to Connection package. diff --git a/projects/packages/jitm/composer.json b/projects/packages/jitm/composer.json index 7b77465245659..26744020cdd07 100644 --- a/projects/packages/jitm/composer.json +++ b/projects/packages/jitm/composer.json @@ -66,7 +66,7 @@ "link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "2.2.x-dev" + "dev-trunk": "2.3.x-dev" } } } diff --git a/projects/packages/jitm/src/class-jitm.php b/projects/packages/jitm/src/class-jitm.php index 704cbf3238487..4e309fb0321f5 100644 --- a/projects/packages/jitm/src/class-jitm.php +++ b/projects/packages/jitm/src/class-jitm.php @@ -20,7 +20,7 @@ */ class JITM { - const PACKAGE_VERSION = '2.2.42'; + const PACKAGE_VERSION = '2.3.0-alpha'; /** * The configuration method that is called from the jetpack-config package. diff --git a/projects/packages/jitm/src/class-post-connection-jitm.php b/projects/packages/jitm/src/class-post-connection-jitm.php index 79aaf3cf50f9e..4ff2eb76fcd95 100644 --- a/projects/packages/jitm/src/class-post-connection-jitm.php +++ b/projects/packages/jitm/src/class-post-connection-jitm.php @@ -40,31 +40,6 @@ public function __construct() { $this->tracking = new Tracking(); } - /** - * Prepare actions according to screen and post type. - * - * @since 1.1.0 - * @since-jetpack 3.8.2 - * - * @uses Jetpack_Autoupdate::get_possible_failures() - * - * @param \WP_Screen $screen WP Core's screen object. - */ - public function prepare_jitms( $screen ) { - parent::prepare_jitms( $screen ); - if ( ! in_array( - $screen->id, - array( - 'jetpack_page_akismet-key-config', - 'admin_page_jetpack_modules', - ), - true - ) ) { - // Not really a JITM. Don't know where else to put this :) . - add_action( 'admin_notices', array( $this, 'delete_user_update_connection_owner_notice' ) ); - } - } - /** * A special filter for WooCommerce, to set a message based on local state. * @@ -229,172 +204,6 @@ public static function jitm_jetpack_boost_activate() { ); } - /** - * This is an entire admin notice dedicated to messaging and handling of the case where a user is trying to delete - * the connection owner. - */ - public function delete_user_update_connection_owner_notice() { - global $current_screen; - - /* - * phpcs:disable WordPress.Security.NonceVerification.Recommended - * - * This function is firing within wp-admin and checks (below) if it is in the midst of a deletion on the users - * page. Nonce will be already checked by WordPress, so we do not need to check ourselves. - */ - - if ( ! isset( $current_screen->base ) || 'users' !== $current_screen->base ) { - return; - } - - if ( ! isset( $_REQUEST['action'] ) || 'delete' !== $_REQUEST['action'] ) { - return; - } - - // Get connection owner or bail. - $connection_manager = new Manager(); - $connection_owner_id = $connection_manager->get_connection_owner_id(); - if ( ! $connection_owner_id ) { - return; - } - $connection_owner_userdata = get_userdata( $connection_owner_id ); - - // Bail if we're not trying to delete connection owner. - $user_ids_to_delete = array(); - if ( isset( $_REQUEST['users'] ) ) { - $user_ids_to_delete = array_map( 'sanitize_text_field', wp_unslash( $_REQUEST['users'] ) ); - } elseif ( isset( $_REQUEST['user'] ) ) { - $user_ids_to_delete[] = sanitize_text_field( wp_unslash( $_REQUEST['user'] ) ); - } - - // phpcs:enable - $user_ids_to_delete = array_map( 'absint', $user_ids_to_delete ); - $deleting_connection_owner = in_array( $connection_owner_id, (array) $user_ids_to_delete, true ); - if ( ! $deleting_connection_owner ) { - return; - } - - // Bail if they're trying to delete themselves to avoid confusion. - if ( get_current_user_id() === $connection_owner_id ) { - return; - } - - // Track it! - if ( method_exists( $this->tracking, 'record_user_event' ) ) { - $this->tracking->record_user_event( 'delete_connection_owner_notice_view' ); - } - - $connected_admins = $connection_manager->get_connected_users( 'jetpack_disconnect' ); - $user = is_a( $connection_owner_userdata, 'WP_User' ) ? esc_html( $connection_owner_userdata->data->user_login ) : ''; - - echo "
"; - echo '

' . esc_html__( 'Important notice about your Jetpack connection:', 'jetpack-jitm' ) . '

'; - echo '

' . sprintf( - /* translators: WordPress User, if available. */ - esc_html__( 'Warning! You are about to delete the Jetpack connection owner (%s) for this site, which may cause some of your Jetpack features to stop working.', 'jetpack-jitm' ), - esc_html( $user ) - ) . '

'; - - if ( ! empty( $connected_admins ) && count( $connected_admins ) > 1 ) { - echo '
'; - echo "'; - - $connected_admin_ids = array_map( - function ( $connected_admin ) { - return $connected_admin->ID; - }, - $connected_admins - ); - - wp_dropdown_users( - array( - 'name' => 'owner', - 'include' => array_diff( $connected_admin_ids, array( $connection_owner_id ) ), - 'show' => 'display_name_with_login', - ) - ); - - echo '

'; - submit_button( esc_html__( 'Set new connection owner', 'jetpack-jitm' ), 'primary', 'jp-switch-connection-owner-submit', false ); - echo '

'; - - echo "
"; - echo '
'; - ?> - - ' . esc_html__( 'Every Jetpack site needs at least one connected admin for the features to work properly. Please connect to your WordPress.com account via the button below. Once you connect, you may refresh this page to see an option to change the connection owner.', 'jetpack-jitm' ) . '

'; - $connect_url = $connection_manager->get_authorization_url(); - $connect_url = add_query_arg( 'from', 'delete_connection_owner_notice', $connect_url ); - echo "" . esc_html__( 'Connect to WordPress.com', 'jetpack-jitm' ) . ''; - } - - echo '

'; - printf( - wp_kses( - /* translators: URL to Jetpack support doc regarding the primary user. */ - __( "Learn more about the connection owner and what will break if you do not have one.", 'jetpack-jitm' ), - array( - 'a' => array( - 'href' => true, - 'target' => true, - 'rel' => true, - ), - ) - ), - esc_url( Redirect::get_url( 'jetpack-support-primary-user' ) ) - ); - echo '

'; - echo '

'; - printf( - wp_kses( - /* translators: URL to contact Jetpack support. */ - __( 'As always, feel free to contact our support team if you have any questions.', 'jetpack-jitm' ), - array( - 'a' => array( - 'href' => true, - 'target' => true, - 'rel' => true, - ), - ) - ), - esc_url( Redirect::get_url( 'jetpack-contact-support' ) ) - ); - echo '

'; - echo '
'; - } - /** * Dismisses a JITM feature class so that it will no longer be shown. * diff --git a/projects/packages/videopress/changelog/update-move-delete-connection-owner-notice b/projects/packages/videopress/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..286356ac211bd --- /dev/null +++ b/projects/packages/videopress/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Auto-formatting of some files. diff --git a/projects/packages/wp-js-data-sync/changelog/update-move-delete-connection-owner-notice b/projects/packages/wp-js-data-sync/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..257377d5d535a --- /dev/null +++ b/projects/packages/wp-js-data-sync/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Auto-formatting files. diff --git a/projects/plugins/backup/changelog/update-move-delete-connection-owner-notice b/projects/plugins/backup/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/backup/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/backup/changelog/update-move-delete-connection-owner-notice#2 b/projects/plugins/backup/changelog/update-move-delete-connection-owner-notice#2 new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/backup/changelog/update-move-delete-connection-owner-notice#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/backup/composer.lock b/projects/plugins/backup/composer.lock index b8fcb1d5827f8..68636398c51a9 100644 --- a/projects/plugins/backup/composer.lock +++ b/projects/plugins/backup/composer.lock @@ -412,7 +412,7 @@ "dist": { "type": "path", "url": "../../packages/connection", - "reference": "dab8bbf39827ae9e82e29437cd2823e07b2faca2" + "reference": "ea20a733eaf9933db0f7f261c1fc8f0fe9f0e016" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -440,7 +440,7 @@ "link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.50.x-dev" + "dev-trunk": "1.51.x-dev" } }, "autoload": { @@ -657,7 +657,7 @@ "dist": { "type": "path", "url": "../../packages/jitm", - "reference": "708bdf617a6e483c8c0ec81bade35db47c354440" + "reference": "d49bbc0fba9e8a2964264a83da308a72223dee92" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -686,7 +686,7 @@ "link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "2.2.x-dev" + "dev-trunk": "2.3.x-dev" } }, "autoload": { diff --git a/projects/plugins/boost/changelog/update-move-delete-connection-owner-notice b/projects/plugins/boost/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/boost/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/boost/changelog/update-move-delete-connection-owner-notice#2 b/projects/plugins/boost/changelog/update-move-delete-connection-owner-notice#2 new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/boost/changelog/update-move-delete-connection-owner-notice#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/boost/composer.lock b/projects/plugins/boost/composer.lock index 514c0ea88d67e..999b6dd753a54 100644 --- a/projects/plugins/boost/composer.lock +++ b/projects/plugins/boost/composer.lock @@ -327,7 +327,7 @@ "dist": { "type": "path", "url": "../../packages/connection", - "reference": "dab8bbf39827ae9e82e29437cd2823e07b2faca2" + "reference": "ea20a733eaf9933db0f7f261c1fc8f0fe9f0e016" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -355,7 +355,7 @@ "link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.50.x-dev" + "dev-trunk": "1.51.x-dev" } }, "autoload": { @@ -497,7 +497,7 @@ "dist": { "type": "path", "url": "../../packages/jitm", - "reference": "708bdf617a6e483c8c0ec81bade35db47c354440" + "reference": "d49bbc0fba9e8a2964264a83da308a72223dee92" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -526,7 +526,7 @@ "link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "2.2.x-dev" + "dev-trunk": "2.3.x-dev" } }, "autoload": { diff --git a/projects/plugins/jetpack/changelog/update-move-delete-connection-owner-notice b/projects/plugins/jetpack/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..a1c1831fa1ef7 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,5 @@ +Significance: patch +Type: other +Comment: Updated composer.lock. + + diff --git a/projects/plugins/jetpack/changelog/update-move-delete-connection-owner-notice#2 b/projects/plugins/jetpack/changelog/update-move-delete-connection-owner-notice#2 new file mode 100644 index 0000000000000..a1c1831fa1ef7 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-move-delete-connection-owner-notice#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: other +Comment: Updated composer.lock. + + diff --git a/projects/plugins/jetpack/composer.lock b/projects/plugins/jetpack/composer.lock index a0bdf9697b7a6..a3d04f525cf40 100644 --- a/projects/plugins/jetpack/composer.lock +++ b/projects/plugins/jetpack/composer.lock @@ -702,7 +702,7 @@ "dist": { "type": "path", "url": "../../packages/connection", - "reference": "dab8bbf39827ae9e82e29437cd2823e07b2faca2" + "reference": "ea20a733eaf9933db0f7f261c1fc8f0fe9f0e016" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -730,7 +730,7 @@ "link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.50.x-dev" + "dev-trunk": "1.51.x-dev" } }, "autoload": { @@ -1118,7 +1118,7 @@ "dist": { "type": "path", "url": "../../packages/jitm", - "reference": "708bdf617a6e483c8c0ec81bade35db47c354440" + "reference": "d49bbc0fba9e8a2964264a83da308a72223dee92" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -1147,7 +1147,7 @@ "link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "2.2.x-dev" + "dev-trunk": "2.3.x-dev" } }, "autoload": { diff --git a/projects/plugins/migration/changelog/update-move-delete-connection-owner-notice b/projects/plugins/migration/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/migration/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/migration/changelog/update-move-delete-connection-owner-notice#2 b/projects/plugins/migration/changelog/update-move-delete-connection-owner-notice#2 new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/migration/changelog/update-move-delete-connection-owner-notice#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/migration/composer.lock b/projects/plugins/migration/composer.lock index e5eec6d94cc04..34dad27f9b49b 100644 --- a/projects/plugins/migration/composer.lock +++ b/projects/plugins/migration/composer.lock @@ -327,7 +327,7 @@ "dist": { "type": "path", "url": "../../packages/connection", - "reference": "dab8bbf39827ae9e82e29437cd2823e07b2faca2" + "reference": "ea20a733eaf9933db0f7f261c1fc8f0fe9f0e016" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -355,7 +355,7 @@ "link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.50.x-dev" + "dev-trunk": "1.51.x-dev" } }, "autoload": { @@ -572,7 +572,7 @@ "dist": { "type": "path", "url": "../../packages/jitm", - "reference": "708bdf617a6e483c8c0ec81bade35db47c354440" + "reference": "d49bbc0fba9e8a2964264a83da308a72223dee92" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -601,7 +601,7 @@ "link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "2.2.x-dev" + "dev-trunk": "2.3.x-dev" } }, "autoload": { diff --git a/projects/plugins/protect/changelog/update-move-delete-connection-owner-notice b/projects/plugins/protect/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/protect/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/protect/changelog/update-move-delete-connection-owner-notice#2 b/projects/plugins/protect/changelog/update-move-delete-connection-owner-notice#2 new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/protect/changelog/update-move-delete-connection-owner-notice#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/protect/composer.lock b/projects/plugins/protect/composer.lock index 1ae480e83c2a3..b1be744242de9 100644 --- a/projects/plugins/protect/composer.lock +++ b/projects/plugins/protect/composer.lock @@ -327,7 +327,7 @@ "dist": { "type": "path", "url": "../../packages/connection", - "reference": "dab8bbf39827ae9e82e29437cd2823e07b2faca2" + "reference": "ea20a733eaf9933db0f7f261c1fc8f0fe9f0e016" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -355,7 +355,7 @@ "link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.50.x-dev" + "dev-trunk": "1.51.x-dev" } }, "autoload": { @@ -572,7 +572,7 @@ "dist": { "type": "path", "url": "../../packages/jitm", - "reference": "708bdf617a6e483c8c0ec81bade35db47c354440" + "reference": "d49bbc0fba9e8a2964264a83da308a72223dee92" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -601,7 +601,7 @@ "link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "2.2.x-dev" + "dev-trunk": "2.3.x-dev" } }, "autoload": { diff --git a/projects/plugins/search/changelog/update-move-delete-connection-owner-notice b/projects/plugins/search/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/search/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/search/changelog/update-move-delete-connection-owner-notice#2 b/projects/plugins/search/changelog/update-move-delete-connection-owner-notice#2 new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/search/changelog/update-move-delete-connection-owner-notice#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/search/composer.lock b/projects/plugins/search/composer.lock index 77f4663497d46..77b8ff0911170 100644 --- a/projects/plugins/search/composer.lock +++ b/projects/plugins/search/composer.lock @@ -327,7 +327,7 @@ "dist": { "type": "path", "url": "../../packages/connection", - "reference": "dab8bbf39827ae9e82e29437cd2823e07b2faca2" + "reference": "ea20a733eaf9933db0f7f261c1fc8f0fe9f0e016" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -355,7 +355,7 @@ "link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.50.x-dev" + "dev-trunk": "1.51.x-dev" } }, "autoload": { @@ -572,7 +572,7 @@ "dist": { "type": "path", "url": "../../packages/jitm", - "reference": "708bdf617a6e483c8c0ec81bade35db47c354440" + "reference": "d49bbc0fba9e8a2964264a83da308a72223dee92" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -601,7 +601,7 @@ "link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "2.2.x-dev" + "dev-trunk": "2.3.x-dev" } }, "autoload": { diff --git a/projects/plugins/social/changelog/update-move-delete-connection-owner-notice b/projects/plugins/social/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/social/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/social/changelog/update-move-delete-connection-owner-notice#2 b/projects/plugins/social/changelog/update-move-delete-connection-owner-notice#2 new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/social/changelog/update-move-delete-connection-owner-notice#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/social/composer.lock b/projects/plugins/social/composer.lock index dc5c204743fdd..b5990bb9d1550 100644 --- a/projects/plugins/social/composer.lock +++ b/projects/plugins/social/composer.lock @@ -327,7 +327,7 @@ "dist": { "type": "path", "url": "../../packages/connection", - "reference": "dab8bbf39827ae9e82e29437cd2823e07b2faca2" + "reference": "ea20a733eaf9933db0f7f261c1fc8f0fe9f0e016" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -355,7 +355,7 @@ "link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.50.x-dev" + "dev-trunk": "1.51.x-dev" } }, "autoload": { @@ -572,7 +572,7 @@ "dist": { "type": "path", "url": "../../packages/jitm", - "reference": "708bdf617a6e483c8c0ec81bade35db47c354440" + "reference": "d49bbc0fba9e8a2964264a83da308a72223dee92" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -601,7 +601,7 @@ "link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "2.2.x-dev" + "dev-trunk": "2.3.x-dev" } }, "autoload": { diff --git a/projects/plugins/starter-plugin/changelog/update-move-delete-connection-owner-notice b/projects/plugins/starter-plugin/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/starter-plugin/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/starter-plugin/changelog/update-move-delete-connection-owner-notice#2 b/projects/plugins/starter-plugin/changelog/update-move-delete-connection-owner-notice#2 new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/starter-plugin/changelog/update-move-delete-connection-owner-notice#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/starter-plugin/composer.lock b/projects/plugins/starter-plugin/composer.lock index d1ec24b2554bc..6a014fdeae517 100644 --- a/projects/plugins/starter-plugin/composer.lock +++ b/projects/plugins/starter-plugin/composer.lock @@ -327,7 +327,7 @@ "dist": { "type": "path", "url": "../../packages/connection", - "reference": "dab8bbf39827ae9e82e29437cd2823e07b2faca2" + "reference": "ea20a733eaf9933db0f7f261c1fc8f0fe9f0e016" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -355,7 +355,7 @@ "link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.50.x-dev" + "dev-trunk": "1.51.x-dev" } }, "autoload": { @@ -572,7 +572,7 @@ "dist": { "type": "path", "url": "../../packages/jitm", - "reference": "708bdf617a6e483c8c0ec81bade35db47c354440" + "reference": "d49bbc0fba9e8a2964264a83da308a72223dee92" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -601,7 +601,7 @@ "link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "2.2.x-dev" + "dev-trunk": "2.3.x-dev" } }, "autoload": { diff --git a/projects/plugins/videopress/changelog/update-move-delete-connection-owner-notice b/projects/plugins/videopress/changelog/update-move-delete-connection-owner-notice new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/videopress/changelog/update-move-delete-connection-owner-notice @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/videopress/changelog/update-move-delete-connection-owner-notice#2 b/projects/plugins/videopress/changelog/update-move-delete-connection-owner-notice#2 new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/videopress/changelog/update-move-delete-connection-owner-notice#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/videopress/composer.lock b/projects/plugins/videopress/composer.lock index 524304efb9aec..22319b86341d9 100644 --- a/projects/plugins/videopress/composer.lock +++ b/projects/plugins/videopress/composer.lock @@ -327,7 +327,7 @@ "dist": { "type": "path", "url": "../../packages/connection", - "reference": "dab8bbf39827ae9e82e29437cd2823e07b2faca2" + "reference": "ea20a733eaf9933db0f7f261c1fc8f0fe9f0e016" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -355,7 +355,7 @@ "link-template": "https://github.com/Automattic/jetpack-connection/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.50.x-dev" + "dev-trunk": "1.51.x-dev" } }, "autoload": { @@ -572,7 +572,7 @@ "dist": { "type": "path", "url": "../../packages/jitm", - "reference": "708bdf617a6e483c8c0ec81bade35db47c354440" + "reference": "d49bbc0fba9e8a2964264a83da308a72223dee92" }, "require": { "automattic/jetpack-a8c-mc-stats": "@dev", @@ -601,7 +601,7 @@ "link-template": "https://github.com/Automattic/jetpack-jitm/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "2.2.x-dev" + "dev-trunk": "2.3.x-dev" } }, "autoload": { From 051be646b77b060bfa20d4939f69386f6084e8e0 Mon Sep 17 00:00:00 2001 From: Robert Felty Date: Thu, 16 Feb 2023 08:51:02 +0100 Subject: [PATCH 02/51] Fix/jetpack search multiple authors (#28975) * better formatting for multiple authors * changelog * Bump package version --------- Co-authored-by: Jason Moon --- .../search/changelog/fix-jetpack-search-multiple-authors | 4 ++++ .../instant-search/components/search-result-expanded.jsx | 8 ++++++++ 2 files changed, 12 insertions(+) create mode 100644 projects/packages/search/changelog/fix-jetpack-search-multiple-authors diff --git a/projects/packages/search/changelog/fix-jetpack-search-multiple-authors b/projects/packages/search/changelog/fix-jetpack-search-multiple-authors new file mode 100644 index 0000000000000..88094bcbf03fb --- /dev/null +++ b/projects/packages/search/changelog/fix-jetpack-search-multiple-authors @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Separated authors by comments if there are multiple authors in a search result diff --git a/projects/packages/search/src/instant-search/components/search-result-expanded.jsx b/projects/packages/search/src/instant-search/components/search-result-expanded.jsx index 47cb368c3287e..97ad26e871b88 100644 --- a/projects/packages/search/src/instant-search/components/search-result-expanded.jsx +++ b/projects/packages/search/src/instant-search/components/search-result-expanded.jsx @@ -37,6 +37,14 @@ export default function SearchResultExpanded( props ) { const firstImage = Array.isArray( fields[ 'image.url.raw' ] ) ? fields[ 'image.url.raw' ][ 0 ] : fields[ 'image.url.raw' ]; + + if ( Array.isArray( fields.author ) ) { + if ( fields.author.length > 3 ) { + fields.author = fields.author.slice( 0, 3 ).join( ', ' ) + '...'; + } else { + fields.author = fields.author.join( ', ' ); + } + } return (
  • Date: Thu, 16 Feb 2023 07:52:25 -0300 Subject: [PATCH 03/51] VideoPress: restore v5/v6 transform for all platforms (#28986) * Allow transform from/to v5/v6 for Simple sites too * restore v5/v6 video block transform * changelog --- .../update-videopress-allow-v5-v6-transforms | 4 ++++ .../jetpack/extensions/blocks/videopress/editor.js | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 projects/plugins/jetpack/changelog/update-videopress-allow-v5-v6-transforms diff --git a/projects/plugins/jetpack/changelog/update-videopress-allow-v5-v6-transforms b/projects/plugins/jetpack/changelog/update-videopress-allow-v5-v6-transforms new file mode 100644 index 0000000000000..a8aa9a6f4d1d1 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-videopress-allow-v5-v6-transforms @@ -0,0 +1,4 @@ +Significance: patch +Type: enhancement + +VideoPress: restore v5/v6 transform for all platforms diff --git a/projects/plugins/jetpack/extensions/blocks/videopress/editor.js b/projects/plugins/jetpack/extensions/blocks/videopress/editor.js index 476ea624b3a00..24528a54ccc28 100644 --- a/projects/plugins/jetpack/extensions/blocks/videopress/editor.js +++ b/projects/plugins/jetpack/extensions/blocks/videopress/editor.js @@ -419,16 +419,18 @@ addFilter( * @returns {object} Modified block settings. */ function addVideoPressCoreVideoTransform( settings, name ) { + // Apply only to videopress/video block. + if ( name !== 'videopress/video' ) { + return settings; + } + const isVideoPressVideoBlockRegistered = getBlockType( 'videopress/video' ); const { available: isVideoPressVideoBlockAvailable } = getJetpackExtensionAvailability( 'videopress/video' ); - if ( isVideoPressVideoBlockRegistered && isVideoPressVideoBlockAvailable && isSimpleSite() ) { - return settings; - } - - if ( name !== 'videopress/video' ) { + // If videopress/video block is not registered or not available, do not extend transforms. + if ( ! isVideoPressVideoBlockRegistered || ! isVideoPressVideoBlockAvailable ) { return settings; } From 15f1f119f4859ded15e0f073ebca52bc732ceb66 Mon Sep 17 00:00:00 2001 From: Francesco Bigiarini Date: Thu, 16 Feb 2023 12:25:27 +0100 Subject: [PATCH 04/51] Add import package (#28824) * [not verified] Add base endpoints. * [not verified] Minor refactoring of DB queries. * [not verified] Added Import package to Config package. * [not verified] Added Import package * [not verified] Changelog * [not verified] Remove unnecessary code * [not verified] Fix: wrong changelog type * [not verified] Fix: outdated jetpack/composer.lock * [not verified] Fix: wrong file name * [not verified] Add support for pages * [not verified] Fix: assign global namespace * [not verified] Add check for existing posts * [not verified] Fix: wrong inheritance * [not verified] Fix: missing post ID * [not verified] Fix undefined type * [not verified] Add missing fields * [not verified] Fix: missing categories and tags * [not verified] Fix: missing ID * [not verified] Add check if the user is connected to WPCOM * [not verified] Update composer.lock files * [not verified] Move terms extraction to its own method * [not verified] changelog * [not verified] Bump version * Bump version --- .../components/changelog/fix-wrong-version | 4 + projects/js-packages/components/package.json | 2 +- .../config/changelog/add-import-package | 4 + projects/packages/config/composer.json | 2 +- projects/packages/config/src/class-config.php | 16 ++ .../import/changelog/add-rest-endpoints | 4 + projects/packages/import/composer.json | 6 +- projects/packages/import/src/class-import.php | 27 --- projects/packages/import/src/class-main.php | 89 +++++++++ .../import/src/endpoints/class-category.php | 102 ++++++++++ .../import/src/endpoints/class-comment.php | 78 ++++++++ .../import/src/endpoints/class-page.php | 45 +++++ .../import/src/endpoints/class-post.php | 158 +++++++++++++++ .../import/src/endpoints/class-tag.php | 61 ++++++ .../import/src/endpoints/trait-import.php | 180 ++++++++++++++++++ .../backup/changelog/update-import-package | 5 + projects/plugins/backup/composer.lock | 4 +- .../boost/changelog/update-import-package | 5 + projects/plugins/boost/composer.lock | 4 +- .../jetpack/changelog/add-import-package | 4 + .../jetpack/changelog/update-import-package | 5 + projects/plugins/jetpack/class.jetpack.php | 1 + projects/plugins/jetpack/composer.json | 1 + projects/plugins/jetpack/composer.lock | 74 ++++++- .../migration/changelog/update-import-package | 5 + projects/plugins/migration/composer.lock | 4 +- .../protect/changelog/update-import-package | 5 + projects/plugins/protect/composer.lock | 4 +- .../search/changelog/update-import-package | 5 + projects/plugins/search/composer.lock | 4 +- .../social/changelog/update-import-package | 5 + projects/plugins/social/composer.lock | 4 +- .../changelog/update-import-package | 5 + projects/plugins/starter-plugin/composer.lock | 4 +- .../changelog/update-import-package | 5 + projects/plugins/videopress/composer.lock | 4 +- 36 files changed, 885 insertions(+), 50 deletions(-) create mode 100644 projects/js-packages/components/changelog/fix-wrong-version create mode 100644 projects/packages/config/changelog/add-import-package create mode 100644 projects/packages/import/changelog/add-rest-endpoints delete mode 100644 projects/packages/import/src/class-import.php create mode 100644 projects/packages/import/src/class-main.php create mode 100644 projects/packages/import/src/endpoints/class-category.php create mode 100644 projects/packages/import/src/endpoints/class-comment.php create mode 100644 projects/packages/import/src/endpoints/class-page.php create mode 100644 projects/packages/import/src/endpoints/class-post.php create mode 100644 projects/packages/import/src/endpoints/class-tag.php create mode 100644 projects/packages/import/src/endpoints/trait-import.php create mode 100644 projects/plugins/backup/changelog/update-import-package create mode 100644 projects/plugins/boost/changelog/update-import-package create mode 100644 projects/plugins/jetpack/changelog/add-import-package create mode 100644 projects/plugins/jetpack/changelog/update-import-package create mode 100644 projects/plugins/migration/changelog/update-import-package create mode 100644 projects/plugins/protect/changelog/update-import-package create mode 100644 projects/plugins/search/changelog/update-import-package create mode 100644 projects/plugins/social/changelog/update-import-package create mode 100644 projects/plugins/starter-plugin/changelog/update-import-package create mode 100644 projects/plugins/videopress/changelog/update-import-package diff --git a/projects/js-packages/components/changelog/fix-wrong-version b/projects/js-packages/components/changelog/fix-wrong-version new file mode 100644 index 0000000000000..599054c81e9b4 --- /dev/null +++ b/projects/js-packages/components/changelog/fix-wrong-version @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Changed wrong version diff --git a/projects/js-packages/components/package.json b/projects/js-packages/components/package.json index c4e4226ff28fe..775fea4841c2e 100644 --- a/projects/js-packages/components/package.json +++ b/projects/js-packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@automattic/jetpack-components", - "version": "0.27.6", + "version": "0.27.7-alpha", "description": "Jetpack Components Package", "author": "Automattic", "license": "GPL-2.0-or-later", diff --git a/projects/packages/config/changelog/add-import-package b/projects/packages/config/changelog/add-import-package new file mode 100644 index 0000000000000..68054e25d828c --- /dev/null +++ b/projects/packages/config/changelog/add-import-package @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Added the Import package. diff --git a/projects/packages/config/composer.json b/projects/packages/config/composer.json index 09dc2304e2a09..74564e1333fd2 100644 --- a/projects/packages/config/composer.json +++ b/projects/packages/config/composer.json @@ -31,7 +31,7 @@ "link-template": "https://github.com/Automattic/jetpack-config/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.13.x-dev" + "dev-trunk": "1.14.x-dev" } } } diff --git a/projects/packages/config/src/class-config.php b/projects/packages/config/src/class-config.php index c4277002342b2..125534da8f914 100644 --- a/projects/packages/config/src/class-config.php +++ b/projects/packages/config/src/class-config.php @@ -15,6 +15,7 @@ use Automattic\Jetpack\Blaze as Blaze; use Automattic\Jetpack\Connection\Manager; use Automattic\Jetpack\Connection\Plugin; +use Automattic\Jetpack\Import\Main as Import_Main; use Automattic\Jetpack\JITM as JITM; use Automattic\Jetpack\JITMS\JITM as JITMS_JITM; use Automattic\Jetpack\Post_List\Post_List as Post_List; @@ -55,6 +56,7 @@ class Config { 'stats' => false, 'stats_admin' => false, 'blaze' => false, + 'import' => false, ); /** @@ -162,6 +164,11 @@ public function on_plugins_loaded() { if ( $this->config['blaze'] ) { $this->ensure_class( 'Automattic\Jetpack\Blaze' ) && $this->ensure_feature( 'blaze' ); } + + if ( $this->config['import'] ) { + $this->ensure_class( 'Automattic\Jetpack\Import\Main' ) + && $this->ensure_feature( 'import' ); + } } /** @@ -355,6 +362,15 @@ protected function enable_blaze() { return true; } + /** + * Enables the Import feature. + */ + protected function enable_import() { + Import_Main::configure(); + + return true; + } + /** * Setup the Connection options. */ diff --git a/projects/packages/import/changelog/add-rest-endpoints b/projects/packages/import/changelog/add-rest-endpoints new file mode 100644 index 0000000000000..4458504769c25 --- /dev/null +++ b/projects/packages/import/changelog/add-rest-endpoints @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Added import REST endpoints. diff --git a/projects/packages/import/composer.json b/projects/packages/import/composer.json index 4794daa03d3d1..9e25faca16c03 100644 --- a/projects/packages/import/composer.json +++ b/projects/packages/import/composer.json @@ -3,7 +3,9 @@ "description": "Set of REST API routes used in WPCOM Unified Importer.", "type": "jetpack-library", "license": "GPL-2.0-or-later", - "require": {}, + "require": { + "automattic/jetpack-connection": "@dev" + }, "require-dev": { "yoast/phpunit-polyfills": "1.0.4", "automattic/jetpack-changelogger": "@dev", @@ -56,7 +58,7 @@ }, "textdomain": "jetpack-import", "version-constants": { - "::PACKAGE_VERSION": "src/class-import.php" + "::PACKAGE_VERSION": "src/class-main.php" } } } diff --git a/projects/packages/import/src/class-import.php b/projects/packages/import/src/class-import.php deleted file mode 100644 index 25ad6671bb29a..0000000000000 --- a/projects/packages/import/src/class-import.php +++ /dev/null @@ -1,27 +0,0 @@ -has_connected_owner() ) { + add_action( 'rest_api_init', array( __CLASS__, 'initialize_rest_api' ) ); + } + + /** + * Runs right after the Jetpack Import package is initialized. + * + * @since $$next-version$$ + */ + do_action( 'jetpack_import_initialized' ); + } + + /** + * Register import related REST routes. + * + * @return void + */ + public static function initialize_rest_api() { + // Set up the REST authentication hooks. + Rest_Authentication::init(); + + $routes = array( + 'categories' => new Endpoints\Category(), + 'comments' => new Endpoints\Comment(), + 'pages' => new Endpoints\Page(), + 'posts' => new Endpoints\Post(), + 'tags' => new Endpoints\Tag(), + ); + + /** + * Allow other plugins to modify import routes. + * + * @since $$next-version$$ + * + * @param array $routes Array of import routes. + */ + self::$routes = apply_filters( 'jetpack_import_types', $routes ); + + // Register all the routes. + foreach ( self::$routes as $route ) { + $route->register_routes(); + } + } +} diff --git a/projects/packages/import/src/endpoints/class-category.php b/projects/packages/import/src/endpoints/class-category.php new file mode 100644 index 0000000000000..a96ee9f77551e --- /dev/null +++ b/projects/packages/import/src/endpoints/class-category.php @@ -0,0 +1,102 @@ +import_id_meta_type = 'term'; + } + + /** + * Registers the routes for the objects of the controller. + * + * @see WP_REST_Terms_Controller::register_rest_route() + */ + public function register_routes() { + register_rest_route( + self::$rest_namespace, + '/categories', + $this->get_route_options() + ); + } + + /** + * Adds the schema from additional fields to a schema array. + * + * The type of object is inferred from the passed schema. + * + * @param array $schema Schema array. + * @return array Modified Schema array. + */ + public function add_additional_fields_schema( $schema ) { + // Parent term is saved like a slug in WXR so we have to rewrite the schema. + $schema['properties']['parent']['description'] = __( 'The parent category slug.', 'jetpack-import' ); + $schema['properties']['parent']['type'] = 'string'; + + // Add the import unique ID to the schema. + return $this->add_unique_identifier_to_schema( $schema ); + } + + /** + * Creates a single category. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + */ + public function create_item( $request ) { + if ( isset( $request['parent'] ) ) { + $parent = get_term_by( 'slug', $request['parent'], 'category' ); + + // Overwrite the parent ID with the parent term ID found using the slug. + $request['parent'] = $parent ? $parent->term_id : 0; + } + + $response = parent::create_item( $request ); + + return $this->add_import_id_metadata( $request, $response ); + } + + /** + * Update the category parent ID. + * + * @param int $resource_id The resource ID. + * @param int $parent_import_id The parent ID. + * @return bool True if updated. + */ + protected function update_parent_id( $resource_id, $parent_import_id ) { + $categories = \get_categories( $this->get_import_db_query( $parent_import_id ) ); + + if ( is_array( $categories ) && count( $categories ) === 1 ) { + $parent_id = $categories[0]; + + return (bool) \wp_update_category( + array( + 'cat_ID' => $resource_id, + 'category_parent' => $parent_id, + ) + ); + } + + return false; + } +} diff --git a/projects/packages/import/src/endpoints/class-comment.php b/projects/packages/import/src/endpoints/class-comment.php new file mode 100644 index 0000000000000..b45e6e58c84f8 --- /dev/null +++ b/projects/packages/import/src/endpoints/class-comment.php @@ -0,0 +1,78 @@ +import_id_meta_type = $this->rest_base; + } + + /** + * Registers the routes for the objects of the controller. + * + * @see WP_REST_Comments_Controller::register_rest_route() + */ + public function register_routes() { + register_rest_route( + self::$rest_namespace, + $this->rest_base, + $this->get_route_options() + ); + } + + /** + * Creates a comment. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error Response object on success, or error object on failure. + */ + public function create_item( $request ) { + $response = parent::create_item( $request ); + + return $this->add_import_id_metadata( $request, $response ); + } + + /** + * Update the comment parent ID. + * + * @param int $resource_id The resource ID. + * @param int $parent_import_id The parent ID. + * @return bool True if updated. + */ + protected function update_parent_id( $resource_id, $parent_import_id ) { + $comments = \get_comments( $this->get_import_db_query( $parent_import_id ) ); + + if ( is_array( $comments ) && count( $comments ) === 1 ) { + $parent_id = $comments[0]; + + return (bool) \wp_update_comment( + array( + 'comment_ID' => $resource_id, + 'comment_parent' => $parent_id, + ) + ); + } + + return false; + } +} diff --git a/projects/packages/import/src/endpoints/class-page.php b/projects/packages/import/src/endpoints/class-page.php new file mode 100644 index 0000000000000..84f6a82edaf17 --- /dev/null +++ b/projects/packages/import/src/endpoints/class-page.php @@ -0,0 +1,45 @@ +get_import_db_query( $parent_import_id ) ); + + if ( is_array( $pages ) && count( $pages ) === 1 ) { + $parent_id = $pages[0]->ID; + + return (bool) \wp_update_post( + array( + 'ID' => $resource_id, + 'post_parent' => $parent_id, + ) + ); + } + + return false; + } +} diff --git a/projects/packages/import/src/endpoints/class-post.php b/projects/packages/import/src/endpoints/class-post.php new file mode 100644 index 0000000000000..d41877d919396 --- /dev/null +++ b/projects/packages/import/src/endpoints/class-post.php @@ -0,0 +1,158 @@ +import_id_meta_type = $post_type; + } + + /** + * Registers the routes for the objects of the controller. + * + * @see WP_REST_Posts_Controller::register_rest_route() + */ + public function register_routes() { + register_rest_route( + self::$rest_namespace, + '/' . $this->rest_base, + $this->get_route_options() + ); + } + + /** + * Adds the schema from additional fields to a schema array. + * + * The type of object is inferred from the passed schema. + * + * @param array $schema Schema array. + * @return array Modified Schema array. + */ + public function add_additional_fields_schema( $schema ) { + // WXR saves terms as slugs, so we need to overwrite the schema. + $schema['properties']['categories']['items']['type'] = 'string'; + $schema['properties']['tags']['items']['type'] = 'string'; + + // Add the import unique ID to the schema. + return $this->add_unique_identifier_to_schema( $schema ); + } + + /** + * Creates a single post / page. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + */ + public function create_item( $request ) { + // Skip if the post already exists. + $post_id = \post_exists( + $request['title'], + '', + $request['date'], + $this->post_type, + $request['status'] + ); + + if ( $post_id ) { + return new \WP_Error( + 'post_exists', + __( 'Cannot create existing post.', 'jetpack-import' ), + array( + 'status' => 400, + 'post_id' => $post_id, + ) + ); + } + + // WXR saves terms as slugs, so we need to convert them to IDs before send the data to the legacy endpoint. + foreach ( array( 'categories', 'tags' ) as $taxonomy ) { + $request[ $taxonomy ] = $this->extract_terms_ids( $request, $taxonomy ); + } + + $response = parent::create_item( $request ); + + return $this->add_import_id_metadata( $request, $response ); + } + + /** + * Extract terms IDs from slugs. + * + * @param WP_REST_Request $request Full details about the request. + * @param string $taxonomy Taxonomy name. + * @return array List of terms IDs. + */ + protected function extract_terms_ids( $request, $taxonomy ) { + $ret = is_array( $request[ $taxonomy ] ) ? $request[ $taxonomy ] : array(); + + if ( ! count( $ret ) ) { + return $ret; + } + + // Extract the terms by ID. + $ids = get_terms( + array( + 'fields' => 'ids', + 'hide_empty' => false, + 'slug' => $ret, + 'taxonomy' => $taxonomy === 'tags' ? 'post_tag' : 'category', + ) + ); + + if ( is_array( $ids ) ) { + return $ids; + } else { + // Flush away any invalid terms. + return array(); + } + } + + /** + * Update the post parent ID. + * + * @param int $resource_id The resource ID. + * @param int $parent_import_id The parent ID. + * @return bool True if updated. + */ + protected function update_parent_id( $resource_id, $parent_import_id ) { + $posts = \get_posts( $this->get_import_db_query( $parent_import_id ) ); + + if ( is_array( $posts ) && count( $posts ) === 1 ) { + $parent_id = $posts[0]; + + return (bool) \wp_update_post( + array( + 'ID' => $resource_id, + 'post_parent' => $parent_id, + ) + ); + } + + return false; + } +} diff --git a/projects/packages/import/src/endpoints/class-tag.php b/projects/packages/import/src/endpoints/class-tag.php new file mode 100644 index 0000000000000..78123c76dc223 --- /dev/null +++ b/projects/packages/import/src/endpoints/class-tag.php @@ -0,0 +1,61 @@ +import_id_meta_type = 'term'; + } + + /** + * Registers the routes for the objects of the controller. + * + * @see WP_REST_Terms_Controller::register_rest_route() + */ + public function register_routes() { + register_rest_route( + self::$rest_namespace, + '/tags', + $this->get_route_options() + ); + } + + /** + * Update the tag parent ID. + * + * @param int $resource_id The resource ID. + * @param int $parent_import_id The parent ID. + * @return bool True if updated. + */ + protected function update_parent_id( $resource_id, $parent_import_id ) { + $terms = \get_terms( $this->get_import_db_query( $parent_import_id ) ); + + if ( is_array( $terms ) && count( $terms ) === 1 ) { + $parent_id = $terms[0]; + + return (bool) \wp_update_term( $resource_id, $this->import_id_meta_type, array( 'parent' => $parent_id ) ); + } + + return false; + } +} diff --git a/projects/packages/import/src/endpoints/trait-import.php b/projects/packages/import/src/endpoints/trait-import.php new file mode 100644 index 0000000000000..77af714cbbb08 --- /dev/null +++ b/projects/packages/import/src/endpoints/trait-import.php @@ -0,0 +1,180 @@ +add_unique_identifier_to_schema( $schema ); + } + + /** + * Create a resource. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + */ + public function create_item( $request ) { + $response = parent::create_item( $request ); + + return $this->add_import_id_metadata( $request, $response ); + } + + /** + * Adds the unique identifier to the schema array. + * + * @param array $schema Schema array. + * @return array Modified Schema array. + */ + protected function add_unique_identifier_to_schema( $schema ) { + // Add the import unique ID to the schema. + $schema['properties'][ $this->import_id_field_name ] = array( + 'description' => __( 'Jetpack Import unique identifier for the term.', 'jetpack-import' ), + 'type' => 'integer', + 'context' => array( 'view', 'embed', 'edit' ), + 'required' => true, + ); + + return $schema; + } + + /** + * Add the import unique ID to the resource metadata. + * + * @param WP_REST_Request $request Full details about the request. + * @param WP_REST_Response $response Response object. + * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + */ + protected function add_import_id_metadata( $request, $response ) { + // Skip on error. + if ( is_wp_error( $response ) ) { + return $response; + } + + $data = $response->get_data(); + + // Skip if the resource has not been added. + if ( $response->get_status() !== 201 ) { + return $response; + } + + // Add the import unique ID to the resource metadata. + \add_metadata( $this->import_id_meta_type, $data['id'], $this->import_id_field_name, $request[ $this->import_id_field_name ], true ); + + // If the resource has a parent. + if ( $request[ $this->import_id_field_name ] !== 0 ) { + // Update the parent. + $this->update_parent_id( $data['id'], $request[ $this->import_id_field_name ] ); + } + + return $response; + } + + /** + * Ensure that the user has permissions to import. + * + * @return bool|\WP_Error + */ + public function import_permissions_callback() { + // The permission check is done in the REST API authentication. It's the same + // as the one used in wp-admin/import.php. + if ( \current_user_can( 'import' ) ) { + return true; + } + + $error_msg = \esc_html__( + 'You are not allowed to perform this action.', + 'jetpack-import' + ); + + return new \WP_Error( 'rest_forbidden', $error_msg, array( 'status' => \rest_authorization_required_code() ) ); + } + + /** + * Get the import DB query. This is used to get the items with a specific + * meta key that have been imported. + * + * @param int $parent_import_id The parent import ID. + * @return array The query. + */ + protected function get_import_db_query( $parent_import_id ) { + // Get the only one item with the parent import ID. + return array( + 'number' => 1, + 'fields' => 'ids', + 'meta_query' => array( + array( + 'key' => $this->import_id_field_name, + 'value' => $parent_import_id, + ), + ), + ); + } + + /** + * Get the register route options. + * + * @see register_rest_route() + * + * @return array The options. + */ + protected function get_route_options() { + return array( + array( + 'methods' => \WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'import_permissions_callback' ), + 'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), + ), + 'allow_batch' => array( 'v1' => true ), + 'schema' => array( $this, 'get_public_item_schema' ), + ); + } + + /** + * Update the resource parent ID. + * + * @param int $resource_id The resource ID. + * @param int $parent_import_id The parent ID. + * @return bool True if updated. + */ + abstract protected function update_parent_id( $resource_id, $parent_import_id ); +} diff --git a/projects/plugins/backup/changelog/update-import-package b/projects/plugins/backup/changelog/update-import-package new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/backup/changelog/update-import-package @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/backup/composer.lock b/projects/plugins/backup/composer.lock index 68636398c51a9..6a2cd31b4c991 100644 --- a/projects/plugins/backup/composer.lock +++ b/projects/plugins/backup/composer.lock @@ -376,7 +376,7 @@ "dist": { "type": "path", "url": "../../packages/config", - "reference": "9fb269f82eb6bbe761c191e257ede2c234c7a15e" + "reference": "d90086a6709e7995e301be3d8bc80d31ea3e0fbb" }, "require-dev": { "automattic/jetpack-changelogger": "@dev" @@ -390,7 +390,7 @@ "link-template": "https://github.com/Automattic/jetpack-config/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.13.x-dev" + "dev-trunk": "1.14.x-dev" } }, "autoload": { diff --git a/projects/plugins/boost/changelog/update-import-package b/projects/plugins/boost/changelog/update-import-package new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/boost/changelog/update-import-package @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/boost/composer.lock b/projects/plugins/boost/composer.lock index 999b6dd753a54..c4d58e98650ed 100644 --- a/projects/plugins/boost/composer.lock +++ b/projects/plugins/boost/composer.lock @@ -291,7 +291,7 @@ "dist": { "type": "path", "url": "../../packages/config", - "reference": "9fb269f82eb6bbe761c191e257ede2c234c7a15e" + "reference": "d90086a6709e7995e301be3d8bc80d31ea3e0fbb" }, "require-dev": { "automattic/jetpack-changelogger": "@dev" @@ -305,7 +305,7 @@ "link-template": "https://github.com/Automattic/jetpack-config/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.13.x-dev" + "dev-trunk": "1.14.x-dev" } }, "autoload": { diff --git a/projects/plugins/jetpack/changelog/add-import-package b/projects/plugins/jetpack/changelog/add-import-package new file mode 100644 index 0000000000000..961b9a3cf1ef4 --- /dev/null +++ b/projects/plugins/jetpack/changelog/add-import-package @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Added the Import package. diff --git a/projects/plugins/jetpack/changelog/update-import-package b/projects/plugins/jetpack/changelog/update-import-package new file mode 100644 index 0000000000000..a1c1831fa1ef7 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-import-package @@ -0,0 +1,5 @@ +Significance: patch +Type: other +Comment: Updated composer.lock. + + diff --git a/projects/plugins/jetpack/class.jetpack.php b/projects/plugins/jetpack/class.jetpack.php index 75b14bfc947ea..19f5a7a110666 100644 --- a/projects/plugins/jetpack/class.jetpack.php +++ b/projects/plugins/jetpack/class.jetpack.php @@ -846,6 +846,7 @@ public function configure() { 'videopress', 'stats', 'stats_admin', + 'import', ) as $feature ) { diff --git a/projects/plugins/jetpack/composer.json b/projects/plugins/jetpack/composer.json index b2c76577be24e..3757a2f4f2e8e 100644 --- a/projects/plugins/jetpack/composer.json +++ b/projects/plugins/jetpack/composer.json @@ -29,6 +29,7 @@ "automattic/jetpack-forms": "@dev", "automattic/jetpack-google-fonts-provider": "@dev", "automattic/jetpack-identity-crisis": "@dev", + "automattic/jetpack-import": "@dev", "automattic/jetpack-jitm": "@dev", "automattic/jetpack-lazy-images": "@dev", "automattic/jetpack-licensing": "@dev", diff --git a/projects/plugins/jetpack/composer.lock b/projects/plugins/jetpack/composer.lock index a3d04f525cf40..10f4519730891 100644 --- a/projects/plugins/jetpack/composer.lock +++ b/projects/plugins/jetpack/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "885f93512258c1b17a95fec63e503ec8", + "content-hash": "995595368021b9c25c1a1a698dde4e89", "packages": [ { "name": "automattic/jetpack-a8c-mc-stats", @@ -666,7 +666,7 @@ "dist": { "type": "path", "url": "../../packages/config", - "reference": "9fb269f82eb6bbe761c191e257ede2c234c7a15e" + "reference": "d90086a6709e7995e301be3d8bc80d31ea3e0fbb" }, "require-dev": { "automattic/jetpack-changelogger": "@dev" @@ -680,7 +680,7 @@ "link-template": "https://github.com/Automattic/jetpack-config/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.13.x-dev" + "dev-trunk": "1.14.x-dev" } }, "autoload": { @@ -1112,6 +1112,73 @@ "relative": true } }, + { + "name": "automattic/jetpack-import", + "version": "dev-trunk", + "dist": { + "type": "path", + "url": "../../packages/import", + "reference": "16a752dfdad19508820a3c080a3eb501ea07770d" + }, + "require": { + "automattic/jetpack-connection": "@dev" + }, + "require-dev": { + "automattic/jetpack-changelogger": "@dev", + "automattic/wordbless": "dev-master", + "yoast/phpunit-polyfills": "1.0.4" + }, + "type": "jetpack-library", + "extra": { + "mirror-repo": "Automattic/jetpack-import", + "changelogger": { + "link-template": "https://github.com/Automattic/jetpack-import/compare/v${old}...v${new}" + }, + "autotagger": true, + "branch-alias": { + "dev-trunk": "0.1.x-dev" + }, + "textdomain": "jetpack-import", + "version-constants": { + "::PACKAGE_VERSION": "src/class-main.php" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "scripts": { + "phpunit": [ + "./vendor/phpunit/phpunit/phpunit --colors=always" + ], + "test-coverage": [ + "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-clover \"$COVERAGE_DIR/clover.xml\"" + ], + "test-php": [ + "@composer phpunit" + ], + "build-production": [ + "echo 'Add your build step to composer.json, please!'" + ], + "build-development": [ + "echo 'Add your build step to composer.json, please!'" + ], + "post-install-cmd": [ + "WorDBless\\Composer\\InstallDropin::copy" + ], + "post-update-cmd": [ + "WorDBless\\Composer\\InstallDropin::copy" + ] + }, + "license": [ + "GPL-2.0-or-later" + ], + "description": "Set of REST API routes used in WPCOM Unified Importer.", + "transport-options": { + "relative": true + } + }, { "name": "automattic/jetpack-jitm", "version": "dev-trunk", @@ -5347,6 +5414,7 @@ "automattic/jetpack-forms": 20, "automattic/jetpack-google-fonts-provider": 20, "automattic/jetpack-identity-crisis": 20, + "automattic/jetpack-import": 20, "automattic/jetpack-jitm": 20, "automattic/jetpack-lazy-images": 20, "automattic/jetpack-licensing": 20, diff --git a/projects/plugins/migration/changelog/update-import-package b/projects/plugins/migration/changelog/update-import-package new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/migration/changelog/update-import-package @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/migration/composer.lock b/projects/plugins/migration/composer.lock index 34dad27f9b49b..1b8c778f1e502 100644 --- a/projects/plugins/migration/composer.lock +++ b/projects/plugins/migration/composer.lock @@ -291,7 +291,7 @@ "dist": { "type": "path", "url": "../../packages/config", - "reference": "9fb269f82eb6bbe761c191e257ede2c234c7a15e" + "reference": "d90086a6709e7995e301be3d8bc80d31ea3e0fbb" }, "require-dev": { "automattic/jetpack-changelogger": "@dev" @@ -305,7 +305,7 @@ "link-template": "https://github.com/Automattic/jetpack-config/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.13.x-dev" + "dev-trunk": "1.14.x-dev" } }, "autoload": { diff --git a/projects/plugins/protect/changelog/update-import-package b/projects/plugins/protect/changelog/update-import-package new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/protect/changelog/update-import-package @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/protect/composer.lock b/projects/plugins/protect/composer.lock index b1be744242de9..f266c8bd5b9cf 100644 --- a/projects/plugins/protect/composer.lock +++ b/projects/plugins/protect/composer.lock @@ -291,7 +291,7 @@ "dist": { "type": "path", "url": "../../packages/config", - "reference": "9fb269f82eb6bbe761c191e257ede2c234c7a15e" + "reference": "d90086a6709e7995e301be3d8bc80d31ea3e0fbb" }, "require-dev": { "automattic/jetpack-changelogger": "@dev" @@ -305,7 +305,7 @@ "link-template": "https://github.com/Automattic/jetpack-config/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.13.x-dev" + "dev-trunk": "1.14.x-dev" } }, "autoload": { diff --git a/projects/plugins/search/changelog/update-import-package b/projects/plugins/search/changelog/update-import-package new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/search/changelog/update-import-package @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/search/composer.lock b/projects/plugins/search/composer.lock index 77b8ff0911170..4fe55dfe0cd78 100644 --- a/projects/plugins/search/composer.lock +++ b/projects/plugins/search/composer.lock @@ -291,7 +291,7 @@ "dist": { "type": "path", "url": "../../packages/config", - "reference": "9fb269f82eb6bbe761c191e257ede2c234c7a15e" + "reference": "d90086a6709e7995e301be3d8bc80d31ea3e0fbb" }, "require-dev": { "automattic/jetpack-changelogger": "@dev" @@ -305,7 +305,7 @@ "link-template": "https://github.com/Automattic/jetpack-config/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.13.x-dev" + "dev-trunk": "1.14.x-dev" } }, "autoload": { diff --git a/projects/plugins/social/changelog/update-import-package b/projects/plugins/social/changelog/update-import-package new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/social/changelog/update-import-package @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/social/composer.lock b/projects/plugins/social/composer.lock index b5990bb9d1550..c1ed43faa3bbd 100644 --- a/projects/plugins/social/composer.lock +++ b/projects/plugins/social/composer.lock @@ -291,7 +291,7 @@ "dist": { "type": "path", "url": "../../packages/config", - "reference": "9fb269f82eb6bbe761c191e257ede2c234c7a15e" + "reference": "d90086a6709e7995e301be3d8bc80d31ea3e0fbb" }, "require-dev": { "automattic/jetpack-changelogger": "@dev" @@ -305,7 +305,7 @@ "link-template": "https://github.com/Automattic/jetpack-config/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.13.x-dev" + "dev-trunk": "1.14.x-dev" } }, "autoload": { diff --git a/projects/plugins/starter-plugin/changelog/update-import-package b/projects/plugins/starter-plugin/changelog/update-import-package new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/starter-plugin/changelog/update-import-package @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/starter-plugin/composer.lock b/projects/plugins/starter-plugin/composer.lock index 6a014fdeae517..677accac3a849 100644 --- a/projects/plugins/starter-plugin/composer.lock +++ b/projects/plugins/starter-plugin/composer.lock @@ -291,7 +291,7 @@ "dist": { "type": "path", "url": "../../packages/config", - "reference": "9fb269f82eb6bbe761c191e257ede2c234c7a15e" + "reference": "d90086a6709e7995e301be3d8bc80d31ea3e0fbb" }, "require-dev": { "automattic/jetpack-changelogger": "@dev" @@ -305,7 +305,7 @@ "link-template": "https://github.com/Automattic/jetpack-config/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.13.x-dev" + "dev-trunk": "1.14.x-dev" } }, "autoload": { diff --git a/projects/plugins/videopress/changelog/update-import-package b/projects/plugins/videopress/changelog/update-import-package new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/videopress/changelog/update-import-package @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/videopress/composer.lock b/projects/plugins/videopress/composer.lock index 22319b86341d9..11307db2997ba 100644 --- a/projects/plugins/videopress/composer.lock +++ b/projects/plugins/videopress/composer.lock @@ -291,7 +291,7 @@ "dist": { "type": "path", "url": "../../packages/config", - "reference": "9fb269f82eb6bbe761c191e257ede2c234c7a15e" + "reference": "d90086a6709e7995e301be3d8bc80d31ea3e0fbb" }, "require-dev": { "automattic/jetpack-changelogger": "@dev" @@ -305,7 +305,7 @@ "link-template": "https://github.com/Automattic/jetpack-config/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "1.13.x-dev" + "dev-trunk": "1.14.x-dev" } }, "autoload": { From 85f481871f3be4230870ea509c3807cb426a1775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Thu, 16 Feb 2023 11:34:44 +0000 Subject: [PATCH 05/51] Story block: remove wp-components frontend dependency (#28743) * Story block: remove wp-components frontend dep * Add `@wordpress/primitives` as a dependency --------- Co-authored-by: Jeremy Herve --- pnpm-lock.yaml | 2 ++ .../update-remove-wp-components-dep-from-story-frontend | 4 ++++ projects/plugins/jetpack/extensions/blocks/story/icon.js | 2 +- .../extensions/blocks/story/player/components/background.js | 2 +- .../extensions/blocks/story/player/components/bullet.js | 5 ++--- .../extensions/blocks/story/player/components/icons.js | 2 +- .../jetpack/extensions/shared/render-material-icon.js | 2 +- projects/plugins/jetpack/package.json | 1 + projects/plugins/jetpack/tools/check-block-assets.php | 2 +- 9 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 projects/plugins/jetpack/changelog/update-remove-wp-components-dep-from-story-frontend diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 26233ceae1cf5..46d40236de500 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1785,6 +1785,7 @@ importers: '@wordpress/icons': 9.17.0 '@wordpress/keycodes': 3.26.0 '@wordpress/notices': 3.26.0 + '@wordpress/primitives': 3.24.0 '@wordpress/token-list': 2.26.0 '@wordpress/url': 3.27.0 '@wordpress/viewport': 5.3.0 @@ -1867,6 +1868,7 @@ importers: '@wordpress/hooks': 3.26.0 '@wordpress/i18n': 4.26.0 '@wordpress/icons': 9.17.0 + '@wordpress/primitives': 3.24.0 '@wordpress/url': 3.27.0 '@wordpress/viewport': 5.3.0_43aktpkp7q4bmohyiyj25up2li '@wordpress/widgets': 3.3.0_57czaiyk6rdr5iy5tfs5pior4u diff --git a/projects/plugins/jetpack/changelog/update-remove-wp-components-dep-from-story-frontend b/projects/plugins/jetpack/changelog/update-remove-wp-components-dep-from-story-frontend new file mode 100644 index 0000000000000..112c92d1c4ae2 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-remove-wp-components-dep-from-story-frontend @@ -0,0 +1,4 @@ +Significance: patch +Type: enhancement + +Story block: remove dependency on wp-components from the frontend code diff --git a/projects/plugins/jetpack/extensions/blocks/story/icon.js b/projects/plugins/jetpack/extensions/blocks/story/icon.js index ae830d9762213..0c71b43193efc 100644 --- a/projects/plugins/jetpack/extensions/blocks/story/icon.js +++ b/projects/plugins/jetpack/extensions/blocks/story/icon.js @@ -1,4 +1,4 @@ -import { Path, G } from '@wordpress/components'; +import { Path, G } from '@wordpress/primitives'; import renderMaterialIcon from '../../shared/render-material-icon'; const icon = renderMaterialIcon( diff --git a/projects/plugins/jetpack/extensions/blocks/story/player/components/background.js b/projects/plugins/jetpack/extensions/blocks/story/player/components/background.js index 06cc62a9c3ee5..1d60a48f91b16 100644 --- a/projects/plugins/jetpack/extensions/blocks/story/player/components/background.js +++ b/projects/plugins/jetpack/extensions/blocks/story/player/components/background.js @@ -1,4 +1,4 @@ -import { SVG } from '@wordpress/components'; +import { SVG } from '@wordpress/primitives'; export default function Background( { currentMedia } ) { const url = currentMedia && currentMedia.type === 'image' ? currentMedia.url : null; diff --git a/projects/plugins/jetpack/extensions/blocks/story/player/components/bullet.js b/projects/plugins/jetpack/extensions/blocks/story/player/components/bullet.js index b4c67a6b5c255..81bf6de2e5017 100644 --- a/projects/plugins/jetpack/extensions/blocks/story/player/components/bullet.js +++ b/projects/plugins/jetpack/extensions/blocks/story/player/components/bullet.js @@ -1,4 +1,3 @@ -import { Button } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; import classNames from 'classnames'; @@ -19,7 +18,7 @@ export default function Bullet( { isEllipsis, disabled, index, isSelected, progr ); } return ( - + ); } diff --git a/projects/plugins/jetpack/extensions/blocks/story/player/components/icons.js b/projects/plugins/jetpack/extensions/blocks/story/player/components/icons.js index 9b2174ca6b92b..a9add8c413c44 100644 --- a/projects/plugins/jetpack/extensions/blocks/story/player/components/icons.js +++ b/projects/plugins/jetpack/extensions/blocks/story/player/components/icons.js @@ -1,4 +1,4 @@ -import { Path } from '@wordpress/components'; +import { Path } from '@wordpress/primitives'; import renderMaterialIcon from '../../../../shared/render-material-icon'; const MaterialIcon = ( { children, size } ) => renderMaterialIcon( children, size, size ); diff --git a/projects/plugins/jetpack/extensions/shared/render-material-icon.js b/projects/plugins/jetpack/extensions/shared/render-material-icon.js index 0478be63ebc79..a69a239b6d9c4 100644 --- a/projects/plugins/jetpack/extensions/shared/render-material-icon.js +++ b/projects/plugins/jetpack/extensions/shared/render-material-icon.js @@ -1,4 +1,4 @@ -import { Path, SVG } from '@wordpress/components'; +import { Path, SVG } from '@wordpress/primitives'; const renderMaterialIcon = ( svg, width = 24, height = 24, viewbox = '0 0 24 24' ) => ( diff --git a/projects/plugins/jetpack/package.json b/projects/plugins/jetpack/package.json index b7e086d5b261c..7c8e8ba9afc08 100644 --- a/projects/plugins/jetpack/package.json +++ b/projects/plugins/jetpack/package.json @@ -71,6 +71,7 @@ "@wordpress/hooks": "3.26.0", "@wordpress/i18n": "4.26.0", "@wordpress/icons": "9.17.0", + "@wordpress/primitives": "3.24.0", "@wordpress/url": "3.27.0", "@wordpress/viewport": "5.3.0", "@wordpress/widgets": "3.3.0", diff --git a/projects/plugins/jetpack/tools/check-block-assets.php b/projects/plugins/jetpack/tools/check-block-assets.php index 43beafc28cefd..9cf2fdbf3b35a 100755 --- a/projects/plugins/jetpack/tools/check-block-assets.php +++ b/projects/plugins/jetpack/tools/check-block-assets.php @@ -75,11 +75,11 @@ 'lodash', 'react', 'react-dom', - 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-keycodes', + 'wp-primitives', ), ); From f29cdf39f2ce22a46584d91c7a7f7c15d299088b Mon Sep 17 00:00:00 2001 From: Douglas Henri Date: Thu, 16 Feb 2023 10:47:43 -0300 Subject: [PATCH 06/51] My Jetpack: Fix button to add bundle in product interstitial component (#28984) Co-authored-by: oskosk --- .../_inc/components/product-detail-card/index.jsx | 2 +- .../_inc/components/product-interstitial/index.jsx | 14 +++++++++++--- .../changelog/fix-my-jetpack-add-security | 4 ++++ projects/packages/my-jetpack/package.json | 2 +- .../packages/my-jetpack/src/class-initializer.php | 2 +- .../changelog/fix-my-jetpack-add-security | 5 +++++ 6 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 projects/packages/my-jetpack/changelog/fix-my-jetpack-add-security create mode 100644 projects/plugins/videopress/changelog/fix-my-jetpack-add-security diff --git a/projects/packages/my-jetpack/_inc/components/product-detail-card/index.jsx b/projects/packages/my-jetpack/_inc/components/product-detail-card/index.jsx index 7836b5b16d200..6e75755143060 100644 --- a/projects/packages/my-jetpack/_inc/components/product-detail-card/index.jsx +++ b/projects/packages/my-jetpack/_inc/components/product-detail-card/index.jsx @@ -187,7 +187,7 @@ const ProductDetailCard = ( { slug, onClick, trackButtonClick, className, suppor function ProductIcon( { slug: iconSlug } ) { const ProIcon = getIconBySlug( iconSlug ); if ( ! ProIcon ) { - return () => null; + return null; } return ( diff --git a/projects/packages/my-jetpack/_inc/components/product-interstitial/index.jsx b/projects/packages/my-jetpack/_inc/components/product-interstitial/index.jsx index cf2dce1b08f07..d44fefab8f3d9 100644 --- a/projects/packages/my-jetpack/_inc/components/product-interstitial/index.jsx +++ b/projects/packages/my-jetpack/_inc/components/product-interstitial/index.jsx @@ -59,8 +59,15 @@ export default function ProductInterstitial( { const clickHandler = useCallback( checkout => { - activate().finally( () => { + const activateOrCheckout = () => ( bundle ? Promise.resolve() : activate() ); + + activateOrCheckout().finally( () => { const product = select( STORE_ID ).getProduct( slug ); + if ( bundle ) { + // Get straight to the checkout page. + checkout?.(); + return; + } const postActivationUrl = product?.postActivationUrl; const hasRequiredPlan = product?.hasRequiredPlan; const isFree = product?.pricingForUi?.isFree; @@ -79,7 +86,7 @@ export default function ProductInterstitial( { checkout?.(); } ); }, - [ navigateToMyJetpackOverviewPage, activate, slug ] + [ navigateToMyJetpackOverviewPage, activate, bundle, slug ] ); const onClickGoBack = useCallback( () => { @@ -113,8 +120,9 @@ export default function ProductInterstitial( { { bundle ? ( ) : ( diff --git a/projects/packages/my-jetpack/changelog/fix-my-jetpack-add-security b/projects/packages/my-jetpack/changelog/fix-my-jetpack-add-security new file mode 100644 index 0000000000000..6c3e03c14d682 --- /dev/null +++ b/projects/packages/my-jetpack/changelog/fix-my-jetpack-add-security @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +My Jetpack: Fix button to add bundle in product interstitial component diff --git a/projects/packages/my-jetpack/package.json b/projects/packages/my-jetpack/package.json index 3618bb360e8a9..58ea139516870 100644 --- a/projects/packages/my-jetpack/package.json +++ b/projects/packages/my-jetpack/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@automattic/jetpack-my-jetpack", - "version": "2.7.10", + "version": "2.7.11-alpha", "description": "WP Admin page with information and configuration shared among all Jetpack stand-alone plugins", "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/packages/my-jetpack/#readme", "bugs": { diff --git a/projects/packages/my-jetpack/src/class-initializer.php b/projects/packages/my-jetpack/src/class-initializer.php index 0a07a199a0fb5..9fc0d73b89353 100644 --- a/projects/packages/my-jetpack/src/class-initializer.php +++ b/projects/packages/my-jetpack/src/class-initializer.php @@ -30,7 +30,7 @@ class Initializer { * * @var string */ - const PACKAGE_VERSION = '2.7.10'; + const PACKAGE_VERSION = '2.7.11-alpha'; /** * Initialize My Jetpack diff --git a/projects/plugins/videopress/changelog/fix-my-jetpack-add-security b/projects/plugins/videopress/changelog/fix-my-jetpack-add-security new file mode 100644 index 0000000000000..2378255b335d1 --- /dev/null +++ b/projects/plugins/videopress/changelog/fix-my-jetpack-add-security @@ -0,0 +1,5 @@ +Significance: patch +Type: fixed +Comment: Version bump + + From c02f97a4261af8c6b89d4dcc59f6d3d345cd4e47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Su=C3=A1rez?= Date: Thu, 16 Feb 2023 13:44:16 -0300 Subject: [PATCH 07/51] VideoPress: resend token when requester retries (#28930) * [not verified] flush the store token when client retries * [not verified] changelog * [not verified] add debgu() line * fix changelog typo --- ...eopress-read-and-support-is-retry-from-token-requester | 4 ++++ .../videopress/src/client/lib/token-bridge/index.ts | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 projects/packages/videopress/changelog/update-videopress-read-and-support-is-retry-from-token-requester diff --git a/projects/packages/videopress/changelog/update-videopress-read-and-support-is-retry-from-token-requester b/projects/packages/videopress/changelog/update-videopress-read-and-support-is-retry-from-token-requester new file mode 100644 index 0000000000000..cc902d7f7b16b --- /dev/null +++ b/projects/packages/videopress/changelog/update-videopress-read-and-support-is-retry-from-token-requester @@ -0,0 +1,4 @@ +Significance: patch +Type: added + +VideoPress: flush token when the requester retries diff --git a/projects/packages/videopress/src/client/lib/token-bridge/index.ts b/projects/packages/videopress/src/client/lib/token-bridge/index.ts index 73266106f9a6a..0cc6dde3439e5 100644 --- a/projects/packages/videopress/src/client/lib/token-bridge/index.ts +++ b/projects/packages/videopress/src/client/lib/token-bridge/index.ts @@ -26,6 +26,7 @@ type TokenBrigeEventProps = { guid: VideoGUID; requestId: string; origin: Origin; + isRetry?: boolean; }; /** @@ -49,7 +50,7 @@ export async function tokenBridgeHandler( const { context = 'main' } = videopressAjax; - const { guid, requestId } = event.data; + const { guid, requestId, isRetry } = event.data; if ( ! guid || ! requestId ) { debug( '(%s) Invalid request', context ); return; @@ -94,10 +95,15 @@ export async function tokenBridgeHandler( { targetOrigin: '*' } ); + if ( isRetry ) { + debug( '(%s) client retrying request. Flush the token.', context ); + } + const tokenData = await getMediaToken( 'playback', { id: Number( postId ), guid, adminAjaxAPI: videopressAjax.ajaxUrl, + flushToken: isRetry, // flush the token if it's a retry } ); if ( ! tokenData?.token ) { From 68ffffe1578fdfebc5f53dc105fb58fc2df38b8e Mon Sep 17 00:00:00 2001 From: Jasper Kang Date: Fri, 17 Feb 2023 06:49:17 +1300 Subject: [PATCH 08/51] Stats: Fix JSON decoding the wrong varible while parsing the response body (#28992) --- .../changelog/fix-decoding-wrong-varible | 4 ++++ .../stats-admin/src/class-rest-controller.php | 15 ++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 projects/packages/stats-admin/changelog/fix-decoding-wrong-varible diff --git a/projects/packages/stats-admin/changelog/fix-decoding-wrong-varible b/projects/packages/stats-admin/changelog/fix-decoding-wrong-varible new file mode 100644 index 0000000000000..dc2de5a332dbc --- /dev/null +++ b/projects/packages/stats-admin/changelog/fix-decoding-wrong-varible @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Stats: fix broken request_as_blog_cached diff --git a/projects/packages/stats-admin/src/class-rest-controller.php b/projects/packages/stats-admin/src/class-rest-controller.php index d2af00dcf3c2e..637ba29136ece 100644 --- a/projects/packages/stats-admin/src/class-rest-controller.php +++ b/projects/packages/stats-admin/src/class-rest-controller.php @@ -497,27 +497,28 @@ protected function request_as_blog_cached( $path, $version = '1.1', $args = arra $cache_key = 'STATS_REST_RESP_' . md5( implode( '|', array( $path, $version, wp_json_encode( $args ), wp_json_encode( $body ), $base_api_path ) ) ); if ( $use_cache ) { - $response_body = get_transient( $cache_key ); - if ( false !== $response_body ) { - return json_decode( $response_body, true ); + $response_body_content = get_transient( $cache_key ); + if ( false !== $response_body_content ) { + return json_decode( $response_body_content, true ); } } - $response = Client::wpcom_json_api_request_as_blog( + $response = Client::wpcom_json_api_request_as_blog( $path, $version, $args, $body, $base_api_path ); - $response_code = wp_remote_retrieve_response_code( $response ); - $response_body_content = wp_remote_retrieve_body( $response ); - $response_body = json_decode( $response_body, true ); if ( is_wp_error( $response ) ) { return $response; } + $response_code = wp_remote_retrieve_response_code( $response ); + $response_body_content = wp_remote_retrieve_body( $response ); + $response_body = json_decode( $response_body_content, true ); + if ( 200 !== $response_code ) { return $this->get_wp_error( $response_body, $response_code ); } From 9e93db46912232560e04bfdb5a4ad99020a241fd Mon Sep 17 00:00:00 2001 From: nunyvega Date: Thu, 16 Feb 2023 18:54:36 +0100 Subject: [PATCH 09/51] VideoPress: Update plugin stable version post release (#29008) * Update VideoPress plugin stable tag post release * changelog --- .../videopress/changelog/update-videopress-stable-version | 5 +++++ projects/plugins/videopress/readme.txt | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 projects/plugins/videopress/changelog/update-videopress-stable-version diff --git a/projects/plugins/videopress/changelog/update-videopress-stable-version b/projects/plugins/videopress/changelog/update-videopress-stable-version new file mode 100644 index 0000000000000..21fe66b8756c7 --- /dev/null +++ b/projects/plugins/videopress/changelog/update-videopress-stable-version @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: changed stable tag post release + + diff --git a/projects/plugins/videopress/readme.txt b/projects/plugins/videopress/readme.txt index d57e959c8853e..700a1233290e4 100644 --- a/projects/plugins/videopress/readme.txt +++ b/projects/plugins/videopress/readme.txt @@ -4,7 +4,7 @@ Tags: video, video-hosting, video-player, cdn, vimeo, youtube, video-streaming, Requires at least: 6.0 Tested up to: 6.1 -Stable tag: 1.3.0 +Stable tag: 1.4.0 Requires PHP: 5.6 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html From 84241c54c7a97d9eb052f60bae146cac12af617c Mon Sep 17 00:00:00 2001 From: Samiff Date: Thu, 16 Feb 2023 11:43:17 -0700 Subject: [PATCH 10/51] Jetpack: backport 11.8.4 changelog and stable tag (#28990) * Jetpack: backport 11.8.4 changelog and stable tag * changelog --- projects/plugins/jetpack/CHANGELOG.md | 5 +++++ .../plugins/jetpack/changelog/update-jetpack-backport-11.8.4 | 5 +++++ projects/plugins/jetpack/readme.txt | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 projects/plugins/jetpack/changelog/update-jetpack-backport-11.8.4 diff --git a/projects/plugins/jetpack/CHANGELOG.md b/projects/plugins/jetpack/CHANGELOG.md index d09b1a0c1ad38..1dbc979ee4b64 100644 --- a/projects/plugins/jetpack/CHANGELOG.md +++ b/projects/plugins/jetpack/CHANGELOG.md @@ -35,6 +35,11 @@ - Subscriptions: fix a bug where comments would be open under pages [#28894] - Update to React 18. [#28710] +## 11.8.4 - 2023-02-15 +### Bug fixes +- Blaze: prevent error on frontend-loaded Gutenberg, and bail early if Jetpack is not connected. [#28955] +- WAF: fix PHP fatal when the jetpack-waf directory has been deleted from the wp-content folder. [#28760] + ## 11.9-a.1 - 2023-02-08 ### Enhancements - Contact form: add a blur effect while the form is loading the styles. [#28212] diff --git a/projects/plugins/jetpack/changelog/update-jetpack-backport-11.8.4 b/projects/plugins/jetpack/changelog/update-jetpack-backport-11.8.4 new file mode 100644 index 0000000000000..9bc1cb9040a03 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-jetpack-backport-11.8.4 @@ -0,0 +1,5 @@ +Significance: patch +Type: other +Comment: Jetpack: backport 11.8.4 changelog and stable tag + + diff --git a/projects/plugins/jetpack/readme.txt b/projects/plugins/jetpack/readme.txt index 0056a89418f8e..99dedba647e2a 100644 --- a/projects/plugins/jetpack/readme.txt +++ b/projects/plugins/jetpack/readme.txt @@ -1,7 +1,7 @@ === Jetpack - WP Security, Backup, Speed, & Growth === Contributors: automattic, adamkheckler, adrianmoldovanwp, aduth, akirk, allendav, alternatekev, andy, annamcphee, annezazu, apeatling, arcangelini, azaozz, batmoo, barry, beaulebens, bindlegirl, biskobe, blobaugh, bjorsch, brbrr, cainm, cena, cfinke, chaselivingston, chellycat, clickysteve, csonnek, danielbachhuber, davoraltman, daniloercoli, delawski, designsimply, dllh, drawmyface, dsmart, dzver, ebinnion, egregor, eliorivero, enej, eoigal, erania-pinnera, ethitter, fgiannar, gcorne, georgestephanis, gibrown, goldsounds, hew, hugobaeta, hypertextranch, iammattthomas, iandunn, jblz, jasmussen, jeffgolenski, jeherve, jenhooks, jenia, jessefriedman, jgs, jkudish, jmdodd, joanrho, johnjamesjacoby, jshreve, kbrownkd, keoshi, koke, kraftbj, lancewillett, leogermani, lschuyler, macmanx, martinremy, matt, matveb, mattwiebe, maverick3x6, mcsf, mdawaffe, mdbitz, MichaelArestad, migueluy, mikeyarce, mkaz, nancythanki, nickmomrik, obenland, oskosk, pento, professor44, rachelsquirrel, rdcoll, ryancowles, richardmuscat, richardmtl, robertbpugh, roccotripaldi, samhotchkiss, samiff, scarstocea, scottsweb, sdixon194, sdquirk, sermitr, simison, stephdau, tmoorewp, tyxla, Viper007Bond, westi, wpkaren, yoavf, zinigor Tags: Security, backup, Woo, malware, scan, spam, CDN, search, social -Stable tag: 11.8 +Stable tag: 11.8.4 Requires at least: 6.0 Requires PHP: 5.6 Tested up to: 6.1 From 4eb26dd15cd5b699ea51c389921f3d82b4c66c60 Mon Sep 17 00:00:00 2001 From: Nate Weller Date: Thu, 16 Feb 2023 14:17:13 -0700 Subject: [PATCH 11/51] WAF: Add WorDBless Support (#28980) * Add automattic/wordbless to the waf package * changelog * Add line break to end of .gitignore * Update composer.json * Split WAF php tests into two separate test projects * Fix missing use statement for Waf_Runner * Fixup project versions * changelog * Remove unrelated updates to videopress release cycle init * Fix test-coverage-html * Use WorDBless\BaseTestCase for WAF activation tests class base * Remove @before tag from set_up method * [not verified] Revert "Remove @before tag from set_up method" This reverts commit 5b1acad446ac5a30d14347561f2db80cbd3b699f. * Composer lock update --------- Co-authored-by: Brandon Kraft --- projects/packages/waf/.gitignore | 1 + .../packages/waf/changelog/add-waf-wordbless | 5 +++ projects/packages/waf/composer.json | 17 +++++++-- .../waf/tests/php/integration/bootstrap.php | 12 +++++++ .../php/integration}/phpunit.xml.dist | 6 ++-- .../php/integration/test-waf-activation.php | 36 +++++++++++++++++++ .../waf/tests/php/{ => unit}/bootstrap.php | 2 +- .../php/{ => unit}/functions-wordpress.php | 0 .../waf/tests/php/unit/phpunit.xml.dist | 21 +++++++++++ .../php/{ => unit}/test-waf-operators.php | 0 .../tests/php/{ => unit}/test-waf-request.php | 0 .../tests/php/{ => unit}/test-waf-runner.php | 0 .../{ => unit}/test-waf-runtime-targets.php | 0 .../tests/php/{ => unit}/test-waf-runtime.php | 0 .../test-waf-standalone-bootstrap.php | 0 .../php/{ => unit}/test-waf-transforms.php | 0 .../jetpack/changelog/add-waf-wordbless | 5 +++ projects/plugins/jetpack/composer.lock | 16 +++++++-- .../protect/changelog/add-waf-wordbless | 5 +++ projects/plugins/protect/composer.lock | 16 +++++++-- 20 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 projects/packages/waf/changelog/add-waf-wordbless create mode 100644 projects/packages/waf/tests/php/integration/bootstrap.php rename projects/packages/waf/{ => tests/php/integration}/phpunit.xml.dist (81%) create mode 100644 projects/packages/waf/tests/php/integration/test-waf-activation.php rename projects/packages/waf/tests/php/{ => unit}/bootstrap.php (72%) rename projects/packages/waf/tests/php/{ => unit}/functions-wordpress.php (100%) create mode 100644 projects/packages/waf/tests/php/unit/phpunit.xml.dist rename projects/packages/waf/tests/php/{ => unit}/test-waf-operators.php (100%) rename projects/packages/waf/tests/php/{ => unit}/test-waf-request.php (100%) rename projects/packages/waf/tests/php/{ => unit}/test-waf-runner.php (100%) rename projects/packages/waf/tests/php/{ => unit}/test-waf-runtime-targets.php (100%) rename projects/packages/waf/tests/php/{ => unit}/test-waf-runtime.php (100%) rename projects/packages/waf/tests/php/{ => unit}/test-waf-standalone-bootstrap.php (100%) rename projects/packages/waf/tests/php/{ => unit}/test-waf-transforms.php (100%) create mode 100644 projects/plugins/jetpack/changelog/add-waf-wordbless create mode 100644 projects/plugins/protect/changelog/add-waf-wordbless diff --git a/projects/packages/waf/.gitignore b/projects/packages/waf/.gitignore index 77d344786d645..0eef3074d4db1 100644 --- a/projects/packages/waf/.gitignore +++ b/projects/packages/waf/.gitignore @@ -1,5 +1,6 @@ vendor/ node_modules/ rules/ +wordpress/ coverage clover.xml diff --git a/projects/packages/waf/changelog/add-waf-wordbless b/projects/packages/waf/changelog/add-waf-wordbless new file mode 100644 index 0000000000000..295867884b189 --- /dev/null +++ b/projects/packages/waf/changelog/add-waf-wordbless @@ -0,0 +1,5 @@ +Significance: patch +Type: added +Comment: Added the automattic/wordbless package. + + diff --git a/projects/packages/waf/composer.json b/projects/packages/waf/composer.json index f39fc190df39c..621ff038f5e53 100644 --- a/projects/packages/waf/composer.json +++ b/projects/packages/waf/composer.json @@ -4,12 +4,14 @@ "type": "jetpack-library", "license": "GPL-2.0-or-later", "require": { + "automattic/jetpack-connection": "@dev", "automattic/jetpack-status": "@dev", "wikimedia/aho-corasick": "^1.0" }, "require-dev": { "yoast/phpunit-polyfills": "1.0.4", - "automattic/jetpack-changelogger": "@dev" + "automattic/jetpack-changelogger": "@dev", + "automattic/wordbless": "@dev" }, "autoload": { "files": [ @@ -21,13 +23,17 @@ }, "scripts": { "phpunit": [ - "./vendor/phpunit/phpunit/phpunit --colors=always" + "./vendor/phpunit/phpunit/phpunit --configuration tests/php/integration/phpunit.xml.dist --colors=always", + "./vendor/phpunit/phpunit/phpunit --configuration tests/php/unit/phpunit.xml.dist --colors=always" ], + "post-install-cmd": "WorDBless\\Composer\\InstallDropin::copy", + "post-update-cmd": "WorDBless\\Composer\\InstallDropin::copy", "test-coverage": [ "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-clover \"$COVERAGE_DIR/clover.xml\"" ], "test-coverage-html": [ - "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-html ./coverage" + "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-html ./coverage --configuration tests/php/integration/phpunit.xml.dist", + "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-html ./coverage --configuration tests/php/unit/phpunit.xml.dist" ], "test-php": [ "@composer phpunit" @@ -54,5 +60,10 @@ "branch-alias": { "dev-trunk": "0.9.x-dev" } + }, + "config": { + "allow-plugins": { + "roots/wordpress-core-installer": true + } } } diff --git a/projects/packages/waf/tests/php/integration/bootstrap.php b/projects/packages/waf/tests/php/integration/bootstrap.php new file mode 100644 index 0000000000000..5751e22ab1eb1 --- /dev/null +++ b/projects/packages/waf/tests/php/integration/bootstrap.php @@ -0,0 +1,12 @@ + - src + ../../../src - tests/php + . diff --git a/projects/packages/waf/tests/php/integration/test-waf-activation.php b/projects/packages/waf/tests/php/integration/test-waf-activation.php new file mode 100644 index 0000000000000..0121efc1420bd --- /dev/null +++ b/projects/packages/waf/tests/php/integration/test-waf-activation.php @@ -0,0 +1,36 @@ +assertSame( get_option( Waf_Runner::MODE_OPTION_NAME ), 'normal' ); + } + +} diff --git a/projects/packages/waf/tests/php/bootstrap.php b/projects/packages/waf/tests/php/unit/bootstrap.php similarity index 72% rename from projects/packages/waf/tests/php/bootstrap.php rename to projects/packages/waf/tests/php/unit/bootstrap.php index d2ad4ccccde12..b16cb15e382d5 100644 --- a/projects/packages/waf/tests/php/bootstrap.php +++ b/projects/packages/waf/tests/php/unit/bootstrap.php @@ -8,5 +8,5 @@ /** * Include the composer autoloader. */ -require_once __DIR__ . '/../../vendor/autoload.php'; +require_once __DIR__ . '/../../../vendor/autoload.php'; require_once __DIR__ . '/functions-wordpress.php'; diff --git a/projects/packages/waf/tests/php/functions-wordpress.php b/projects/packages/waf/tests/php/unit/functions-wordpress.php similarity index 100% rename from projects/packages/waf/tests/php/functions-wordpress.php rename to projects/packages/waf/tests/php/unit/functions-wordpress.php diff --git a/projects/packages/waf/tests/php/unit/phpunit.xml.dist b/projects/packages/waf/tests/php/unit/phpunit.xml.dist new file mode 100644 index 0000000000000..e901dd1acf030 --- /dev/null +++ b/projects/packages/waf/tests/php/unit/phpunit.xml.dist @@ -0,0 +1,21 @@ + + + + + + + ../../../src + + + + + . + + + diff --git a/projects/packages/waf/tests/php/test-waf-operators.php b/projects/packages/waf/tests/php/unit/test-waf-operators.php similarity index 100% rename from projects/packages/waf/tests/php/test-waf-operators.php rename to projects/packages/waf/tests/php/unit/test-waf-operators.php diff --git a/projects/packages/waf/tests/php/test-waf-request.php b/projects/packages/waf/tests/php/unit/test-waf-request.php similarity index 100% rename from projects/packages/waf/tests/php/test-waf-request.php rename to projects/packages/waf/tests/php/unit/test-waf-request.php diff --git a/projects/packages/waf/tests/php/test-waf-runner.php b/projects/packages/waf/tests/php/unit/test-waf-runner.php similarity index 100% rename from projects/packages/waf/tests/php/test-waf-runner.php rename to projects/packages/waf/tests/php/unit/test-waf-runner.php diff --git a/projects/packages/waf/tests/php/test-waf-runtime-targets.php b/projects/packages/waf/tests/php/unit/test-waf-runtime-targets.php similarity index 100% rename from projects/packages/waf/tests/php/test-waf-runtime-targets.php rename to projects/packages/waf/tests/php/unit/test-waf-runtime-targets.php diff --git a/projects/packages/waf/tests/php/test-waf-runtime.php b/projects/packages/waf/tests/php/unit/test-waf-runtime.php similarity index 100% rename from projects/packages/waf/tests/php/test-waf-runtime.php rename to projects/packages/waf/tests/php/unit/test-waf-runtime.php diff --git a/projects/packages/waf/tests/php/test-waf-standalone-bootstrap.php b/projects/packages/waf/tests/php/unit/test-waf-standalone-bootstrap.php similarity index 100% rename from projects/packages/waf/tests/php/test-waf-standalone-bootstrap.php rename to projects/packages/waf/tests/php/unit/test-waf-standalone-bootstrap.php diff --git a/projects/packages/waf/tests/php/test-waf-transforms.php b/projects/packages/waf/tests/php/unit/test-waf-transforms.php similarity index 100% rename from projects/packages/waf/tests/php/test-waf-transforms.php rename to projects/packages/waf/tests/php/unit/test-waf-transforms.php diff --git a/projects/plugins/jetpack/changelog/add-waf-wordbless b/projects/plugins/jetpack/changelog/add-waf-wordbless new file mode 100644 index 0000000000000..a1c1831fa1ef7 --- /dev/null +++ b/projects/plugins/jetpack/changelog/add-waf-wordbless @@ -0,0 +1,5 @@ +Significance: patch +Type: other +Comment: Updated composer.lock. + + diff --git a/projects/plugins/jetpack/composer.lock b/projects/plugins/jetpack/composer.lock index 10f4519730891..09f77eb3eefc8 100644 --- a/projects/plugins/jetpack/composer.lock +++ b/projects/plugins/jetpack/composer.lock @@ -2418,14 +2418,16 @@ "dist": { "type": "path", "url": "../../packages/waf", - "reference": "6e38e0e44373497b441f60ca21806f217d70248e" + "reference": "ab08a17e5e6f9e04b5036ad4f3e64b041707386c" }, "require": { + "automattic/jetpack-connection": "@dev", "automattic/jetpack-status": "@dev", "wikimedia/aho-corasick": "^1.0" }, "require-dev": { "automattic/jetpack-changelogger": "@dev", + "automattic/wordbless": "@dev", "yoast/phpunit-polyfills": "1.0.4" }, "type": "jetpack-library", @@ -2450,13 +2452,21 @@ }, "scripts": { "phpunit": [ - "./vendor/phpunit/phpunit/phpunit --colors=always" + "./vendor/phpunit/phpunit/phpunit --configuration tests/php/integration/phpunit.xml.dist --colors=always", + "./vendor/phpunit/phpunit/phpunit --configuration tests/php/unit/phpunit.xml.dist --colors=always" + ], + "post-install-cmd": [ + "WorDBless\\Composer\\InstallDropin::copy" + ], + "post-update-cmd": [ + "WorDBless\\Composer\\InstallDropin::copy" ], "test-coverage": [ "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-clover \"$COVERAGE_DIR/clover.xml\"" ], "test-coverage-html": [ - "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-html ./coverage" + "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-html ./coverage --configuration tests/php/integration/phpunit.xml.dist", + "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-html ./coverage --configuration tests/php/unit/phpunit.xml.dist" ], "test-php": [ "@composer phpunit" diff --git a/projects/plugins/protect/changelog/add-waf-wordbless b/projects/plugins/protect/changelog/add-waf-wordbless new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/protect/changelog/add-waf-wordbless @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/protect/composer.lock b/projects/plugins/protect/composer.lock index f266c8bd5b9cf..12b07ab9a1b9d 100644 --- a/projects/plugins/protect/composer.lock +++ b/projects/plugins/protect/composer.lock @@ -1352,14 +1352,16 @@ "dist": { "type": "path", "url": "../../packages/waf", - "reference": "6e38e0e44373497b441f60ca21806f217d70248e" + "reference": "ab08a17e5e6f9e04b5036ad4f3e64b041707386c" }, "require": { + "automattic/jetpack-connection": "@dev", "automattic/jetpack-status": "@dev", "wikimedia/aho-corasick": "^1.0" }, "require-dev": { "automattic/jetpack-changelogger": "@dev", + "automattic/wordbless": "@dev", "yoast/phpunit-polyfills": "1.0.4" }, "type": "jetpack-library", @@ -1384,13 +1386,21 @@ }, "scripts": { "phpunit": [ - "./vendor/phpunit/phpunit/phpunit --colors=always" + "./vendor/phpunit/phpunit/phpunit --configuration tests/php/integration/phpunit.xml.dist --colors=always", + "./vendor/phpunit/phpunit/phpunit --configuration tests/php/unit/phpunit.xml.dist --colors=always" + ], + "post-install-cmd": [ + "WorDBless\\Composer\\InstallDropin::copy" + ], + "post-update-cmd": [ + "WorDBless\\Composer\\InstallDropin::copy" ], "test-coverage": [ "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-clover \"$COVERAGE_DIR/clover.xml\"" ], "test-coverage-html": [ - "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-html ./coverage" + "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-html ./coverage --configuration tests/php/integration/phpunit.xml.dist", + "php -dpcov.directory=. ./vendor/bin/phpunit --coverage-html ./coverage --configuration tests/php/unit/phpunit.xml.dist" ], "test-php": [ "@composer phpunit" From 2cc7dbdabc704cb83e57cee7afcb8869d68768b1 Mon Sep 17 00:00:00 2001 From: Peter Petrov Date: Fri, 17 Feb 2023 01:31:42 +0200 Subject: [PATCH 12/51] [Boost] Add CSS/JS minification (#28686) * Add page optimize plugin files; Exclude page optimize plugin files from phpcs * Allow page optimize to be enabled/disabled via Boost settings; Update plugin hooks to initialize on boost plugin file; Prevent minification to happen in WP admin * changelog * Prefix page optimize code to allow running with original page optimize * Update options to avoid collision with official page optimize plugin * Add migration for old page optimize options This is necessary, to make sure the page optimize in Boost is backwards compatible with existing page optimize installations. * Fix fatal error when accessing a cached URL * Update concatenated stylesheets to support style_loader_tag filter * Allow disabling minify via GET param if enabled * Refactor page optimize code as a Boost feature; Ignore phpcs for minify feature * Handle PHP constants from page optimize; Add missing functionality from page optimize * Remove global variable usage * Fix fatal error * Fix concatenation initialized too early * Remove old page optimize plugin * Update Minify description in UI * Fix fatal error during CSS concatenation * Remove page optimize compatibility Options won't be migrated. An upcoming commit will revert to the option names page optimize uses. * Update page optimize settings to use original names * Remove ability to disable minify feature via specific GET param There's already a param for this - jb-disable-modules. * Update cssmin to use composer package instead of separate files * Fix versioning * Hide minify feature behind a PHP constant --------- Co-authored-by: Mark George --- projects/plugins/boost/.phpcsignore | 2 + .../js/pages/settings/sections/Modules.svelte | 14 + .../features/optimizations/Optimizations.php | 5 + .../optimizations/minify/Concatenate_CSS.php | 214 +++++++++++ .../optimizations/minify/Concatenate_JS.php | 291 +++++++++++++++ .../features/optimizations/minify/Config.php | 46 +++ .../minify/Dependency_Path_Mapping.php | 145 ++++++++ .../features/optimizations/minify/Minify.php | 63 ++++ .../minify/functions-helpers.php | 299 ++++++++++++++++ .../features/optimizations/minify/service.php | 337 ++++++++++++++++++ .../boost/changelog/add-boost-minification | 4 + .../boost/changelog/add-boost-minification#2 | 5 + projects/plugins/boost/composer.json | 7 +- projects/plugins/boost/composer.lock | 59 ++- projects/plugins/boost/jetpack-boost.php | 4 +- projects/plugins/boost/package.json | 2 +- 16 files changed, 1490 insertions(+), 7 deletions(-) create mode 100644 projects/plugins/boost/.phpcsignore create mode 100644 projects/plugins/boost/app/features/optimizations/minify/Concatenate_CSS.php create mode 100644 projects/plugins/boost/app/features/optimizations/minify/Concatenate_JS.php create mode 100644 projects/plugins/boost/app/features/optimizations/minify/Config.php create mode 100644 projects/plugins/boost/app/features/optimizations/minify/Dependency_Path_Mapping.php create mode 100644 projects/plugins/boost/app/features/optimizations/minify/Minify.php create mode 100644 projects/plugins/boost/app/features/optimizations/minify/functions-helpers.php create mode 100644 projects/plugins/boost/app/features/optimizations/minify/service.php create mode 100644 projects/plugins/boost/changelog/add-boost-minification create mode 100644 projects/plugins/boost/changelog/add-boost-minification#2 diff --git a/projects/plugins/boost/.phpcsignore b/projects/plugins/boost/.phpcsignore new file mode 100644 index 0000000000000..4a50d6733770d --- /dev/null +++ b/projects/plugins/boost/.phpcsignore @@ -0,0 +1,2 @@ +# For the time being, ignore page optimize refactor +/app/features/optimizations/minify/ diff --git a/projects/plugins/boost/app/assets/src/js/pages/settings/sections/Modules.svelte b/projects/plugins/boost/app/assets/src/js/pages/settings/sections/Modules.svelte index 4721488b03f3a..a972a32a4f61b 100644 --- a/projects/plugins/boost/app/assets/src/js/pages/settings/sections/Modules.svelte +++ b/projects/plugins/boost/app/assets/src/js/pages/settings/sections/Modules.svelte @@ -24,6 +24,7 @@ const criticalCssLink = getRedirectUrl( 'jetpack-boost-critical-css' ); const deferJsLink = getRedirectUrl( 'jetpack-boost-defer-js' ); const lazyLoadLink = getRedirectUrl( 'jetpack-boost-lazy-load' ); + const minifyCssLink = getRedirectUrl( 'jetpack-boost-minify-css' ); // svelte-ignore unused-export-let - Ignored values supplied by svelte-navigator. export let location, navigate; @@ -134,6 +135,19 @@ + +

    {__( 'Minify', 'jetpack-boost' )}Beta

    +

    + web.dev.`, + 'jetpack-boost' + )} + vars={externalLinkTemplateVar( minifyCssLink )} + /> +

    + + diff --git a/projects/plugins/boost/app/features/optimizations/Optimizations.php b/projects/plugins/boost/app/features/optimizations/Optimizations.php index a39b39267f443..11c3c420256b7 100644 --- a/projects/plugins/boost/app/features/optimizations/Optimizations.php +++ b/projects/plugins/boost/app/features/optimizations/Optimizations.php @@ -7,6 +7,7 @@ use Automattic\Jetpack_Boost\Features\Optimizations\Cloud_CSS\Cloud_CSS; use Automattic\Jetpack_Boost\Features\Optimizations\Critical_CSS\Critical_CSS; use Automattic\Jetpack_Boost\Features\Optimizations\Lazy_Images\Lazy_Images; +use Automattic\Jetpack_Boost\Features\Optimizations\Minify\Minify; use Automattic\Jetpack_Boost\Features\Optimizations\Render_Blocking_JS\Render_Blocking_JS; use Automattic\Jetpack_Boost\Lib\Premium_Features; use Automattic\Jetpack_Boost\REST_API\Contracts\Has_Endpoints; @@ -38,6 +39,10 @@ public function __construct() { new Image_Guide(), ); + if ( defined( 'JETPACK_BOOST_MINIFY' ) && JETPACK_BOOST_MINIFY ) { + $features[] = new Minify(); + } + foreach ( $features as $feature ) { $slug = $feature->get_slug(); $this->features[ $slug ] = new Optimization( $feature ); diff --git a/projects/plugins/boost/app/features/optimizations/minify/Concatenate_CSS.php b/projects/plugins/boost/app/features/optimizations/minify/Concatenate_CSS.php new file mode 100644 index 0000000000000..cb468c980180d --- /dev/null +++ b/projects/plugins/boost/app/features/optimizations/minify/Concatenate_CSS.php @@ -0,0 +1,214 @@ +old_styles = new WP_Styles(); + } else { + $this->old_styles = $styles; + } + + // Unset all the object properties except our private copy of the styles object. + // We have to unset everything so that the overload methods talk to $this->old_styles->whatever + // instead of $this->whatever. + foreach ( array_keys( get_object_vars( $this ) ) as $key ) { + if ( 'old_styles' === $key ) { + continue; + } + unset( $this->$key ); + } + + $this->dependency_path_mapping = new Dependency_Path_Mapping( + apply_filters( 'page_optimize_site_url', $this->base_url ) + ); + } + + function do_items( $handles = false, $group = false ) { + $handles = false === $handles ? $this->queue : (array) $handles; + $stylesheets = array(); + $siteurl = apply_filters( 'page_optimize_site_url', $this->base_url ); + + $this->all_deps( $handles ); + + $stylesheet_group_index = 0; + // Merge CSS into a single file + $concat_group = 'concat'; + // Concat group on top (first array element gets processed earlier) + $stylesheets[ $concat_group ] = array(); + + foreach ( $this->to_do as $key => $handle ) { + $obj = $this->registered[ $handle ]; + $obj->src = apply_filters( 'style_loader_src', $obj->src, $obj->handle ); + + // Core is kind of broken and returns "true" for src of "colors" handle + // http://core.trac.wordpress.org/attachment/ticket/16827/colors-hacked-fixed.diff + // http://core.trac.wordpress.org/ticket/20729 + $css_url = $obj->src; + if ( 'colors' == $obj->handle && true === $css_url ) { + $css_url = wp_style_loader_src( $css_url, $obj->handle ); + } + + $css_url_parsed = parse_url( $obj->src ); + $extra = $obj->extra; + + // Don't concat by default + $do_concat = false; + + // Only try to concat static css files + if ( false !== strpos( $css_url_parsed['path'], '.css' ) ) { + $do_concat = true; + } elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ), esc_html( $obj->src ) ); + } + + // Don't try to concat styles which are loaded conditionally (like IE stuff) + if ( isset( $extra['conditional'] ) ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ) ); + } + $do_concat = false; + } + + // Don't concat rtl stuff for now until concat supports it correctly + if ( $do_concat && 'rtl' === $this->text_direction && ! empty( $extra['rtl'] ) ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ) ); + } + $do_concat = false; + } + + // Don't try to concat externally hosted scripts + $is_internal_uri = $this->dependency_path_mapping->is_internal_uri( $css_url ); + if ( $do_concat && ! $is_internal_uri ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ), esc_url( $css_url ) ); + } + $do_concat = false; + } + + if ( $do_concat ) { + // Resolve paths and concat styles that exist in the filesystem + $css_realpath = $this->dependency_path_mapping->dependency_src_to_fs_path( $css_url ); + if ( false === $css_realpath ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ), esc_html( $css_realpath ) ); + } + $do_concat = false; + } + } + + // Skip concating CSS from exclusion list + $exclude_list = jetpack_boost_page_optimize_css_exclude_list(); + foreach ( $exclude_list as $exclude ) { + if ( $do_concat && $handle === $exclude ) { + $do_concat = false; + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ) ); + } + } + } + + // Allow plugins to disable concatenation of certain stylesheets. + if ( $do_concat && ! apply_filters( 'css_do_concat', $do_concat, $handle ) ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ) ); + } + } + $do_concat = apply_filters( 'css_do_concat', $do_concat, $handle ); + + if ( true === $do_concat ) { + $media = $obj->args; + if ( empty( $media ) ) { + $media = 'all'; + } + + $stylesheets[ $concat_group ][ $media ][ $handle ] = $css_url_parsed['path']; + $this->done[] = $handle; + } else { + ++$stylesheet_group_index; + $stylesheets[ $stylesheet_group_index ]['noconcat'][] = $handle; + ++$stylesheet_group_index; + } + unset( $this->to_do[ $key ] ); + } + + foreach ( $stylesheets as $idx => $stylesheets_group ) { + foreach ( $stylesheets_group as $media => $css ) { + if ( 'noconcat' == $media ) { + foreach ( $css as $handle ) { + if ( $this->do_item( $handle, $group ) ) { + $this->done[] = $handle; + } + } + continue; + } elseif ( count( $css ) > 1 ) { + $fs_paths = array(); + foreach ( $css as $css_uri_path ) { + $fs_paths[] = $this->dependency_path_mapping->uri_path_to_fs_path( $css_uri_path ); + } + + $mtime = max( array_map( 'filemtime', $fs_paths ) ); + if ( jetpack_boost_page_optimize_use_concat_base_dir() ) { + $path_str = implode( ',', array_map( 'jetpack_boost_page_optimize_remove_concat_base_prefix', $fs_paths ) ); + } else { + $path_str = implode( ',', $css ); + } + $path_str = "$path_str?m=$mtime"; + + if ( $this->allow_gzip_compression ) { + $path_64 = base64_encode( gzcompress( $path_str ) ); + if ( strlen( $path_str ) > ( strlen( $path_64 ) + 1 ) ) { + $path_str = '-' . $path_64; + } + } + + $href = $siteurl . '/_static/??' . $path_str; + } else { + $href = jetpack_boost_page_optimize_cache_bust_mtime( current( $css ), $siteurl ); + } + + $handles = array_keys( $css ); + $css_id = "$media-css-" . md5( $href ); + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + $style_tag = ""; + } else { + $style_tag = ""; + } + + $style_tag = apply_filters( 'page_optimize_style_loader_tag', $style_tag, $handles, $href, $media ); + $style_tag = apply_filters( 'style_loader_tag', $style_tag, $handles, $href, $media ); + + echo $style_tag . "\n"; + + array_map( array( $this, 'print_inline_style' ), array_keys( $css ) ); + } + } + + return $this->done; + } + + function __isset( $key ) { + return isset( $this->old_styles->$key ); + } + + function __unset( $key ) { + unset( $this->old_styles->$key ); + } + + function &__get( $key ) { + return $this->old_styles->$key; + } + + function __set( $key, $value ) { + $this->old_styles->$key = $value; + } +} diff --git a/projects/plugins/boost/app/features/optimizations/minify/Concatenate_JS.php b/projects/plugins/boost/app/features/optimizations/minify/Concatenate_JS.php new file mode 100644 index 0000000000000..948a3994dc5ab --- /dev/null +++ b/projects/plugins/boost/app/features/optimizations/minify/Concatenate_JS.php @@ -0,0 +1,291 @@ +old_scripts = new WP_Scripts(); + } else { + $this->old_scripts = $scripts; + } + + // Unset all the object properties except our private copy of the scripts object. + // We have to unset everything so that the overload methods talk to $this->old_scripts->whatever + // instead of $this->whatever. + foreach ( array_keys( get_object_vars( $this ) ) as $key ) { + if ( 'old_scripts' === $key ) { + continue; + } + unset( $this->$key ); + } + + $this->dependency_path_mapping = new Dependency_Path_Mapping( + apply_filters( 'page_optimize_site_url', $this->base_url ) + ); + } + + protected function has_inline_content( $handle ) { + $before_output = $this->get_data( $handle, 'before' ); + if ( ! empty( $before_output ) ) { + return true; + } + + $after_output = $this->get_data( $handle, 'after' ); + if ( ! empty( $after_output ) ) { + return true; + } + + // JavaScript translations + $has_translations = ! empty( $this->registered[ $handle ]->textdomain ); + if ( $has_translations ) { + return true; + } + + return false; + } + + function do_items( $handles = false, $group = false ) { + $handles = false === $handles ? $this->queue : (array) $handles; + $javascripts = array(); + $siteurl = apply_filters( 'page_optimize_site_url', $this->base_url ); + $this->all_deps( $handles ); + $level = 0; + + $using_strict = false; + foreach ( $this->to_do as $key => $handle ) { + $script_is_strict = false; + if ( in_array( $handle, $this->done ) || ! isset( $this->registered[ $handle ] ) ) { + continue; + } + + if ( 0 === $group && $this->groups[ $handle ] > 0 ) { + $this->in_footer[] = $handle; + unset( $this->to_do[ $key ] ); + continue; + } + + if ( ! $this->registered[ $handle ]->src ) { // Defines a group. + // if there are localized items, echo them + $this->print_extra_script( $handle ); + $this->done[] = $handle; + continue; + } + + if ( false === $group && in_array( $handle, $this->in_footer, true ) ) { + $this->in_footer = array_diff( $this->in_footer, (array) $handle ); + } + + $obj = $this->registered[ $handle ]; + $js_url = $obj->src; + $js_url_parsed = parse_url( $js_url ); + + // Don't concat by default + $do_concat = false; + + // Only try to concat static js files + if ( false !== strpos( $js_url_parsed['path'], '.js' ) ) { + $do_concat = jetpack_boost_page_optimize_should_concat_js(); + } elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ), esc_html( $obj->src ) ); + } + + // Don't try to concat externally hosted scripts + $is_internal_uri = $this->dependency_path_mapping->is_internal_uri( $js_url ); + if ( $do_concat && ! $is_internal_uri ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ), esc_url( $js_url ) ); + } + $do_concat = false; + } + + if ( $do_concat ) { + // Resolve paths and concat scripts that exist in the filesystem + $js_realpath = $this->dependency_path_mapping->dependency_src_to_fs_path( $js_url ); + if ( false === $js_realpath ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ), esc_html( $js_realpath ) ); + } + $do_concat = false; + } + } + + if ( $do_concat && $this->has_inline_content( $handle ) ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ) ); + } + $do_concat = false; + } + + // Skip core scripts that use Strict Mode + if ( $do_concat && ( 'react' === $handle || 'react-dom' === $handle ) ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ) ); + } + $do_concat = false; + $script_is_strict = true; + } elseif ( $do_concat && preg_match_all( '/^[\',"]use strict[\',"];/Uims', file_get_contents( $js_realpath ), $matches ) ) { + // Skip third-party scripts that use Strict Mode + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ) ); + } + $do_concat = false; + $script_is_strict = true; + } else { + $script_is_strict = false; + } + + // Skip concating scripts from exclusion list + $exclude_list = jetpack_boost_page_optimize_js_exclude_list(); + foreach ( $exclude_list as $exclude ) { + if ( $do_concat && $handle === $exclude ) { + $do_concat = false; + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ) ); + } + } + } + + // Allow plugins to disable concatenation of certain scripts. + if ( $do_concat && ! apply_filters( 'js_do_concat', $do_concat, $handle ) ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo sprintf( "\n\n", esc_html( $handle ) ); + } + } + $do_concat = apply_filters( 'js_do_concat', $do_concat, $handle ); + + if ( true === $do_concat ) { + if ( ! isset( $javascripts[ $level ] ) ) { + $javascripts[ $level ]['type'] = 'concat'; + } + + $javascripts[ $level ]['paths'][] = $js_url_parsed['path']; + $javascripts[ $level ]['handles'][] = $handle; + + } else { + ++$level; + $javascripts[ $level ]['type'] = 'do_item'; + $javascripts[ $level ]['handle'] = $handle; + ++$level; + } + unset( $this->to_do[ $key ] ); + + if ( $using_strict !== $script_is_strict ) { + if ( $script_is_strict ) { + $using_strict = true; + $strict_count = 0; + } else { + $using_strict = false; + } + } + + if ( $script_is_strict ) { + ++$strict_count; + } + } + + if ( empty( $javascripts ) ) { + return $this->done; + } + + foreach ( $javascripts as $js_array ) { + if ( 'do_item' == $js_array['type'] ) { + if ( $this->do_item( $js_array['handle'], $group ) ) { + $this->done[] = $js_array['handle']; + } + } elseif ( 'concat' == $js_array['type'] ) { + array_map( array( $this, 'print_extra_script' ), $js_array['handles'] ); + + if ( isset( $js_array['paths'] ) && count( $js_array['paths'] ) > 1 ) { + $fs_paths = array(); + foreach ( $js_array['paths'] as $js_url ) { + $fs_paths[] = $this->dependency_path_mapping->uri_path_to_fs_path( $js_url ); + } + + $mtime = max( array_map( 'filemtime', $fs_paths ) ); + if ( jetpack_boost_page_optimize_use_concat_base_dir() ) { + $path_str = implode( ',', array_map( 'jetpack_boost_page_optimize_remove_concat_base_prefix', $fs_paths ) ); + } else { + $path_str = implode( ',', $js_array['paths'] ); + } + $path_str = "$path_str?m=$mtime"; + + if ( $this->allow_gzip_compression ) { + $path_64 = base64_encode( gzcompress( $path_str ) ); + if ( strlen( $path_str ) > ( strlen( $path_64 ) + 1 ) ) { + $path_str = '-' . $path_64; + } + } + + $href = $siteurl . '/_static/??' . $path_str; + } elseif ( isset( $js_array['paths'] ) && is_array( $js_array['paths'] ) ) { + $href = jetpack_boost_page_optimize_cache_bust_mtime( $js_array['paths'][0], $siteurl ); + } + + $this->done = array_merge( $this->done, $js_array['handles'] ); + + // Print before/after scripts from wp_inline_scripts() and concatenated script tag + if ( isset( $js_array['extras']['before'] ) ) { + foreach ( $js_array['extras']['before'] as $inline_before ) { + echo $inline_before; + } + } + + if ( isset( $href ) ) { + $handles = implode( ',', $js_array['handles'] ); + + $load_mode = jetpack_boost_page_optimize_load_mode_js(); + + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + $tag = "\n"; + } else { + $tag = "\n"; + } + + if ( is_array( $js_array['handles'] ) && count( $js_array['handles'] ) === 1 ) { + // Because we have a single script, let's apply the `script_loader_tag` filter as core does in `do_item()`. + // That way, we interfere less with plugin and theme script filtering. For example, without this filter, + // there is a case where we block the TwentyTwenty theme from adding async/defer attributes. + // https://github.com/Automattic/page-optimize/pull/44 + $tag = apply_filters( 'script_loader_tag', $tag, $js_array['handles'][0], $href ); + } + + echo $tag; + } + + if ( isset( $js_array['extras']['after'] ) ) { + foreach ( $js_array['extras']['after'] as $inline_after ) { + echo $inline_after; + } + } + } + } + + do_action( 'js_concat_did_items', $javascripts ); + + return $this->done; + } + + function __isset( $key ) { + return isset( $this->old_scripts->$key ); + } + + function __unset( $key ) { + unset( $this->old_scripts->$key ); + } + + function &__get( $key ) { + return $this->old_scripts->$key; + } + + function __set( $key, $value ) { + $this->old_scripts->$key = $value; + } +} diff --git a/projects/plugins/boost/app/features/optimizations/minify/Config.php b/projects/plugins/boost/app/features/optimizations/minify/Config.php new file mode 100644 index 0000000000000..8b42baaab3f7e --- /dev/null +++ b/projects/plugins/boost/app/features/optimizations/minify/Config.php @@ -0,0 +1,46 @@ +site_url = $site_url; + $this->site_uri_path = parse_url( $site_url, PHP_URL_PATH ); + $this->site_dir = trailingslashit( $site_dir ); + + // Only resolve content URLs if they are under the site URL + if ( $this->is_internal_uri( $content_url ) ) { + $this->content_uri_path = parse_url( trailingslashit( $content_url ), PHP_URL_PATH ); + $this->content_dir = trailingslashit( $content_dir ); + } + + // Only resolve plugin URLs if they are under the site URL + if ( $this->is_internal_uri( $plugin_url ) ) { + $this->plugin_uri_path = parse_url( trailingslashit( $plugin_url ), PHP_URL_PATH ); + $this->plugin_dir = trailingslashit( $plugin_dir ); + } + } + + /** + * Given the full URL of a script/style dependency, return its local filesystem path. + */ + function dependency_src_to_fs_path( $src ) { + if ( ! $this->is_internal_uri( $src ) ) { + // If a URI is not internal, we can have no confidence + // we are resolving to the correct file. + return false; + } + + $src_parts = parse_url( $src ); + if ( false === $src_parts ) { + return false; + } + + if ( empty( $src_parts['path'] ) ) { + // We can't find anything to resolve + return false; + } + $path = $src_parts['path']; + + if ( empty( $src_parts['host'] ) ) { + // With no host, this is a path relative to the WordPress root + $fs_path = "{$this->site_dir}{$path}"; + + return file_exists( $fs_path ) ? $fs_path : false; + } + + return $this->uri_path_to_fs_path( $path ); + } + + /** + * Given a URI path of a script/style resource, return its local filesystem path. + */ + function uri_path_to_fs_path( $uri_path ) { + if ( 1 === preg_match( '#(?:^|/)\.\.?(?:/|$)#', $uri_path ) ) { + // Reject relative paths + return false; + } + + // The plugin URI path may be contained within the content URI path, so we check it before the content URI. + // And both the plugin and content URI paths must be contained within the site URI path, + // so we check them before checking the site URI. + if ( isset( $this->plugin_uri_path ) && static::is_descendant_uri( $this->plugin_uri_path, $uri_path ) ) { + $file_path = $this->plugin_dir . substr( $uri_path, strlen( $this->plugin_uri_path ) ); + } elseif ( isset( $this->content_uri_path ) && static::is_descendant_uri( $this->content_uri_path, $uri_path ) ) { + $file_path = $this->content_dir . substr( $uri_path, strlen( $this->content_uri_path ) ); + } elseif ( static::is_descendant_uri( $this->site_uri_path, $uri_path ) ) { + $file_path = $this->site_dir . substr( $uri_path, strlen( $this->site_uri_path ) ); + } + + if ( isset( $file_path ) && file_exists( $file_path ) ) { + return $file_path; + } else { + return false; + } + } + + /** + * Determine whether a URI is internal, contained by this site. + * + * This method helps ensure we only resolve to local FS paths. + */ + function is_internal_uri( $uri ) { + if ( jetpack_boost_page_optimize_starts_with( '/', $uri ) && ! jetpack_boost_page_optimize_starts_with( '//', $uri ) ) { + // Absolute paths are internal because they are based on the site dir (typically ABSPATH), + // and this looks like an absolute path. + return true; + } + + // To be internal, a URL must have the same scheme, host, and port as the site URL + // and start with the same path as the site URL. + return static::is_descendant_uri( $this->site_url, $uri ); + } + + /** + * Check whether a path is descended from the given directory path. + * + * Does not handle relative paths. + */ + static function is_descendant_uri( $dir_path, $candidate ) { + // Ensure a trailing slash to avoid false matches like + // "/wp-content/resource" being judged a descendant of "/wp". + $dir_path = trailingslashit( $dir_path ); + + return jetpack_boost_page_optimize_starts_with( $dir_path, $candidate ); + } +} diff --git a/projects/plugins/boost/app/features/optimizations/minify/Minify.php b/projects/plugins/boost/app/features/optimizations/minify/Minify.php new file mode 100644 index 0000000000000..6011e8b220ec7 --- /dev/null +++ b/projects/plugins/boost/app/features/optimizations/minify/Minify.php @@ -0,0 +1,63 @@ +allow_gzip_compression = true; // @todo - used constant ALLOW_GZIP_COMPRESSION = true if not defined. + } + + if ( jetpack_boost_page_optimize_should_concat_css() ) { + global $wp_styles; + + $wp_styles = new Concatenate_CSS( $wp_styles ); + $wp_styles->allow_gzip_compression = true; // @todo - used constant ALLOW_GZIP_COMPRESSION = true if not defined. + } + } +} diff --git a/projects/plugins/boost/app/features/optimizations/minify/functions-helpers.php b/projects/plugins/boost/app/features/optimizations/minify/functions-helpers.php new file mode 100644 index 0000000000000..0d4910ac68228 --- /dev/null +++ b/projects/plugins/boost/app/features/optimizations/minify/functions-helpers.php @@ -0,0 +1,299 @@ + filemtime( $cache_file ) ) { + unlink( $cache_file ); + } + } +} + +// Unschedule cache cleanup, and purge cache directory +function jetpack_boost_page_optimize_deactivate() { + $cache_folder = Config::get_cache_dir_path(); + + jetpack_boost_page_optimize_cache_cleanup( $cache_folder, 0 /* max file age in seconds */ ); + + wp_clear_scheduled_hook( Config::get_cron_cache_cleanup_hook(), [ $cache_folder ] ); +} + +function jetpack_boost_page_optimize_uninstall() { + // Run cleanup on uninstall. You can uninstall an active plugin w/o deactivation. + jetpack_boost_page_optimize_deactivate(); + + // JS + delete_option( 'page_optimize-js' ); + delete_option( 'page_optimize-load-mode' ); + delete_option( 'page_optimize-js-exclude' ); + // CSS + delete_option( 'page_optimize-css' ); + delete_option( 'page_optimize-css-exclude' ); + +} + +function jetpack_boost_page_optimize_get_text_domain() { + return 'page-optimize'; +} + +function jetpack_boost_page_optimize_should_concat_js() { + // Support query param for easy testing + if ( isset( $_GET['concat-js'] ) ) { + return $_GET['concat-js'] !== '0'; + } + + return (bool) get_option( 'page_optimize-js', jetpack_boost_page_optimize_js_default() ); +} + +// TODO: Support JS load mode regardless of whether concat is enabled +function jetpack_boost_page_optimize_load_mode_js() { + // Support query param for easy testing + if ( ! empty( $_GET['load-mode-js'] ) ) { + $load_mode = jetpack_boost_page_optimize_sanitize_js_load_mode( $_GET['load-mode-js'] ); + } else { + $load_mode = jetpack_boost_page_optimize_sanitize_js_load_mode( get_option( 'page_optimize-load-mode', jetpack_boost_page_optimize_js_load_mode_default() ) ); + } + + return $load_mode; +} + +function jetpack_boost_page_optimize_should_concat_css() { + // Support query param for easy testing + if ( isset( $_GET['concat-css'] ) ) { + return $_GET['concat-css'] !== '0'; + } + + return (bool) get_option( 'page_optimize-css', jetpack_boost_page_optimize_css_default() ); +} + +function jetpack_boost_page_optimize_js_default() { + return true; +} + +function jetpack_boost_page_optimize_css_default() { + return true; +} + +function jetpack_boost_page_optimize_js_load_mode_default() { + return ''; +} + +function jetpack_boost_page_optimize_js_exclude_list() { + $exclude_list = get_option( 'page_optimize-js-exclude' ); + if ( false === $exclude_list ) { + // Use the default since the option is not set + return jetpack_boost_page_optimize_js_exclude_list_default(); + } + if ( '' === $exclude_list ) { + return array(); + } + + return explode( ',', $exclude_list ); +} + +function jetpack_boost_page_optimize_js_exclude_list_default() { + // WordPress core stuff, a lot of other plugins depend on it. + return array( 'jquery', 'jquery-core', 'underscore', 'backbone' ); +} + +function jetpack_boost_page_optimize_css_exclude_list() { + $exclude_list = get_option( 'page_optimize-css-exclude' ); + if ( false === $exclude_list ) { + // Use the default since the option is not set + return jetpack_boost_page_optimize_css_exclude_list_default(); + } + if ( '' === $exclude_list ) { + return array(); + } + + return explode( ',', $exclude_list ); +} + +function jetpack_boost_page_optimize_css_exclude_list_default() { + // WordPress core stuff + return array( 'admin-bar', 'dashicons' ); +} + +function jetpack_boost_page_optimize_sanitize_js_load_mode( $value ) { + switch ( $value ) { + case 'async': + case 'defer': + break; + default: + $value = ''; + break; + } + + return $value; +} + +function jetpack_boost_page_optimize_sanitize_exclude_field( $value ) { + if ( empty( $value ) ) { + return ''; + } + + $excluded_strings = explode( ',', sanitize_text_field( $value ) ); + $sanitized_values = array(); + foreach ( $excluded_strings as $excluded_string ) { + if ( ! empty( $excluded_string ) ) { + $sanitized_values[] = trim( $excluded_string ); + } + } + + return implode( ',', $sanitized_values ); +} + +/** + * Determines whether a string starts with another string. + */ +function jetpack_boost_page_optimize_starts_with( $prefix, $str ) { + $prefix_length = strlen( $prefix ); + if ( strlen( $str ) < $prefix_length ) { + return false; + } + + return substr( $str, 0, $prefix_length ) === $prefix; +} + +/** + * Answers whether the plugin should provide concat resource URIs + * that are relative to a common ancestor directory. Assuming a common ancestor + * allows us to skip resolving resource URIs to filesystem paths later on. + */ +function jetpack_boost_page_optimize_use_concat_base_dir() { + return defined( 'PAGE_OPTIMIZE_CONCAT_BASE_DIR' ) && file_exists( PAGE_OPTIMIZE_CONCAT_BASE_DIR ); +} + +/** + * Get a filesystem path relative to a configured base path for resources + * that will be concatenated. Assuming a common ancestor allows us to skip + * resolving resource URIs to filesystem paths later on. + */ +function jetpack_boost_page_optimize_remove_concat_base_prefix( $original_fs_path ) { + $abspath = Config::get_abspath(); + + // Always check longer path first + if ( strlen( $abspath ) > strlen( PAGE_OPTIMIZE_CONCAT_BASE_DIR ) ) { + $longer_path = $abspath; + $shorter_path = PAGE_OPTIMIZE_CONCAT_BASE_DIR; + } else { + $longer_path = PAGE_OPTIMIZE_CONCAT_BASE_DIR; + $shorter_path = $abspath; + } + + $prefix_abspath = trailingslashit( $longer_path ); + if ( jetpack_boost_page_optimize_starts_with( $prefix_abspath, $original_fs_path ) ) { + return substr( $original_fs_path, strlen( $prefix_abspath ) ); + } + + $prefix_basedir = trailingslashit( $shorter_path ); + if ( jetpack_boost_page_optimize_starts_with( $prefix_basedir, $original_fs_path ) ) { + return substr( $original_fs_path, strlen( $prefix_basedir ) ); + } + + // If we end up here, this is a resource we shouldn't have tried to concat in the first place + return '/page-optimize-resource-outside-base-path/' . basename( $original_fs_path ); +} + +function jetpack_boost_page_optimize_schedule_cache_cleanup() { + $cache_folder = Config::get_cache_dir_path(); + $args = array( $cache_folder ); + + $cache_cleanup_hook = Config::get_cron_cache_cleanup_hook(); + + // If caching is on, and job isn't queued for current cache folder + if ( false !== $cache_folder && false === wp_next_scheduled( $cache_cleanup_hook, $args ) ) { + wp_schedule_event( time(), 'daily', $cache_cleanup_hook, $args ); + } +} + +// Cases when we don't want to concat +function jetpack_boost_page_optimize_bail() { + // Bail if we're in customizer + global $wp_customize; + if ( isset( $wp_customize ) ) { + return true; + } + + // Bail if Divi theme is active, and we're in the Divi Front End Builder + if ( ! empty( $_GET['et_fb'] ) && 'Divi' === wp_get_theme()->get_template() ) { + return true; + } + + // Bail if we're editing pages in Brizy Editor + if ( class_exists( 'Brizy_Editor' ) && method_exists( 'Brizy_Editor', 'prefix' ) && ( isset( $_GET[ Brizy_Editor::prefix( '-edit-iframe' ) ] ) || isset( $_GET[ Brizy_Editor::prefix( '-edit' ) ] ) ) ) { + return true; + } + + return false; +} + +// Taken from utils.php/Jetpack_Boost_Page_Optimize_Utils +function jetpack_boost_page_optimize_cache_bust_mtime( $path, $siteurl ) { + static $dependency_path_mapping; + + $url = $siteurl . $path; + + if ( strpos( $url, '?m=' ) ) { + return $url; + } + + $parts = parse_url( $url ); + if ( ! isset( $parts['path'] ) || empty( $parts['path'] ) ) { + return $url; + } + + if ( empty( $dependency_path_mapping ) ) { + $dependency_path_mapping = new Dependency_Path_Mapping(); + } + + $file = $dependency_path_mapping->dependency_src_to_fs_path( $url ); + + $mtime = false; + if ( file_exists( $file ) ) { + $mtime = filemtime( $file ); + } + + if ( ! $mtime ) { + return $url; + } + + if ( false === strpos( $url, '?' ) ) { + $q = ''; + } else { + list( $url, $q ) = explode( '?', $url, 2 ); + if ( strlen( $q ) ) { + $q = '&' . $q; + } + } + + return "$url?m={$mtime}{$q}"; +} diff --git a/projects/plugins/boost/app/features/optimizations/minify/service.php b/projects/plugins/boost/app/features/optimizations/minify/service.php new file mode 100644 index 0000000000000..75774286da462 --- /dev/null +++ b/projects/plugins/boost/app/features/optimizations/minify/service.php @@ -0,0 +1,337 @@ + 'text/css', + 'js' => 'application/javascript', + ); +} + +function jetpack_boost_page_optimize_service_request() { + $cache_dir = Config::get_cache_dir_path(); + $use_cache = ! empty( $cache_dir ); + if ( $use_cache && ! is_dir( $cache_dir ) && ! mkdir( $cache_dir, 0775, true ) ) { + $use_cache = false; + error_log( + sprintf( + /* translators: a filesystem path to a directory */ + __( "Disabling page-optimize cache. Unable to create cache directory '%s'.", jetpack_boost_page_optimize_get_text_domain() ), + $cache_dir + ) + ); + } + + if ( $use_cache && ( ! is_dir( $cache_dir ) || ! is_writable( $cache_dir ) || ! is_executable( $cache_dir ) ) ) { + $use_cache = false; + error_log( + sprintf( + /* translators: a filesystem path to a directory */ + __( "Disabling page-optimize cache. Unable to write to cache directory '%s'.", jetpack_boost_page_optimize_get_text_domain() ), + $cache_dir + ) + ); + } + + if ( $use_cache ) { + $request_uri_hash = md5( $_SERVER['REQUEST_URI'] ); + $cache_file = $cache_dir . "/page-optimize-cache-$request_uri_hash"; + $cache_file_meta = $cache_dir . "/page-optimize-cache-meta-$request_uri_hash"; + + if ( file_exists( $cache_file ) ) { + if ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) { + if ( strtotime( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) < filemtime( $cache_file ) ) { + header( 'HTTP/1.1 304 Not Modified' ); + exit; + } + } + + if ( file_exists( $cache_file_meta ) ) { + $meta = json_decode( file_get_contents( $cache_file_meta ) ); + if ( null !== $meta && isset( $meta->headers ) ) { + foreach ( $meta->headers as $header ) { + header( $header ); + } + } + } + + $etag = '"' . md5( file_get_contents( $cache_file ) ) . '"'; + + header( 'X-Page-Optimize: cached' ); + header( 'Cache-Control: max-age=' . 31536000 ); + header( 'ETag: ' . $etag ); + + echo file_get_contents( $cache_file ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- We need to trust this unfortunately. + die(); + } + } + + $output = jetpack_boost_page_optimize_build_output(); + $content = $output['content']; + $headers = $output['headers']; + + foreach ( $headers as $header ) { + header( $header ); + } + header( 'X-Page-Optimize: uncached' ); + header( 'Cache-Control: max-age=' . 31536000 ); + header( 'ETag: "' . md5( $content ) . '"' ); + + echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- We need to trust this unfortunately. + + if ( $use_cache ) { + file_put_contents( $cache_file, $content ); + file_put_contents( $cache_file_meta, json_encode( array( 'headers' => $headers ) ) ); + } + + die(); +} + +function jetpack_boost_page_optimize_build_output() { + $jetpack_boost_page_optimize_types = jetpack_boost_page_optimize_types(); + + /* Config */ + $concat_max_files = 150; + $concat_unique = true; + + /* Main() */ + if ( ! in_array( $_SERVER['REQUEST_METHOD'], array( 'GET', 'HEAD' ) ) ) { + jetpack_boost_page_optimize_status_exit( 400 ); + } + + // /_static/??/foo/bar.css,/foo1/bar/baz.css?m=293847g + // or + // /_static/??-eJzTT8vP109KLNJLLi7W0QdyDEE8IK4CiVjn2hpZGluYmKcDABRMDPM= + $args = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_QUERY ); + if ( ! $args || false === strpos( $args, '?' ) ) { + jetpack_boost_page_optimize_status_exit( 400 ); + } + + $args = substr( $args, strpos( $args, '?' ) + 1 ); + + // /foo/bar.css,/foo1/bar/baz.css?m=293847g + // or + // -eJzTT8vP109KLNJLLi7W0QdyDEE8IK4CiVjn2hpZGluYmKcDABRMDPM= + if ( '-' == $args[0] ) { + $args = @gzuncompress( base64_decode( substr( $args, 1 ) ) ); + + // Invalid data, abort! + if ( false === $args ) { + jetpack_boost_page_optimize_status_exit( 400 ); + } + } + + // /foo/bar.css,/foo1/bar/baz.css?m=293847g + $version_string_pos = strpos( $args, '?' ); + if ( false !== $version_string_pos ) { + $args = substr( $args, 0, $version_string_pos ); + } + + // /foo/bar.css,/foo1/bar/baz.css + $args = explode( ',', $args ); + if ( ! $args ) { + jetpack_boost_page_optimize_status_exit( 400 ); + } + + // array( '/foo/bar.css', '/foo1/bar/baz.css' ) + if ( 0 == count( $args ) || count( $args ) > $concat_max_files ) { + jetpack_boost_page_optimize_status_exit( 400 ); + } + + // If we're in a subdirectory context, use that as the root. + // We can't assume that the root serves the same content as the subdir. + $subdir_path_prefix = ''; + $request_path = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ); + $_static_index = strpos( $request_path, '/_static/' ); + if ( $_static_index > 0 ) { + $subdir_path_prefix = substr( $request_path, 0, $_static_index ); + } + unset( $request_path, $_static_index ); + + $last_modified = 0; + $pre_output = ''; + $output = ''; + + $should_minify_css = Config::is_css_minify_enabled(); + + if ( $should_minify_css ) { + $css_minify = new CssMin\Minifier(); + } + + foreach ( $args as $uri ) { + $fullpath = jetpack_boost_page_optimize_get_path( $uri ); + + if ( ! file_exists( $fullpath ) ) { + jetpack_boost_page_optimize_status_exit( 404 ); + } + + $mime_type = jetpack_boost_page_optimize_get_mime_type( $fullpath ); + if ( ! in_array( $mime_type, $jetpack_boost_page_optimize_types ) ) { + jetpack_boost_page_optimize_status_exit( 400 ); + } + + if ( $concat_unique ) { + if ( ! isset( $last_mime_type ) ) { + $last_mime_type = $mime_type; + } + + if ( $last_mime_type != $mime_type ) { + jetpack_boost_page_optimize_status_exit( 400 ); + } + } + + $stat = stat( $fullpath ); + if ( false === $stat ) { + jetpack_boost_page_optimize_status_exit( 500 ); + } + + if ( $stat['mtime'] > $last_modified ) { + $last_modified = $stat['mtime']; + } + + $buf = file_get_contents( $fullpath ); + if ( false === $buf ) { + jetpack_boost_page_optimize_status_exit( 500 ); + } + + if ( 'text/css' == $mime_type ) { + $dirpath = '/' . ltrim( $subdir_path_prefix . dirname( $uri ), '/' ); + + // url(relative/path/to/file) -> url(/absolute/and/not/relative/path/to/file) + $buf = jetpack_boost_page_optimize_relative_path_replace( $buf, $dirpath ); + + // AlphaImageLoader(...src='relative/path/to/file'...) -> AlphaImageLoader(...src='/absolute/path/to/file'...) + $buf = preg_replace( + '/(Microsoft.AlphaImageLoader\s*\([^\)]*src=(?:\'|")?)([^\/\'"\s\)](?:(?@charset\s+[\'"][^\'"]+[\'"];)/i', + function ( $match ) { + global $pre_output; + + if ( 0 === strpos( $pre_output, '@charset' ) ) { + return ''; + } + + $pre_output = $match[0] . "\n" . $pre_output; + + return ''; + }, + $buf + ); + } + + // Move the @import rules on top of the concatenated output. + // Only @charset rule are allowed before them. + if ( false !== strpos( $buf, '@import' ) ) { + $buf = preg_replace_callback( + '/(?P@import\s+(?:url\s*\()?[\'"\s]*)(?P[^\'"\s](?:https?:\/\/.+\/?)?.+?)(?P[\'"\s\)]*;)/i', + function ( $match ) use ( $dirpath ) { + global $pre_output; + + if ( 0 !== strpos( $match['path'], 'http' ) && '/' != $match['path'][0] ) { + $pre_output .= $match['pre_path'] . ( $dirpath == '/' ? '/' : $dirpath . '/' ) . + $match['path'] . $match['post_path'] . "\n"; + } else { + $pre_output .= $match[0] . "\n"; + } + + return ''; + }, + $buf + ); + } + + if ( $should_minify_css ) { + $buf = $css_minify->run( $buf ); + } + } + + if ( $jetpack_boost_page_optimize_types['js'] === $mime_type ) { + $output .= "$buf;\n"; + } else { + $output .= "$buf"; + } + } + + $headers = array( + 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', $last_modified ) . ' GMT', + 'Content-Length: ' . ( strlen( $pre_output ) + strlen( $output ) ), + "Content-Type: $mime_type", + ); + + return array( + 'headers' => $headers, + 'content' => $pre_output . $output, + ); +} + +function jetpack_boost_page_optimize_status_exit( $status ) { + http_response_code( $status ); + exit; +} + +function jetpack_boost_page_optimize_get_mime_type( $file ) { + $jetpack_boost_page_optimize_types = jetpack_boost_page_optimize_types(); + + $lastdot_pos = strrpos( $file, '.' ); + if ( false === $lastdot_pos ) { + return false; + } + + $ext = substr( $file, $lastdot_pos + 1 ); + + return isset( $jetpack_boost_page_optimize_types[ $ext ] ) ? $jetpack_boost_page_optimize_types[ $ext ] : false; +} + +function jetpack_boost_page_optimize_relative_path_replace( $buf, $dirpath ) { + // url(relative/path/to/file) -> url(/absolute/and/not/relative/path/to/file) + $buf = preg_replace( + '/(:?\s*url\s*\()\s*(?:\'|")?\s*([^\/\'"\s\)](?:(?uri_path_to_fs_path( $uri ); + } + + if ( false === $path ) { + jetpack_boost_page_optimize_status_exit( 404 ); + } + + return $path; +} + +jetpack_boost_page_optimize_service_request(); diff --git a/projects/plugins/boost/changelog/add-boost-minification b/projects/plugins/boost/changelog/add-boost-minification new file mode 100644 index 0000000000000..e7d6c76f0ed57 --- /dev/null +++ b/projects/plugins/boost/changelog/add-boost-minification @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Add page optimizer functionality. diff --git a/projects/plugins/boost/changelog/add-boost-minification#2 b/projects/plugins/boost/changelog/add-boost-minification#2 new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/boost/changelog/add-boost-minification#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/boost/composer.json b/projects/plugins/boost/composer.json index d7902407ecdbf..a5808cd664555 100644 --- a/projects/plugins/boost/composer.json +++ b/projects/plugins/boost/composer.json @@ -3,7 +3,7 @@ "description": "Boost your WordPress site's performance, from the creators of Jetpack", "type": "library", "license": "GPL-2.0-or-later", - "version": "1.7.1-alpha", + "version": "1.8.0-alpha", "authors": [ { "name": "Automattic, Inc.", @@ -25,7 +25,8 @@ "automattic/jetpack-my-jetpack": "@dev", "automattic/jetpack-plugin-deactivation": "@dev", "automattic/jetpack-plugins-installer": "@dev", - "tedivm/jshrink": "1.4.0" + "tedivm/jshrink": "1.4.0", + "tubalmartin/cssmin": "^4.1" }, "require-dev": { "automattic/jetpack-changelogger": "@dev", @@ -71,7 +72,7 @@ "platform": { "ext-intl": "0.0.0" }, - "autoloader-suffix": "b1e77e6231d50e7663f84529b6a3dfda_jetpack_boostⓥ1_7_1_alpha", + "autoloader-suffix": "b1e77e6231d50e7663f84529b6a3dfda_jetpack_boostⓥ1_8_0_alpha", "allow-plugins": { "roots/wordpress-core-installer": true, "automattic/jetpack-autoloader": true, diff --git a/projects/plugins/boost/composer.lock b/projects/plugins/boost/composer.lock index c4d58e98650ed..ab5623968ea89 100644 --- a/projects/plugins/boost/composer.lock +++ b/projects/plugins/boost/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f4bb747a13beccc4926a371351e628a6", + "content-hash": "dbf8a68a4f510020adcc7a807448c5a6", "packages": [ { "name": "automattic/jetpack-a8c-mc-stats", @@ -1200,6 +1200,63 @@ } ], "time": "2020-11-30T18:10:21+00:00" + }, + { + "name": "tubalmartin/cssmin", + "version": "v4.1.1", + "source": { + "type": "git", + "url": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port.git", + "reference": "3cbf557f4079d83a06f9c3ff9b957c022d7805cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tubalmartin/YUI-CSS-compressor-PHP-port/zipball/3cbf557f4079d83a06f9c3ff9b957c022d7805cf", + "reference": "3cbf557f4079d83a06f9c3ff9b957c022d7805cf", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "php": ">=5.3.2" + }, + "require-dev": { + "cogpowered/finediff": "0.3.*", + "phpunit/phpunit": "4.8.*" + }, + "bin": [ + "cssmin" + ], + "type": "library", + "autoload": { + "psr-4": { + "tubalmartin\\CssMin\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Túbal Martín", + "homepage": "http://tubalmartin.me/" + } + ], + "description": "A PHP port of the YUI CSS compressor", + "homepage": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port", + "keywords": [ + "compress", + "compressor", + "css", + "cssmin", + "minify", + "yui" + ], + "support": { + "issues": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port/issues", + "source": "https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port" + }, + "time": "2018-01-15T15:26:51+00:00" } ], "packages-dev": [ diff --git a/projects/plugins/boost/jetpack-boost.php b/projects/plugins/boost/jetpack-boost.php index 09775cc72bfc9..985bdde1f580b 100644 --- a/projects/plugins/boost/jetpack-boost.php +++ b/projects/plugins/boost/jetpack-boost.php @@ -9,7 +9,7 @@ * Plugin Name: Jetpack Boost * Plugin URI: https://jetpack.com/boost * Description: Boost your WordPress site's performance, from the creators of Jetpack - * Version: 1.7.1-alpha + * Version: 1.8.0-alpha * Author: Automattic - Jetpack Site Speed team * Author URI: https://jetpack.com/boost/ * License: GPL-2.0+ @@ -29,7 +29,7 @@ die; } -define( 'JETPACK_BOOST_VERSION', '1.7.1-alpha' ); +define( 'JETPACK_BOOST_VERSION', '1.8.0-alpha' ); define( 'JETPACK_BOOST_SLUG', 'jetpack-boost' ); if ( ! defined( 'JETPACK_BOOST_CLIENT_NAME' ) ) { diff --git a/projects/plugins/boost/package.json b/projects/plugins/boost/package.json index bba28aa6b5d79..61c0182d93864 100644 --- a/projects/plugins/boost/package.json +++ b/projects/plugins/boost/package.json @@ -1,6 +1,6 @@ { "name": "jetpack-boost", - "version": "1.7.1-alpha", + "version": "1.8.0-alpha", "description": "Boost your WordPress site's performance, from the creators of Jetpack", "directories": { "test": "tests" From f5ae7f78695327a3daf5eab804389962560a7994 Mon Sep 17 00:00:00 2001 From: Peter Petrov Date: Fri, 17 Feb 2023 01:31:53 +0200 Subject: [PATCH 13/51] [Boost] Fix features/optimizations initialization (#28888) * Update feature/optimization initialization to respect setup_trigger * changelog * Refactor feature/optimization initialization * Update optimizations setup to be properly registered * Update Optimizations instance to handle feature endpoint initialization This will update features to no longer take care of rest api initialization themselves. * Simplify setup process, to avoid unnecessary hooking * Fix Setup not collecting instances * Fix optimizations initializing before plugins_loaded --- .../plugins/boost/app/contracts/Has_Setup.php | 8 ------ .../app/features/image-guide/Image_Guide.php | 4 --- .../features/optimizations/Optimizations.php | 26 ++++++++++--------- .../optimizations/cloud-css/Cloud_CSS.php | 9 ------- .../critical-css/Critical_CSS.php | 10 ------- .../lazy-images/class-lazy-images.php | 4 --- .../class-render-blocking-js.php | 5 ---- .../features/setup-prompt/Setup_Prompt.php | 7 ----- projects/plugins/boost/app/lib/Setup.php | 3 +-- .../boost/changelog/fix-boost-features-init | 4 +++ 10 files changed, 19 insertions(+), 61 deletions(-) create mode 100644 projects/plugins/boost/changelog/fix-boost-features-init diff --git a/projects/plugins/boost/app/contracts/Has_Setup.php b/projects/plugins/boost/app/contracts/Has_Setup.php index 948f0227dceeb..cb6cc7af3d40a 100644 --- a/projects/plugins/boost/app/contracts/Has_Setup.php +++ b/projects/plugins/boost/app/contracts/Has_Setup.php @@ -18,12 +18,4 @@ interface Has_Setup { * @return mixed */ public function setup(); - - /** - * Return a string - which action should the setup method be run on? - * Typically, this should return `init` or `admin_init` - * - * @return string - */ - public function setup_trigger(); } diff --git a/projects/plugins/boost/app/features/image-guide/Image_Guide.php b/projects/plugins/boost/app/features/image-guide/Image_Guide.php index 27518e0af107b..b10d4047d35af 100644 --- a/projects/plugins/boost/app/features/image-guide/Image_Guide.php +++ b/projects/plugins/boost/app/features/image-guide/Image_Guide.php @@ -46,10 +46,6 @@ public static function get_slug() { return 'image-guide'; } - public function setup_trigger() { - return 'init'; - } - public function enqueue_assets() { wp_enqueue_script( 'jetpack-boost-guide', plugins_url( 'dist/guide.js', __FILE__ ), array(), JETPACK_BOOST_VERSION, true ); wp_enqueue_style( 'jetpack-boost-guide', plugins_url( 'dist/guide.css', __FILE__ ), array(), JETPACK_BOOST_VERSION, 'screen' ); diff --git a/projects/plugins/boost/app/features/optimizations/Optimizations.php b/projects/plugins/boost/app/features/optimizations/Optimizations.php index 11c3c420256b7..540678f1e4ac9 100644 --- a/projects/plugins/boost/app/features/optimizations/Optimizations.php +++ b/projects/plugins/boost/app/features/optimizations/Optimizations.php @@ -10,7 +10,9 @@ use Automattic\Jetpack_Boost\Features\Optimizations\Minify\Minify; use Automattic\Jetpack_Boost\Features\Optimizations\Render_Blocking_JS\Render_Blocking_JS; use Automattic\Jetpack_Boost\Lib\Premium_Features; +use Automattic\Jetpack_Boost\Lib\Setup; use Automattic\Jetpack_Boost\REST_API\Contracts\Has_Endpoints; +use Automattic\Jetpack_Boost\REST_API\REST_API; class Optimizations implements Has_Setup { @@ -95,12 +97,11 @@ public function register_endpoints( $feature ) { if ( empty( $feature->get_endpoints() ) ) { return false; } + + REST_API::register( $feature->get_endpoints() ); } - /** - * @inheritDoc - */ - public function setup() { + public function init_features() { foreach ( $this->available_modules() as $slug => $optimization ) { @@ -108,7 +109,8 @@ public function setup() { continue; } - $optimization->feature->setup(); + Setup::add( $optimization->feature ); + $this->register_endpoints( $optimization->feature ); do_action( "jetpack_boost_{$slug}_initialized", $this ); @@ -116,6 +118,13 @@ public function setup() { } } + /** + * @inheritDoc + */ + public function setup() { + add_action( 'plugins_loaded', array( $this, 'init_features' ) ); + } + /** * Get the lists of modules explicitly disabled from the 'jb-disable-modules' query string. * The parameter is a comma separated value list of module slug. @@ -135,11 +144,4 @@ public function get_disabled_modules() { return array(); } - /** - * @inheritDoc - */ - public function setup_trigger() { - return 'plugins_loaded'; - } - } diff --git a/projects/plugins/boost/app/features/optimizations/cloud-css/Cloud_CSS.php b/projects/plugins/boost/app/features/optimizations/cloud-css/Cloud_CSS.php index a6c926bff8dfa..e02ffe481f35b 100644 --- a/projects/plugins/boost/app/features/optimizations/cloud-css/Cloud_CSS.php +++ b/projects/plugins/boost/app/features/optimizations/cloud-css/Cloud_CSS.php @@ -13,7 +13,6 @@ use Automattic\Jetpack_Boost\REST_API\Endpoints\Cloud_CSS_Status; use Automattic\Jetpack_Boost\REST_API\Endpoints\Request_Cloud_CSS; use Automattic\Jetpack_Boost\REST_API\Endpoints\Update_Cloud_CSS; -use Automattic\Jetpack_Boost\REST_API\REST_API; class Cloud_CSS implements Feature, Has_Endpoints { @@ -42,7 +41,6 @@ public function setup() { add_filter( 'jetpack_boost_js_constants', array( $this, 'add_critical_css_constants' ) ); add_filter( 'jetpack_boost_total_problem_count', array( $this, 'update_total_problem_count' ) ); - REST_API::register( $this->get_endpoints() ); Critical_CSS_Invalidator::init(); Cloud_CSS_Cron::init(); @@ -61,13 +59,6 @@ public function get_endpoints() { ); } - /** - * @inheritDoc - */ - public function setup_trigger() { - return 'init'; - } - public function display_critical_css() { // Don't look for Critical CSS in the dashboard. diff --git a/projects/plugins/boost/app/features/optimizations/critical-css/Critical_CSS.php b/projects/plugins/boost/app/features/optimizations/critical-css/Critical_CSS.php index fade29c1da903..656abf7a163ea 100644 --- a/projects/plugins/boost/app/features/optimizations/critical-css/Critical_CSS.php +++ b/projects/plugins/boost/app/features/optimizations/critical-css/Critical_CSS.php @@ -19,7 +19,6 @@ use Automattic\Jetpack_Boost\REST_API\Endpoints\Generator_Success; use Automattic\Jetpack_Boost\REST_API\Endpoints\Recommendations_Dismiss; use Automattic\Jetpack_Boost\REST_API\Endpoints\Recommendations_Reset; -use Automattic\Jetpack_Boost\REST_API\REST_API; class Critical_CSS implements Feature, Has_Endpoints { @@ -68,8 +67,6 @@ public function setup() { add_filter( 'jetpack_boost_js_constants', array( $this, 'add_critical_css_constants' ) ); - REST_API::register( $this->get_endpoints() ); - // Admin Notices Regenerate_Admin_Notice::init(); @@ -167,11 +164,4 @@ public function get_endpoints() { Generator_Error::class, ); } - - /** - * @inheritDoc - */ - public function setup_trigger() { - return 'init'; - } } diff --git a/projects/plugins/boost/app/features/optimizations/lazy-images/class-lazy-images.php b/projects/plugins/boost/app/features/optimizations/lazy-images/class-lazy-images.php index 905d6501e83a4..ce2a5a72aca98 100644 --- a/projects/plugins/boost/app/features/optimizations/lazy-images/class-lazy-images.php +++ b/projects/plugins/boost/app/features/optimizations/lazy-images/class-lazy-images.php @@ -14,8 +14,4 @@ public function setup() { public static function get_slug() { return 'lazy-images'; } - - public function setup_trigger() { - return 'init'; - } } diff --git a/projects/plugins/boost/app/features/optimizations/render-blocking-js/class-render-blocking-js.php b/projects/plugins/boost/app/features/optimizations/render-blocking-js/class-render-blocking-js.php index 9719643b9d825..3862a3b599b91 100644 --- a/projects/plugins/boost/app/features/optimizations/render-blocking-js/class-render-blocking-js.php +++ b/projects/plugins/boost/app/features/optimizations/render-blocking-js/class-render-blocking-js.php @@ -309,9 +309,4 @@ public function is_opened_script( $buffer ) { public static function get_slug() { return 'render-blocking-js'; } - - public function setup_trigger() { - return 'init'; - } - } diff --git a/projects/plugins/boost/app/features/setup-prompt/Setup_Prompt.php b/projects/plugins/boost/app/features/setup-prompt/Setup_Prompt.php index 51d5b32c4214c..f8dd936871816 100644 --- a/projects/plugins/boost/app/features/setup-prompt/Setup_Prompt.php +++ b/projects/plugins/boost/app/features/setup-prompt/Setup_Prompt.php @@ -35,13 +35,6 @@ public function enqueue_scripts() { wp_enqueue_style( 'jetpack-boost-admin-banner', plugins_url( '../../assets/dist/admin-banner.css', __FILE__ ), array(), JETPACK_BOOST_VERSION ); } - /** - * Get the action hoot that defines when to setup the prompt. - */ - public function setup_trigger() { - return 'admin_init'; - } - public function connection_prompt() { include __DIR__ . '/_inc/banner.php'; } diff --git a/projects/plugins/boost/app/lib/Setup.php b/projects/plugins/boost/app/lib/Setup.php index 7e2d3098ceb1b..b5b4f1786ad95 100644 --- a/projects/plugins/boost/app/lib/Setup.php +++ b/projects/plugins/boost/app/lib/Setup.php @@ -27,10 +27,9 @@ class Setup { * @return void */ public static function add( Has_Setup $instance ) { - $action = $instance->setup_trigger(); + $instance->setup(); self::$instances[] = $instance; - add_action( $action, array( $instance, 'setup' ) ); } public function get_instances() { diff --git a/projects/plugins/boost/changelog/fix-boost-features-init b/projects/plugins/boost/changelog/fix-boost-features-init new file mode 100644 index 0000000000000..ab8f17dd64b5b --- /dev/null +++ b/projects/plugins/boost/changelog/fix-boost-features-init @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Fix feature/optimization initialization happening always on plugins_loaded, due to setup_trigger not getting respected. From 6ec8977c3c1ea59c40d24331814521eaa7c2d8fb Mon Sep 17 00:00:00 2001 From: ouikhuan Date: Fri, 17 Feb 2023 08:46:27 +0800 Subject: [PATCH 14/51] Update initial screen copy for migration plugin (#28993) * Update initial screen content with new copy * changelog * Make title consistent between screens --- .../changelog/update-initial-screen-content | 4 +++ .../migration/src/class-wpcom-migration.php | 2 +- .../src/js/components/migration/index.tsx | 25 ++++++++----------- .../src/js/components/migration/loading.tsx | 2 +- .../components/migration/styles.module.scss | 21 +++------------- 5 files changed, 21 insertions(+), 33 deletions(-) create mode 100644 projects/plugins/migration/changelog/update-initial-screen-content diff --git a/projects/plugins/migration/changelog/update-initial-screen-content b/projects/plugins/migration/changelog/update-initial-screen-content new file mode 100644 index 0000000000000..454f56a9a87f6 --- /dev/null +++ b/projects/plugins/migration/changelog/update-initial-screen-content @@ -0,0 +1,4 @@ +Significance: minor +Type: changed + +Change initial screen wording with new copy diff --git a/projects/plugins/migration/src/class-wpcom-migration.php b/projects/plugins/migration/src/class-wpcom-migration.php index 8f3e74c4ba7d3..08322c74cb232 100644 --- a/projects/plugins/migration/src/class-wpcom-migration.php +++ b/projects/plugins/migration/src/class-wpcom-migration.php @@ -72,7 +72,7 @@ public function admin_menu_hook_callback() { 'manage_options', 'wpcom-migration', array( $this, 'plugin_settings_page' ), - 'dashicons-admin-generic', + 'dashicons-migrate', 79 // right before the Settings menu (80) ); diff --git a/projects/plugins/migration/src/js/components/migration/index.tsx b/projects/plugins/migration/src/js/components/migration/index.tsx index f567b8f13ea92..1a95bfc6cd81b 100644 --- a/projects/plugins/migration/src/js/components/migration/index.tsx +++ b/projects/plugins/migration/src/js/components/migration/index.tsx @@ -84,35 +84,32 @@ export function Migration( props: Props ) { } - title={ __( 'Move to WordPress.com', 'wpcom-migration' ) } + title={ __( "Let's start moving your site over", 'wpcom-migration' ) } images={ [ migrationImage1 ] } >

    { __( - 'Whether the result of poor performance, lack of support or limited bandwidth, ' + - "migrating your site to WordPress.com shouldn't be hard. That's our job! " + - 'Migrate your site now and get managed by experienced, dedicated and specailists on ' + - 'WordPress professionals.', + "You're a few steps away from upgrading your site to the speed and power of WordPress.com. " + + "Here's how it works: ", 'wpcom-migration' ) }

    -
      -
    • +
        +
      1. { __( 'Click Get started.', 'wpcom-migration' ) }
      2. +
      3. { __( - 'No need to worry about budget - this is a free migration service offically provided by WordPress.com.', + "Choose what you'd like to move over from your old site - whether that's just the basics, or all of your content, plugins, and settings.", 'wpcom-migration' ) }
      4. -
      5. +
      6. { __( - 'This is seamless and automated process. It takes one click to back-up and migrate your entire site to WordPress.com', + "Sit back, and let the plugin do the work. We'll email you when your migration's ready.", 'wpcom-migration' ) }
      7. -
      8. - { __( 'Move to WordPress.com provides low to zero downtime.', 'wpcom-migration' ) } -
      9. -
    +
  • { __( 'Welcome to WordPress.com!', 'wpcom-migration' ) }
  • +
    { ToS }

    @@ -104,20 +78,21 @@ {/if} - {#each $activeRecommendations as recommendation (recommendation.key)} + {#each $activeIssues as issue (issue.key)}
    - dismiss( recommendation.key )} /> + dismissIssue( issue.key )} />

    - {recommendation.label} + {issue.provider_name}

    - {#each [ recommendation.errors[ 0 ] ] as errorSet} -
    - -
    - {/each} +
    + +
    {/each}
    diff --git a/projects/plugins/boost/app/assets/src/js/stores/critical-css-recommendations.ts b/projects/plugins/boost/app/assets/src/js/stores/critical-css-recommendations.ts index d69092160c672..d154b1eaf102b 100644 --- a/projects/plugins/boost/app/assets/src/js/stores/critical-css-recommendations.ts +++ b/projects/plugins/boost/app/assets/src/js/stores/critical-css-recommendations.ts @@ -1,94 +1,110 @@ -import { writable, derived } from 'svelte/store'; +import { writable, derived, get } from 'svelte/store'; +import { __ } from '@wordpress/i18n'; import api from '../api/api'; import { castToString } from '../utils/cast-to-string'; -import { objectFilter } from '../utils/object-filter'; import { sortByFrequency } from '../utils/sort-by-frequency'; -import { CriticalCssErrorDetails, criticalCssStatus } from './critical-css-status'; +import { criticalCssStatus, updateIssues } from './critical-css-status'; import type { JSONObject } from '../utils/json-types'; -const importantProviders = [ - 'core_front_page', - 'core_posts_page', - 'singular_page', - 'singular_post', -]; +type Critical_CSS_Error_Type = + | 'SuccessTargetError' + | 'UrlError' + | 'HttpError' + | 'UnknownError' + | 'CrossDomainError' + | 'LoadTimeoutError' + | 'RedirectError' + | 'UrlVerifyError' + | 'EmptyCSSError' + | 'XFrameDenyError'; + +export interface CriticalCssErrorDetails { + url: string; + message: string; + meta: JSONObject; + type: Critical_CSS_Error_Type; +} -const initialState = Jetpack_Boost.criticalCssDismissedRecommendations || []; -const dismissed = writable< string[] >( initialState ); +export type CriticalCssIssue = { + provider_name: string; + key: string; + status: 'active' | 'dismissed'; + errors: CriticalCssErrorDetails[]; +}; /** * Specification for a set of errors that can appear as a part of a recommendation. * Every error in the set is of the same type. */ export type ErrorSet = { - type: string; // Type of errors in this set. + type: Critical_CSS_Error_Type; // Type of errors in this set. firstMeta: JSONObject; // Meta from the first error, for convenience. byUrl: { [ url: string ]: CriticalCssErrorDetails; // Each error keyed by URL. }; }; -/** - * Specification of the Recommendation data structure used for display. - */ -type Recommendation = { - key: string; // Provider Key associated with this recommendation. - label: string; // Label for the Provider Key. - errors: ErrorSet[]; // Sets of errors grouped for display. Mostly grouped by error type, but can also group by HTTP error code. -}; +const issuesStore = derived( criticalCssStatus, $status => { + return $status.issues || []; +} ); + +const dismissalErrorStore = writable( null ); +export const dismissalError = { subscribe: dismissalErrorStore.subscribe }; /** - * Derived store containing Critical CSS recommendations based on Critical CSS - * status and the provider key errors inside. + * Derived datastore: contains the number of provider keys which failed in the + * latest Critical CSS generation run. */ -export const recommendations = derived( criticalCssStatus, state => { - if ( ! state.providers_errors ) { - return []; +export const failedProviderKeyCount = derived( issuesStore, $issues => { + if ( $issues.length === 0 ) { + return 0; } - - return Object.entries( state.providers_errors ).map< Recommendation >( - ( [ key, urlErrors ] ) => ( { - key, - label: state.provider_key_labels[ key ] || key, - errors: groupErrorsByFrequency( urlErrors ), - } ) - ); + return $issues.reduce( ( acc, curr ) => ( curr.errors.length > 0 ? acc + 1 : acc ), 0 ); } ); /** * Store used to track Critical CSS Recommendations which have been dismissed. * Exported as a read-only store. */ -export const dismissedRecommendations = { subscribe: dismissed.subscribe }; +export const dismissedIssues = derived( issuesStore, $issues => { + if ( $issues.length === 0 ) { + return []; + } + return $issues.filter( r => r.status === 'dismissed' ); +} ); /** * Derived store containing Critical CSS recommendations which have not been dismissed. */ -export const activeRecommendations = derived( - [ recommendations, dismissedRecommendations ], - ( [ recommends, dismisses ] ) => recommends.filter( r => ! dismisses.includes( r.key ) ) -); +export const activeIssues = derived( issuesStore, $issues => { + if ( $issues.length === 0 ) { + return []; + } + return $issues.filter( r => r.status === 'active' ); +} ); /** * Derived datastore: Returns the most important Set of errors among the recommendations. * Used for displaying the most important error as a showstopper if no URLS succeeded. */ -export const primaryErrorSet = derived( recommendations, recommends => { +export const primaryErrorSet = derived( issuesStore, $issues => { + const importantProviders = [ + 'core_front_page', + 'core_posts_page', + 'singular_page', + 'singular_post', + ]; + for ( const key of importantProviders ) { - const recommendation = recommends.find( r => r.key === key ); - if ( recommendation ) { - return recommendation.errors[ 0 ]; + const issue = $issues.find( r => r.key === key ); + if ( issue ) { + return groupErrorsByFrequency( issue ); } } return undefined; } ); -/** - * Store used to track Critical CSS Recommendations dismissal error. - */ -export const dismissalError = writable( null ); - /** * Set the dismissal error if something wrong occurred * during the event to dismiss a recommendation or the event @@ -97,35 +113,27 @@ export const dismissalError = writable( null ); * @param {string} title Error display title. * @param {Object} error Error. */ -export function setDismissalError( title: string, error: JSONObject ): void { - dismissalError.set( { +function setDismissalError( title: string, error: JSONObject ): void { + dismissalErrorStore.set( { title, error, } ); } -/** - * Dismiss the recommendation associated with the given provider key. Calls the - * API to update the back end in lock-step. - * - * @param {string} key Key of recommendation to dismiss. - */ -export async function dismissRecommendation( key: string ): Promise< void > { - await api.post( '/recommendations/dismiss', { - providerKey: key, - nonce: Jetpack_Boost.nonces[ 'recommendations/dismiss' ], - } ); - dismissed.update( keys => [ ...keys, key ] ); -} - /** * Clear all the dismissed recommendations. */ -export async function clearDismissedRecommendations(): Promise< void > { +export async function clearDismissedIssues(): Promise< void > { await api.post( '/recommendations/reset', { nonce: Jetpack_Boost.nonces[ 'recommendations/reset' ], } ); - dismissed.set( [] ); + const issues = get( issuesStore ); + updateIssues( + issues.map( issue => { + issue.status = 'active'; + return issue; + } ) + ); } /** @@ -133,16 +141,20 @@ export async function clearDismissedRecommendations(): Promise< void > { * a SortedErrorSet; an array which contains each type of error grouped. Also * groups things like HTTP errors by code. * - * @param {Object} errors Errors in an object keyed by URL to group + * @param issue The recommendation the errors belong to. */ -function groupErrorsByFrequency( errors: { - [ url: string ]: CriticalCssErrorDetails; -} ): ErrorSet[] { - const groupKeys = Object.values( errors ).map( groupKey ); +export function groupErrorsByFrequency( issue: CriticalCssIssue ): ErrorSet[] { + const { errors } = issue; + const groupKeys = errors.map( error => groupKey( error ) ); const groupOrder = sortByFrequency( groupKeys ); return groupOrder.map( group => { - const byUrl = objectFilter( errors, v => groupKey( v ) === group ); + const byUrl = errors.reduce< { [ url: string ]: CriticalCssErrorDetails } >( ( acc, error ) => { + if ( groupKey( error ) === group ) { + acc[ error.url ] = error; + } + return acc; + }, {} ); const first = byUrl[ Object.keys( byUrl )[ 0 ] ]; return { @@ -159,7 +171,7 @@ function groupErrorsByFrequency( errors: { * * @param {CriticalCssErrorDetails} error */ -function groupKey( error: CriticalCssErrorDetails ) { +export function groupKey( error: CriticalCssErrorDetails ) { if ( error.type === 'HttpError' ) { return error.type + '-' + castToString( error.meta.code, '' ); } @@ -170,3 +182,39 @@ function groupKey( error: CriticalCssErrorDetails ) { return error.type; } + +/** + * Dismiss the recommendation associated with the given provider key. Calls the + * API to update the back end in lock-step. + * + * @param {string} key Key of recommendation to dismiss. + */ +export async function dismissIssue( key: string ): Promise< void > { + const issues = get( issuesStore ); + const issue = issues.find( el => el.key === key ); + if ( issue ) { + issue.status = 'dismissed'; + updateIssues( issues ); + } + try { + await api.post( '/recommendations/dismiss', { + providerKey: key, + nonce: Jetpack_Boost.nonces[ 'recommendations/dismiss' ], + } ); + } catch ( error ) { + setDismissalError( __( 'Failed to dismiss recommendation', 'jetpack-boost' ), error ); + } +} +/** + * Show the previously dismissed recommendations. + */ +export async function showDismissedIssues() { + try { + await clearDismissedIssues(); + } catch ( error ) { + setDismissalError( + __( 'Failed to show the dismissed recommendations', 'jetpack-boost' ), + error + ); + } +} diff --git a/projects/plugins/boost/app/assets/src/js/stores/critical-css-status.ts b/projects/plugins/boost/app/assets/src/js/stores/critical-css-status.ts index 5a3bf3b3f64fd..2de3244eaf680 100644 --- a/projects/plugins/boost/app/assets/src/js/stores/critical-css-status.ts +++ b/projects/plugins/boost/app/assets/src/js/stores/critical-css-status.ts @@ -1,16 +1,11 @@ import { derived, writable } from 'svelte/store'; import api from '../api/api'; import { modules } from './modules'; +import type { CriticalCssIssue } from './critical-css-recommendations'; import type { ProviderKeyUrls, ProvidersSuccessRatio } from '../utils/generate-critical-css'; import type { JSONObject } from '../utils/json-types'; import type { Viewport } from '../utils/types'; -export interface CriticalCssErrorDetails { - message: string; - type: string; - meta: JSONObject; -} - export interface CriticalCssStatus { progress: number; retried_show_stopper?: boolean; @@ -24,15 +19,10 @@ export interface CriticalCssStatus { core_providers?: string[]; core_providers_status?: string; status_error?: Error | string; - providers_errors?: { - [ providerKey: string ]: { - [ url: string ]: CriticalCssErrorDetails; - }; - }; - provider_key_labels?: { [ name: string ]: string }; success_count?: number; created?: number; viewports?: Viewport[]; + issues?: CriticalCssIssue[]; } const SUCCESS = 'success'; @@ -58,14 +48,6 @@ export function getStatus() { return status; } -/** - * Derived datastore: contains the number of provider keys which failed in the - * latest Critical CSS generation run. - */ -export const failedProviderKeyCount = derived( { subscribe }, state => - state.providers_errors ? Object.keys( state.providers_errors ).length : 0 -); - /** * Derived datastore: Returns true if the Critical CSS status indicates the process * is complete - i.e.: is success or fail. @@ -210,6 +192,13 @@ export function setError(): void { } ) ); } +export function updateIssues( issues: CriticalCssIssue[] ): void { + return update( state => ( { + ...state, + issues, + } ) ); +} + export const criticalCssStatus = { subscribe, }; diff --git a/projects/plugins/boost/app/assets/src/js/utils/describe-critical-css-recommendations.ts b/projects/plugins/boost/app/assets/src/js/utils/describe-critical-css-recommendations.ts index c6ba21ee30e1d..30cc04c4f9ba5 100644 --- a/projects/plugins/boost/app/assets/src/js/utils/describe-critical-css-recommendations.ts +++ b/projects/plugins/boost/app/assets/src/js/utils/describe-critical-css-recommendations.ts @@ -1,8 +1,7 @@ import { __, _n, sprintf } from '@wordpress/i18n'; import UrlComponentsExample from '../pages/settings/elements/UrlComponentsExample.svelte'; import { castToNumber } from './cast-to-number'; -import type { ErrorSet } from '../stores/critical-css-recommendations'; -import type { CriticalCssErrorDetails } from '../stores/critical-css-status'; +import type { CriticalCssErrorDetails, ErrorSet } from '../stores/critical-css-recommendations'; import type { SvelteComponent } from 'svelte'; type Suggestion = { diff --git a/projects/plugins/boost/app/assets/src/js/utils/generate-critical-css.ts b/projects/plugins/boost/app/assets/src/js/utils/generate-critical-css.ts index 3c5e456d337e8..4d76c1bbe3c54 100644 --- a/projects/plugins/boost/app/assets/src/js/utils/generate-critical-css.ts +++ b/projects/plugins/boost/app/assets/src/js/utils/generate-critical-css.ts @@ -1,7 +1,7 @@ import { get } from 'svelte/store'; import { __ } from '@wordpress/i18n'; import { hideRegenerateCriticalCssSuggestion } from '../stores/config'; -import { clearDismissedRecommendations } from '../stores/critical-css-recommendations'; +import { clearDismissedIssues } from '../stores/critical-css-recommendations'; import { requestGeneration, sendGenerationResult, @@ -73,7 +73,7 @@ export default async function generateCriticalCss( try { if ( reset ) { - await clearDismissedRecommendations(); + await clearDismissedIssues(); updateGenerateStatus( { status: 'requesting', progress: 0 } ); hideRegenerateCriticalCssSuggestion(); } diff --git a/projects/plugins/boost/app/assets/src/js/utils/object-filter.ts b/projects/plugins/boost/app/assets/src/js/utils/object-filter.ts deleted file mode 100644 index 693718ca9f292..0000000000000 --- a/projects/plugins/boost/app/assets/src/js/utils/object-filter.ts +++ /dev/null @@ -1,26 +0,0 @@ -// TODO: Fix issue with @template causing an issue with eslint fix. -/* eslint-disable */ -/** - * Handy helper method to run filter on an Object. Similar to Array.filter, - * but for objects. - * - * Usually templated ValueType can be auto-detected by TypeScript and won't - * need to be specified. - * - * @template {*} ValueType - Type of object values. - * @param { Object } obj - Object to map. - * @param { Function } predicate - Callback to run on each object value. - */ -/* eslint-enable */ -export function objectFilter< ValueType >( - obj: { [ name: string ]: ValueType }, - predicate: ( value: ValueType, key?: string ) => boolean -): { [ name: string ]: ValueType } { - return Object.entries( obj ).reduce( ( filtered, [ key, value ] ) => { - if ( predicate( value, key ) ) { - filtered[ key ] = value; - } - - return filtered; - }, {} as { [ name: string ]: ValueType } ); -} diff --git a/projects/plugins/boost/app/features/optimizations/critical-css/Critical_CSS.php b/projects/plugins/boost/app/features/optimizations/critical-css/Critical_CSS.php index 656abf7a163ea..ecdb301eb1c0c 100644 --- a/projects/plugins/boost/app/features/optimizations/critical-css/Critical_CSS.php +++ b/projects/plugins/boost/app/features/optimizations/critical-css/Critical_CSS.php @@ -9,7 +9,6 @@ use Automattic\Jetpack_Boost\Lib\Critical_CSS\Critical_CSS_State; use Automattic\Jetpack_Boost\Lib\Critical_CSS\Critical_CSS_Storage; use Automattic\Jetpack_Boost\Lib\Critical_CSS\Display_Critical_CSS; -use Automattic\Jetpack_Boost\Lib\Critical_CSS\Recommendations; use Automattic\Jetpack_Boost\Lib\Critical_CSS\Source_Providers\Source_Providers; use Automattic\Jetpack_Boost\REST_API\Contracts\Endpoint; use Automattic\Jetpack_Boost\REST_API\Contracts\Has_Endpoints; @@ -48,13 +47,6 @@ public function __construct() { * This is only run if Critical CSS module has been activated. */ public function setup() { - // Touch to setup the post type. This is a temporary hack. - // This should instantiate a new Post_Type_Storage class, - // so that Critical_CSS class is responsible - // for setting up the storage. - $recommendations = new Recommendations(); - $recommendations->attach_hooks(); - add_action( 'wp', array( $this, 'display_critical_css' ) ); if ( Generator::is_generating_critical_css() ) { diff --git a/projects/plugins/boost/app/features/optimizations/critical-css/Generator.php b/projects/plugins/boost/app/features/optimizations/critical-css/Generator.php index 6bee4d5b6b074..bbc0eb733ebe1 100644 --- a/projects/plugins/boost/app/features/optimizations/critical-css/Generator.php +++ b/projects/plugins/boost/app/features/optimizations/critical-css/Generator.php @@ -61,20 +61,13 @@ public function get_critical_css_status() { ); } - $providers_errors = $this->state->get_providers_errors(); - $provider_key_labels = array_combine( - array_keys( $providers_errors ), - array_map( array( $this, 'describe_provider_key' ), array_keys( $providers_errors ) ) - ); - return array( 'status' => Critical_CSS_State::SUCCESS, 'progress' => $this->state->get_percent_complete(), 'success_count' => $this->state->get_providers_success_count(), 'core_providers' => self::CORE_PROVIDER_KEYS, 'core_providers_status' => $this->state->get_core_providers_status( self::CORE_PROVIDER_KEYS ), - 'providers_errors' => $providers_errors, - 'provider_key_labels' => $provider_key_labels, + 'issues' => $this->get_issues(), 'created' => $this->state->get_created_time(), 'updated' => $this->state->get_updated_time(), ); @@ -98,6 +91,36 @@ public function find_provider_for( $provider_key ) { return false; } + /** + * Get providers errors. + * + * @return array + */ + public function get_issues() { + + $providers_errors = $this->state->get_providers_errors(); + $issue_status = $this->state->get_provider_issue_status(); + $issues = array(); + foreach ( $providers_errors as $provider => $url_errors ) { + $errors = array(); + foreach ( $url_errors as $url => $error ) { + $error['url'] = $url; + $errors[] = $error; + } + $label = $this->describe_provider_key( $provider ); + + $status = ! empty( $issue_status[ $provider ] ) ? $issue_status[ $provider ] : 'active'; + $issues[] = array( + 'provider_name' => $label, + 'key' => $provider, + 'status' => $status, + 'errors' => $errors, + ); + } + + return $issues; + } + /** * Returns a descriptive label for a provider key, or the raw provider key * if none found. @@ -154,6 +177,7 @@ public static function is_generating_critical_css() { return $is_generating; } + // phpcs:enable WordPress.Security.NonceVerification.Recommended public function make_generation_request() { diff --git a/projects/plugins/boost/app/lib/critical-css/Critical_CSS_State.php b/projects/plugins/boost/app/lib/critical-css/Critical_CSS_State.php index 978aec0eede10..a795190869f9d 100644 --- a/projects/plugins/boost/app/lib/critical-css/Critical_CSS_State.php +++ b/projects/plugins/boost/app/lib/critical-css/Critical_CSS_State.php @@ -107,6 +107,26 @@ private function get_state_transient() { ); } + public function get_provider_issue_status() { + return $this->collate_column( 'issue_status' ); + } + public function set_provider_issue_status( $provider_key, $status ) { + $valid_statuses = array( 'dismissed', 'active' ); + if ( ! in_array( $status, $valid_statuses, true ) ) { + return; + } + + $this->sources[ $provider_key ]['issue_status'] = $status; + $this->save(); + } + + public function reset_provider_issue_status() { + foreach ( $this->sources as $provider_key => $source ) { + $this->sources[ $provider_key ]['issue_status'] = 'active'; + } + $this->save(); + } + public function maybe_set_status() { if ( $this->get_total_providers_count() === $this->get_processed_providers_count() ) { // Only consider the generation a success if at least one provider was successful diff --git a/projects/plugins/boost/app/lib/critical-css/Recommendations.php b/projects/plugins/boost/app/lib/critical-css/Recommendations.php deleted file mode 100644 index 367b528fd20b7..0000000000000 --- a/projects/plugins/boost/app/lib/critical-css/Recommendations.php +++ /dev/null @@ -1,32 +0,0 @@ -dismissed_recommendations = new Collection( 'jetpack_boost_dismissed_recommendations' ); - } - - public function attach_hooks() { - add_filter( 'jetpack_boost_js_constants', array( $this, 'add_boost_js_constants' ) ); - } - - public function add_boost_js_constants( $constants ) { - $constants['criticalCssDismissedRecommendations'] = $this->dismissed_recommendations->get(); - - return $constants; - } - - public function dismiss( $recommendation_for_provider ) { - $this->dismissed_recommendations->append( $recommendation_for_provider ); - } - - public function reset() { - $this->dismissed_recommendations->delete(); - } - -} diff --git a/projects/plugins/boost/app/rest-api/endpoints/Generator_Request.php b/projects/plugins/boost/app/rest-api/endpoints/Generator_Request.php index e583ae029fa7c..38df2616d8370 100644 --- a/projects/plugins/boost/app/rest-api/endpoints/Generator_Request.php +++ b/projects/plugins/boost/app/rest-api/endpoints/Generator_Request.php @@ -5,7 +5,6 @@ use Automattic\Jetpack_Boost\Admin\Regenerate_Admin_Notice; use Automattic\Jetpack_Boost\Features\Optimizations\Critical_CSS\Generator; use Automattic\Jetpack_Boost\Lib\Critical_CSS\Critical_CSS_Storage; -use Automattic\Jetpack_Boost\Lib\Critical_CSS\Recommendations; use Automattic\Jetpack_Boost\REST_API\Contracts\Endpoint; use Automattic\Jetpack_Boost\REST_API\Permissions\Current_User_Admin; @@ -21,13 +20,11 @@ public function response( $request ) { $generator = new Generator(); if ( $reset ) { - $storage = new Critical_CSS_Storage(); - $recommendations = new Recommendations(); + $storage = new Critical_CSS_Storage(); // Create a new Critical CSS Request block to track creation request. $storage->clear(); $generator->make_generation_request(); - $recommendations->reset(); Regenerate_Admin_Notice::dismiss(); } diff --git a/projects/plugins/boost/app/rest-api/endpoints/Generator_Success.php b/projects/plugins/boost/app/rest-api/endpoints/Generator_Success.php index 5f2cf39190487..ad45704b96a18 100644 --- a/projects/plugins/boost/app/rest-api/endpoints/Generator_Success.php +++ b/projects/plugins/boost/app/rest-api/endpoints/Generator_Success.php @@ -6,7 +6,6 @@ use Automattic\Jetpack_Boost\Features\Optimizations\Critical_CSS\Generator; use Automattic\Jetpack_Boost\Lib\Critical_CSS\Critical_CSS_State; use Automattic\Jetpack_Boost\Lib\Critical_CSS\Critical_CSS_Storage; -use Automattic\Jetpack_Boost\Lib\Critical_CSS\Recommendations; use Automattic\Jetpack_Boost\Lib\Nonce; use Automattic\Jetpack_Boost\REST_API\Contracts\Endpoint; use Automattic\Jetpack_Boost\REST_API\Permissions\Current_User_Admin; @@ -70,13 +69,11 @@ public function response( $request ) { ); } - $storage = new Critical_CSS_Storage(); - $recommendations = new Recommendations(); - $generator = new Generator(); + $storage = new Critical_CSS_Storage(); + $generator = new Generator(); $storage->store_css( $cache_key, $params['data'] ); $generator->state->set_source_success( $cache_key ); - $recommendations->reset(); Regenerate_Admin_Notice::dismiss(); Critical_CSS_State::set_fresh(); diff --git a/projects/plugins/boost/app/rest-api/endpoints/Recommendations_Dismiss.php b/projects/plugins/boost/app/rest-api/endpoints/Recommendations_Dismiss.php index abacdb5eb6f59..6214315c81fba 100644 --- a/projects/plugins/boost/app/rest-api/endpoints/Recommendations_Dismiss.php +++ b/projects/plugins/boost/app/rest-api/endpoints/Recommendations_Dismiss.php @@ -2,7 +2,7 @@ namespace Automattic\Jetpack_Boost\REST_API\Endpoints; -use Automattic\Jetpack_Boost\Lib\Critical_CSS\Recommendations; +use Automattic\Jetpack_Boost\Lib\Critical_CSS\Critical_CSS_State; use Automattic\Jetpack_Boost\REST_API\Contracts\Endpoint; use Automattic\Jetpack_Boost\REST_API\Permissions\Current_User_Admin; use Automattic\Jetpack_Boost\REST_API\Permissions\Nonce; @@ -19,8 +19,9 @@ public function response( $request ) { wp_send_json_error(); } - $recommendations = new Recommendations(); - $recommendations->dismiss( $provider_key ); + $state = new Critical_CSS_State(); + $state->set_provider_issue_status( $provider_key, 'dismissed' ); + wp_send_json_success(); } diff --git a/projects/plugins/boost/app/rest-api/endpoints/Recommendations_Reset.php b/projects/plugins/boost/app/rest-api/endpoints/Recommendations_Reset.php index 963a8a43c4221..d362050c9fe3e 100644 --- a/projects/plugins/boost/app/rest-api/endpoints/Recommendations_Reset.php +++ b/projects/plugins/boost/app/rest-api/endpoints/Recommendations_Reset.php @@ -1,7 +1,7 @@ reset(); + $state = new Critical_CSS_State(); + $state->reset_provider_issue_status(); wp_send_json_success(); } diff --git a/projects/plugins/boost/changelog/boost-fix-critical-css-notices b/projects/plugins/boost/changelog/boost-fix-critical-css-notices new file mode 100644 index 0000000000000..baf282852c170 --- /dev/null +++ b/projects/plugins/boost/changelog/boost-fix-critical-css-notices @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: User non-facing refactor + + From 4fd1cd0b51fa8a027bf53f566d4e8c4c312114e7 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Fri, 17 Feb 2023 00:54:36 -0500 Subject: [PATCH 16/51] tools: Strengthen report about old PHP in dev env check (#29003) The note that "Version 8.0 or later is recommended" issued by `check-development-environment.sh` when using PHP 7.4 is being read to imply that 7.4 should work, which is not the case for our tooling (it just should be ok for running plugins). The message will now state "Version 8.0 or later is recommended. Tooling may raise errors with earlier versions." --- tools/check-development-environment.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/check-development-environment.sh b/tools/check-development-environment.sh index d973a88197c3f..0095504c735e4 100755 --- a/tools/check-development-environment.sh +++ b/tools/check-development-environment.sh @@ -203,7 +203,7 @@ else elif php -r "exit( version_compare( PHP_VERSION, '$PHP_VERSION', '>=' ) ? 0 : 1 );"; then success "ok (version $VER)" elif php -r "exit( version_compare( PHP_VERSION, '$MIN_PHP_VERSION', '>=' ) ? 0 : 1 );"; then - warning "ok (version $VER)" 'php' "Version $PHP_VERSION or later is recommended." + warning "ok (version $VER)" 'php' "Version $PHP_VERSION or later is recommended. Tooling may raise errors with earlier versions." else failure 'too old' 'php' "PHP at $BIN is version $VER. Version $MIN_PHP_VERSION or later is required; $PHP_VERSION or later is recommended." fi From 20b388c035e5a2a8010b4e47e15d030743540dd3 Mon Sep 17 00:00:00 2001 From: Francesco Bigiarini Date: Fri, 17 Feb 2023 09:07:25 +0100 Subject: [PATCH 17/51] Fix import hierarchies (#29012) * Fix imported resources hierarchies * changelog --- .../import/changelog/fix-import-hierarchies | 4 ++ .../import/src/endpoints/class-category.php | 26 +------------ .../import/src/endpoints/class-comment.php | 38 ++++++++----------- .../import/src/endpoints/class-page.php | 27 ++++++------- .../import/src/endpoints/class-post.php | 26 +------------ .../import/src/endpoints/class-tag.php | 19 ---------- .../import/src/endpoints/trait-import.php | 15 -------- 7 files changed, 32 insertions(+), 123 deletions(-) create mode 100644 projects/packages/import/changelog/fix-import-hierarchies diff --git a/projects/packages/import/changelog/fix-import-hierarchies b/projects/packages/import/changelog/fix-import-hierarchies new file mode 100644 index 0000000000000..70edcc3cc2e91 --- /dev/null +++ b/projects/packages/import/changelog/fix-import-hierarchies @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Fixed various imported resources hierarchies diff --git a/projects/packages/import/src/endpoints/class-category.php b/projects/packages/import/src/endpoints/class-category.php index a96ee9f77551e..2ddcb7b202463 100644 --- a/projects/packages/import/src/endpoints/class-category.php +++ b/projects/packages/import/src/endpoints/class-category.php @@ -64,7 +64,7 @@ public function add_additional_fields_schema( $schema ) { * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { - if ( isset( $request['parent'] ) ) { + if ( ! empty( $request['parent'] ) ) { $parent = get_term_by( 'slug', $request['parent'], 'category' ); // Overwrite the parent ID with the parent term ID found using the slug. @@ -75,28 +75,4 @@ public function create_item( $request ) { return $this->add_import_id_metadata( $request, $response ); } - - /** - * Update the category parent ID. - * - * @param int $resource_id The resource ID. - * @param int $parent_import_id The parent ID. - * @return bool True if updated. - */ - protected function update_parent_id( $resource_id, $parent_import_id ) { - $categories = \get_categories( $this->get_import_db_query( $parent_import_id ) ); - - if ( is_array( $categories ) && count( $categories ) === 1 ) { - $parent_id = $categories[0]; - - return (bool) \wp_update_category( - array( - 'cat_ID' => $resource_id, - 'category_parent' => $parent_id, - ) - ); - } - - return false; - } } diff --git a/projects/packages/import/src/endpoints/class-comment.php b/projects/packages/import/src/endpoints/class-comment.php index b45e6e58c84f8..638cf5592ed04 100644 --- a/projects/packages/import/src/endpoints/class-comment.php +++ b/projects/packages/import/src/endpoints/class-comment.php @@ -24,7 +24,7 @@ public function __construct() { parent::__construct(); // @see add_comment_meta - $this->import_id_meta_type = $this->rest_base; + $this->import_id_meta_type = 'comment'; } /** @@ -47,32 +47,24 @@ public function register_routes() { * @return WP_REST_Response|WP_Error Response object on success, or error object on failure. */ public function create_item( $request ) { - $response = parent::create_item( $request ); - - return $this->add_import_id_metadata( $request, $response ); - } + // Resolve comment post ID. + if ( ! empty( $request['post'] ) ) { + $posts = \get_posts( $this->get_import_db_query( $request['post'] ) ); - /** - * Update the comment parent ID. - * - * @param int $resource_id The resource ID. - * @param int $parent_import_id The parent ID. - * @return bool True if updated. - */ - protected function update_parent_id( $resource_id, $parent_import_id ) { - $comments = \get_comments( $this->get_import_db_query( $parent_import_id ) ); + // Overwrite the comment parent post ID. + $request['post'] = is_array( $posts ) && count( $posts ) ? $posts[0] : 0; + } - if ( is_array( $comments ) && count( $comments ) === 1 ) { - $parent_id = $comments[0]; + // Resolve comment parent ID. + if ( ! empty( $request['parent'] ) ) { + $comments = \get_comments( $this->get_import_db_query( $request['parent'] ) ); - return (bool) \wp_update_comment( - array( - 'comment_ID' => $resource_id, - 'comment_parent' => $parent_id, - ) - ); + // Overwrite the comment parent post ID. + $request['parent'] = is_array( $comments ) && count( $comments ) ? $comments[0] : 0; } - return false; + $response = parent::create_item( $request ); + + return $this->add_import_id_metadata( $request, $response ); } } diff --git a/projects/packages/import/src/endpoints/class-page.php b/projects/packages/import/src/endpoints/class-page.php index 84f6a82edaf17..8d10533339d4e 100644 --- a/projects/packages/import/src/endpoints/class-page.php +++ b/projects/packages/import/src/endpoints/class-page.php @@ -20,26 +20,21 @@ public function __construct() { } /** - * Update the post parent ID. + * Creates a single page. * - * @param int $resource_id The resource ID. - * @param int $parent_import_id The parent ID. - * @return bool True if updated. + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ - protected function update_parent_id( $resource_id, $parent_import_id ) { - $pages = \get_pages( $this->get_import_db_query( $parent_import_id ) ); + public function create_item( $request ) { + if ( ! empty( $request['parent'] ) ) { + $pages = \get_pages( $this->get_import_db_query( $request['parent'] ) ); - if ( is_array( $pages ) && count( $pages ) === 1 ) { - $parent_id = $pages[0]->ID; - - return (bool) \wp_update_post( - array( - 'ID' => $resource_id, - 'post_parent' => $parent_id, - ) - ); + // Overwrite the page parent page ID. + $request['parent'] = is_array( $pages ) && count( $pages ) ? $pages[0]->ID : 0; } - return false; + $response = parent::create_item( $request ); + + return $this->add_import_id_metadata( $request, $response ); } } diff --git a/projects/packages/import/src/endpoints/class-post.php b/projects/packages/import/src/endpoints/class-post.php index d41877d919396..5a3be46033790 100644 --- a/projects/packages/import/src/endpoints/class-post.php +++ b/projects/packages/import/src/endpoints/class-post.php @@ -64,7 +64,7 @@ public function add_additional_fields_schema( $schema ) { } /** - * Creates a single post / page. + * Creates a single post. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. @@ -131,28 +131,4 @@ protected function extract_terms_ids( $request, $taxonomy ) { return array(); } } - - /** - * Update the post parent ID. - * - * @param int $resource_id The resource ID. - * @param int $parent_import_id The parent ID. - * @return bool True if updated. - */ - protected function update_parent_id( $resource_id, $parent_import_id ) { - $posts = \get_posts( $this->get_import_db_query( $parent_import_id ) ); - - if ( is_array( $posts ) && count( $posts ) === 1 ) { - $parent_id = $posts[0]; - - return (bool) \wp_update_post( - array( - 'ID' => $resource_id, - 'post_parent' => $parent_id, - ) - ); - } - - return false; - } } diff --git a/projects/packages/import/src/endpoints/class-tag.php b/projects/packages/import/src/endpoints/class-tag.php index 78123c76dc223..154db4beb200e 100644 --- a/projects/packages/import/src/endpoints/class-tag.php +++ b/projects/packages/import/src/endpoints/class-tag.php @@ -39,23 +39,4 @@ public function register_routes() { $this->get_route_options() ); } - - /** - * Update the tag parent ID. - * - * @param int $resource_id The resource ID. - * @param int $parent_import_id The parent ID. - * @return bool True if updated. - */ - protected function update_parent_id( $resource_id, $parent_import_id ) { - $terms = \get_terms( $this->get_import_db_query( $parent_import_id ) ); - - if ( is_array( $terms ) && count( $terms ) === 1 ) { - $parent_id = $terms[0]; - - return (bool) \wp_update_term( $resource_id, $this->import_id_meta_type, array( 'parent' => $parent_id ) ); - } - - return false; - } } diff --git a/projects/packages/import/src/endpoints/trait-import.php b/projects/packages/import/src/endpoints/trait-import.php index 77af714cbbb08..b6fc9a974ac1f 100644 --- a/projects/packages/import/src/endpoints/trait-import.php +++ b/projects/packages/import/src/endpoints/trait-import.php @@ -99,12 +99,6 @@ protected function add_import_id_metadata( $request, $response ) { // Add the import unique ID to the resource metadata. \add_metadata( $this->import_id_meta_type, $data['id'], $this->import_id_field_name, $request[ $this->import_id_field_name ], true ); - // If the resource has a parent. - if ( $request[ $this->import_id_field_name ] !== 0 ) { - // Update the parent. - $this->update_parent_id( $data['id'], $request[ $this->import_id_field_name ] ); - } - return $response; } @@ -168,13 +162,4 @@ protected function get_route_options() { 'schema' => array( $this, 'get_public_item_schema' ), ); } - - /** - * Update the resource parent ID. - * - * @param int $resource_id The resource ID. - * @param int $parent_import_id The parent ID. - * @return bool True if updated. - */ - abstract protected function update_parent_id( $resource_id, $parent_import_id ); } From 65e69f634a81793959f2a547069e9917f63e4a9b Mon Sep 17 00:00:00 2001 From: Karen Attfield Date: Fri, 17 Feb 2023 08:17:35 +0000 Subject: [PATCH 18/51] Jetpack Live Branches: Adding options to populate CRM and Woo data (#28873) --- .../jetpack-live-branches.user.js | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/tools/jetpack-live-branches/jetpack-live-branches.user.js b/tools/jetpack-live-branches/jetpack-live-branches.user.js index 67cf56772e464..ada1db104c9ee 100644 --- a/tools/jetpack-live-branches/jetpack-live-branches.user.js +++ b/tools/jetpack-live-branches/jetpack-live-branches.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Jetpack Live Branches // @namespace https://wordpress.com/ -// @version 1.26 +// @version 1.27 // @description Adds links to PRs pointing to Jurassic Ninja sites for live-testing a changeset // @grant GM_xmlhttpRequest // @connect jurassic.ninja @@ -165,6 +165,14 @@ label: 'Pre-generate content', name: 'content', }, + { + label: 'Pre-generate CRM data', + name: 'jpcrm-populate-crm-data', + }, + { + label: 'Pre-generate CRM Woo data', + name: 'jpcrm-populate-woo-data', + }, { label: 'xmlrpc.php unavailable', name: 'blockxmlrpc', @@ -229,10 +237,6 @@ label: 'WP Job Manager', name: 'wp-job-manager', }, - { - label: 'Jetpack CRM', - name: 'zero-bs-crm', - }, { label: 'Jetpack Debug Helper', name: 'jetpack-debug-helper', @@ -325,11 +329,17 @@ if ( input.value ) { query.push( encodeURIComponent( input.name ) + '=' + encodeURIComponent( input.value ) ); } else { + if ( + input.name === 'jpcrm-populate-crm-data' || + input.value === 'jpcrm-populate-woo-data' + ) { + query.push( encodeURIComponent( 'jpcrm' ) ); + } query.push( encodeURIComponent( input.name ) ); } } ); // prettier-ignore - return `${ host }/create?${ query.join( '&' ).replace( /%(2F|5[BD])/g, m => decodeURIComponent( m ) ) }`; + return [ `${ host }/create?${ query.join( '&' ).replace( /%(2F|5[BD])/g, m => decodeURIComponent( m ) ) }`, query ]; } /** @@ -420,10 +430,27 @@ */ function updateLink() { const $link = $( '#jetpack-beta-branch-link' ); - const url = getLink(); + const [ url, query ] = getLink(); if ( url.match( /[?&]branch(es\.[^&=]*)?=/ ) ) { - $link.attr( 'href', url ).text( url ); + if ( + query.includes( 'jpcrm-populate-crm-data' ) && + ! url.match( /[?&]branches\.zero-bs-crm/ ) + ) { + // /jpcrm-populate-crm-data/ + $link + .attr( 'href', null ) + .text( 'Select the Jetpack CRM plugin in order to populate with CRM data' ); + } else if ( + query.includes( 'jpcrm-populate-woo-data' ) && + ! query.includes( 'woocommerce' ) + ) { + $link + .attr( 'href', null ) + .text( 'Select the WooCommerce plugin in order to populate with CRM Woo data' ); + } else { + $link.attr( 'href', url ).text( url ); + } } else { $link.attr( 'href', null ).text( 'Select at least one plugin to test' ); } From fd06f842965fa55ccf1efff62d5e3d54e764024f Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Fri, 17 Feb 2023 10:30:10 +0100 Subject: [PATCH 19/51] General: enabled automated plugin releases for Migration (#29014) --- .../changelog/update-migration-enable-autoupdates | 4 ++++ projects/plugins/migration/composer.json | 7 ++++++- projects/plugins/migration/composer.lock | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 projects/plugins/migration/changelog/update-migration-enable-autoupdates diff --git a/projects/plugins/migration/changelog/update-migration-enable-autoupdates b/projects/plugins/migration/changelog/update-migration-enable-autoupdates new file mode 100644 index 0000000000000..4a3ebbf015d16 --- /dev/null +++ b/projects/plugins/migration/changelog/update-migration-enable-autoupdates @@ -0,0 +1,4 @@ +Significance: patch +Type: added + +General: enable automated plugin releases. diff --git a/projects/plugins/migration/composer.json b/projects/plugins/migration/composer.json index ff99960eccce9..65584e7fe5eee 100644 --- a/projects/plugins/migration/composer.json +++ b/projects/plugins/migration/composer.json @@ -59,9 +59,14 @@ "minimum-stability": "dev", "prefer-stable": true, "extra": { + "autorelease": true, + "autotagger": { + "v": false + }, "mirror-repo": "Automattic/wpcom-migration", "release-branch-prefix": "migration", - "wp-plugin-slug": "wpcom-migration" + "wp-plugin-slug": "wpcom-migration", + "wp-svn-autopublish": true }, "config": { "allow-plugins": { diff --git a/projects/plugins/migration/composer.lock b/projects/plugins/migration/composer.lock index 1b8c778f1e502..ddcb8718da499 100644 --- a/projects/plugins/migration/composer.lock +++ b/projects/plugins/migration/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1ddcdf6c42199ee2e81f1e3125bff4f1", + "content-hash": "1fd3765ca177131d6455d3228f5260a2", "packages": [ { "name": "automattic/jetpack-a8c-mc-stats", From 773fb225a7b4e3a14e0d1d16c6c2ddc048dee9a0 Mon Sep 17 00:00:00 2001 From: ouikhuan Date: Fri, 17 Feb 2023 19:46:16 +0800 Subject: [PATCH 20/51] Update useAnalytics hook doc to including assets section (#29016) * Adding a new section in README to describe including assets in backend * changelog * Fix version mismatch --- .../changelog/update-use-analytics-hook-doc | 4 +++ .../shared-extension-utils/package.json | 2 +- .../src/hooks/readme.md | 35 +++++++++++++++++-- 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 projects/js-packages/shared-extension-utils/changelog/update-use-analytics-hook-doc diff --git a/projects/js-packages/shared-extension-utils/changelog/update-use-analytics-hook-doc b/projects/js-packages/shared-extension-utils/changelog/update-use-analytics-hook-doc new file mode 100644 index 0000000000000..cd088c0ff6475 --- /dev/null +++ b/projects/js-packages/shared-extension-utils/changelog/update-use-analytics-hook-doc @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Add a new section to describe including assets from backend diff --git a/projects/js-packages/shared-extension-utils/package.json b/projects/js-packages/shared-extension-utils/package.json index 4d2733ef41195..78bede3a54602 100644 --- a/projects/js-packages/shared-extension-utils/package.json +++ b/projects/js-packages/shared-extension-utils/package.json @@ -1,6 +1,6 @@ { "name": "@automattic/jetpack-shared-extension-utils", - "version": "0.8.4", + "version": "0.9.0-alpha", "description": "Utility functions used by the block editor extensions", "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/shared-extension-utils/#readme", "bugs": { diff --git a/projects/js-packages/shared-extension-utils/src/hooks/readme.md b/projects/js-packages/shared-extension-utils/src/hooks/readme.md index 812c35c517144..492a6f3b5950c 100644 --- a/projects/js-packages/shared-extension-utils/src/hooks/readme.md +++ b/projects/js-packages/shared-extension-utils/src/hooks/readme.md @@ -10,6 +10,37 @@ use Automattic\Jetpack\Connection\Initial_State as Connection_Initial_State; wp_add_inline_script( 'your-app-script-handle-in-editor', Connection_Initial_State::render(), 'before' ); ``` +Adding Tracks related class and including the check function in your admin ui page: +```php +use Automattic\Jetpack\Status as Status; +use Automattic\Jetpack\Terms_Of_Service; +use Automattic\Jetpack\Tracking; + +/** + * Returns whether we are in condition to track to use + * Analytics functionality like Tracks, MC, or GA. + */ +public static function can_use_analytics() { + $status = new Status(); + $connection = new Connection_Manager(); + $tracking = new Tracking( 'jetpack', $connection ); + + return $tracking->should_enable_tracking( new Terms_Of_Service(), $status ); +} +``` + +Then adding the assets in the `enqueue_admin_scripts` function after the `Assets::register_script` function: +```php +public function enqueue_admin_scripts() { + ... + // Required for Analytics. + if ( self::can_use_analytics() ) { + Tracking::register_tracks_functions_scripts( true ); + } + ... +} +``` + ## Usage ```es6 @@ -23,7 +54,7 @@ tracks.recordEvent( 'jetpack_editor_block_upgrade_click', { ``` The hook function also accepts parameters to record a "page view" event when the component renders. -You can also import a wrapped version of `recordEvent` that checks for a Jetpack connected user before actually recording the event. +You can also import a wrapped version of `recordEvent` that checks for a Jetpack connected user before actually recording the event. ```es6 const Component = () => { @@ -33,7 +64,7 @@ const Component = () => { pageViewSuffix: '', } ); const recordClick = useCallback( () => { recordEvent( 'event_name', {} ) }, [] ); - + return ( diff --git a/projects/plugins/migration/src/js/components/migration/styles.module.scss b/projects/plugins/migration/src/js/components/migration/styles.module.scss index 672210e72cf2e..b4913d0d9db08 100644 --- a/projects/plugins/migration/src/js/components/migration/styles.module.scss +++ b/projects/plugins/migration/src/js/components/migration/styles.module.scss @@ -1,3 +1,5 @@ +@import "@automattic/typography/styles/fonts"; + :global { #wpcom-migration-root { .jp-connection__connect-screen-layout ol.migration-listing { From c128089c4a7de3db9eff056b0700f5ee79763f2e Mon Sep 17 00:00:00 2001 From: Karen Attfield Date: Fri, 17 Feb 2023 14:11:30 +0000 Subject: [PATCH 23/51] CRM: Cleaning up PHPCS comments in ZeroBSCRM.FormatHelpers.php (#28996) Mistakenly added in #28956 --- .../crm/changelog/fix-crm-remove-phpcsdisable-leftover | 5 +++++ projects/plugins/crm/includes/ZeroBSCRM.FormatHelpers.php | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 projects/plugins/crm/changelog/fix-crm-remove-phpcsdisable-leftover diff --git a/projects/plugins/crm/changelog/fix-crm-remove-phpcsdisable-leftover b/projects/plugins/crm/changelog/fix-crm-remove-phpcsdisable-leftover new file mode 100644 index 0000000000000..a3f37271c7fcc --- /dev/null +++ b/projects/plugins/crm/changelog/fix-crm-remove-phpcsdisable-leftover @@ -0,0 +1,5 @@ +Significance: patch +Type: removed +Comment: Removing phpcs comments + + diff --git a/projects/plugins/crm/includes/ZeroBSCRM.FormatHelpers.php b/projects/plugins/crm/includes/ZeroBSCRM.FormatHelpers.php index f6344685127cc..2cff417f2685a 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.FormatHelpers.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.FormatHelpers.php @@ -1148,7 +1148,6 @@ function zeroBSCRM_html_taskDate($task=array()){ return $start_d . ' - ' . $end_d; } - // phpcs:disable /* ====================================================== / Tasks ====================================================== */ @@ -1959,5 +1958,4 @@ function zeroBSCRM_format_migrationVersion($ver=''){ return $migrationName; - } -// phpcs: enable \ No newline at end of file + } \ No newline at end of file From f3b2868a8594cd1838cb307fd19a088f0ef0b7ff Mon Sep 17 00:00:00 2001 From: Grant Kinney Date: Fri, 17 Feb 2023 09:43:01 -0600 Subject: [PATCH 24/51] Writing prompts: adds initial scaffolding for block (#29013) --- .../add-blogging-prompts-block-scaffolding | 4 ++ .../blocks/blogging-prompt/attributes.js | 3 ++ .../blogging-prompt/blogging-prompt.php | 50 +++++++++++++++++ .../extensions/blocks/blogging-prompt/edit.js | 42 +++++++++++++++ .../blocks/blogging-prompt/editor.js | 7 +++ .../blocks/blogging-prompt/editor.scss | 5 ++ .../extensions/blocks/blogging-prompt/icon.js | 13 +++++ .../blocks/blogging-prompt/index.js | 54 +++++++++++++++++++ .../plugins/jetpack/extensions/index.json | 1 + 9 files changed, 179 insertions(+) create mode 100644 projects/plugins/jetpack/changelog/add-blogging-prompts-block-scaffolding create mode 100644 projects/plugins/jetpack/extensions/blocks/blogging-prompt/attributes.js create mode 100644 projects/plugins/jetpack/extensions/blocks/blogging-prompt/blogging-prompt.php create mode 100644 projects/plugins/jetpack/extensions/blocks/blogging-prompt/edit.js create mode 100644 projects/plugins/jetpack/extensions/blocks/blogging-prompt/editor.js create mode 100644 projects/plugins/jetpack/extensions/blocks/blogging-prompt/editor.scss create mode 100644 projects/plugins/jetpack/extensions/blocks/blogging-prompt/icon.js create mode 100644 projects/plugins/jetpack/extensions/blocks/blogging-prompt/index.js diff --git a/projects/plugins/jetpack/changelog/add-blogging-prompts-block-scaffolding b/projects/plugins/jetpack/changelog/add-blogging-prompts-block-scaffolding new file mode 100644 index 0000000000000..5bd8d037e39bc --- /dev/null +++ b/projects/plugins/jetpack/changelog/add-blogging-prompts-block-scaffolding @@ -0,0 +1,4 @@ +Significance: minor +Type: other + +Writing prompts: adds initial scaffolding for block diff --git a/projects/plugins/jetpack/extensions/blocks/blogging-prompt/attributes.js b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/attributes.js new file mode 100644 index 0000000000000..edfdf8db56e5d --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/attributes.js @@ -0,0 +1,3 @@ +export default { + // @TODO - Add block attributes here +}; diff --git a/projects/plugins/jetpack/extensions/blocks/blogging-prompt/blogging-prompt.php b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/blogging-prompt.php new file mode 100644 index 0000000000000..45ece826b2c59 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/blogging-prompt.php @@ -0,0 +1,50 @@ + __NAMESPACE__ . '\load_assets' ) + ); +} +add_action( 'init', __NAMESPACE__ . '\register_block' ); + +/** + * Blogging Prompts block registration/dependency declaration. + * + * @param array $attr Array containing the Blogging Prompts block attributes. + * @param string $content String containing the Blogging Prompts block content. + * + * @return string + */ +function load_assets( $attr, $content ) { + /* + * Enqueue necessary scripts and styles. + */ + Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME ); + + return sprintf( + '
    %2$s
    ', + esc_attr( Blocks::classes( FEATURE_NAME, $attr ) ), + $content + ); +} diff --git a/projects/plugins/jetpack/extensions/blocks/blogging-prompt/edit.js b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/edit.js new file mode 100644 index 0000000000000..7306f9ee7c27d --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/edit.js @@ -0,0 +1,42 @@ +import { BlockIcon } from '@wordpress/block-editor'; +import { Placeholder } from '@wordpress/components'; +// import { useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import './editor.scss'; +import icon from './icon'; + +function BloggingPromptsBetaEdit( { + // attributes, + className, + // noticeOperations, + noticeUI, + // setAttributes, +} ) { + /** + * Write the block editor UI. + * + * @returns {object} The UI displayed when user edits this block. + */ + // const [ notice, setNotice ] = useState(); + + /* Call this function when you want to show an error in the placeholder. */ + // const setErrorNotice = () => { + // noticeOperations.removeAllNotices(); + // noticeOperations.createErrorNotice( __( 'Put error message here.', 'jetpack' ) ); + // }; + + return ( +
    + } + notices={ noticeUI } + > + { __( 'User input goes here?', 'jetpack' ) } + +
    + ); +} + +export default BloggingPromptsBetaEdit; diff --git a/projects/plugins/jetpack/extensions/blocks/blogging-prompt/editor.js b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/editor.js new file mode 100644 index 0000000000000..d05f403942058 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/editor.js @@ -0,0 +1,7 @@ +/** + * Internal dependencies + */ +import registerJetpackBlock from '../../shared/register-jetpack-block'; +import { name, settings } from '.'; + +registerJetpackBlock( name, settings ); diff --git a/projects/plugins/jetpack/extensions/blocks/blogging-prompt/editor.scss b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/editor.scss new file mode 100644 index 0000000000000..60c36e56ab7e8 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/editor.scss @@ -0,0 +1,5 @@ +/** + * Editor styles for Blogging Prompts + */ + +.wp-block-jetpack-blogging-prompts-beta { } diff --git a/projects/plugins/jetpack/extensions/blocks/blogging-prompt/icon.js b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/icon.js new file mode 100644 index 0000000000000..f1a4e3f5c7931 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/icon.js @@ -0,0 +1,13 @@ +/** + * External dependencies + */ +import { SVG, Path } from '@wordpress/components'; + +export default ( + + + +); diff --git a/projects/plugins/jetpack/extensions/blocks/blogging-prompt/index.js b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/index.js new file mode 100644 index 0000000000000..a75b1d8d3e210 --- /dev/null +++ b/projects/plugins/jetpack/extensions/blocks/blogging-prompt/index.js @@ -0,0 +1,54 @@ +import { ExternalLink } from '@wordpress/components'; +import { Fragment } from '@wordpress/element'; +import { __, _x } from '@wordpress/i18n'; +import { getIconColor } from '../../shared/block-icons'; +import attributes from './attributes'; +import edit from './edit'; +import icon from './icon'; + +/** + * Style dependencies + */ +import './editor.scss'; + +export const name = 'blogging-prompt'; +export const title = __( 'Writing Prompt', 'jetpack' ); +export const settings = { + title, + description: ( + +

    { __( 'Answer a new and inspiring writing prompt each day.', 'jetpack' ) }

    + { /* @TODO add link */ } + { __( 'Learn more.', 'jetpack' ) } +
    + ), + icon: { + src: icon, + foreground: getIconColor(), + }, + category: 'jetpack', + keywords: [ + _x( 'writing', 'block search term', 'jetpack' ), + _x( 'blogging', 'block search term', 'jetpack' ), + ], + supports: { + align: false, + alignWide: false, + anchor: false, + customClassName: true, + className: true, + html: false, + inserter: true, + multiple: false, + reusable: true, + }, + edit, + /* @TODO Write the block editor output */ + save: () => null, + attributes, + example: { + attributes: { + // @TODO: Add default values for block attributes, for generating the block preview. + }, + }, +}; diff --git a/projects/plugins/jetpack/extensions/index.json b/projects/plugins/jetpack/extensions/index.json index 85519c1bac58c..a12adf4dd02ef 100644 --- a/projects/plugins/jetpack/extensions/index.json +++ b/projects/plugins/jetpack/extensions/index.json @@ -47,6 +47,7 @@ ], "beta": [ "amazon", + "blogging-prompt", "conversation", "dialogue", "google-docs-embed", From d44dac5099caddc1e2fefd742e23e3060c548dbc Mon Sep 17 00:00:00 2001 From: Clemen Date: Fri, 17 Feb 2023 15:52:00 +0000 Subject: [PATCH 25/51] Crm/fix/2641 disable frontend breaks jp connections (#28970) * Check if it's a XMLRPC or REST request * changelog * Update changelog * Remove comments (clean code: code is clear enough) --- .../crm-fix-disable-frontend-breaks-jp-connections | 4 ++++ projects/plugins/crm/includes/ZeroBSCRM.Core.php | 14 ++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 projects/plugins/crm/changelog/crm-fix-disable-frontend-breaks-jp-connections diff --git a/projects/plugins/crm/changelog/crm-fix-disable-frontend-breaks-jp-connections b/projects/plugins/crm/changelog/crm-fix-disable-frontend-breaks-jp-connections new file mode 100644 index 0000000000000..15d43ab4e9210 --- /dev/null +++ b/projects/plugins/crm/changelog/crm-fix-disable-frontend-breaks-jp-connections @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Before kill the frontend (when the option is enabled), skip it for XMLRPC or REST requests diff --git a/projects/plugins/crm/includes/ZeroBSCRM.Core.php b/projects/plugins/crm/includes/ZeroBSCRM.Core.php index e70d56779bda0..f0aab37ff4e79 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.Core.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.Core.php @@ -1819,10 +1819,16 @@ public function init() { // } Catch front end loads :) if ( $this->settings->get( 'killfrontend' ) == 1 ) { - - // http://wordpress.stackexchange.com/questions/12863/check-if-were-on-the-wp-login-page - // } 2.0.2 also allow /wild stuff (e.g. welcome wiz) - if ( ! zeroBSCRM_isLoginPage() && ! zeroBSCRM_isWelcomeWizPage() && ! zeroBSCRM_isAPIRequest() ) { + global $pagenow; + + if ( ! zeroBSCRM_isLoginPage() + && ! zeroBSCRM_isWelcomeWizPage() + && ! zeroBSCRM_isAPIRequest() + && ! defined( 'XMLRPC_REQUEST' ) + && ! defined( 'REST_REQUEST' ) + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + && ! ( 'index.php' === $pagenow && ! empty( $_GET['rest_route'] ) ) + ) { zeroBSCRM_stopFrontEnd(); From fafa0c5a05a64b60eec8bc9ef3d343a209855fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Su=C3=A1rez?= Date: Fri, 17 Feb 2023 13:09:16 -0300 Subject: [PATCH 26/51] Jetpack: tweak MediaButton component (#29027) * [not verified] tweak extended media button * changelog * rollback allowing custom label * fix button width in MediaPlaceholder context * restore removed icon line --- .../update-jetpack-tweak-media-button | 4 ++++ .../shared/external-media/editor.scss | 23 +++++++++++++++++++ .../external-media/media-button/media-menu.js | 6 +++-- 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 projects/plugins/jetpack/changelog/update-jetpack-tweak-media-button diff --git a/projects/plugins/jetpack/changelog/update-jetpack-tweak-media-button b/projects/plugins/jetpack/changelog/update-jetpack-tweak-media-button new file mode 100644 index 0000000000000..1b3be433422e4 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-jetpack-tweak-media-button @@ -0,0 +1,4 @@ +Significance: patch +Type: enhancement + +Jetpack: tweak MediaButton component diff --git a/projects/plugins/jetpack/extensions/shared/external-media/editor.scss b/projects/plugins/jetpack/extensions/shared/external-media/editor.scss index 73b4f239132ed..e50ac92582bc7 100644 --- a/projects/plugins/jetpack/extensions/shared/external-media/editor.scss +++ b/projects/plugins/jetpack/extensions/shared/external-media/editor.scss @@ -411,12 +411,35 @@ $grid-size: 8px; justify-content: space-between; } +.jetpack-external-media-button-menu__dropdown { + width: 100%; + + .jetpack-external-media-button-menu { + width: 100%; + flex-direction: row; + text-align: left; + padding-left: 12px; + padding-right: 12px; + + .jetpack-external-media-button-menu__label { + flex-grow: 2; + } + } +} + // Reset placeholder button margin. .components-placeholder__fieldset, .editor-post-featured-image { .components-dropdown .jetpack-external-media-button-menu { + width: auto; margin-right: 8px; margin-bottom: 1em; + padding-left: 6px; + padding-right: 6px; + + > svg { + display: none; + } } } diff --git a/projects/plugins/jetpack/extensions/shared/external-media/media-button/media-menu.js b/projects/plugins/jetpack/extensions/shared/external-media/media-button/media-menu.js index 5e3225b216c8f..adb5b1edf3499 100644 --- a/projects/plugins/jetpack/extensions/shared/external-media/media-button/media-menu.js +++ b/projects/plugins/jetpack/extensions/shared/external-media/media-button/media-menu.js @@ -1,6 +1,6 @@ import { Button, MenuItem, MenuGroup, Dropdown, NavigableMenu } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { media } from '@wordpress/icons'; +import { Icon, media } from '@wordpress/icons'; import MediaSources from './media-sources'; function MediaButtonMenu( props ) { @@ -37,6 +37,7 @@ function MediaButtonMenu( props ) { <> { // override original button only when it's a simple button with text, or a featured image @@ -55,7 +56,8 @@ function MediaButtonMenu( props ) { aria-expanded={ isOpen } onClick={ onToggle } > - { label } +
    { label }
    + ); } } From 2053cab08e7922b05316412ca976762b3cc46d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Su=C3=A1rez?= Date: Fri, 17 Feb 2023 13:31:23 -0300 Subject: [PATCH 27/51] VideoPress: recognize admin actions to handle generated chapter (#28945) * [not verified] add isAutogeneratedChapterFile() async helper fn * [not verified] check autogenerated chapter in useVideoData() hook * [not verified] update isAutogeneratedChapter in useSyncMedia() * [not verified] delegate checking isAutogeneratedChapter to hook * [not verified] rename var that allows overwrite chapter * [not verified] allow upload auto-chapter when doesnt exist * [not verified] add debug() line when when allowed overrite chapter * [not verified] debug() lines * [not verified] isAutogeneratedChapterFile() API accept token * [not verified] changelog * isAutogeneratedChapterFile() handles privacy * move logic to detect autogen to useSyncMedia * store the default auto-chapter in local state * update chapter src once saves * rely on attr to check autogen chapter --- ...ue-when-getting-autogenerated-chapter-file | 4 + .../client/block-editor/blocks/video/edit.tsx | 75 ++----------------- .../hooks/use-video-data-update/index.ts | 45 ++++++++--- .../hooks/use-video-data-update/types.ts | 8 +- .../hooks/use-video-data/index.ts | 2 +- .../src/client/lib/video-tracks/index.ts | 55 ++++++++++++++ 6 files changed, 103 insertions(+), 86 deletions(-) create mode 100644 projects/packages/videopress/changelog/update-videopress-fix-issue-when-getting-autogenerated-chapter-file diff --git a/projects/packages/videopress/changelog/update-videopress-fix-issue-when-getting-autogenerated-chapter-file b/projects/packages/videopress/changelog/update-videopress-fix-issue-when-getting-autogenerated-chapter-file new file mode 100644 index 0000000000000..890c4f23e116b --- /dev/null +++ b/projects/packages/videopress/changelog/update-videopress-fix-issue-when-getting-autogenerated-chapter-file @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +VideoPress: fix detecting auto-generated issue diff --git a/projects/packages/videopress/src/client/block-editor/blocks/video/edit.tsx b/projects/packages/videopress/src/client/block-editor/blocks/video/edit.tsx index 890d60c4da200..813ad081fef4b 100644 --- a/projects/packages/videopress/src/client/block-editor/blocks/video/edit.tsx +++ b/projects/packages/videopress/src/client/block-editor/blocks/video/edit.tsx @@ -20,7 +20,6 @@ import debugFactory from 'debug'; * Internal dependencies */ import { isStandaloneActive, isVideoPressActive } from '../../../lib/connection'; -import getMediaToken from '../../../lib/get-media-token'; import { buildVideoPressURL, getVideoPressUrl } from '../../../lib/url'; import { useSyncMedia } from '../../hooks/use-video-data-update'; import ConnectBanner from './components/banner/connect-banner'; @@ -117,7 +116,6 @@ export default function VideoPressEdit( { align, videoRatio, tracks, - isPrivate, src, caption, isExample, @@ -139,75 +137,16 @@ export default function VideoPressEdit( { // Get the redirect URI for the connection flow. const [ isRedirectingToMyJetpack, setIsRedirectingToMyJetpack ] = useState( false ); - /* - * Request token when site is private - */ - const [ token, setToken ] = useState( null ); - useEffect( () => { - if ( ! isPrivate ) { - return setToken( null ); - } - - getMediaToken( 'playback', { guid } ).then( tokenData => { - setToken( tokenData?.token ); - } ); - }, [ isPrivate ] ); - - // Store if the chapters file is auto-generated in a local state. - const [ isAutoGeneratedChapter, setIsAutoGeneratedChapter ] = useState( true ); // Detect if the chapter file is auto-generated. const chapter = tracks?.filter( track => track.kind === 'chapters' )?.[ 0 ]; - useEffect( () => { - if ( ! chapter || ! chapter.src ) { - return; - } - - // Wait for the token when the video is private. - if ( isPrivate && ! token ) { - return; - } - - let queryString = ''; - if ( token ) { - queryString = '?' + new URLSearchParams( { metadata_token: token } ).toString(); - } - - const chapterUrl = - 'https://videos.files.wordpress.com/' + guid + '/' + chapter.src + queryString; - - try { - fetch( chapterUrl ) - .then( function ( response ) { - response.text().then( function ( text ) { - if ( ! text ) { - return; - } - - const isAutoGeneratedChaptersFile = /videopress-chapters-auto-generated/.test( text ); - if ( isAutoGeneratedChaptersFile ) { - debug( 'Chapter %o auto-generated detected', chapter.src ); - } - setIsAutoGeneratedChapter( isAutoGeneratedChaptersFile ); - } ); - } ) - .catch( function ( error ) { - // eslint-disable-next-line no-console - console.error( error ); - } ); - } catch ( error ) { - throw new Error( error?.message ?? error ); - } - }, [ chapter, guid, token, isPrivate ] ); - - const { videoData, isRequestingVideoData, error: syncError } = useSyncMedia( - attributes, - setAttributes, - { - isAutoGeneratedChapter, - } - ); + const { + videoData, + isRequestingVideoData, + error: syncError, + isOverwriteChapterAllowed, + } = useSyncMedia( attributes, setAttributes ); const { filename, private_enabled_for_site: privateEnabledForSite } = videoData; @@ -570,7 +509,7 @@ export default function VideoPressEdit( { select( editorStore ).isSavingPost(), [] ); const wasSaving = usePrevious( isSaving ); const invalidateResolution = useDispatch( coreStore ).invalidateResolution; @@ -254,6 +255,29 @@ export function useSyncMedia( setAttributes( attributesToUpdate ); }, [ videoData, isRequestingVideoData ] ); + const chapterFileUrl = attributes.tracks.filter( + track => track.kind === 'chapters' && track.srcLang === 'en' + )[ 0 ]?.src; + + useEffect( () => { + ( async () => { + // Check if the (default) chapter file has been autogenerated. + if ( ! chapterFileUrl ) { + debug( 'Allow overwrite chapter: File does not exist' ); + setIsOverwriteChapterAllowed( true ); + } else { + const chapterUrl = 'https://videos.files.wordpress.com/' + guid + '/' + chapterFileUrl; + const isAutogenerated = await isAutogeneratedChapterFile( chapterUrl, { guid, isPrivate } ); + debug( + 'Chapter %o detected. Overwritable: %o', + chapterFileUrl, + isAutogenerated ? 'yes' : 'no' + ); + setIsOverwriteChapterAllowed( isAutogenerated ); + } + } )(); + }, [ chapterFileUrl ] ); + const updateMediaHandler = useMediaDataUpdate( id ); /* @@ -329,12 +353,12 @@ export function useSyncMedia( const chapters = extractVideoChapters( dataToUpdate?.description ); if ( - options.isAutoGeneratedChapter && + isOverwriteChapterAllowed && attributes?.guid && dataToUpdate?.description?.length && validateChapters( chapters ) ) { - debug( 'Auto-generated chapter detected. Processing...' ); + debug( 'Autogenerated chapter detected. Processing...' ); const track: UploadTrackDataProps = { label: __( 'English (auto-generated)', 'jetpack-videopress-pkg' ), srcLang: 'en', @@ -342,7 +366,7 @@ export function useSyncMedia( tmpFile: generateChaptersFile( dataToUpdate.description ), }; - debug( 'Auto-generated track: %o', track ); + debug( 'Autogenerated track: %o', track ); uploadTrackForGuid( track, attributes.guid ).then( ( src: string ) => { const autoGeneratedTrackIndex = attributes.tracks.findIndex( @@ -403,5 +427,6 @@ export function useSyncMedia( videoData, isRequestingVideoData, error, + isOverwriteChapterAllowed, }; } diff --git a/projects/packages/videopress/src/client/block-editor/hooks/use-video-data-update/types.ts b/projects/packages/videopress/src/client/block-editor/hooks/use-video-data-update/types.ts index ebc6fb5f950a3..8907f213dcf06 100644 --- a/projects/packages/videopress/src/client/block-editor/hooks/use-video-data-update/types.ts +++ b/projects/packages/videopress/src/client/block-editor/hooks/use-video-data-update/types.ts @@ -2,18 +2,12 @@ import { WPComV2VideopressPostMetaEndpointBodyProps } from '../../../types'; import { TrackProps } from '../../blocks/video/types'; import { VideoDataProps } from '../use-video-data/types'; -export type UseSyncMediaOptionsProps = { - /* - * Define if the chapters file is auto-generated - */ - isAutoGeneratedChapter: boolean; -}; - export type UseSyncMediaProps = { forceInitialState: ( data: WPComV2VideopressPostMetaEndpointBodyProps ) => void; videoData: VideoDataProps; isRequestingVideoData: boolean; error: object | null; + isOverwriteChapterAllowed: boolean; }; export type ArrangeTracksAttributesProps = [ Array< TrackProps >, boolean ]; diff --git a/projects/packages/videopress/src/client/block-editor/hooks/use-video-data/index.ts b/projects/packages/videopress/src/client/block-editor/hooks/use-video-data/index.ts index 2de4371939009..74ab5f57d3e15 100644 --- a/projects/packages/videopress/src/client/block-editor/hooks/use-video-data/index.ts +++ b/projects/packages/videopress/src/client/block-editor/hooks/use-video-data/index.ts @@ -40,7 +40,7 @@ export default function useVideoData( { useEffect( () => { if ( ! isUserConnected ) { - debug( 'User is not connected ❌' ); + debug( 'User is not connected' ); return; } diff --git a/projects/packages/videopress/src/client/lib/video-tracks/index.ts b/projects/packages/videopress/src/client/lib/video-tracks/index.ts index 50576d57ab342..2f59379a43e72 100644 --- a/projects/packages/videopress/src/client/lib/video-tracks/index.ts +++ b/projects/packages/videopress/src/client/lib/video-tracks/index.ts @@ -7,6 +7,11 @@ import apiFetch from '@wordpress/api-fetch'; */ import getMediaToken from '../get-media-token'; import { DeleteTrackDataProps, UploadTrackDataProps } from './types'; +/** + * Types + */ +import type { VideoGUID } from '../../block-editor/blocks/video/types'; +import type { MediaTokenProps } from '../get-media-token/types'; export const TRACK_KIND_OPTIONS = [ 'subtitles', @@ -19,6 +24,56 @@ export const TRACK_KIND_OPTIONS = [ const { siteType = '' } = window?.videoPressEditorState || {}; const shouldUseJetpackVideoFetch = siteType !== 'simple'; +type isAutogeneratedChaterFileParamsProps = { + guid?: VideoGUID; + isPrivate?: boolean; +}; + +/** + * Load the file content, and check if it's autogenerated, + * based on the `videopress-chapters-auto-generated` comment. + * The function will try to anticipate the video privacy, + * based on the block attributes. + * If the first request fails, it will try again with the token. + * + * @param {string} fileUrl - the track file url + * @param {isAutogeneratedChaterFileParamsProps} params - function parameters + * @returns {Promise} true if the file is autogenerated. + */ +export async function isAutogeneratedChapterFile( + fileUrl: string, + params?: isAutogeneratedChaterFileParamsProps +): Promise< boolean > { + if ( ! fileUrl ) { + return false; + } + + let tokenData: null | MediaTokenProps; + let queryString = ''; + + // Try to anticipate the video privacy, based on the block attributes. + if ( params.isPrivate ) { + tokenData = await getMediaToken( 'playback', { guid: params.guid } ); + queryString = '?' + new URLSearchParams( { metadata_token: tokenData?.token } ).toString(); + } + + let response = await fetch( fileUrl + queryString ); + + // If the file is private, and response is 403, try with the token. + if ( ! response.ok && response.status === 403 && params.guid ) { + tokenData = await getMediaToken( 'playback', { guid: params.guid } ); + queryString = '?' + new URLSearchParams( { metadata_token: tokenData?.token } ).toString(); + response = await fetch( fileUrl + queryString ); + } + + if ( ! response.ok ) { + return false; + } + + const text = await response.text(); + return /videopress-chapters-auto-generated/.test( text ); +} + const videoPressUploadTrack = function ( track: UploadTrackDataProps, guid: string ) { return new Promise( function ( resolve, reject ) { const { kind, srcLang, label, tmpFile: vttFile } = track; From 851cec8ddcb358277ba35b4bf4e5f237e7e9a544 Mon Sep 17 00:00:00 2001 From: Clemen Date: Fri, 17 Feb 2023 18:05:40 +0000 Subject: [PATCH 28/51] CRM: Encode textarea fields produce HTML entities on views (#28941) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [not verified] Don't encode textarea fields before store it in DB * Add changelog * Use sanitize_textarea_field instead the default sanitization * Updating changelog * Update projects/plugins/crm/changelog/fix-crm-html-entities-for-special-characters-in-textareas Co-authored-by: André Kallehauge <3846700+kallehauge@users.noreply.github.com> --------- Co-authored-by: André Kallehauge <3846700+kallehauge@users.noreply.github.com> --- ...m-html-entities-for-special-characters-in-textareas | 4 ++++ .../plugins/crm/includes/ZeroBSCRM.DAL3.Helpers.php | 10 ++++------ 2 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 projects/plugins/crm/changelog/fix-crm-html-entities-for-special-characters-in-textareas diff --git a/projects/plugins/crm/changelog/fix-crm-html-entities-for-special-characters-in-textareas b/projects/plugins/crm/changelog/fix-crm-html-entities-for-special-characters-in-textareas new file mode 100644 index 0000000000000..713732c0e6442 --- /dev/null +++ b/projects/plugins/crm/changelog/fix-crm-html-entities-for-special-characters-in-textareas @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Special characters in textarea fields (contacts, transactions, quotes) produce visible HTML entities diff --git a/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Helpers.php b/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Helpers.php index 28425589ebe96..b863df5d805bb 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Helpers.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Helpers.php @@ -3112,12 +3112,10 @@ function zeroBS_buildObjArr($arraySource=array(),$startingArray=array(),$fieldPr $retArray[$outputPrefix.$fK] = intval($retArray[$outputPrefix.$fK]); break; - - case 'textarea': - - $retArray[$outputPrefix.$fK] = zeroBSCRM_textProcess($arraySource[$fieldPrefix.$fK]); - - break; + case 'textarea': + // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase + $retArray[ $outputPrefix . $fK ] = sanitize_textarea_field( $arraySource[ $fieldPrefix . $fK ] ); + break; case 'date': From 72e79100af49b37d87a2753cc25f2b06bedd9cda Mon Sep 17 00:00:00 2001 From: Douglas Henri Date: Fri, 17 Feb 2023 15:07:25 -0300 Subject: [PATCH 29/51] VideoPress: Fix dashboard fatal mistake when reading malformed local video (#29011) * fix issue with malformed local video * changelog * casting input to array for non-local files --- .../changelog/fix-videopress-local-library-fatal | 4 ++++ projects/packages/videopress/src/class-data.php | 15 ++++++++++++--- .../videopress/src/class-upload-exception.php | 1 + .../client/admin/components/video-list/index.tsx | 4 ++-- .../videopress/src/client/state/constants.js | 3 ++- 5 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 projects/packages/videopress/changelog/fix-videopress-local-library-fatal diff --git a/projects/packages/videopress/changelog/fix-videopress-local-library-fatal b/projects/packages/videopress/changelog/fix-videopress-local-library-fatal new file mode 100644 index 0000000000000..62288ceff4286 --- /dev/null +++ b/projects/packages/videopress/changelog/fix-videopress-local-library-fatal @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +VideoPress: Fix dashboard fatal mistake when reading malformed local video diff --git a/projects/packages/videopress/src/class-data.php b/projects/packages/videopress/src/class-data.php index 5317b20f1925c..89f2c9a003ff6 100644 --- a/projects/packages/videopress/src/class-data.php +++ b/projects/packages/videopress/src/class-data.php @@ -237,15 +237,23 @@ public static function get_initial_state() { // Tweak local videos data. $local_videos = array_map( function ( $video ) { + $video = (array) $video; $id = $video['id']; $media_details = $video['media_details']; $jetpack_videopress = $video['jetpack_videopress']; + $read_error = null; + + // In malformed files, the media_details or jetpack_videopress properties are not arrays. + if ( ! is_array( $media_details ) || ! is_array( $jetpack_videopress ) ) { + $media_details = (array) $media_details; + $jetpack_videopress = (array) $jetpack_videopress; + $read_error = Upload_Exception::ERROR_MALFORMED_FILE; + } // Check if video is already uploaded to VideoPress or has some error. try { $uploader = new Uploader( $id ); $is_uploaded_to_videopress = $uploader->is_uploaded(); - $read_error = null; } catch ( Upload_Exception $e ) { $is_uploaded_to_videopress = false; $read_error = $e->getCode(); @@ -282,10 +290,11 @@ function ( $video ) { // Tweak VideoPress videos data. $videos = array_map( function ( $video ) { + $video = (array) $video; $id = $video['id']; $guid = $video['jetpack_videopress_guid']; - $media_details = $video['media_details']; - $jetpack_videopress = $video['jetpack_videopress']; + $media_details = (array) $video['media_details']; + $jetpack_videopress = (array) $video['jetpack_videopress']; $videopress_media_details = $media_details['videopress']; $width = $media_details['width']; diff --git a/projects/packages/videopress/src/class-upload-exception.php b/projects/packages/videopress/src/class-upload-exception.php index b1ef0ebcb6b08..17db79ab618cd 100644 --- a/projects/packages/videopress/src/class-upload-exception.php +++ b/projects/packages/videopress/src/class-upload-exception.php @@ -14,4 +14,5 @@ class Upload_Exception extends \Exception { const ERROR_INVALID_ATTACHMENT_ID = 0; const ERROR_FILE_NOT_FOUND = 1; const ERROR_MIME_TYPE_NOT_SUPPORTED = 2; + const ERROR_MALFORMED_FILE = 3; } diff --git a/projects/packages/videopress/src/client/admin/components/video-list/index.tsx b/projects/packages/videopress/src/client/admin/components/video-list/index.tsx index 5fe15c5325873..4e4b15b78687d 100644 --- a/projects/packages/videopress/src/client/admin/components/video-list/index.tsx +++ b/projects/packages/videopress/src/client/admin/components/video-list/index.tsx @@ -11,7 +11,7 @@ import { useState } from 'react'; * Internal dependencies */ import { - ERROR_MIME_TYPE_NOT_SUPPORTED, + LOCAL_VIDEO_ERROR_MIME_TYPE_NOT_SUPPORTED, VIDEO_PRIVACY_LEVELS, VIDEO_PRIVACY_LEVEL_PRIVATE, } from '../../../state/constants'; @@ -162,7 +162,7 @@ export const LocalVideoList = ( { Date: Fri, 17 Feb 2023 19:48:29 +0100 Subject: [PATCH 30/51] Reviews: allow Caribou to approve changes to the Import package (#29018) --- .github/files/required-review.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/files/required-review.yaml b/.github/files/required-review.yaml index 317231b741f29..886f4af821007 100644 --- a/.github/files/required-review.yaml +++ b/.github/files/required-review.yaml @@ -35,6 +35,7 @@ - '!projects/js-packages/svelte-data-sync-client/**' - '!projects/packages/wp-js-data-sync/**' - '!projects/packages/backup/**' + - '!projects/packages/import/**' - '!projects/packages/search/**' - '!projects/packages/stats/**' - '!projects/packages/stats-admin/**' @@ -59,10 +60,11 @@ - avengers - jetpack-approvers -# The Caribou team reviews changes to the Migration plugin, +# The Caribou team reviews changes to the Migration plugin and its Import package, # and can add dependencies to the monorepo's lock file. - name: Migration paths: + - 'projects/packages/import/**' - 'projects/plugins/migration/**' - '!projects/plugins/*/composer.lock' - '!projects/plugins/*/composer.json' From cdcde6b0f8c149e2837e4ba65187a9444e2d44af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Su=C3=A1rez?= Date: Fri, 17 Feb 2023 16:27:20 -0300 Subject: [PATCH 31/51] Jetpack: extend media button for VideoPress video block (#29032) * [not verified] extend media button for videopress/video * changelog --- ...ate-jetpack-extend-media-button-for-videopress-video-block | 4 ++++ .../plugins/jetpack/extensions/shared/external-media/index.js | 1 + 2 files changed, 5 insertions(+) create mode 100644 projects/plugins/jetpack/changelog/update-jetpack-extend-media-button-for-videopress-video-block diff --git a/projects/plugins/jetpack/changelog/update-jetpack-extend-media-button-for-videopress-video-block b/projects/plugins/jetpack/changelog/update-jetpack-extend-media-button-for-videopress-video-block new file mode 100644 index 0000000000000..78000d3956308 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-jetpack-extend-media-button-for-videopress-video-block @@ -0,0 +1,4 @@ +Significance: minor +Type: compat + +Jetpack: extend media button for VideoPress video block diff --git a/projects/plugins/jetpack/extensions/shared/external-media/index.js b/projects/plugins/jetpack/extensions/shared/external-media/index.js index 5a9ff909aa8ba..62ab8d25283b1 100644 --- a/projects/plugins/jetpack/extensions/shared/external-media/index.js +++ b/projects/plugins/jetpack/extensions/shared/external-media/index.js @@ -31,6 +31,7 @@ if ( isCurrentUserConnected() && 'function' === typeof useBlockEditContext ) { 'jetpack/slideshow', 'jetpack/story', 'jetpack/tiled-gallery', + 'videopress/video', ]; return allowedBlocks.indexOf( name ) > -1 && render.toString().indexOf( 'coblocks' ) === -1; From b81cd67d0c04add7e8d07916b4e2c89ceb14026d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dami=C3=A1n=20Su=C3=A1rez?= Date: Fri, 17 Feb 2023 17:30:31 -0300 Subject: [PATCH 32/51] VideoPress: tweak poster control styles (#29033) * [not verified] tweak uploading/replacing video poster * [not verified] simplify media button text * changelog --- .../update-jetpack-tweak-media-button | 4 ++ .../poster-image-block-control/index.tsx | 48 ++++++++++++------- .../poster-image-block-control/types.ts | 2 +- 3 files changed, 35 insertions(+), 19 deletions(-) create mode 100644 projects/packages/videopress/changelog/update-jetpack-tweak-media-button diff --git a/projects/packages/videopress/changelog/update-jetpack-tweak-media-button b/projects/packages/videopress/changelog/update-jetpack-tweak-media-button new file mode 100644 index 0000000000000..4d46bb9acc0a1 --- /dev/null +++ b/projects/packages/videopress/changelog/update-jetpack-tweak-media-button @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +VideoPress: tweak poster control styles diff --git a/projects/packages/videopress/src/client/block-editor/blocks/video/components/poster-image-block-control/index.tsx b/projects/packages/videopress/src/client/block-editor/blocks/video/components/poster-image-block-control/index.tsx index 92905b2e7c909..d94e0d06516fc 100644 --- a/projects/packages/videopress/src/client/block-editor/blocks/video/components/poster-image-block-control/index.tsx +++ b/projects/packages/videopress/src/client/block-editor/blocks/video/components/poster-image-block-control/index.tsx @@ -3,14 +3,19 @@ */ import { MediaUploadCheck, MediaUpload } from '@wordpress/block-editor'; import { ToolbarButton, Dropdown, NavigableMenu, MenuItem } from '@wordpress/components'; +import { createInterpolateElement } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; import { linkOff, image as imageIcon } from '@wordpress/icons'; -import { VideoControlProps } from '../../types'; -import styles from './style.module.scss'; /** * Internal dependencies */ -import { VideoPosterCardProsp } from './types'; +import styles from './style.module.scss'; +/** + * Types + */ +import type { VideoPosterCardProps } from './types'; +import type { AdminAjaxQueryAttachmentsResponseItemProps } from '../../../../../types'; +import type { VideoControlProps } from '../../types'; import type React from 'react'; const VIDEO_POSTER_ALLOWED_MEDIA_TYPES = [ 'image' ]; @@ -18,18 +23,28 @@ const VIDEO_POSTER_ALLOWED_MEDIA_TYPES = [ 'image' ]; /** * Simple component that renders info about video poster. * - * @param {VideoPosterCardProsp} props - Component props. + * @param {VideoPosterCardProps} props - Component props. * @returns {React.ReactElement} VideoPosterCard component */ -function VideoPosterCard( { poster }: VideoPosterCardProsp ) { - const notes = __( - 'No custom Poster image selected. You can upload or select an image from your media library to override the default video image.', - 'jetpack-videopress-pkg' +function VideoPosterCard( { poster }: VideoPosterCardProps ): React.ReactElement { + const notes = createInterpolateElement( + __( + 'No custom Poster image selected. You can upload or select an image from your media library to override the default video image.', + 'jetpack-videopress-pkg' + ), + { + strong: , + } ); - const overridingNotes = __( - 'You are currently overriding the default Poster image. Remove it if you want to use the default image generated by VideoPress.', - 'jetpack-videopress-pkg' + const overridingNotes = createInterpolateElement( + __( + 'You are currently overriding the default Poster image. Remove it if you want to use the default image generated by VideoPress.', + 'jetpack-videopress-pkg' + ), + { + strong: , + } ); return
    { poster ? overridingNotes : notes }
    ; @@ -45,9 +60,9 @@ export default function PosterImageBlockControl( { attributes, setAttributes, clientId, -}: VideoControlProps ) { +}: VideoControlProps ): React.ReactElement { const { poster } = attributes; - const onSelectPoster = image => { + const onSelectPoster = ( image: AdminAjaxQueryAttachmentsResponseItemProps ) => { setAttributes( { poster: image.url } ); }; @@ -55,9 +70,6 @@ export default function PosterImageBlockControl( { setAttributes( { poster: '' } ); }; - const selectPosterLabel = __( 'Select Poster Image', 'jetpack-videopress-pkg' ); - const replacePosterLabel = __( 'Replace Poster Image', 'jetpack-videopress-pkg' ); - return ( { + onSelect={ ( image: AdminAjaxQueryAttachmentsResponseItemProps ) => { onSelectPoster( image ); onClose(); } } @@ -90,7 +102,7 @@ export default function PosterImageBlockControl( { onClick={ open } aria-describedby={ videoPosterDescription } > - { ! poster ? selectPosterLabel : replacePosterLabel } + { __( 'Open Media Library', 'jetpack-videopress-pkg' ) }
    + + +
    ) } - > - { accessLabel } - - ) } - renderContent={ ( { onClose } ) => ( -
    - -
    - { __( 'Audience', 'jetpack' ) } - { Object.keys( accessOptions ).map( key => ( -
    - { - const obj = {}; - obj[ META_NAME_FOR_POST_LEVEL_ACCESS_SETTINGS ] = event?.target?.value; - return setPostMeta( obj ); - } } - /> - -

    - { accessOptions[ key ].info } -

    -
    - ) ) } -
    -
    - ) } - /> - ) } + /> + + ) } + + { ! withModal && canEdit && ( + + + + ) } + ) } /> diff --git a/projects/plugins/jetpack/extensions/blocks/subscriptions/utils.js b/projects/plugins/jetpack/extensions/blocks/subscriptions/utils.js index 22ecdb63b0729..0356d1f091ab2 100644 --- a/projects/plugins/jetpack/extensions/blocks/subscriptions/utils.js +++ b/projects/plugins/jetpack/extensions/blocks/subscriptions/utils.js @@ -33,7 +33,7 @@ export const isNewsletterFeatureEnabled = () => { export default function GetAddPaidPlanButton( { context = 'other', hasNewsletterPlans } ) { const addPaidPlanButtonText = hasNewsletterPlans ? _x( 'Manage plans', 'unused context to distinguish translations', 'jetpack' ) - : __( 'Add paid plan', 'jetpack' ); + : __( 'Add Payments', 'jetpack' ); if ( 'toolbar' === context ) { return ( From f02bf404ddfbe38d9d9c6a2b35135995301facb5 Mon Sep 17 00:00:00 2001 From: ouikhuan Date: Mon, 20 Feb 2023 18:19:05 +0800 Subject: [PATCH 40/51] Update readme.txt for migration plugin (#29040) * Update readme.txt for migration plugin --- .../changelog/update-migration-readme | 4 ++ projects/plugins/migration/readme.txt | 63 ++++++------------- 2 files changed, 23 insertions(+), 44 deletions(-) create mode 100644 projects/plugins/migration/changelog/update-migration-readme diff --git a/projects/plugins/migration/changelog/update-migration-readme b/projects/plugins/migration/changelog/update-migration-readme new file mode 100644 index 0000000000000..155f5189e78b0 --- /dev/null +++ b/projects/plugins/migration/changelog/update-migration-readme @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Update readme.txt for migration plugin diff --git a/projects/plugins/migration/readme.txt b/projects/plugins/migration/readme.txt index 4b07c350b1505..aa399e2d3464d 100644 --- a/projects/plugins/migration/readme.txt +++ b/projects/plugins/migration/readme.txt @@ -1,6 +1,6 @@ === Move to WordPress.com === -Contributors: automattic, -Tags: jetpack, stuff +Contributors: automattic +Tags: migrate, migration, backup, restore, transfer, move, copy, wordpress.com, automattic, import, importer, hosting Requires at least: 6.0 Requires PHP: 5.6 Tested up to: 6.1 @@ -8,61 +8,36 @@ Stable tag: 0.1.0-alpha License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html -Move to WordPress.com plugin - -== Description == - A WordPress plugin that helps users to migrate their sites to WordPress.com -== Installation == - -Installation instructions go here. - -== Frequently Asked Questions == - -= A question that someone might have = - -An answer to that question. - -== Screenshots == +== Description == -1. This screen shot description corresponds to screenshot-1.(png|jpg|jpeg|gif). Note that the screenshot is taken from -the /assets directory or the directory that contains the stable readme.txt (tags or trunk). Screenshots in the /assets -directory take precedence. For example, `/assets/screenshot-1.png` would win over `/tags/4.3/screenshot-1.png` -(or jpg, jpeg, gif). -2. This is the second screen shot +### Move your site over to WordPress.com ### -== Changelog == +This free plugin offers a simple way to migrate any site to WordPress.com managed hosting. Get the superior speed, performance, security, and support you need to take your site to the next level. - +### It’s up to you ### -== Arbitrary section == +Migrate just your site or bring your content and settings along with it, including blog posts, pages, themes, plugins, site styles, fonts, and colors. -You may provide arbitrary sections, in the same format as the ones above. This may be of use for extremely complicated -plugins where more information needs to be conveyed that doesn't fit into the categories of "description" or -"installation." Arbitrary sections will be shown below the built-in sections outlined above. +### Relax and let the plugin do the work ### -== A brief Markdown Example == +The migration is automatic – set it in motion, walk away, and we’ll send you an email once it’s done. -Ordered list: +### The same, but better ### -1. Some feature -1. Another feature -1. Something else about the plugin +Thanks to the seamless transfer from your old site to the new one, your visitors will never notice you’ve switched. But once you see the improvement, you will. -Unordered list: +### You’re not alone ### -* something -* something else -* third thing +If you need a little help during or after the migration, you’ll have round-the-clock access to WordPress.com experts with email and live-chat support. -Here's a link to [WordPress](https://wordpress.org/ "Your favorite software") and one to [Markdown's Syntax Documentation][markdown syntax]. -Titles are optional, naturally. +== Installation == -[markdown syntax]: http://daringfireball.net/projects/markdown/syntax -"Markdown is what the parser uses to process much of the readme file" +1. To begin, click on the Plugins link in the left hand sidebar, then click Add New. +2. Search for Move to WordPress.com. The latest version will be in the search results. Click the Install Now button. +3. Next, click the Activate button. After activating, you can navigate to Move to WordPress.com in your admin area. -Markdown uses email style notation for blockquotes and I've been told: -> Asterisks for *emphasis*. Double it up for **strong**. +== Changelog == -`` + \ No newline at end of file From 5e92e1c63281227afe235030ae4f7957646f7021 Mon Sep 17 00:00:00 2001 From: MILLER/F Date: Mon, 20 Feb 2023 11:22:20 +0100 Subject: [PATCH 41/51] [Paid Newletters] tests for paid newsletters regressions (#28966) * Fix function case in PaidNewletter tests * Added premium-content test suite * Added changelog * First tests working * Added phpunit tests Can be run with ``` jetpack docker phpunit -- -c tests/php.multisite.xml --testsuite=premium-content ``` * Added test for regular subscriber * Added tests for comments * Enable jetpack_subscriptions_newsletter_feature_enabled and add comments tests * Added test_comments_are_not_displaying_for_paid_subscribers_when_defaults_to_false * Fix tests * Moved tests to the right folder and added @covers * Adding more @covers --- ...tests-add-tests-for-newsletter-regressions | 4 + .../premium-content/_inc/access-check.php | 3 +- .../plugins/jetpack/tests/php.multisite.xml | 3 + ...est-jetpack-token-subscription-service.php | 12 ++ .../test_class.jetpack-premium-content.php | 198 ++++++++++++++++++ .../test_class.jetpack-subscriptions.php | 72 ++++++- 6 files changed, 288 insertions(+), 4 deletions(-) create mode 100644 projects/plugins/jetpack/changelog/tests-add-tests-for-newsletter-regressions create mode 100644 projects/plugins/jetpack/tests/php/extensions/blocks/premium-content/class-test-jetpack-token-subscription-service.php create mode 100644 projects/plugins/jetpack/tests/php/extensions/blocks/premium-content/test_class.jetpack-premium-content.php diff --git a/projects/plugins/jetpack/changelog/tests-add-tests-for-newsletter-regressions b/projects/plugins/jetpack/changelog/tests-add-tests-for-newsletter-regressions new file mode 100644 index 0000000000000..ed77bf50d15b7 --- /dev/null +++ b/projects/plugins/jetpack/changelog/tests-add-tests-for-newsletter-regressions @@ -0,0 +1,4 @@ +Significance: patch +Type: other + +Tests for paid-newsletters regressions diff --git a/projects/plugins/jetpack/extensions/blocks/premium-content/_inc/access-check.php b/projects/plugins/jetpack/extensions/blocks/premium-content/_inc/access-check.php index 5479d35142609..f4cb8f7fdcd5e 100644 --- a/projects/plugins/jetpack/extensions/blocks/premium-content/_inc/access-check.php +++ b/projects/plugins/jetpack/extensions/blocks/premium-content/_inc/access-check.php @@ -9,7 +9,7 @@ use Automattic\Jetpack\Extensions\Premium_Content\Subscription_Service\Token_Subscription_Service; -require __DIR__ . '/subscription-service/include.php'; +require_once __DIR__ . '/subscription-service/include.php'; /** * Determines if the memberships module is set up. @@ -75,6 +75,7 @@ function current_visitor_can_access( $attributes, $block ) { * If the current WordPress install has as signed in user * they can see the content. */ + if ( current_user_can_edit() ) { return true; } diff --git a/projects/plugins/jetpack/tests/php.multisite.xml b/projects/plugins/jetpack/tests/php.multisite.xml index d343207a6b6d0..0107be28d1a23 100644 --- a/projects/plugins/jetpack/tests/php.multisite.xml +++ b/projects/plugins/jetpack/tests/php.multisite.xml @@ -51,6 +51,9 @@ php/modules/subscriptions + + php/extensions/blocks/premium-content + php/modules/contact-form diff --git a/projects/plugins/jetpack/tests/php/extensions/blocks/premium-content/class-test-jetpack-token-subscription-service.php b/projects/plugins/jetpack/tests/php/extensions/blocks/premium-content/class-test-jetpack-token-subscription-service.php new file mode 100644 index 0000000000000..5484f43160dad --- /dev/null +++ b/projects/plugins/jetpack/tests/php/extensions/blocks/premium-content/class-test-jetpack-token-subscription-service.php @@ -0,0 +1,12 @@ +product_id => array( + 'status' => $status ? $status : 'active', + 'end_date' => $subscription_end_date ? $subscription_end_date : time() + HOUR_IN_SECONDS, + 'product_id' => $this->product_id, + ), + ); + + return array( + 'blog_sub' => $is_subscribed ? 'active' : 'inactive', + 'subscriptions' => $subscriptions, + ); + } + + /** + * Stubs WPCOM_Token_Subscription_Service in order to return the provided token. + * + * @param array $payload + * @return mixed + */ + private function set_returned_token( $payload ) { + // We remove anything else + $service = subscription_service(); + $this->assertTrue( is_a( $service, '\Tests\Automattic\Jetpack\Extensions\Premium_Content\Test_Jetpack_Token_Subscription_Service' ) ); + $_GET['token'] = JWT::encode( $payload, $service->get_key() ); + } + + private function set_up_users_and_plans() { + // We create a paid subscriber + $paid_subscriber_id = $this->factory->user->create( + array( + 'user_email' => 'test-paid@example.com', + ) + ); + + $regular_subscriber_id = $this->factory->user->create( + array( + 'user_email' => 'test-subscriber@example.com', + ) + ); + + $non_subscriber_id = $this->factory->user->create( + array( + 'user_email' => 'test@example.com', + ) + ); + + // We create a plan + $plan_id = $this->factory->post->create( + array( + 'post_type' => Jetpack_Memberships::$post_type_plan, + ) + ); + update_post_meta( $plan_id, 'jetpack_memberships_product_id', $this->product_id ); + $this->factory->post->create(); + + // We set the plan to the paid_subscriber_id + add_filter( + 'earn_get_user_subscriptions_for_site_id', + static function ( $subscriptions, $subscriber_id ) use ( $paid_subscriber_id, $plan_id ) { + if ( $subscriber_id === $paid_subscriber_id ) { + $subscriptions = array_merge( $subscriptions, array( $plan_id ) ); + } + + return $subscriptions; + }, + 10, + 2 + ); + + return array( $non_subscriber_id, $regular_subscriber_id, $paid_subscriber_id, $plan_id ); + } + + /** + * Admin has access all the time + * + * @covers \Automattic\Jetpack\Extensions\Premium_Content\current_visitor_can_access + * + * @return void + */ + public function test_access_check_current_visitor_can_access_admin() { + $admin_user_id = $this->factory->user->create( + array( + 'user_email' => 'test-admin@example.com', + ) + ); + + get_user_by( 'id', $admin_user_id )->add_role( 'administrator' ); + $post_id = $this->factory->post->create(); + $GLOBALS['post'] = get_post( $post_id ); + wp_set_current_user( $admin_user_id ); + $this->assertTrue( current_visitor_can_access( array(), array() ) ); + } + + /** + * Test current_visitor_can_access works for different types of users + * + * @covers \Automattic\Jetpack\Extensions\Premium_Content\current_visitor_can_access + * + * @return void + */ + public function test_access_check_current_visitor_can_access_regular_users() { + $users_plans = $this->set_up_users_and_plans(); + $non_subscriber_id = $users_plans[0]; + $regular_subscriber_id = $users_plans[1]; + $paid_subscriber_id = $users_plans[2]; + $plan_id = $users_plans[3]; + + // We setup the token for the regular user + wp_set_current_user( $non_subscriber_id ); + $payload = $this->get_payload( false, false ); + $this->set_returned_token( $payload ); + $this->assertFalse( current_visitor_can_access( array( 'selectedPlanId' => $plan_id ), array() ) ); + + // We setup the token for the regular subscriber + wp_set_current_user( $regular_subscriber_id ); + $payload = $this->get_payload( true, false ); + $this->set_returned_token( $payload ); + $this->assertFalse( current_visitor_can_access( array( 'selectedPlanId' => $plan_id ), array() ) ); + + // We setup the token for the paid user + wp_set_current_user( $paid_subscriber_id ); + $payload = $this->get_payload( true, true ); + $this->set_returned_token( $payload ); + $this->assertTrue( current_visitor_can_access( array( 'selectedPlanId' => $plan_id ), array() ) ); + } + + /** + * Test that plan id can be passed 2 ways + * + * @covers \Automattic\Jetpack\Extensions\Premium_Content\current_visitor_can_access + * + * @return void + */ + public function test_access_check_current_visitor_can_access_passing_plan_id() { + $users_plans = $this->set_up_users_and_plans(); + $paid_subscriber_id = $users_plans[2]; + $plan_id = $users_plans[3]; + + wp_set_current_user( $paid_subscriber_id ); + $payload = $this->get_payload( true, true ); + $this->set_returned_token( $payload ); + // We check it fails if the plan is not passed + $this->assertFalse( current_visitor_can_access( array(), array() ) ); + + // The plan id can be passed in 2 ways. + $this->assertTrue( current_visitor_can_access( array( 'selectedPlanId' => $plan_id ), array() ) ); + $this->assertTrue( current_visitor_can_access( array(), (object) array( 'context' => array( 'premium-content/planId' => $plan_id ) ) ) ); + } +} diff --git a/projects/plugins/jetpack/tests/php/modules/subscriptions/test_class.jetpack-subscriptions.php b/projects/plugins/jetpack/tests/php/modules/subscriptions/test_class.jetpack-subscriptions.php index efc12e0cb1d45..2978491900aec 100644 --- a/projects/plugins/jetpack/tests/php/modules/subscriptions/test_class.jetpack-subscriptions.php +++ b/projects/plugins/jetpack/tests/php/modules/subscriptions/test_class.jetpack-subscriptions.php @@ -3,11 +3,13 @@ require_once JETPACK__PLUGIN_DIR . 'modules/subscriptions.php'; require_once JETPACK__PLUGIN_DIR . 'extensions/blocks/premium-content/_inc/subscription-service/include.php'; require_once JETPACK__PLUGIN_DIR . 'modules/memberships/class-jetpack-memberships.php'; +require_once JETPACK__PLUGIN_DIR . 'extensions/blocks/subscriptions/subscriptions.php'; use Automattic\Jetpack\Extensions\Premium_Content\JWT; use Automattic\Jetpack\Extensions\Premium_Content\Subscription_Service\WPCOM_Offline_Subscription_Service; use Automattic\Jetpack\Extensions\Premium_Content\Subscription_Service\WPCOM_Online_Subscription_Service; use Automattic\Jetpack\Extensions\Premium_Content\Subscription_Service\WPCOM_Token_Subscription_Service; +use function Automattic\Jetpack\Extensions\Subscriptions\register_block as register_subscription_block; define( 'EARN_JWT_SIGNING_KEY', 'whatever=' ); @@ -31,6 +33,8 @@ public function tear_down() { // Clean up remove_all_filters( 'earn_get_user_subscriptions_for_site_id' ); remove_all_filters( 'test_jetpack_is_supported_jetpack_recurring_payments' ); + remove_all_filters( 'jetpack_subscriptions_newsletter_feature_enabled' ); + parent::tear_down(); } @@ -285,7 +289,7 @@ public function test_subscriber_access_level( $type_user_id, $logged, $token_set $payload = $this->get_payload( $is_blog_subscriber, $is_paid_subscriber, $subscription_end_date, $status ); $post_id = $this->setup_jetpack_paid_newsletters(); - $this->setReturnedSubscriptions( $payload ); + $this->set_returned_subscriptions( $payload ); $GLOBALS['post'] = get_post( $post_id ); update_post_meta( $post_id, '_jetpack_newsletter_access', $post_access_level ); @@ -324,6 +328,69 @@ public function test_subscriber_access_level( $type_user_id, $logged, $token_set ); } + /** + * Tests for regression from https://github.com/Automattic/jetpack/commit/e2c3b99c39047a15de02ca82f23893185916e2d9 + * + * @covers \Automattic\Jetpack\Extensions\Subscriptions\maybe_close_comments + * + * @return void + */ + public function test_comments_are_not_displaying_on_not_pages() { + add_filter( 'jetpack_subscriptions_newsletter_feature_enabled', '__return_true' ); + register_subscription_block(); + + // When no post id is set, the comments should default to whatever is passed as default + $this->assertFalse( apply_filters( 'comments_open', false, null ) ); + $this->assertTrue( apply_filters( 'comments_open', true, null ) ); + } + + /** + * Tests for regression from https://github.com/Automattic/jetpack/commit/e2c3b99c39047a15de02ca82f23893185916e2d9 + * + * @covers \Automattic\Jetpack\Extensions\Subscriptions\maybe_close_comments + * + * @return void + */ + public function test_comments_are_displaying_on_not_accessible_pages() { + add_filter( 'jetpack_subscriptions_newsletter_feature_enabled', '__return_true' ); + register_subscription_block(); + + // When post-id is passed, it should prevent access depending of the user access + $payload = $this->get_payload( true, false, null, null ); + $post_id = $this->setup_jetpack_paid_newsletters(); + $subscription_service = $this->set_returned_token( $payload ); + $GLOBALS['post'] = get_post( $post_id ); + $post_access_level = 'paid_subscribers'; + update_post_meta( $post_id, '_jetpack_newsletter_access', $post_access_level ); + $this->assertFalse( $subscription_service->visitor_can_view_content( array( $this->plan_id ), $post_access_level ) ); + + $this->assertFalse( apply_filters( 'comments_open', true, $post_id ) ); + } + + /** + * Tests for regression from https://github.com/Automattic/jetpack/commit/e2c3b99c39047a15de02ca82f23893185916e2d9 + * + * @covers \Automattic\Jetpack\Extensions\Subscriptions\maybe_close_comments + * + * @return void + */ + public function test_comments_are_not_displaying_for_paid_subscribers_when_defaults_to_false() { + add_filter( 'jetpack_subscriptions_newsletter_feature_enabled', '__return_true' ); + register_subscription_block(); + + // When post-id is passed, it should prevent access depending of the user access + $payload = $this->get_payload( true, true, null, null ); + $post_id = $this->setup_jetpack_paid_newsletters(); + $subscription_service = $this->set_returned_token( $payload ); + $GLOBALS['post'] = get_post( $post_id ); + $post_access_level = 'paid_subscribers'; + update_post_meta( $post_id, '_jetpack_newsletter_access', $post_access_level ); + $this->assertTrue( $subscription_service->visitor_can_view_content( array( $this->plan_id ), $post_access_level ) ); + + // The user has access, BUT it still does NOT display comments if defaults to false + $this->assertFalse( apply_filters( 'comments_open', false, $post_id ) ); + } + /** * Setup the newsletter post * @@ -348,7 +415,7 @@ private function setup_jetpack_paid_newsletters() { * @param array $payload . * @return WPCOM_Online_Subscription_Service */ - private function setReturnedSubscriptions( $payload ) { + private function set_returned_subscriptions( $payload ) { remove_all_filters( 'earn_get_user_subscriptions_for_site_id' ); $paid_subscriber_id = $this->paid_subscriber_id; add_filter( @@ -367,5 +434,4 @@ static function ( $subscriptions, $subscriber_id ) use ( $paid_subscriber_id, $p return new WPCOM_Online_Subscription_Service(); } - } From b46b19419a063b506f21eee56ca084d5a51a1a14 Mon Sep 17 00:00:00 2001 From: Karen Attfield Date: Mon, 20 Feb 2023 13:37:40 +0000 Subject: [PATCH 42/51] CRM: Clean up - remove redundant eslintrc.js file (#28948) --- projects/plugins/crm/.eslintignore | 3 +- projects/plugins/crm/.eslintrc.js | 28 ------------------- .../changelog/update-crm-remove-eslintrcjs | 5 ++++ 3 files changed, 7 insertions(+), 29 deletions(-) delete mode 100644 projects/plugins/crm/.eslintrc.js create mode 100644 projects/plugins/crm/changelog/update-crm-remove-eslintrcjs diff --git a/projects/plugins/crm/.eslintignore b/projects/plugins/crm/.eslintignore index 7949bfd787430..4889d0764ba8c 100644 --- a/projects/plugins/crm/.eslintignore +++ b/projects/plugins/crm/.eslintignore @@ -4,4 +4,5 @@ # They can be removed here as lint errors are addressed. /js/ /modules/ -gulpfile.esm.js \ No newline at end of file +gulpfile.esm.js +webpack.config.js \ No newline at end of file diff --git a/projects/plugins/crm/.eslintrc.js b/projects/plugins/crm/.eslintrc.js deleted file mode 100644 index aababcc8f2a73..0000000000000 --- a/projects/plugins/crm/.eslintrc.js +++ /dev/null @@ -1,28 +0,0 @@ -// eslint-disable-next-line import/no-extraneous-dependencies -const loadIgnorePatterns = require( 'jetpack-js-tools/load-eslint-ignore.js' ); - -module.exports = { - root: true, - extends: [ - require.resolve( 'jetpack-js-tools/eslintrc/base' ), - require.resolve( 'jetpack-js-tools/eslintrc/wp-eslint-plugin/recommended' ), - ], - ignorePatterns: loadIgnorePatterns( __dirname ), - rules: { - camelcase: 0, - 'no-var': 0, - 'prefer-const': 0, - 'prettier/prettier': 0, - // This is not a react project. - 'react-hooks/rules-of-hooks': 0, - - // Don't require JSDoc on functions initially. - 'jsdoc/check-tag-names': 0, - 'jsdoc/require-jsdoc': 0, - 'jsdoc/require-returns': 0, - 'jsdoc/require-description': 0, - 'jsdoc/require-property-description': 0, - 'jsdoc/require-param-description': 0, - 'jsdoc/require-param-type': 0, - }, -}; diff --git a/projects/plugins/crm/changelog/update-crm-remove-eslintrcjs b/projects/plugins/crm/changelog/update-crm-remove-eslintrcjs new file mode 100644 index 0000000000000..ef5bcac2d1d4c --- /dev/null +++ b/projects/plugins/crm/changelog/update-crm-remove-eslintrcjs @@ -0,0 +1,5 @@ +Significance: patch +Type: removed +Comment: Tooling related - removing a redundant eslintrc.js file + + From a1d8fbd4c8a97d1b8181b550aa92e48304467943 Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Mon, 20 Feb 2023 19:11:16 +0100 Subject: [PATCH 43/51] General: add External link icon to external links (#28922) --- .../changelog/fix-missing-external-links | 4 ++++ .../components/components/pricing-table/index.tsx | 9 +++------ .../changelog/fix-missing-external-links | 4 ++++ .../connect-screen/basic/test/component.jsx | 4 ++-- .../components/connect-screen/basic/visual.jsx | 9 +++------ .../required-plan/test/component.jsx | 4 ++-- .../connect-screen/required-plan/visual.jsx | 11 +++-------- .../disconnect-dialog/steps/step-disconnect.jsx | 14 +++++--------- .../disconnect-dialog/test/step-disconnect.jsx | 4 ++-- .../components/manage-connection-dialog/index.jsx | 14 +++++--------- .../client/components/connect-button/index.jsx | 13 +++---------- .../_inc/client/components/footer/index.jsx | 8 ++++++++ .../_inc/client/components/footer/style.scss | 4 ++++ .../components/jetpack-notices/state-notices.jsx | 5 ++--- .../plugins/jetpack/_inc/client/traffic/ads.jsx | 3 ++- .../jetpack/changelog/fix-missing-external-links | 4 ++++ .../social/changelog/fix-missing-external-links | 4 ++++ .../src/js/components/connection-screen/index.js | 9 +++------ 18 files changed, 63 insertions(+), 64 deletions(-) create mode 100644 projects/js-packages/components/changelog/fix-missing-external-links create mode 100644 projects/js-packages/connection/changelog/fix-missing-external-links create mode 100644 projects/plugins/jetpack/changelog/fix-missing-external-links create mode 100644 projects/plugins/social/changelog/fix-missing-external-links diff --git a/projects/js-packages/components/changelog/fix-missing-external-links b/projects/js-packages/components/changelog/fix-missing-external-links new file mode 100644 index 0000000000000..911c3a1a6291c --- /dev/null +++ b/projects/js-packages/components/changelog/fix-missing-external-links @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Use External Link icons for external links diff --git a/projects/js-packages/components/components/pricing-table/index.tsx b/projects/js-packages/components/components/pricing-table/index.tsx index 4682ddec64d68..6d6abd90934c2 100644 --- a/projects/js-packages/components/components/pricing-table/index.tsx +++ b/projects/js-packages/components/components/pricing-table/index.tsx @@ -1,3 +1,4 @@ +import { ExternalLink } from '@wordpress/components'; import { createInterpolateElement } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; import { Icon, check, closeSmall } from '@wordpress/icons'; @@ -29,13 +30,9 @@ const ToS = createInterpolateElement( 'jetpack' ), { - tosLink: , + tosLink: , shareDetailsLink: ( - + ), } ); diff --git a/projects/js-packages/connection/changelog/fix-missing-external-links b/projects/js-packages/connection/changelog/fix-missing-external-links new file mode 100644 index 0000000000000..63ba68b0e295f --- /dev/null +++ b/projects/js-packages/connection/changelog/fix-missing-external-links @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Add External link icon to links at the bottom of the disconnect modal. diff --git a/projects/js-packages/connection/components/connect-screen/basic/test/component.jsx b/projects/js-packages/connection/components/connect-screen/basic/test/component.jsx index b8ae1f9e08b39..e60b572ba2ce5 100644 --- a/projects/js-packages/connection/components/connect-screen/basic/test/component.jsx +++ b/projects/js-packages/connection/components/connect-screen/basic/test/component.jsx @@ -32,14 +32,14 @@ describe( 'ConnectScreen', () => { it( 'applies correct href to terms of service', () => { render( ); - const terms = screen.getByRole( 'link', { name: 'Terms of Service' } ); + const terms = screen.getByRole( 'link', { name: 'Terms of Service (opens in a new tab)' } ); expect( terms ).toHaveAttribute( 'href', 'https://jetpack.com/redirect/?source=wpcom-tos' ); expect( terms ).toHaveAttribute( 'target', '_blank' ); } ); it( 'applies correct href to share', () => { render( ); - const share = screen.getByRole( 'link', { name: 'share details' } ); + const share = screen.getByRole( 'link', { name: 'share details (opens in a new tab)' } ); expect( share ).toHaveAttribute( 'href', 'https://jetpack.com/redirect/?source=jetpack-support-what-data-does-jetpack-sync' diff --git a/projects/js-packages/connection/components/connect-screen/basic/visual.jsx b/projects/js-packages/connection/components/connect-screen/basic/visual.jsx index 255e99f45c5e5..9f98faa13def1 100644 --- a/projects/js-packages/connection/components/connect-screen/basic/visual.jsx +++ b/projects/js-packages/connection/components/connect-screen/basic/visual.jsx @@ -1,4 +1,5 @@ import { getRedirectUrl, ActionButton } from '@automattic/jetpack-components'; +import { ExternalLink } from '@wordpress/components'; import { createInterpolateElement } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import PropTypes from 'prop-types'; @@ -12,13 +13,9 @@ export const ToS = createInterpolateElement( 'jetpack' ), { - tosLink: , + tosLink: , shareDetailsLink: ( - + ), } ); diff --git a/projects/js-packages/connection/components/connect-screen/required-plan/test/component.jsx b/projects/js-packages/connection/components/connect-screen/required-plan/test/component.jsx index 61ae1fd89c94c..61c1a9ae8f5a4 100644 --- a/projects/js-packages/connection/components/connect-screen/required-plan/test/component.jsx +++ b/projects/js-packages/connection/components/connect-screen/required-plan/test/component.jsx @@ -37,14 +37,14 @@ describe( 'ConnectScreenRequiredPlan', () => { it( 'applies correct href to terms of service', () => { render( ); - const terms = screen.getByRole( 'link', { name: 'Terms of Service' } ); + const terms = screen.getByRole( 'link', { name: 'Terms of Service (opens in a new tab)' } ); expect( terms ).toHaveAttribute( 'href', 'https://jetpack.com/redirect/?source=wpcom-tos' ); expect( terms ).toHaveAttribute( 'target', '_blank' ); } ); it( 'applies correct href to share', () => { render( ); - const share = screen.getByRole( 'link', { name: 'share details' } ); + const share = screen.getByRole( 'link', { name: 'share details (opens in a new tab)' } ); expect( share ).toHaveAttribute( 'href', 'https://jetpack.com/redirect/?source=jetpack-support-what-data-does-jetpack-sync' diff --git a/projects/js-packages/connection/components/connect-screen/required-plan/visual.jsx b/projects/js-packages/connection/components/connect-screen/required-plan/visual.jsx index 9eef2ccbc0cf1..390bf7d3f825d 100644 --- a/projects/js-packages/connection/components/connect-screen/required-plan/visual.jsx +++ b/projects/js-packages/connection/components/connect-screen/required-plan/visual.jsx @@ -1,4 +1,5 @@ import { getRedirectUrl, PricingCard, ActionButton } from '@automattic/jetpack-components'; +import { ExternalLink } from '@wordpress/components'; import { createInterpolateElement } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import PropTypes from 'prop-types'; @@ -36,15 +37,9 @@ const ConnectScreenRequiredPlanVisual = props => { 'jetpack' ), { - tosLink: ( - - ), + tosLink: , shareDetailsLink: ( - + ), } ); diff --git a/projects/js-packages/connection/components/disconnect-dialog/steps/step-disconnect.jsx b/projects/js-packages/connection/components/disconnect-dialog/steps/step-disconnect.jsx index 31e37acaae4ee..4bbbe95017b65 100644 --- a/projects/js-packages/connection/components/disconnect-dialog/steps/step-disconnect.jsx +++ b/projects/js-packages/connection/components/disconnect-dialog/steps/step-disconnect.jsx @@ -1,5 +1,5 @@ import { getRedirectUrl } from '@automattic/jetpack-components'; -import { Button } from '@wordpress/components'; +import { Button, ExternalLink } from '@wordpress/components'; import { createInterpolateElement } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import PropTypes from 'prop-types'; @@ -129,7 +129,7 @@ const StepDisconnect = props => {
    -
    + -
    +

    - { __( "Manage your clients' sites with ease", 'jetpack' ) } + { __( 'Manage your clients’ sites with ease', 'jetpack' ) }

    { sprintf( /* translators: %s is the percentage discount the users get in the agencies portal */ __( - `Manage your clients' sites with ease and get a %s discount with the Jetpack licensing platform.`, + 'Manage your clients’ sites with ease and get a %s discount with the Jetpack licensing platform.', 'jetpack' ), `${ discountPercentage }%` diff --git a/projects/plugins/jetpack/_inc/client/components/support-card/index.jsx b/projects/plugins/jetpack/_inc/client/components/support-card/index.jsx index a263dd3880417..d2a4309615f32 100644 --- a/projects/plugins/jetpack/_inc/client/components/support-card/index.jsx +++ b/projects/plugins/jetpack/_inc/client/components/support-card/index.jsx @@ -1,4 +1,5 @@ import { getRedirectUrl } from '@automattic/jetpack-components'; +import { ExternalLink } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; import classNames from 'classnames'; import Button from 'components/button'; @@ -76,7 +77,7 @@ class SupportCard extends React.Component {

    -

    { __( "We're here to help", 'jetpack' ) }

    +

    { __( 'We’re here to help', 'jetpack' ) }

    { hasSupport ? sprintf( @@ -90,25 +91,27 @@ class SupportCard extends React.Component { ) }

    - -

    diff --git a/projects/plugins/jetpack/changelog/fix-external-link-jetpack-support-card b/projects/plugins/jetpack/changelog/fix-external-link-jetpack-support-card new file mode 100644 index 0000000000000..130fdcef797b5 --- /dev/null +++ b/projects/plugins/jetpack/changelog/fix-external-link-jetpack-support-card @@ -0,0 +1,4 @@ +Significance: patch +Type: other + +Admin Page: use external icons for external links in support card. From df0304df2309e866ce00ae7b5d32c3eeee464a26 Mon Sep 17 00:00:00 2001 From: Karen Attfield Date: Tue, 21 Feb 2023 08:32:51 +0000 Subject: [PATCH 47/51] CRM: Composer and version updates in prep for the next release (#29029) --- projects/plugins/crm/CHANGELOG.md | 4 ++-- projects/plugins/crm/ZeroBSCRM.php | 2 +- projects/plugins/crm/changelog/init-release-cycle#2 | 5 +++++ .../plugins/crm/changelog/update-crm-next-alpha-version | 5 +++++ projects/plugins/crm/composer.json | 8 +++++--- projects/plugins/crm/composer.lock | 2 +- projects/plugins/crm/package.json | 2 +- 7 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 projects/plugins/crm/changelog/init-release-cycle#2 create mode 100644 projects/plugins/crm/changelog/update-crm-next-alpha-version diff --git a/projects/plugins/crm/CHANGELOG.md b/projects/plugins/crm/CHANGELOG.md index b4cee90b13bce..04f0eb700f3aa 100644 --- a/projects/plugins/crm/CHANGELOG.md +++ b/projects/plugins/crm/CHANGELOG.md @@ -5,7 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [5.5.4-alpha] - 2023-02-15 +## [5.5.4-a.1] - 2023-02-15 ### Added - adds the necessary migration to move all files that were inside the zbscrm-store folder with a flat struture to the new jpcrm-storage folder that uses a hierarchical structure [#28350] - Copy tests from old repo. [#28354] @@ -59,4 +59,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved: Security around phone numbers viewing - Improved: Added a migration to remove outdated AKA lines -[5.5.4-alpha]: https://github.com/Automattic/zero-bs-crm/compare/v5.5.3...v5.5.4-alpha +[5.5.4-a.1]: https://github.com/Automattic/jetpack-crm/compare/v5.5.3...v5.5.4-a.1 diff --git a/projects/plugins/crm/ZeroBSCRM.php b/projects/plugins/crm/ZeroBSCRM.php index 683b2477f6948..cc073986a16fa 100644 --- a/projects/plugins/crm/ZeroBSCRM.php +++ b/projects/plugins/crm/ZeroBSCRM.php @@ -3,7 +3,7 @@ * Plugin Name: Jetpack CRM * Plugin URI: https://jetpackcrm.com * Description: Jetpack CRM is the simplest CRM for WordPress. Self host your own Customer Relationship Manager using WP. - * Version: 5.5.5-alpha + * Version: 5.5.4-a.2 * Author: Automattic - Jetpack CRM team * Author URI: https://jetpackcrm.com * Text Domain: zero-bs-crm diff --git a/projects/plugins/crm/changelog/init-release-cycle#2 b/projects/plugins/crm/changelog/init-release-cycle#2 new file mode 100644 index 0000000000000..5e88f22ac8a0a --- /dev/null +++ b/projects/plugins/crm/changelog/init-release-cycle#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Init 5.5.4-a.2 + + diff --git a/projects/plugins/crm/changelog/update-crm-next-alpha-version b/projects/plugins/crm/changelog/update-crm-next-alpha-version new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/crm/changelog/update-crm-next-alpha-version @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/crm/composer.json b/projects/plugins/crm/composer.json index add2ec6fbc369..d9d5b9e112bc3 100644 --- a/projects/plugins/crm/composer.json +++ b/projects/plugins/crm/composer.json @@ -37,7 +37,7 @@ "platform": { "php": "7.3" }, - "autoloader-suffix": "06c775433a83ed276f0a1d8ac25f93ba_crmⓥ5_5_5_alpha", + "autoloader-suffix": "06c775433a83ed276f0a1d8ac25f93ba_crmⓥ5_5_4_a_2", "allow-plugins": { "automattic/jetpack-autoloader": true, "automattic/jetpack-composer-plugin": true @@ -65,10 +65,12 @@ }, "autorelease": true, "mirror-repo": "Automattic/jetpack-crm", + "dev-releases": true, "changelogger": { - "link-template": "https://github.com/Automattic/zero-bs-crm/compare/v${old}...v${new}" + "link-template": "https://github.com/Automattic/jetpack-crm/compare/v${old}...v${new}" }, "release-branch-prefix": "crm", - "wp-plugin-slug": "zero-bs-crm" + "wp-plugin-slug": "zero-bs-crm", + "wp-svn-autopublish": true } } diff --git a/projects/plugins/crm/composer.lock b/projects/plugins/crm/composer.lock index 0695838ff3854..8f94a30c7498b 100644 --- a/projects/plugins/crm/composer.lock +++ b/projects/plugins/crm/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3e27168b59f27ffa476536c99520a818", + "content-hash": "e4211adecf939624fad89bc9151c2017", "packages": [ { "name": "automattic/jetpack-autoloader", diff --git a/projects/plugins/crm/package.json b/projects/plugins/crm/package.json index afa4b4e72112b..30b21a76652c2 100644 --- a/projects/plugins/crm/package.json +++ b/projects/plugins/crm/package.json @@ -1,6 +1,6 @@ { "name": "@automattic/jetpack-crm", - "version": "5.5.5-alpha", + "version": "5.5.4-a.2", "description": "The CRM for WordPress", "author": "Automattic", "license": "GPL-2.0", From e192292ddf61e1bf8fe156f09c5623cfde463dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gergely=20M=C3=A1rk=20Juh=C3=A1sz?= <36671565+gmjuhasz@users.noreply.github.com> Date: Tue, 21 Feb 2023 12:04:54 +0100 Subject: [PATCH 48/51] Add SIG feature flag check to use-publicize-config (#29001) * Add check for social image generator is enabled * changelog * Remove editor.js * Fixup versions * Update changelogs * Fixup versions * remove accidental change * Remove commit linting of other file --- .../add-social-image-generator-feature-flag | 4 ++++ .../publicize-components/package.json | 2 +- .../src/hooks/use-publicize-config/index.js | 1 + .../add-social-image-generator-feature-flag | 4 ++++ projects/packages/publicize/composer.json | 2 +- projects/packages/publicize/package.json | 2 +- .../publicize/src/class-publicize-base.php | 16 ++++++++++++++++ .../add-social-image-generator-feature-flag | 4 ++++ .../add-social-image-generator-feature-flag#2 | 5 +++++ .../jetpack/class.jetpack-gutenberg.php | 7 ++++--- projects/plugins/jetpack/composer.lock | 4 ++-- .../add-social-image-generator-feature-flag | 4 ++++ .../add-social-image-generator-feature-flag#2 | 5 +++++ projects/plugins/social/composer.json | 2 +- projects/plugins/social/composer.lock | 4 ++-- projects/plugins/social/jetpack-social.php | 2 +- .../social/src/class-jetpack-social.php | 19 ++++++++++--------- 17 files changed, 66 insertions(+), 21 deletions(-) create mode 100644 projects/js-packages/publicize-components/changelog/add-social-image-generator-feature-flag create mode 100644 projects/packages/publicize/changelog/add-social-image-generator-feature-flag create mode 100644 projects/plugins/jetpack/changelog/add-social-image-generator-feature-flag create mode 100644 projects/plugins/jetpack/changelog/add-social-image-generator-feature-flag#2 create mode 100644 projects/plugins/social/changelog/add-social-image-generator-feature-flag create mode 100644 projects/plugins/social/changelog/add-social-image-generator-feature-flag#2 diff --git a/projects/js-packages/publicize-components/changelog/add-social-image-generator-feature-flag b/projects/js-packages/publicize-components/changelog/add-social-image-generator-feature-flag new file mode 100644 index 0000000000000..8604656b25c53 --- /dev/null +++ b/projects/js-packages/publicize-components/changelog/add-social-image-generator-feature-flag @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Add Social Image Generator feature flag to Jetpack Social diff --git a/projects/js-packages/publicize-components/package.json b/projects/js-packages/publicize-components/package.json index 2ea217084c1a4..e9ee8d9b9d811 100644 --- a/projects/js-packages/publicize-components/package.json +++ b/projects/js-packages/publicize-components/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@automattic/jetpack-publicize-components", - "version": "0.16.1", + "version": "0.17.0-alpha", "description": "A library of JS components required by the Publicize editor plugin", "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/publicize-components/#readme", "bugs": { diff --git a/projects/js-packages/publicize-components/src/hooks/use-publicize-config/index.js b/projects/js-packages/publicize-components/src/hooks/use-publicize-config/index.js index acda548c91547..faca6b26e386c 100644 --- a/projects/js-packages/publicize-components/src/hooks/use-publicize-config/index.js +++ b/projects/js-packages/publicize-components/src/hooks/use-publicize-config/index.js @@ -94,6 +94,7 @@ export default function usePublicizeConfig() { numberOfSharesRemaining: sharesData.shares_remaining, hasPaidPlan: !! getJetpackData()?.social?.hasPaidPlan, isEnhancedPublishingEnabled: !! getJetpackData()?.social?.isEnhancedPublishingEnabled, + isSocialImageGeneratorEnabled: !! getJetpackData()?.social?.isSocialImageGeneratorEnabled, connectionsAdminUrl: connectionsRootUrl + getSiteFragment(), adminUrl: getJetpackData()?.social?.adminUrl, }; diff --git a/projects/packages/publicize/changelog/add-social-image-generator-feature-flag b/projects/packages/publicize/changelog/add-social-image-generator-feature-flag new file mode 100644 index 0000000000000..8604656b25c53 --- /dev/null +++ b/projects/packages/publicize/changelog/add-social-image-generator-feature-flag @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Add Social Image Generator feature flag to Jetpack Social diff --git a/projects/packages/publicize/composer.json b/projects/packages/publicize/composer.json index 5a5439f02db26..c0e3822e34805 100644 --- a/projects/packages/publicize/composer.json +++ b/projects/packages/publicize/composer.json @@ -55,7 +55,7 @@ "link-template": "https://github.com/Automattic/jetpack-publicize/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "0.19.x-dev" + "dev-trunk": "0.20.x-dev" } }, "config": { diff --git a/projects/packages/publicize/package.json b/projects/packages/publicize/package.json index 15bbe6488b37f..7abb6d08be2b1 100644 --- a/projects/packages/publicize/package.json +++ b/projects/packages/publicize/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@automattic/jetpack-publicize", - "version": "0.19.5", + "version": "0.20.0-alpha", "description": "Publicize makes it easy to share your site’s posts on several social media networks automatically when you publish a new post.", "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/packages/publicize/#readme", "bugs": { diff --git a/projects/packages/publicize/src/class-publicize-base.php b/projects/packages/publicize/src/class-publicize-base.php index b7abd570f9a70..c92b32b37e320 100644 --- a/projects/packages/publicize/src/class-publicize-base.php +++ b/projects/packages/publicize/src/class-publicize-base.php @@ -1567,6 +1567,22 @@ public function is_enhanced_publishing_enabled( $blog_id ) { return ! empty( $data['is_enhanced_publishing_enabled'] ); } + /** + * Check if the social image generator is enabled. + * + * @param int $blog_id The blog ID for the current blog. + * @return bool + */ + public function is_social_image_generator_enabled( $blog_id ) { + $data = $this->get_api_data( $blog_id ); + + if ( empty( $data ) ) { + return false; + } + + return ! empty( $data['is_social_image_generator_enabled'] ); + } + /** * Call the WPCOM REST API to calculate the scheduled shares. * diff --git a/projects/plugins/jetpack/changelog/add-social-image-generator-feature-flag b/projects/plugins/jetpack/changelog/add-social-image-generator-feature-flag new file mode 100644 index 0000000000000..680b5ccc7d45d --- /dev/null +++ b/projects/plugins/jetpack/changelog/add-social-image-generator-feature-flag @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Add Social Image Generator feature flag to Jetpack Social diff --git a/projects/plugins/jetpack/changelog/add-social-image-generator-feature-flag#2 b/projects/plugins/jetpack/changelog/add-social-image-generator-feature-flag#2 new file mode 100644 index 0000000000000..a1c1831fa1ef7 --- /dev/null +++ b/projects/plugins/jetpack/changelog/add-social-image-generator-feature-flag#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: other +Comment: Updated composer.lock. + + diff --git a/projects/plugins/jetpack/class.jetpack-gutenberg.php b/projects/plugins/jetpack/class.jetpack-gutenberg.php index b3ef0e2ebb236..8ee5b937e10fb 100644 --- a/projects/plugins/jetpack/class.jetpack-gutenberg.php +++ b/projects/plugins/jetpack/class.jetpack-gutenberg.php @@ -705,9 +705,10 @@ public static function enqueue_block_editor_assets() { if ( Jetpack::is_module_active( 'publicize' ) && function_exists( 'publicize_init' ) ) { $publicize = publicize_init(); $initial_state['social'] = array( - 'sharesData' => $publicize->get_publicize_shares_info( $blog_id ), - 'hasPaidPlan' => $publicize->has_paid_plan(), - 'isEnhancedPublishingEnabled' => $publicize->is_enhanced_publishing_enabled( $blog_id ), + 'sharesData' => $publicize->get_publicize_shares_info( $blog_id ), + 'hasPaidPlan' => $publicize->has_paid_plan(), + 'isEnhancedPublishingEnabled' => $publicize->is_enhanced_publishing_enabled( $blog_id ), + 'isSocialImageGeneratorEnabled' => $publicize->is_social_image_generator_enabled( $blog_id ), ); } diff --git a/projects/plugins/jetpack/composer.lock b/projects/plugins/jetpack/composer.lock index 7ca9afa7aef26..8050c9780ad59 100644 --- a/projects/plugins/jetpack/composer.lock +++ b/projects/plugins/jetpack/composer.lock @@ -1758,7 +1758,7 @@ "dist": { "type": "path", "url": "../../packages/publicize", - "reference": "d1d63872b7e42b99436423077f9de620cceacf65" + "reference": "85b040fdaf32308620cf7db7268d782e96815504" }, "require": { "automattic/jetpack-assets": "@dev", @@ -1781,7 +1781,7 @@ "link-template": "https://github.com/Automattic/jetpack-publicize/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "0.19.x-dev" + "dev-trunk": "0.20.x-dev" } }, "autoload": { diff --git a/projects/plugins/social/changelog/add-social-image-generator-feature-flag b/projects/plugins/social/changelog/add-social-image-generator-feature-flag new file mode 100644 index 0000000000000..8604656b25c53 --- /dev/null +++ b/projects/plugins/social/changelog/add-social-image-generator-feature-flag @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Add Social Image Generator feature flag to Jetpack Social diff --git a/projects/plugins/social/changelog/add-social-image-generator-feature-flag#2 b/projects/plugins/social/changelog/add-social-image-generator-feature-flag#2 new file mode 100644 index 0000000000000..9aa70e3ec1f75 --- /dev/null +++ b/projects/plugins/social/changelog/add-social-image-generator-feature-flag#2 @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Updated composer.lock. + + diff --git a/projects/plugins/social/composer.json b/projects/plugins/social/composer.json index ca254e5af5fea..3512f62a3909f 100644 --- a/projects/plugins/social/composer.json +++ b/projects/plugins/social/composer.json @@ -78,6 +78,6 @@ "automattic/jetpack-autoloader": true, "automattic/jetpack-composer-plugin": true }, - "autoloader-suffix": "c4802e05bbcf59fd3b6350e8d3e5482c_socialⓥ1_7_1_alpha" + "autoloader-suffix": "c4802e05bbcf59fd3b6350e8d3e5482c_socialⓥ1_8_0_alpha" } } diff --git a/projects/plugins/social/composer.lock b/projects/plugins/social/composer.lock index decfe503360aa..41d18573514a6 100644 --- a/projects/plugins/social/composer.lock +++ b/projects/plugins/social/composer.lock @@ -1012,7 +1012,7 @@ "dist": { "type": "path", "url": "../../packages/publicize", - "reference": "d1d63872b7e42b99436423077f9de620cceacf65" + "reference": "85b040fdaf32308620cf7db7268d782e96815504" }, "require": { "automattic/jetpack-assets": "@dev", @@ -1035,7 +1035,7 @@ "link-template": "https://github.com/Automattic/jetpack-publicize/compare/v${old}...v${new}" }, "branch-alias": { - "dev-trunk": "0.19.x-dev" + "dev-trunk": "0.20.x-dev" } }, "autoload": { diff --git a/projects/plugins/social/jetpack-social.php b/projects/plugins/social/jetpack-social.php index 1d6216306e265..8ed78c6897343 100644 --- a/projects/plugins/social/jetpack-social.php +++ b/projects/plugins/social/jetpack-social.php @@ -4,7 +4,7 @@ * Plugin Name: Jetpack Social * Plugin URI: https://wordpress.org/plugins/jetpack-social * Description: Share your site’s posts on several social media networks automatically when you publish a new post. - * Version: 1.7.1-alpha + * Version: 1.8.0-alpha * Author: Automattic - Jetpack Social team * Author URI: https://jetpack.com/social/ * License: GPLv2 or later diff --git a/projects/plugins/social/src/class-jetpack-social.php b/projects/plugins/social/src/class-jetpack-social.php index 38f59bca38194..588844f12e0bb 100644 --- a/projects/plugins/social/src/class-jetpack-social.php +++ b/projects/plugins/social/src/class-jetpack-social.php @@ -296,17 +296,18 @@ class_exists( 'Jetpack' ) || array( 'siteFragment' => ( new Status() )->get_site_suffix(), 'social' => array( - 'adminUrl' => esc_url_raw( admin_url( 'admin.php?page=jetpack-social' ) ), - 'sharesData' => $publicize->get_publicize_shares_info( Jetpack_Options::get_option( 'id' ) ), - 'reviewRequestDismissed' => self::is_review_request_dismissed(), - 'dismissReviewRequestPath' => '/jetpack/v4/social/review-dismiss', - 'connectionRefreshPath' => '/jetpack/v4/publicize/connection-test-results', - 'resharePath' => '/jetpack/v4/publicize/{postId}', - 'publicizeConnectionsUrl' => esc_url_raw( + 'adminUrl' => esc_url_raw( admin_url( 'admin.php?page=jetpack-social' ) ), + 'sharesData' => $publicize->get_publicize_shares_info( Jetpack_Options::get_option( 'id' ) ), + 'reviewRequestDismissed' => self::is_review_request_dismissed(), + 'dismissReviewRequestPath' => '/jetpack/v4/social/review-dismiss', + 'connectionRefreshPath' => '/jetpack/v4/publicize/connection-test-results', + 'resharePath' => '/jetpack/v4/publicize/{postId}', + 'publicizeConnectionsUrl' => esc_url_raw( 'https://jetpack.com/redirect/?source=jetpack-social-connections-block-editor&site=' ), - 'hasPaidPlan' => $publicize->has_paid_plan(), - 'isEnhancedPublishingEnabled' => $publicize->is_enhanced_publishing_enabled( Jetpack_Options::get_option( 'id' ) ), + 'hasPaidPlan' => $publicize->has_paid_plan(), + 'isEnhancedPublishingEnabled' => $publicize->is_enhanced_publishing_enabled( Jetpack_Options::get_option( 'id' ) ), + 'isSocialImageGeneratorEnabled' => $publicize->is_social_image_generator_enabled( Jetpack_Options::get_option( 'id' ) ), ), ) ); From 79574e3cfe46ff494363d74d199eee3efacee088 Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Tue, 21 Feb 2023 12:30:37 +0100 Subject: [PATCH 49/51] Admin Page: use external link icon for jetpack app link in card (#29048) --- .../jetpack/_inc/client/components/apps-card/index.jsx | 5 ++--- .../jetpack/changelog/fix-external-link-jetpack-app-card | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 projects/plugins/jetpack/changelog/fix-external-link-jetpack-app-card diff --git a/projects/plugins/jetpack/_inc/client/components/apps-card/index.jsx b/projects/plugins/jetpack/_inc/client/components/apps-card/index.jsx index fdc705b7d3892..ebd321c093494 100644 --- a/projects/plugins/jetpack/_inc/client/components/apps-card/index.jsx +++ b/projects/plugins/jetpack/_inc/client/components/apps-card/index.jsx @@ -1,5 +1,6 @@ import { imagePath } from 'constants/urls'; import { getRedirectUrl } from '@automattic/jetpack-components'; +import { ExternalLink } from '@wordpress/components'; import { createInterpolateElement } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import classNames from 'classnames'; @@ -78,11 +79,9 @@ class AppsCard extends React.Component { ), { a: ( -
    ), diff --git a/projects/plugins/jetpack/changelog/fix-external-link-jetpack-app-card b/projects/plugins/jetpack/changelog/fix-external-link-jetpack-app-card new file mode 100644 index 0000000000000..ee4e8eb04d4cc --- /dev/null +++ b/projects/plugins/jetpack/changelog/fix-external-link-jetpack-app-card @@ -0,0 +1,4 @@ +Significance: patch +Type: other + +Admin Page: update link in Jetpack App card to include external link icon. From ca78ea5d1d878122210db5ee539c0890d15a706d Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Tue, 21 Feb 2023 07:16:04 -0500 Subject: [PATCH 50/51] tools: Allow selecting more than one but not all plugins in create-release-branch.sh (#29058) Turns out this is something we're going to be doing a lot, releasing Jetpack and mu-wpcom-plugin but not Backup or Social. So now we can either list multiple plugins on the command line or be prompted for each candidate plugin if only one is supplied. Also, update the bash version check to require 4.3 (released 9 years ago) instead of just 4.0, as this uses "unset" which was introduced in that version. --- tools/check-development-environment.sh | 4 +- tools/create-release-branch.sh | 60 +++++++++++++++++++----- tools/includes/check-osx-bash-version.sh | 4 +- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/tools/check-development-environment.sh b/tools/check-development-environment.sh index 0095504c735e4..089e2c3ea7ce2 100755 --- a/tools/check-development-environment.sh +++ b/tools/check-development-environment.sh @@ -137,10 +137,10 @@ echo "===========" echo "" checking 'Usable version of bash' -if [[ -n "${BASH_VERSINFO}" && -n "${BASH_VERSINFO[0]}" && ${BASH_VERSINFO[0]} -ge 4 ]]; then +if [[ -n "${BASH_VERSINFO}" && -n "${BASH_VERSINFO[0]}" && ( ${BASH_VERSINFO[0]} -gt 4 || ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -ge 3 ) ]]; then success "ok (version $BASH_VERSION)" else - failure "too old" '' "Bash at $BASH is $BASH_VERSION. Version 4 or later is required." "If you're on Mac OS, you can install an updated version of bash with ${CS}brew install bash${CE}" + failure "too old" '' "Bash at $BASH is $BASH_VERSION. Version 4.3 or later is required." "If you're on Mac OS, you can install an updated version of bash with ${CS}brew install bash${CE}" fi checking "Standard tools are available" diff --git a/tools/create-release-branch.sh b/tools/create-release-branch.sh index 71be2070b0208..8968098c4eda8 100755 --- a/tools/create-release-branch.sh +++ b/tools/create-release-branch.sh @@ -14,12 +14,12 @@ BASE=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) # Instructions function usage { cat <<-EOH - usage: $0 [options] [] + usage: $0 [options] [] Create a new release branch for the specified prefix or plugin. - The should be a release branch prefix used by at least one - monorepo plugin, but may also be the name of a directory in projects/plugins/ - or a path to a plugin directory or file. + The should be a release branch prefix used by at least one + monorepo plugin, but may also be the name of one or more directories in + projects/plugins/ or paths to plugin directories or files. If no is specified (and we're not non-interactive), you will be prompted. You'll also be prompted if more than one plugin matches the prefix. @@ -60,10 +60,19 @@ if $INTERACTIVE && [[ ! -t 0 ]]; then debug "Input is not a terminal, forcing --non-interactive." INTERACTIVE=false fi -if [[ ${#ARGS[@]} -ne 1 && ${#ARGS[@]} -ne 2 ]]; then +if [[ ${#ARGS[@]} -lt 1 ]]; then usage fi +VERARG= +if [[ ${#ARGS[@]} -gt 1 ]]; then + normalize_version_number "${ARGS[-1]}" + if [[ "$NORMALIZED_VERSION" =~ ^[0-9]+(\.[0-9]+)+(-.*)?$ ]]; then + VERARG=${ARGS[-1]} + unset 'ARGS[-1]' + fi +fi + # Collect available prefixes declare -A PREFIXES TMP=$(jq -r '.extra["release-branch-prefix"] // empty | [ ., input_filename ] | @tsv' "$BASE"/projects/plugins/*/composer.json) @@ -72,7 +81,7 @@ while IFS=$'\t' read -r prefix file; do done <<<"$TMP" # If is a known prefix, use the corresponding plugins. Otherwise, process it as a plugin arg. -if [[ -n "${PREFIXES[${ARGS[0]}]}" ]]; then +if [[ ${#ARGS[@]} -eq 1 && -n "${PREFIXES[${ARGS[0]}]}" ]]; then PREFIX=${ARGS[0]} mapfile -t DIRS <<<"${PREFIXES[$PREFIX]}" else @@ -84,14 +93,41 @@ else fi DIRS=( "$PLUGIN_DIR" ) - if [[ "${PREFIXES[$PREFIX]}" == *$'\n'* ]]; then + if [[ ${#ARGS[@]} -gt 1 ]]; then + process_plugin_arg "${ARGS[0]}" + PLUGIN_NAME=$(jq --arg n "${ARGS[0]}" -r '.name // $n' "$PLUGIN_DIR/composer.json") + PREFIX=$(jq -r '.extra["release-branch-prefix"] // ""' "$PLUGIN_DIR/composer.json") + if [[ -z "$PREFIX" ]]; then + die "Plugin $PLUGIN_NAME does not have a release branch prefix defined in composer.json. Aborting." + fi + DIRS=( "$PLUGIN_DIR" ) + + for ARG in "${ARGS[@]:1}"; do + process_plugin_arg "$ARG" + PLUGIN_NAME2=$(jq --arg n "${ARGS[0]}" -r '.name // $n' "$PLUGIN_DIR/composer.json") + PREFIX2=$(jq -r '.extra["release-branch-prefix"] // ""' "$PLUGIN_DIR/composer.json") + if [[ "$PREFIX" != "$PREFIX2" ]]; then + die "Plugin $PLUGIN_NAME2 does not use the same prefix as $PLUGIN_NAME ($PREFIX != $PREFIX2). Aborting." + fi + DIRS+=( "$PLUGIN_DIR" ) + done + elif [[ "${PREFIXES[$PREFIX]}" == *$'\n'* ]]; then info "Plugin $PLUGIN_NAME uses prefix $PREFIX, which is used in multiple plugins:" echo " ${PREFIXES[$PREFIX]//$'\n'/$'\n '}" # shellcheck disable=SC2310 if proceed_p '' 'Release all these plugins?'; then mapfile -t DIRS <<<"${PREFIXES[$PREFIX]}" else - proceed_p ' ' "Release only $PLUGIN_NAME?" + mapfile -t ASK <<<"${PREFIXES[$PREFIX]}" + for DIR in "${ASK[@]}"; do + if [[ "$DIR" != "$PLUGIN_DIR" ]] && proceed_p ' ' "Release ${DIR#"$BASE/projects/"} too?"; then + DIRS+=( "$DIR" ) + fi + done + echo '' + echo 'Selected plugins:' + printf " %s\n" "${DIRS[@]}" + proceed_p '' "Release these plugins?" fi fi fi @@ -154,13 +190,13 @@ function check_ver { return 0 } VERSIONS=() -if [[ -n "${ARGS[1]}" && ${#DIRS[@]} -gt 1 ]]; then +if [[ -n "$VERARG" && ${#DIRS[@]} -gt 1 ]]; then debug "Ignoring specified version since more than one plugin matches." - ARGS[1]= + VERARG= fi -if [[ -n "${ARGS[1]}" ]]; then +if [[ -n "$VERARG" ]]; then # Check the version. - check_ver "${ARGS[1]}" 0 + check_ver "$VERARG" 0 info "Using version number $NORMALIZED_VERSION for plugin ${NAMES[0]}" VERSIONS+=( "$NORMALIZED_VERSION" ) else diff --git a/tools/includes/check-osx-bash-version.sh b/tools/includes/check-osx-bash-version.sh index d3fef5fb65735..428cab2a0fbb4 100644 --- a/tools/includes/check-osx-bash-version.sh +++ b/tools/includes/check-osx-bash-version.sh @@ -4,12 +4,12 @@ # like the one above, because poor OS X users will have the new bash at # /usr/local/bin/bash instead of /bin/bash like the rest of the world expects. -if [[ -z "${BASH_VERSINFO}" || -z "${BASH_VERSINFO[0]}" || ${BASH_VERSINFO[0]} -lt 4 ]]; then +if [[ -z "${BASH_VERSINFO}" || -z "${BASH_VERSINFO[0]}" || ${BASH_VERSINFO[0]} -lt 4 || ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 3 ]]; then . "$(dirname "$BASH_SOURCE[0]")/chalk-lite.sh" [[ "$BASH_VERSION" ]] && V=" You have $BASH_VERSION." || V= error <<-EOM - This script requires Bash version >= 4.$V + This script requires Bash version >= 4.3.$V If you're on Mac OS, you can install an updated version of bash with brew install bash From bc5e94b2649b0c093ec09375d93d3a680321e892 Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Tue, 21 Feb 2023 13:22:13 +0100 Subject: [PATCH 51/51] Protect: remove example full path from UI (#29037) --- .../plugins/protect/changelog/fix-protect-example-standalone | 4 ++++ .../protect/src/js/components/standalone-mode-modal/index.jsx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 projects/plugins/protect/changelog/fix-protect-example-standalone diff --git a/projects/plugins/protect/changelog/fix-protect-example-standalone b/projects/plugins/protect/changelog/fix-protect-example-standalone new file mode 100644 index 0000000000000..0d4fee6a164c4 --- /dev/null +++ b/projects/plugins/protect/changelog/fix-protect-example-standalone @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Admin: remove example full path from example in UI diff --git a/projects/plugins/protect/src/js/components/standalone-mode-modal/index.jsx b/projects/plugins/protect/src/js/components/standalone-mode-modal/index.jsx index 16a3f29a752d7..520eed1fe28d2 100644 --- a/projects/plugins/protect/src/js/components/standalone-mode-modal/index.jsx +++ b/projects/plugins/protect/src/js/components/standalone-mode-modal/index.jsx @@ -20,7 +20,7 @@ const StandaloneModeModal = () => { { createInterpolateElement( __( - 'To ensure the firewall can best protect your site, please update: auto_prepend_file PHP directive to point to src/users/user66501445/public/wp-content/jetpack-waf/bootstrap.php Typically this is set either in an .htaccess file or in the global PHP configuration; contact your host for further assistance.', + 'To ensure the firewall can best protect your site, please update: auto_prepend_file PHP directive to point to wp-content/jetpack-waf/bootstrap.php Typically this is set either in an .htaccess file or in the global PHP configuration; contact your host for further assistance.', 'jetpack-protect' ), {