From f52f223ae2f9115e4dbbfb58b6b513da83953c75 Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Wed, 18 Dec 2024 12:26:10 +0200 Subject: [PATCH 01/45] Remove duplicate views: Fix the Stats and Promote with blaze pages (#40630) * Fix the Stats and Promote with blaze pages * Update fix-wp-admin-post-fixes Update the comment --- .../jetpack-mu-wpcom/changelog/fix-wp-admin-post-fixes | 5 +++++ .../features/wpcom-admin-interface/wpcom-admin-interface.php | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 projects/packages/jetpack-mu-wpcom/changelog/fix-wp-admin-post-fixes diff --git a/projects/packages/jetpack-mu-wpcom/changelog/fix-wp-admin-post-fixes b/projects/packages/jetpack-mu-wpcom/changelog/fix-wp-admin-post-fixes new file mode 100644 index 0000000000000..bbf2e7375d50c --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/changelog/fix-wp-admin-post-fixes @@ -0,0 +1,5 @@ +Significance: patch +Type: fixed +Comment: Fix the stats and promote with blaze quicklinks in edit.php for Simple sites that are part of the remove duplicate views experiment + + diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/wpcom-admin-interface.php b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/wpcom-admin-interface.php index 6f366cd924c11..fb7af7b332ac0 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/wpcom-admin-interface.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/wpcom-admin-interface.php @@ -118,6 +118,8 @@ function ( $location ) { const WPCOM_DUPLICATED_VIEW = array( 'edit.php', + 'admin.php?page=stats', + 'tools.php?page=advertising', 'edit.php?post_type=jetpack-portfolio', 'edit.php?post_type=jetpack-testimonial', 'edit-tags.php?taxonomy=category', From 64ab237e7488de4ca2656951bc66314a05351a9a Mon Sep 17 00:00:00 2001 From: Karen Attfield Date: Wed, 18 Dec 2024 15:28:33 +0000 Subject: [PATCH 02/45] Photon: Ensure VIP site are correctly identified within isVIP. (#39941) Co-authored-by: Sergey Mitroshin --- .../jetpack/changelog/fix-photon-on-vip | 4 ++++ .../jetpack/class.jetpack-gutenberg.php | 4 ++++ .../blocks/tiled-gallery/tiled-gallery.php | 3 ++- .../blocks/tiled-gallery/utils/index.js | 21 +++++++++++++++++-- 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 projects/plugins/jetpack/changelog/fix-photon-on-vip diff --git a/projects/plugins/jetpack/changelog/fix-photon-on-vip b/projects/plugins/jetpack/changelog/fix-photon-on-vip new file mode 100644 index 0000000000000..5d205154e23f6 --- /dev/null +++ b/projects/plugins/jetpack/changelog/fix-photon-on-vip @@ -0,0 +1,4 @@ +Significance: patch +Type: other + +Photon: Ensure VIP sites are correctly identified, to prevent unnecessary early Photonization of URLs. diff --git a/projects/plugins/jetpack/class.jetpack-gutenberg.php b/projects/plugins/jetpack/class.jetpack-gutenberg.php index ee8d7ddb4e3cc..aede14da9b1e1 100644 --- a/projects/plugins/jetpack/class.jetpack-gutenberg.php +++ b/projects/plugins/jetpack/class.jetpack-gutenberg.php @@ -715,6 +715,7 @@ public static function enqueue_block_editor_assets() { $modules = $module_list_endpoint->get_modules(); } + $jetpack_plan = Jetpack_Plan::get(); $initial_state = array( 'available_blocks' => self::get_availability(), 'blocks_variation' => $blocks_variation, @@ -731,6 +732,9 @@ public static function enqueue_block_editor_assets() { // this is the equivalent of JP initial state siteData.showMyJetpack (class-jetpack-redux-state-helper) // used to determine if we can link to My Jetpack from the block editor 'is_my_jetpack_available' => My_Jetpack_Initializer::should_initialize(), + 'jetpack_plan' => array( + 'data' => $jetpack_plan['product_slug'], + ), /** * Enable the RePublicize UI in the block editor context. * diff --git a/projects/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php b/projects/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php index 3be4604368cef..33b925fc2f0f5 100644 --- a/projects/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php +++ b/projects/plugins/jetpack/extensions/blocks/tiled-gallery/tiled-gallery.php @@ -58,7 +58,8 @@ public static function render( $attr, $content ) { Jetpack_Gutenberg::load_assets_as_required( __DIR__ ); $is_squareish_layout = self::is_squareish_layout( $attr ); - + // For backward compatibility (ensuring Tiled Galleries using now deprecated versions of the block are not affected). + // See isVIP() in utils/index.js. $jetpack_plan = Jetpack_Plan::get(); wp_localize_script( 'jetpack-gallery-settings', 'jetpack_plan', array( 'data' => $jetpack_plan['product_slug'] ) ); diff --git a/projects/plugins/jetpack/extensions/blocks/tiled-gallery/utils/index.js b/projects/plugins/jetpack/extensions/blocks/tiled-gallery/utils/index.js index 9a4e4f2ac3c6e..3de6ec8bdd0df 100644 --- a/projects/plugins/jetpack/extensions/blocks/tiled-gallery/utils/index.js +++ b/projects/plugins/jetpack/extensions/blocks/tiled-gallery/utils/index.js @@ -4,11 +4,23 @@ import { isSimpleSite, } from '@automattic/jetpack-shared-extension-utils'; import { isBlobURL } from '@wordpress/blob'; +import { select } from '@wordpress/data'; import { range } from 'lodash'; import photon from 'photon'; import isOfflineMode from '../../../shared/is-offline-mode'; import { PHOTON_MAX_RESIZE } from '../constants'; +let jetpackPlanFromState; + +window.addEventListener( 'load', function () { + const hasImageCompare = select( 'core/block-editor' ) + .getBlocks() + .some( block => block.name === 'jetpack/image-compare' ); + if ( hasImageCompare && ! jetpackPlanFromState ) { + jetpackPlanFromState = window?.Jetpack_Editor_Initial_State?.jetpack?.jetpack_plan; + } +} ); + export function isSquareishLayout( layout ) { return [ 'circle', 'square' ].includes( layout ); } @@ -112,9 +124,14 @@ export function photonizedImgProps( img, galleryAtts = {} ) { } function isVIP() { /*global jetpack_plan*/ - if ( typeof jetpack_plan !== 'undefined' && jetpack_plan.data === 'vip' ) { - return true; + // Use `jetpackPlanFromState` if available, otherwise fall back to `jetpack_plan` defined within the render function in tiled-gallery.php. + let jetpackPlan; + if ( typeof jetpackPlanFromState !== 'undefined' ) { + jetpackPlan = jetpackPlanFromState; + } else if ( typeof jetpack_plan !== 'undefined' ) { + jetpackPlan = jetpack_plan; } + return jetpackPlan && jetpackPlan?.data === 'vip'; } /** From 829b8dc6b330ada0ceec66f9236d31721375542b Mon Sep 17 00:00:00 2001 From: Karen Attfield Date: Wed, 18 Dec 2024 15:28:51 +0000 Subject: [PATCH 03/45] Restaurant Menu CPT: Replace most jQuery with Javascript (#40645) --- .../changelog/update-nova-cpt-jquery-to-js | 4 + .../custom-post-types/js/many-items.js | 207 ++++++++++-------- .../custom-post-types/js/menu-checkboxes.js | 67 ++++-- .../modules/custom-post-types/nova.php | 4 +- 4 files changed, 173 insertions(+), 109 deletions(-) create mode 100644 projects/plugins/jetpack/changelog/update-nova-cpt-jquery-to-js diff --git a/projects/plugins/jetpack/changelog/update-nova-cpt-jquery-to-js b/projects/plugins/jetpack/changelog/update-nova-cpt-jquery-to-js new file mode 100644 index 0000000000000..a3ef11151211c --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-nova-cpt-jquery-to-js @@ -0,0 +1,4 @@ +Significance: patch +Type: other + +Restaurant Menu CPT: Convert much of the jQuery usage to JavaScript diff --git a/projects/plugins/jetpack/modules/custom-post-types/js/many-items.js b/projects/plugins/jetpack/modules/custom-post-types/js/many-items.js index 09c7ad911f091..4a3903dc04a05 100644 --- a/projects/plugins/jetpack/modules/custom-post-types/js/many-items.js +++ b/projects/plugins/jetpack/modules/custom-post-types/js/many-items.js @@ -1,111 +1,144 @@ -( function ( $ ) { - var menuSelector, nonceInput, methods; - - methods = { - init: function ( /*options*/ ) { - var $this = this, - tbody, - row; - - this.on( 'keypress.manyItemsTable', function ( event ) { - if ( 13 !== event.which ) { - return; - } +( function () { + let menuSelector, nonceInput; + const initializedTables = new Set(); + + const methods = { + init: function ( table ) { + let tbody = table.lastElementChild; + while ( tbody && tbody.tagName !== 'TBODY' ) { + tbody = tbody.previousElementSibling; + } + const row = tbody.querySelector( 'tr:first-child' ).cloneNode( true ); + + table.dataset.form = table.closest( 'form' ); + table.dataset.tbody = tbody; + table.dataset.row = row; + table.dataset.currentRow = row; + + menuSelector = document.getElementById( 'nova-menu-tax' ); + nonceInput = document.getElementById( '_wpnonce' ); + + table.addEventListener( 'keypress', function ( event ) { + if ( event.which !== 13 ) return; event.preventDefault(); - if ( 'function' === typeof FormData ) { - methods.submitRow.apply( $this ); + if ( typeof FormData === 'function' ) { + methods.submitRow.call( table ); } - methods.addRow.apply( $this ); - } ).on( 'focus.manyItemsTable', ':input', function ( /*event*/ ) { - $this.data( 'currentRow', $( this ).parents( 'tr:first' ) ); + methods.addRow.call( table ); } ); - tbody = this.find( 'tbody:last' ); - row = tbody.find( 'tr:first' ).clone(); - - this.data( 'form', this.parents( 'form:first' ) ); - this.data( 'tbody', tbody ); - this.data( 'row', row ); - this.data( 'currentRow', row ); - - menuSelector = $( '#nova-menu-tax' ); - nonceInput = $( '#_wpnonce' ); + table.addEventListener( 'focusin', function ( event ) { + if ( event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA' ) { + table.dataset.currentRow = event.target.closest( 'tr' ); + } + } ); - return this; + initializedTables.add( table ); + return table; }, - destroy: function () { - this.off( '.manyItemsTable' ); - - return this; + destroy: function ( table ) { + if ( this.observer ) { + this.observer.disconnect(); + } + table.removeEventListener( 'keypress', methods.keypressHandler ); + table.removeEventListener( 'focusin', methods.focusinHandler ); + initializedTables.delete( table ); + return table; }, - submitRow: function () { - var submittedRow, currentInputs, allInputs, partialFormData; + submitRow: function ( table ) { + const submittedRow = table.dataset.currentRow; + const currentInputs = submittedRow.querySelectorAll( 'input, textarea, select' ); + const form = document.querySelector( table.dataset.form ); + const allInputs = Array.from( form.querySelectorAll( 'input, textarea, select' ) ); - submittedRow = this.data( 'currentRow' ); - currentInputs = submittedRow.find( ':input' ); - allInputs = this.data( 'form' ) - .find( ':input' ) - .not( currentInputs ) - .attr( 'disabled', true ) - .end(); + currentInputs.forEach( input => ( input.disabled = true ) ); + allInputs + .filter( input => ! currentInputs.includes( input ) ) + .forEach( input => ( input.disabled = true ) ); - partialFormData = new FormData( this.data( 'form' ).get( 0 ) ); + const partialFormData = new FormData( form ); partialFormData.append( 'ajax', '1' ); - partialFormData.append( 'nova_menu_tax', menuSelector.val() ); - partialFormData.append( '_wpnonce', nonceInput.val() ); - - allInputs.attr( 'disabled', false ); - - $.ajax( { - url: '', - type: 'POST', - data: partialFormData, - processData: false, - contentType: false, - } ).complete( function ( xhr ) { - submittedRow.html( xhr.responseText ); - } ); + partialFormData.append( 'nova_menu_tax', menuSelector.value ); + partialFormData.append( '_wpnonce', nonceInput.value ); - currentInputs.attr( 'disabled', true ); + fetch( '', { + method: 'POST', + body: partialFormData, + } ) + .then( response => response.text() ) + .then( responseText => { + submittedRow.innerHTML = responseText; + } ); - return this; + allInputs.forEach( input => ( input.disabled = false ) ); + + return table; }, - addRow: function () { - var row = this.data( 'row' ).clone(); - row.appendTo( this.data( 'tbody' ) ); - row.find( ':input:first' ).focus(); + addRow: function ( table ) { + const row = table.dataset.row.cloneNode( true ); + + const tbody = table.dataset.tbody; + tbody.appendChild( row ); + + const firstInput = row.querySelector( 'input, textarea, select' ); + if ( firstInput ) firstInput.focus(); - return this; + return table; }, - }; - $.fn.manyItemsTable = function ( method ) { - // Method calling logic - if ( methods[ method ] ) { - return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ) ); - } else if ( typeof method === 'object' || ! method ) { - return methods.init.apply( this, arguments ); - } - $.error( 'Method ' + method + ' does not exist on jQuery.manyItemsTable' ); - return this; + clickAddRow: function ( table ) { + let tbody = table.lastElementChild; + + while ( tbody && tbody.tagName !== 'TBODY' ) { + tbody = tbody.previousElementSibling; + } + const row = tbody.querySelector( 'tr:first-child' ).cloneNode( true ); + + row.querySelectorAll( 'input, textarea' ).forEach( input => { + input.value = ''; + } ); + + tbody.appendChild( row ); + }, }; - $.fn.clickAddRow = function () { - var tbody = this.find( 'tbody:last' ), - row = tbody.find( 'tr:first' ).clone(); + const observeTableRemoval = function ( list ) { + const observer = new MutationObserver( mutations => { + mutations.forEach( mutation => { + mutation.removedNodes.forEach( node => { + if ( node.matches && node.matches( '.many-items-table' ) ) { + methods.destroy( node ); + } + } ); + } ); + } ); - $( row ).find( 'input, textarea' ).val( '' ); - $( row ).appendTo( tbody ); + observer.observe( list, { childList: true, subtree: true } ); }; -} )( jQuery ); - -jQuery( '.many-items-table' ).one( 'focus', ':input', function ( event ) { - jQuery( event.delegateTarget ).manyItemsTable(); -} ); -jQuery( '.many-items-table' ).on( 'click', 'a.nova-new-row', function ( event ) { - jQuery( event.delegateTarget ).clickAddRow(); -} ); + + // Initialization for many-items-table + document.addEventListener( 'focusin', event => { + const table = event.target.closest( '.many-items-table' ); + if ( table && ! initializedTables.has( table ) ) { + methods.init( table ); + } + } ); + + document.addEventListener( 'click', event => { + if ( event.target.matches( 'a.nova-new-row' ) ) { + const table = event.target.closest( '.many-items-table' ); + if ( table ) { + event.preventDefault(); + methods.clickAddRow( table ); + } + } + } ); + const list = document.querySelector( '#the-list' ); // Scope to the specific table + if ( list ) { + observeTableRemoval( list ); + } +} )(); diff --git a/projects/plugins/jetpack/modules/custom-post-types/js/menu-checkboxes.js b/projects/plugins/jetpack/modules/custom-post-types/js/menu-checkboxes.js index b422eff4e24eb..ed3418d76ccdf 100644 --- a/projects/plugins/jetpack/modules/custom-post-types/js/menu-checkboxes.js +++ b/projects/plugins/jetpack/modules/custom-post-types/js/menu-checkboxes.js @@ -1,48 +1,75 @@ -( function ( $ ) { - var NovaCheckBoxes = { +( function () { + const NovaCheckBoxes = { inputs: null, popInputs: null, initialize: function () { - NovaCheckBoxes.popInputs = $( '#nova_menuchecklist-pop' ).find( ':checkbox' ); + // Get all checkboxes in the "nova_menuchecklist-pop" + NovaCheckBoxes.popInputs = document.querySelectorAll( + '#nova_menuchecklist-pop input[type="checkbox"]' + ); - NovaCheckBoxes.inputs = $( '#nova_menuchecklist' ) - .find( ':checkbox' ) - .change( NovaCheckBoxes.checkOne ) - .change( NovaCheckBoxes.syncPop ); + // Get all checkboxes in the "nova_menuchecklist" and add event listeners + NovaCheckBoxes.inputs = document.querySelectorAll( + '#nova_menuchecklist input[type="checkbox"]' + ); + NovaCheckBoxes.inputs.forEach( input => { + input.addEventListener( 'change', NovaCheckBoxes.checkOne ); + input.addEventListener( 'change', NovaCheckBoxes.syncPop ); + } ); + // If no checkboxes are checked, check the first one if ( ! NovaCheckBoxes.isChecked() ) { NovaCheckBoxes.checkFirst(); } + // Sync the state of the "pop" inputs NovaCheckBoxes.syncPop(); }, syncPop: function () { - NovaCheckBoxes.popInputs.each( function () { - var $this = $( this ); - $this.prop( 'checked', $( '#in-nova_menu-' + $this.val() ).is( ':checked' ) ); + NovaCheckBoxes.popInputs.forEach( popInput => { + const linkedInput = document.querySelector( `#in-nova_menu-${ popInput.value }` ); + popInput.checked = linkedInput ? linkedInput.checked : false; } ); }, isChecked: function () { - return NovaCheckBoxes.inputs.is( ':checked' ); + return Array.from( NovaCheckBoxes.inputs ).some( input => input.checked ); }, checkFirst: function () { - NovaCheckBoxes.inputs.first().prop( 'checked', true ); + const firstInput = NovaCheckBoxes.inputs[ 0 ]; + if ( firstInput ) { + firstInput.checked = true; + } }, - checkOne: function ( /*event*/ ) { - if ( $( this ).is( ':checked' ) ) { - return NovaCheckBoxes.inputs.not( this ).prop( 'checked', false ); + checkOne: function () { + const currentInput = this; + + // If the current checkbox is checked, uncheck all other checkboxes + if ( currentInput.checked ) { + NovaCheckBoxes.inputs.forEach( input => { + if ( input !== currentInput ) { + input.checked = false; + } + } ); + return; } - if ( $( this ).closest( '#nova_menuchecklist' ).find( ':checked' ).length > 0 ) { - return $( this ).prop( 'checked', false ); + const checklist = document.querySelector( '#nova_menuchecklist' ); + + // If at least one checkbox is still checked, uncheck the current one + if ( checklist.querySelectorAll( 'input[type="checkbox"]:checked' ).length > 0 ) { + currentInput.checked = false; + return; } - return NovaCheckBoxes.checkFirst(); + + // Otherwise, check the first checkbox + NovaCheckBoxes.checkFirst(); }, }; - $( NovaCheckBoxes.initialize ); -} )( jQuery ); + // Initialize when the DOM is fully loaded + document.addEventListener( 'DOMContentLoaded', NovaCheckBoxes.initialize ); +} )(); diff --git a/projects/plugins/jetpack/modules/custom-post-types/nova.php b/projects/plugins/jetpack/modules/custom-post-types/nova.php index a5299f4c59fa3..69256670c29aa 100644 --- a/projects/plugins/jetpack/modules/custom-post-types/nova.php +++ b/projects/plugins/jetpack/modules/custom-post-types/nova.php @@ -584,7 +584,7 @@ public function add_admin_menus() { '_inc/build/custom-post-types/js/menu-checkboxes.min.js', 'modules/custom-post-types/js/menu-checkboxes.js' ), - array( 'jquery' ), + array(), $this->version, true ); @@ -1146,7 +1146,7 @@ public function enqueue_many_items_scripts() { '_inc/build/custom-post-types/js/many-items.min.js', 'modules/custom-post-types/js/many-items.js' ), - array( 'jquery' ), + array(), $this->version, true ); From 832e258dc6a097d7de53be27cb6db08a5ea7fc40 Mon Sep 17 00:00:00 2001 From: Ashar Fuadi Date: Wed, 18 Dec 2024 23:19:27 +0700 Subject: [PATCH 04/45] Gutenberg 19.8.0 hotfix: don't show the template-locked rendering mode for pages (#40664) This avoids triggering a bug in Gutenberg 19.8.0 which meant editor roles were unable to edit pages. --- .../changelog/hotfix-template-locked-bug | 4 ++++ .../src/class-jetpack-mu-wpcom.php | 1 + .../wpcom-hotfixes/wpcom-hotfixes.php | 20 +++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 projects/packages/jetpack-mu-wpcom/changelog/hotfix-template-locked-bug create mode 100644 projects/packages/jetpack-mu-wpcom/src/features/wpcom-hotfixes/wpcom-hotfixes.php diff --git a/projects/packages/jetpack-mu-wpcom/changelog/hotfix-template-locked-bug b/projects/packages/jetpack-mu-wpcom/changelog/hotfix-template-locked-bug new file mode 100644 index 0000000000000..d3c084bd1a72d --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/changelog/hotfix-template-locked-bug @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Gutenberg 19.8.0 hotfix: don't show the template-locked rendering mode for pages diff --git a/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php b/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php index a607b7e67d910..26cf4192d604a 100644 --- a/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php +++ b/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php @@ -111,6 +111,7 @@ public static function load_features() { require_once __DIR__ . '/features/wpcom-admin-dashboard/wpcom-admin-dashboard.php'; require_once __DIR__ . '/features/wpcom-block-editor/class-jetpack-wpcom-block-editor.php'; require_once __DIR__ . '/features/wpcom-block-editor/functions.editor-type.php'; + require_once __DIR__ . '/features/wpcom-hotfixes/wpcom-hotfixes.php'; require_once __DIR__ . '/features/wpcom-logout/wpcom-logout.php'; require_once __DIR__ . '/features/wpcom-themes/wpcom-theme-fixes.php'; diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-hotfixes/wpcom-hotfixes.php b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-hotfixes/wpcom-hotfixes.php new file mode 100644 index 0000000000000..199033db6b7f5 --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-hotfixes/wpcom-hotfixes.php @@ -0,0 +1,20 @@ + Date: Wed, 18 Dec 2024 12:31:01 -0500 Subject: [PATCH 05/45] My Jetpack: Plans section- Paid plan expiration date improvements. (#40575) * My Jetpack: Fix & improve plans section expiry date. --- .../_inc/components/plans-section/index.tsx | 37 +++++++++++++++---- .../fix-mj-plans-section-expire-date | 4 ++ 2 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 projects/packages/my-jetpack/changelog/fix-mj-plans-section-expire-date diff --git a/projects/packages/my-jetpack/_inc/components/plans-section/index.tsx b/projects/packages/my-jetpack/_inc/components/plans-section/index.tsx index 0a7f47e1d3f04..b4b3aef6dba03 100644 --- a/projects/packages/my-jetpack/_inc/components/plans-section/index.tsx +++ b/projects/packages/my-jetpack/_inc/components/plans-section/index.tsx @@ -1,5 +1,5 @@ import { Text, H3, Title, Button } from '@automattic/jetpack-components'; -import { dateI18n } from '@wordpress/date'; +import { getDate, dateI18n } from '@wordpress/date'; import { __, _n, sprintf } from '@wordpress/i18n'; import clsx from 'clsx'; import { useCallback } from 'react'; @@ -40,8 +40,16 @@ const PlanSection: FC< PlanSectionProps > = ( { purchase } ) => { }; const PlanExpiry: FC< PlanSectionProps > = ( { purchase } ) => { - const { ID, expiry_date, expiry_status, product_name, product_slug, subscribed_date, domain } = - purchase; + const { + ID, + expiry_date, + expiry_status, + partner_name, + product_name, + product_slug, + subscribed_date, + domain, + } = purchase; const managePurchaseUrl = `https://wordpress.com/me/purchases/${ domain }/${ ID }`; const renewUrl = `https://wordpress.com/checkout/${ product_slug }/renew/${ ID }/${ domain }`; @@ -56,14 +64,19 @@ const PlanExpiry: FC< PlanSectionProps > = ( { purchase } ) => { } ); const expiryMessage = useCallback( () => { - const displayDate = dateI18n( 'F jS, Y', expiry_date ); + const hundredYearDate = getDate( subscribed_date ); + hundredYearDate.setFullYear( hundredYearDate.getFullYear() + 100 ); + + // If expiry_date is null, we'll default to 100 years in the future (same behavior in Store Admin). + const expiryDate = dateI18n( 'F jS, Y', expiry_date ?? hundredYearDate ); + if ( isExpiringPurchase ) { // Expiring soon if ( isExpiringSoon ) { return sprintf( // translators: %1$s is the formatted date to display, i.e.- November 24th, 2024 __( 'Expiring soon on %1$s', 'jetpack-my-jetpack' ), - displayDate + expiryDate ); } @@ -71,16 +84,24 @@ const PlanExpiry: FC< PlanSectionProps > = ( { purchase } ) => { return sprintf( // translators: %1$s is the formatted date to display, i.e.- November 24th, 2024 __( 'Expired on %1$s', 'jetpack-my-jetpack' ), - displayDate + expiryDate ); } + if ( ! expiry_date && partner_name ) { + // This means the subscription was provisioned by a hosting partner. + return sprintf( + // translators: %1$s is the name of the hosting partner. i.e.- Bluehost, InMotion, Pressable, Jurassic Ninja, etc.. + __( 'Managed by: %1$s', 'jetpack-my-jetpack' ), + partner_name + ); + } return sprintf( // translators: %1$s is the formatted date to display, i.e.- November 24th, 2024 __( 'Expires on %1$s', 'jetpack-my-jetpack' ), - displayDate + expiryDate ); - }, [ expiry_date, isExpiringPurchase, isExpiringSoon ] ); + }, [ expiry_date, isExpiringPurchase, isExpiringSoon, partner_name, subscribed_date ] ); const expiryAction = useCallback( () => { if ( ! isExpiringPurchase ) { diff --git a/projects/packages/my-jetpack/changelog/fix-mj-plans-section-expire-date b/projects/packages/my-jetpack/changelog/fix-mj-plans-section-expire-date new file mode 100644 index 0000000000000..06f2b73ed6726 --- /dev/null +++ b/projects/packages/my-jetpack/changelog/fix-mj-plans-section-expire-date @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +My Jetpack: Plans section: Improvements to how we display plan expiration date. From 21b4c4f00c460e8314ba58c7bdbbd702f1342bae Mon Sep 17 00:00:00 2001 From: Ian Ramos <5714212+IanRamosC@users.noreply.github.com> Date: Wed, 18 Dec 2024 15:54:14 -0300 Subject: [PATCH 06/45] My Jetpack: support features as recommendations (#40492) * My Jetpack: add feature as possible module recommendation * changelog * Add the module classes for the 3 features * Add config for feature modules * Refactor module product class * Fix PHAN errors --- .../changelog/add-feature-recommendations | 4 + .../my-jetpack/src/class-products.php | 38 ++-- .../src/products/class-module-product.php | 38 ++++ .../src/products/class-newsletter.php | 179 ++++++++++++++++++ .../src/products/class-related-posts.php | 179 ++++++++++++++++++ .../src/products/class-site-accelerator.php | 179 ++++++++++++++++++ 6 files changed, 600 insertions(+), 17 deletions(-) create mode 100644 projects/packages/my-jetpack/changelog/add-feature-recommendations create mode 100644 projects/packages/my-jetpack/src/products/class-newsletter.php create mode 100644 projects/packages/my-jetpack/src/products/class-related-posts.php create mode 100644 projects/packages/my-jetpack/src/products/class-site-accelerator.php diff --git a/projects/packages/my-jetpack/changelog/add-feature-recommendations b/projects/packages/my-jetpack/changelog/add-feature-recommendations new file mode 100644 index 0000000000000..700e01f03c9a4 --- /dev/null +++ b/projects/packages/my-jetpack/changelog/add-feature-recommendations @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +My Jetpack: add features as possible modules to the recommendations list. diff --git a/projects/packages/my-jetpack/src/class-products.php b/projects/packages/my-jetpack/src/class-products.php index 87e277dcae26a..8f8681fdb2ab8 100644 --- a/projects/packages/my-jetpack/src/class-products.php +++ b/projects/packages/my-jetpack/src/class-products.php @@ -119,24 +119,28 @@ class Products { */ public static function get_products_classes() { $classes = array( - 'anti-spam' => Products\Anti_Spam::class, - 'backup' => Products\Backup::class, - 'boost' => Products\Boost::class, - 'crm' => Products\Crm::class, - 'creator' => Products\Creator::class, - 'extras' => Products\Extras::class, - 'jetpack-ai' => Products\Jetpack_Ai::class, + 'anti-spam' => Products\Anti_Spam::class, + 'backup' => Products\Backup::class, + 'boost' => Products\Boost::class, + 'crm' => Products\Crm::class, + 'creator' => Products\Creator::class, + 'extras' => Products\Extras::class, + 'jetpack-ai' => Products\Jetpack_Ai::class, // TODO: Remove this duplicate class ('ai')? See: https://github.com/Automattic/jetpack/pull/35910#pullrequestreview-2456462227 - 'ai' => Products\Jetpack_Ai::class, - 'scan' => Products\Scan::class, - 'search' => Products\Search::class, - 'social' => Products\Social::class, - 'security' => Products\Security::class, - 'protect' => Products\Protect::class, - 'videopress' => Products\Videopress::class, - 'stats' => Products\Stats::class, - 'growth' => Products\Growth::class, - 'complete' => Products\Complete::class, + 'ai' => Products\Jetpack_Ai::class, + 'scan' => Products\Scan::class, + 'search' => Products\Search::class, + 'social' => Products\Social::class, + 'security' => Products\Security::class, + 'protect' => Products\Protect::class, + 'videopress' => Products\Videopress::class, + 'stats' => Products\Stats::class, + 'growth' => Products\Growth::class, + 'complete' => Products\Complete::class, + // Features + 'newsletter' => Products\Newsletter::class, + 'site-accelerator' => Products\Site_Accelerator::class, + 'related-posts' => Products\Related_Posts::class, ); /** diff --git a/projects/packages/my-jetpack/src/products/class-module-product.php b/projects/packages/my-jetpack/src/products/class-module-product.php index 5472cfec02e26..9d1a14f0fee86 100644 --- a/projects/packages/my-jetpack/src/products/class-module-product.php +++ b/projects/packages/my-jetpack/src/products/class-module-product.php @@ -7,6 +7,7 @@ namespace Automattic\Jetpack\My_Jetpack; +use Automattic\Jetpack\Connection\Manager as Connection_Manager; use Jetpack; use WP_Error; @@ -26,6 +27,13 @@ abstract class Module_Product extends Product { */ public static $module_name = null; + /** + * Whether this module is a Jetpack feature + * + * @var boolean + */ + public static $is_feature = false; + /** * Get the plugin slug - ovewrite it ans return Jetpack's * @@ -79,12 +87,42 @@ public static function is_module_active() { return Jetpack::is_module_active( static::$module_name ); } + /** + * Get the product status. + * We don't use parent::get_status() to avoid complexity. + * + * @return string Product status. + */ + private static function get_feature_status() { + if ( ! static::is_plugin_installed() ) { + return Products::STATUS_PLUGIN_ABSENT; + } + + if ( ! static::is_plugin_active() ) { + return Products::STATUS_INACTIVE; + } + + if ( static::$requires_user_connection && ! ( new Connection_Manager() )->has_connected_owner() ) { + return Products::STATUS_USER_CONNECTION_ERROR; + } + + if ( ! static::is_module_active() ) { + return Products::STATUS_MODULE_DISABLED; + } + + return Products::STATUS_ACTIVE; + } + /** * Gets the current status of the product * * @return string */ public static function get_status() { + if ( static::$is_feature ) { + return static::get_feature_status(); + } + $status = parent::get_status(); if ( Products::STATUS_INACTIVE === $status && ! static::is_module_active() ) { $status = Products::STATUS_MODULE_DISABLED; diff --git a/projects/packages/my-jetpack/src/products/class-newsletter.php b/projects/packages/my-jetpack/src/products/class-newsletter.php new file mode 100644 index 0000000000000..66d806d5ea6ca --- /dev/null +++ b/projects/packages/my-jetpack/src/products/class-newsletter.php @@ -0,0 +1,179 @@ + true, + 'is_free' => true, + ); + } + + /** + * Checks whether the Product is active. + * + * @return boolean + */ + public static function is_active() { + return static::is_jetpack_plugin_active(); + } + + /** + * Checks whether the plugin is installed + * + * @return boolean + */ + public static function is_plugin_installed() { + return static::is_jetpack_plugin_installed(); + } + + /** + * Get the URL where the user manages the product + * + * @return ?string + */ + public static function get_manage_url() { + return admin_url( 'admin.php?page=jetpack#/settings?term=newsletter' ); + } + + /** + * Activates the Jetpack plugin + * + * @return null|WP_Error Null on success, WP_Error on invalid file. + */ + public static function activate_plugin() { + $plugin_filename = static::get_installed_plugin_filename( self::JETPACK_PLUGIN_SLUG ); + + if ( $plugin_filename ) { + return activate_plugin( $plugin_filename ); + } + } +} diff --git a/projects/packages/my-jetpack/src/products/class-related-posts.php b/projects/packages/my-jetpack/src/products/class-related-posts.php new file mode 100644 index 0000000000000..e5b10ec989931 --- /dev/null +++ b/projects/packages/my-jetpack/src/products/class-related-posts.php @@ -0,0 +1,179 @@ + true, + 'is_free' => true, + ); + } + + /** + * Checks whether the Product is active. + * + * @return boolean + */ + public static function is_active() { + return static::is_jetpack_plugin_active(); + } + + /** + * Checks whether the plugin is installed + * + * @return boolean + */ + public static function is_plugin_installed() { + return static::is_jetpack_plugin_installed(); + } + + /** + * Get the URL where the user manages the product + * + * @return ?string + */ + public static function get_manage_url() { + return admin_url( 'admin.php?page=jetpack#/traffic?term=related%20posts' ); + } + + /** + * Activates the Jetpack plugin + * + * @return null|WP_Error Null on success, WP_Error on invalid file. + */ + public static function activate_plugin() { + $plugin_filename = static::get_installed_plugin_filename( self::JETPACK_PLUGIN_SLUG ); + + if ( $plugin_filename ) { + return activate_plugin( $plugin_filename ); + } + } +} diff --git a/projects/packages/my-jetpack/src/products/class-site-accelerator.php b/projects/packages/my-jetpack/src/products/class-site-accelerator.php new file mode 100644 index 0000000000000..42cda9bc8a798 --- /dev/null +++ b/projects/packages/my-jetpack/src/products/class-site-accelerator.php @@ -0,0 +1,179 @@ + true, + 'is_free' => true, + ); + } + + /** + * Checks whether the Product is active. + * + * @return boolean + */ + public static function is_active() { + return static::is_jetpack_plugin_active(); + } + + /** + * Checks whether the plugin is installed + * + * @return boolean + */ + public static function is_plugin_installed() { + return static::is_jetpack_plugin_installed(); + } + + /** + * Get the URL where the user manages the product + * + * @return ?string + */ + public static function get_manage_url() { + return admin_url( 'admin.php?page=jetpack#/settings?term=site%20accelerator' ); + } + + /** + * Activates the Jetpack plugin + * + * @return null|WP_Error Null on success, WP_Error on invalid file. + */ + public static function activate_plugin() { + $plugin_filename = static::get_installed_plugin_filename( self::JETPACK_PLUGIN_SLUG ); + + if ( $plugin_filename ) { + return activate_plugin( $plugin_filename ); + } + } +} From 3ed576dddb5ab6db78afe0202dfa2731ec45f68e Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Wed, 18 Dec 2024 15:12:18 -0500 Subject: [PATCH 07/45] ci: Check for use of SCSS `random()` (#40666) Normal CSS can't do random numbers. SCSS has a `random()` function, which produces random values in the output CSS. Unfortunately this makes the built CSS change for each build, which means that every PR merged will require a Simple deploy. To avoid this, add a CI check looking for calls to the function in all `.scss` files. Also do the same for `unique-id()`. --- .github/files/lint-project-structure.sh | 11 +++++++++++ .../changelog/update-no-scss-random | 4 ++++ .../src/features/holiday-snow/holiday-snow.scss | 14 +++++++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 projects/packages/jetpack-mu-wpcom/changelog/update-no-scss-random diff --git a/.github/files/lint-project-structure.sh b/.github/files/lint-project-structure.sh index 175f7e6c4575f..194bf66cd9d32 100755 --- a/.github/files/lint-project-structure.sh +++ b/.github/files/lint-project-structure.sh @@ -635,4 +635,15 @@ while IFS= read -r FILE; do done < <( git grep -h --line-number --column -o "$RE" "$FILE" ) done < <( git -c core.quotepath=off grep -l "$RE" ) +# - Check for `random(` in scss files. +debug "Checking for SCSS random." +while IFS= read -r FILE; do + EXIT=1 + while IFS=: read -r LINE COL X; do + X=${X%(} + echo "::error file=$FILE,line=$LINE,col=$COL::Do not use SCSS \`$X()\`. It means that every build will have different CSS, dirtying the diffs (and making for redudant Simple deploys if this gets into a relevant plugin)." + done < <( git grep -h --line-number --column -o '\(random\|unique-id\)\s*(' "$FILE" ) +done < <( git -c core.quotepath=off grep -l '\(random\|unique-id\)\s*(' '*.sass' '*.scss' ) + + exit $EXIT diff --git a/projects/packages/jetpack-mu-wpcom/changelog/update-no-scss-random b/projects/packages/jetpack-mu-wpcom/changelog/update-no-scss-random new file mode 100644 index 0000000000000..dfbf589fd7a43 --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/changelog/update-no-scss-random @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Holiday snow: Replace SCSS `random()` with pregenerated arrays of random numbers to make builds reproducable. diff --git a/projects/packages/jetpack-mu-wpcom/src/features/holiday-snow/holiday-snow.scss b/projects/packages/jetpack-mu-wpcom/src/features/holiday-snow/holiday-snow.scss index c548402cf8483..093158e54a445 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/holiday-snow/holiday-snow.scss +++ b/projects/packages/jetpack-mu-wpcom/src/features/holiday-snow/holiday-snow.scss @@ -10,14 +10,22 @@ $snow_density: 10; $snow_speed: 9s; $snow_selector: '#jetpack-holiday-snow'; +// Random numbers, to replace the `random` function so we can have reproducable builds. +// Needs $snow_density entries. Intergers 3-6. +$snow_sizes: 6, 6, 3, 5, 3, 4, 6, 5, 4, 6; +// Needs $snow_density entries. Floats 0.6-1.0. +$snow_alphas: 0.8, 1, 0.9, 1, 0.6, 1, 1, 1, 0.8, 1; +// Needs $snow_density * 2 entries. Floats 0-1. +$snow_positions: 0.17857, 0.30782, 0.65476, 0.04422, 0.31145, 0.02525, 0.72542, 0.19153, 0.26094, 0.12121, 0.47466, 0.76351, 0.46259, 0.92007, 0.24915, 0.44915, 0.19088, 0.86993, 0.62925, 0.68707; + html { $grad: ( ); @for $i from 0 to $snow_density { - $v: random(4) + 2; - $alpha: random(5) * .1 + .5; - $grad: $grad, radial-gradient($v+px $v+px at (random($grid_width - $v * 2) + $v)+px (random($grid_width - $v * 2) + $v)+px, + $v: nth($snow_sizes, $i + 1); + $alpha: nth($snow_alphas, $i + 1); + $grad: $grad, radial-gradient($v+px $v+px at (round(nth($snow_positions, $i * 2 + 1) * ($grid_width - $v * 2)) + $v)+px (round(nth($snow_positions, $i * 2 + 2) * ($grid_width - $v * 2)) + $v)+px, rgba(255, 255, 255, $alpha) 50%, rgba(0, 0, 0, 0)); } From 988bafb3ee2136de2ec9d1672cf286502c5448fb Mon Sep 17 00:00:00 2001 From: Nate Weller Date: Wed, 18 Dec 2024 13:20:32 -0700 Subject: [PATCH 08/45] Protect Status: prevent undefined extension warning (#40622) --- .../changelog/fix-php-undefined-array-key-warning | 4 ++++ projects/packages/protect-status/src/class-scan-status.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 projects/packages/protect-status/changelog/fix-php-undefined-array-key-warning diff --git a/projects/packages/protect-status/changelog/fix-php-undefined-array-key-warning b/projects/packages/protect-status/changelog/fix-php-undefined-array-key-warning new file mode 100644 index 0000000000000..72562089ff171 --- /dev/null +++ b/projects/packages/protect-status/changelog/fix-php-undefined-array-key-warning @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Fix PHP warnings caused by uninstalled extensions. diff --git a/projects/packages/protect-status/src/class-scan-status.php b/projects/packages/protect-status/src/class-scan-status.php index 32deca2eba526..6f743cc397b63 100644 --- a/projects/packages/protect-status/src/class-scan-status.php +++ b/projects/packages/protect-status/src/class-scan-status.php @@ -243,7 +243,7 @@ private static function normalize_api_data( $scan_data ) { // Theme and Plugin Threats if ( ! empty( $scan_threat->extension ) && in_array( $scan_threat->extension->type, array( 'plugin', 'theme' ), true ) ) { - $installed_extension = 'plugin' === $scan_threat->extension->type ? $plugins[ $scan_threat->extension->slug ] : $themes[ $scan_threat->extension->slug ]; + $installed_extension = 'plugin' === $scan_threat->extension->type ? ( $plugins[ $scan_threat->extension->slug ] ?? null ) : ( $themes[ $scan_threat->extension->slug ] ?? null ); // If the extension is no longer installed, skip this threat. // todo: use version_compare() From 6cc1f1477187a1f37aaaaac9ad0779e2187555ab Mon Sep 17 00:00:00 2001 From: Calypso Bot Date: Wed, 18 Dec 2024 22:30:22 +0100 Subject: [PATCH 09/45] phan: Update custom stubs (#40654) Co-authored-by: matticbot --- .phan/stubs/phpunit-stubs.php | 2 +- .phan/stubs/woocommerce-internal-stubs.php | 3 ++- .phan/stubs/woocommerce-payments-stubs.php | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.phan/stubs/phpunit-stubs.php b/.phan/stubs/phpunit-stubs.php index 801a8a4e4e6b1..0d417e8d3000a 100644 --- a/.phan/stubs/phpunit-stubs.php +++ b/.phan/stubs/phpunit-stubs.php @@ -1,6 +1,6 @@ Date: Wed, 18 Dec 2024 17:02:30 -0500 Subject: [PATCH 10/45] codeql: Remove unneeded advanced config file (#40674) GitHub has a "default" config and an "advanced" config. It turns out the "advanced" config we have here doesn't do anything very advanced, we can switch to the default config. See https://github.com/Automattic/jetpack/security/code-scanning/438 When I did that, it disabled the workflow but didn't create a PR to delete this file for us. Guess we have to do that manually. --- .github/workflows/codeql-analysis.yml | 39 --------------------------- 1 file changed, 39 deletions(-) delete mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 63a7d71893189..0000000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: "CodeQL Code Scanning Analysis" - -on: - push: - branches: [ trunk ] - pull_request: - branches: [ trunk ] - schedule: - - cron: '0 19 * * 0' -concurrency: - group: codeql-analysis-${{ github.event_name }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - timeout-minutes: 7 # 2021-01-18: Successful runs seem to take 3-5 minutes - - strategy: - fail-fast: false - matrix: - language: ['javascript'] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - - - name: Autobuild - uses: github/codeql-action/autobuild@v3 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 From 6382dad286a31019bd83f2503c62a1cd6f9598c4 Mon Sep 17 00:00:00 2001 From: tbradsha <32492176+tbradsha@users.noreply.github.com> Date: Wed, 18 Dec 2024 15:22:27 -0700 Subject: [PATCH 11/45] Tools: Add steps to release script (#40556) * Add var to disable tracks * First pass at stepification * Rework release steps * Wording tweaks * Add some safety checks * Prevent pipefail * Disable shellcheck SC1091 (not following source files) * Update comment Co-authored-by: Brad Jorsch * Remove spare tab * Rework usage output * Add undocumented --list-steps option * Oops Co-authored-by: Brad Jorsch * Add multi-plugin support back to usage output Co-authored-by: Brad Jorsch --------- Co-authored-by: Brad Jorsch --- tools/includes/send_tracks_event.sh | 4 +- tools/release-plugin.sh | 792 +++++++++++++++------------- 2 files changed, 425 insertions(+), 371 deletions(-) diff --git a/tools/includes/send_tracks_event.sh b/tools/includes/send_tracks_event.sh index 6f6660f6c096b..7f417f1da33a2 100644 --- a/tools/includes/send_tracks_event.sh +++ b/tools/includes/send_tracks_event.sh @@ -14,8 +14,8 @@ function get_uuid { # - 1: Event name # - 2: An optional JSON-formatted payload of extra tracks params, e.g. `{"a":1, "b":2}` function send_tracks_event { - # Bail if no event name is provided. - if [[ -z "$1" ]]; then + # Bail if no event name is provided or JP_DISABLE_TRACKS is set. + if [[ -z "$1" || $JP_DISABLE_TRACKS == 1 ]]; then return fi diff --git a/tools/release-plugin.sh b/tools/release-plugin.sh index 37fa2fe545063..b3ce49b1aac09 100755 --- a/tools/release-plugin.sh +++ b/tools/release-plugin.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# shellcheck disable=SC1091 set -eo pipefail @@ -12,128 +13,454 @@ BASE=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) . "$BASE/tools/includes/changelogger.sh" . "$BASE/tools/includes/send_tracks_event.sh" +VERSION_REGEX='^[0-9]+(\.[0-9]+)+(-.*)?$' +CUR_STEP=0 + +RELEASE_STEPS=( + 'do_trunk_and_prelease_branch_prep' + 'do_changelogs' + 'do_readme' + 'do_commit_changelog_and_readme' + 'do_push_and_build' + 'do_packagist_check' + 'do_create_release_branches' + 'do_create_prerelease_PR' + 'do_final_instructions' +) + # Instructions function usage { cat <<-EOH - usage: $0 [options] [] [ [] ...] - - Conduct a full release of specified plugins through release branch creation. Just the plugin name is fine, such as 'jetpack' or 'backup.' The version is optional, and if not specified, will be set to the next stable version. + Usage: + $0 [-s ] [] [ [] ...] Options: - -h Show this help message. + -h, --help Show this help message. + -s , --step Start at a given step. + Plugin name to release (e.g. jetpack) + Version number (defaults to next stable) + + Conduct a full release of specified plugins through release branch creation. + Accepts the plugin name without a prefix, such as 'jetpack' or 'backup'. The + version is optional; if not specified it will be set to the next stable version. + EOH exit 1 } -# Make sure the GitHub CLI is installed. -if ! command -v gh &> /dev/null; then - yellow "This tool requires the GitHub CLI, which was not found." - if command -v brew &> /dev/null; then - proceed_p "Install the GitHub CLI via brew?" "" Y - brew install gh - else - die "Please install the GitHub CLI before proceeding" +# Preliminary environment checks. +function preflight_checks { + # Make sure the GitHub CLI is installed. + if ! command -v gh &> /dev/null; then + yellow "This tool requires the GitHub CLI, which was not found." + if command -v brew &> /dev/null; then + proceed_p "Install the GitHub CLI via brew?" "" Y + brew install gh + else + die "Please install the GitHub CLI before proceeding" + fi fi -fi - -GH_VER="$( gh --version | grep -E -o -m1 '[0-9]+\.[0-9]+\.[0-9]+' )" -if ! version_compare "$GH_VER" "2.21.2"; then - command -v brew &> /dev/null && WITH=" with 'brew upgrade gh'" || WITH= - die "Your version of the GH CLI is out of date. Please upgrade your version$WITH and start again" -fi -# Make sure we're signed into the GitHub CLI. -if ! gh auth status --hostname github.com &> /dev/null; then - yellow "You are not signed into the GitHub CLI." - proceed_p "Sign in to the GitHub CLI?" "" Y - gh auth login -fi - -# Get the options passed and parse them. -while getopts "h" opt; do - case ${opt} in - h) - usage - ;; - ?) - error "Invalid argument" - echo "" - usage - ;; - esac -done -shift "$(($OPTIND -1))" - -# Parse arguments in associated array of plugins/project => version format. -if [ $# -eq 0 ]; then - usage -fi - -declare -A PROJECTS -while [[ $# -gt 0 ]]; do - if [[ "$1" =~ ^[a-zA-Z\-]+$ ]]; then - PLUGIN=$1 - else - die "Script must be passed in [version] format. Got $1" + GH_VER="$( gh --version | grep -E -o -m1 '[0-9]+\.[0-9]+\.[0-9]+' )" + if ! version_compare "$GH_VER" "2.21.2"; then + command -v brew &> /dev/null && WITH=" with 'brew upgrade gh'" || WITH= + die "Your version of the GH CLI is out of date. Please upgrade your version$WITH and start again" fi - if [[ "$2" =~ ^[0-9]+(\.[0-9]+)+(-.*)?$ ]]; then - PROJECTS["$PLUGIN"]=$2 - SHIFT="2" - else - PROJECTS["$PLUGIN"]='' - SHIFT="1" + # Make sure we're signed into the GitHub CLI. + if ! gh auth status --hostname github.com &> /dev/null; then + yellow "You are not signed into the GitHub CLI." + proceed_p "Sign in to the GitHub CLI?" "" Y + gh auth login fi - shift "$SHIFT" -done +} -# Check that the projects are valid. -for PLUGIN in "${!PROJECTS[@]}"; do - # Get the project slug. - SLUG="${PLUGIN#projects/}" # DWIM - SLUG="${SLUG%/}" # Sanitize - SLUG="plugins/$SLUG" +function verify_prerelease_branch { + [[ $(git branch --show-current) != "prerelease" ]] && die 'Not on prerelease branch!' + return 0 +} + +function normalize_plugin_name { + SLUG="$1" + + # Normalize slug + SLUG="${SLUG#projects/}" # Remove leading 'projects/' + SLUG="${SLUG#plugins/}" # Remove leading 'plugins/' + SLUG="${SLUG%/}" # Remove trailing slash + SLUG="plugins/$SLUG" # Add leading 'plugins/' if [[ ! -e "$BASE/projects/$SLUG/composer.json" ]]; then die "$SLUG isn't a valid project!" elif ! jq -e '.extra["release-branch-prefix"]' "$BASE/projects/$SLUG/composer.json" &>/dev/null; then die "$SLUG has no release branch prefix!" + fi + echo "$SLUG" +} + +# Generates a command that can be used to resume the release script from the current step. +# Currently unused. +function generate_resume_command() { + local cmd="$0 -s $CUR_STEP" + for PLUGIN in "${!PROJECTS[@]}"; do + cmd+=" ${PLUGIN#plugins/} ${PROJECTS[$PLUGIN]}" + done + echo "$cmd" +} + +function do_trunk_and_prelease_branch_prep() { + # Make sure we're standing on trunk and working directory is clean + CURRENT_BRANCH="$( git rev-parse --abbrev-ref HEAD )" + if [[ "$CURRENT_BRANCH" != "trunk" ]]; then + proceed_p "Not currently checked out to trunk." "Check out trunk before continuing?" Y + git checkout trunk && git pull + fi + + if [[ -n "$(git status --porcelain)" ]]; then + die "Working directory not clean, make sure you're working from a clean checkout and try again." + fi + + yellow "Installing root packages." + pnpm jetpack install --root + + yellow "Checking out prerelease branch." + # Is there an upstream prerelease branch already? + R=$( git ls-remote --heads origin prerelease ) + if [[ -n "$R" ]]; then + error "There's an existing prerelease branch on GitHub!" + R=${R%%[ $'\t']*} + TMP=$( gh pr list --head=prerelease --state=open --json number,author,url,createdAt,title --jq '.[] | "\( .url ) - \( .createdAt | fromdateiso8601 | strftime( "%F %H:%IZ" ) ) - \( .title ) [\( .author.name )]"' ) + if [[ -n "$TMP" ]]; then + echo "Someone probably needs to merge the following PR:" + echo "$TMP" + exit 1 + fi + git fetch -q origin trunk "$R" || die "Something unexpected went wrong fetching the commit from GitHub" + if git diff --quiet origin/trunk..."$R"; then + echo "There don't seem to be any changes between that and trunk. If its author has abandoned the release it should be safe to delete the branch." + exit 1 + fi + if ! git diff --quiet origin/trunk..."$R" '*/CHANGELOG.md'; then + echo "Looks like someone is in the middle of a release! Wait for them to merge the changes back into trunk." + exit 1 + fi + echo "Looks like someone may be in the middle of a release! Wait for them to merge the changes back into trunk, or to abandon the release." + exit 1 + fi + + # Check out and push pre-release branch + if git rev-parse --verify prerelease &>/dev/null; then + proceed_p "Existing local prerelease branch found." "Delete it?" Y + git branch -D prerelease + fi + + git checkout -b prerelease + if ! git push -u origin HEAD; then + send_tracks_event "jetpack_release_prerelease_push" '{"result": "failure"}' + die "Branch push failed. Check #jetpack-releases and make sure no one is doing a release already, then delete the branch at https://github.com/Automattic/jetpack/branches" + fi + GITBASE=$( git rev-parse --verify HEAD ) + send_tracks_event "jetpack_release_prerelease_push" '{"result": "success"}' +} + +function do_changelogs { + verify_prerelease_branch + # Loop through the projects and update the changelogs after building the arguments. + for PLUGIN in "${!PROJECTS[@]}"; do + yellow "Updating the changelog files for $PLUGIN." + + # Add the PR numbers to the changelog. + ARGS=('-p') + + # Add alpha and beta flags. + VERSION="${PROJECTS[$PLUGIN]}" + case $VERSION in + *-a* ) ARGS+=('-a');; + *-beta ) ARGS+=('-b');; + esac + + # Explicitly pass the version number we want so there are no surprises. + ARGS+=( '-r' "${PROJECTS[$PLUGIN]}" ) + ARGS+=("$PLUGIN"); + tools/changelogger-release.sh "${ARGS[@]}" + done + + # When it completes, wait for user to edit anything they want, then push key to continue. + read -r -s -p $'Edit and save all the changelog entries you want in a separate terminal or in your text editor of choice.\nCheck for consistency between the different entries, and keep in mind that your plugin changelog will be used in the plugin readme file.\n\nOnce you are happy with your work, press enter to continue the release process.' + echo "" +} + +function do_readme { + verify_prerelease_branch + for PLUGIN in "${!PROJECTS[@]}"; do + # check if the plugin even has a readme.txt file. + if [[ ! -e "$BASE/projects/$PLUGIN/readme.txt" ]]; then + yellow "$PLUGIN has no readme.txt file, skipping." + continue + fi + yellow "Updating the readme.txt file for $PLUGIN." + ARGS=() + # Add alpha and beta flags. + VERSION="${PROJECTS[$PLUGIN]}" + case $VERSION in + *-a* ) ARGS+=('-a');; + *-beta ) ARGS+=('-b');; + * ) ARGS+=('-s');; + esac + pnpm jetpack release "$PLUGIN" readme "${ARGS[@]}" + done +} + +function do_commit_changelog_and_readme { + verify_prerelease_branch + yellow "Committing changes." + git add --all + git commit -am "Changelog and readme.txt edits." + + # If we're releasing Jetpack and it's a beta, amend the readme.txt + if [[ -v PROJECTS["plugins/jetpack"] && "${PROJECTS[plugins/jetpack]}" == *-beta ]]; then + yellow "Releasing a beta for Jetpack, amending the readme.txt" + pnpm jetpack changelog squash plugins/jetpack readme + git commit -am "Amend readme.txt" + fi +} + +function do_push_and_build { + verify_prerelease_branch + HEADSHA=$(git rev-parse HEAD) + yellow "Pushing changes." + git push -u origin prerelease + + yellow "Waiting for build to complete and push to mirror repos" + BUILDID= + + # If the build ID doesn't exist, try every five seconds until timeout after a minute. + TIMEOUT=$((SECONDS+60)) + while [[ $SECONDS -lt $TIMEOUT && -z "$BUILDID" ]]; do + echo "Waiting for build to become available..." + sleep 5 + BUILDID="$( gh run list -b prerelease -w Build --json event,databaseId,headSha | jq --arg HEADSHA "$HEADSHA" '.[] | select(.event=="push" and .headSha==$HEADSHA) | .databaseId' )" + done + + if [[ -z "$BUILDID" ]]; then + send_tracks_event "jetpack_release_github_build" '{"result": "not_found"}' + die "Build ID not found. Check GitHub actions to see if build on prerelease branch is running, then continue with manual steps." + fi + + yellow "Build ID found, waiting for build to complete and push to mirror repos." + if ! gh run watch "${BUILDID[0]}" --exit-status; then + send_tracks_event "jetpack_release_github_build" '{"result": "failure"}' + echo "Build failed! Check for build errors on GitHub for more information." && die + fi + + send_tracks_event "jetpack_release_github_build" '{"result": "success"}' + yellow "Build is complete." +} + +function do_packagist_check { + verify_prerelease_branch + # Wait for new versions of any composer packages to be up. + # We expect a new version when (1) the package is touched in this release and (2) it has no change entry files remaining. + POLL_ARGS=() + cd "$BASE" + for PKGDIR in $(git -c core.quotepath=off diff --name-only "$GITBASE..HEAD" projects/packages/ | sed 's!^\(projects/packages/[^/]*\)/.*!\1!' | sort -u); do + cd "$BASE/$PKGDIR" + CHANGES_DIR=$(jq -r '.extra.changelogger["changes-dir"] // "changelog"' composer.json) + if [[ ! -d "$CHANGES_DIR" || -z "$(ls -- "$CHANGES_DIR")" ]]; then + POLL_ARGS+=( "$( jq -r .name composer.json )=$( changelogger version current )" ) + fi + done + cd "$BASE" + if [[ ${#POLL_ARGS[@]} -gt 0 ]]; then + yellow "Waiting for packagist to get updated packages..." + tools/js-tools/await-packagist-updates.mjs "${POLL_ARGS[@]}" + yellow "Packagist is updated!" + fi +} + +function do_create_release_branches { + # Run tools/create-release-branch.sh to create a release branch for each project. + for PREFIX in "${PREFIXES[@]}"; do + git checkout prerelease + PROJECT=$(jq -r --arg prefix "$PREFIX" '.[$prefix] | if length == 1 then "plugins/\(first)" else empty end' <<<"$PREFIXDATA") + if [[ -n "$PROJECT" && -n "${PROJECTS[$PROJECT]}" ]]; then + VERSION="${PROJECTS[$PROJECT]}" + yellow "Creating release branch for $PROJECT $VERSION" + tools/create-release-branch.sh "$PROJECT" "$VERSION" + else + yellow "Creating release branch for $PREFIX" + tools/create-release-branch.sh "$PREFIX" + fi + done + + yellow "Release branches created!" +} + +function do_create_prerelease_PR { + yellow "Creating a PR to merge the prerelease branch into trunk." + git checkout prerelease + + # Handle any package changes merged into trunk while we were working. + git fetch + git merge origin/trunk + tools/fixup-project-versions.sh + if [[ -n "$(git status --porcelain)" ]]; then + git commit -am 'Version bumps' + fi + git push + PLUGINS_CHANGED= + for PLUGIN in "${!PROJECTS[@]}"; do + PLUGINS_CHANGED+="$(basename "$PLUGIN") ${PROJECTS[$PLUGIN]}, " + done + # Remove the trailing comma and space + PLUGINS_CHANGED=${PLUGINS_CHANGED%, } + sed "s/%RELEASED_PLUGINS%/$PLUGINS_CHANGED/g" .github/files/BACKPORT_RELEASE_CHANGES.md > .github/files/TEMP_BACKPORT_RELEASE_CHANGES.md + gh pr create --title "Backport $PLUGINS_CHANGED Changes" --body "$(cat .github/files/TEMP_BACKPORT_RELEASE_CHANGES.md)" --label "[Status] Needs Review" --repo "Automattic/jetpack" --head "$(git rev-parse --abbrev-ref HEAD)" + rm .github/files/TEMP_BACKPORT_RELEASE_CHANGES.md +} + +function do_final_instructions { + yellow "Release script complete!" + + echo '' + echo 'Next you need to merge the above PR into trunk.' + + AUTO=() + MANUALTAG=() + MANUALTAGONLY=() + MANUALPUB=() + MANUALBOTH=() + for PLUGIN in "${!PROJECTS[@]}"; do + F="$BASE/projects/$PLUGIN/composer.json" + if ! jq -e '.extra["mirror-repo"] // false' "$F" &>/dev/null; then + continue + fi + + if ! jq -e '.extra["wp-plugin-slug"] // .extra["wp-theme-slug"] // false' "$F" &>/dev/null; then + if ! jq -e '.extra["autotagger"]' "$F" &>/dev/null; then + MANUALTAGONLY+=( "$PLUGIN" ) + fi + continue + fi + + if jq -e '.extra["autotagger"]' "$F" &>/dev/null; then + if jq -e '.extra["wp-svn-autopublish"] // false' "$F" &>/dev/null; then + AUTO+=( "$PLUGIN" ) + else + MANUALPUB+=( "$PLUGIN" ) + fi + else + if jq -e '.extra["wp-svn-autopublish"] // false' "$F" &>/dev/null; then + MANUALTAG+=( "$PLUGIN" ) + else + MANUALBOTH+=( "$PLUGIN" ) + fi + fi + done + + if [[ ${#AUTO[@]} -gt 0 ]]; then + cat <<-EOM + + For these plugins: ${AUTO[*]} + The release will shortly be tagged to GitHub and released to SVN and you can + then smoke test the release. Once ready, use \`./tools/stable-tag.sh \` + to update the stable tag, and you're done! + EOM + fi + + if [[ ${#MANUALTAGONLY[@]} -gt 0 ]]; then + cat <<-EOM + + For these plugins: ${MANUALTAGONLY[*]} + Wait for the changes to appear in the mirror repo and conduct a GitHub + release. Then you're done! + EOM + fi + + if [[ ${#MANUALTAG[@]} -gt 0 ]]; then + cat <<-EOM + + For these plugins: ${MANUALTAG[*]} + Wait for the changes to appear in the mirror repo and conduct a GitHub + release. The changes will then be automatically released to SVN and you can + then smote test the release. Once ready, use \`./tools/stable-tag.sh \` + to update the stable tag, and you're done! + EOM + fi + + if [[ ${#MANUALPUB[@]} -gt 0 ]]; then + cat <<-EOM + + For these plugins: ${MANUALPUB[*]} + The release will shortly be tagged to GitHub. Once the tag appears, deploy it + to SVN by running \`./tools/deploy-to-svn.sh \`, and smoke test. + When ready, flip the stable tag with \`./tools/stable-tag.sh \` and + you're all set. + EOM + fi + + if [[ ${#MANUALBOTH[@]} -gt 0 ]]; then + cat <<-EOM + + For these plugins: ${MANUALBOTH[*]} + Wait for the changes to appear in the mirror repo, and conduct a GitHub + release. Next, deploy the tag to SVN by running + \`./tools/deploy-to-svn.sh \`, and smoke test. When ready, flip + the stable tag with \`./tools/stable-tag.sh \` and you're all set. + EOM + fi +} + +preflight_checks + +# No args, help flag, or invalid flag, so show usage. +if [[ $# -eq 0 || $1 == '-h' || $1 == '--help' ]]; then + usage +elif [[ $1 == '-s' || $1 == '--step' ]]; then + if [[ $2 =~ ^[0-9]$ ]]; then + CUR_STEP="$2" + shift 2 else - PROJECTS["$SLUG"]="${PROJECTS[$PLUGIN]}" - unset "PROJECTS[$PLUGIN]" + usage fi -done +elif [[ $1 == '--list-steps' ]]; then + echo 'Use the following steps at your own risk:' + for i in "${!RELEASE_STEPS[@]}"; do + echo " $i: ${RELEASE_STEPS[$i]}" + done + exit 1 +fi -# Try to obtain a version number for plugins that we didn't supply. -for SLUG in "${!PROJECTS[@]}"; do - if [[ -z "${PROJECTS[$SLUG]}" ]]; then - cd "$BASE/projects/$SLUG" - PROJECTS["$SLUG"]=$(changelogger version next) || die "Cannot determine version number for $SLUG. Please supply one on the command line." +# Parse arguments in associated array of plugin => version format. +declare -A PROJECTS +while [[ $# -gt 0 ]]; do + # Grab plugin name + PLUGIN=$(normalize_plugin_name "$1") + shift + + # Grab version number if provided. + if [[ "$1" =~ $VERSION_REGEX ]]; then + VERSION=$1 + shift + else + cd "$BASE/projects/$PLUGIN" + VERSION=$(changelogger version next) || die "Cannot determine version number for $PLUGIN. Please supply one on the command line." fi + + PROJECTS["$PLUGIN"]="$VERSION" done cd "$BASE" -# Check the plugin version(s) to use for the plugin(s). -function check_ver { - normalize_version_number "$2" - if [[ ! "$NORMALIZED_VERSION" =~ ^[0-9]+(\.[0-9]+)+(-.*)?$ ]]; then +for PLUGIN in "${!PROJECTS[@]}"; do + normalize_version_number "${PROJECTS[$PLUGIN]}" + if [[ ! "$NORMALIZED_VERSION" =~ $VERSION_REGEX ]]; then red "\"$NORMALIZED_VERSION\" does not appear to be a valid version number." - return 1 + die "Please specify a valid version number." fi - local CUR_VERSION - CUR_VERSION=$("$BASE/tools/plugin-version.sh" "$1") + CUR_VERSION=$("$BASE/tools/plugin-version.sh" "$PLUGIN") # shellcheck disable=SC2310 if version_compare "$CUR_VERSION" "$NORMALIZED_VERSION"; then - proceed_p "Version $NORMALIZED_VERSION <= $CUR_VERSION." - return $? - fi - return 0 -} - -for PLUGIN in "${!PROJECTS[@]}"; do - if ! check_ver "$PLUGIN" "${PROJECTS[$PLUGIN]}"; then - die "Please specify a valid version number." + proceed_p "$PLUGIN: Version $NORMALIZED_VERSION is lower than $CUR_VERSION." || die "User aborted script." fi - echo "Releasing $PLUGIN ${PROJECTS[$PLUGIN]}" + echo "$PLUGIN: $CUR_VERSION -> ${PROJECTS[$PLUGIN]}" done proceed_p "" "Proceed releasing above projects?" Y @@ -191,284 +518,11 @@ if [[ ${#PREFIXES[@]} -gt 1 ]]; then proceed_p "" "" Y fi -# Make sure we're standing on trunk and working directory is clean -CURRENT_BRANCH="$( git rev-parse --abbrev-ref HEAD )" -if [[ "$CURRENT_BRANCH" != "trunk" ]]; then - proceed_p "Not currently checked out to trunk." "Check out trunk before continuing?" Y - git checkout trunk && git pull -fi - -if [[ -n "$(git status --porcelain)" ]]; then - die "Working directory not clean, make sure you're working from a clean checkout and try again." -fi - -yellow "Installing root packages." -pnpm jetpack install --root - -yellow "Checking out prerelease branch." -# Is there an upstream prerelease branch already? -R=$( git ls-remote --heads origin prerelease ) -if [[ -n "$R" ]]; then - error "There's an existing prerelease branch on GitHub!" - R=${R%%[ $'\t']*} - TMP=$( gh pr list --head=prerelease --state=open --json number,author,url,createdAt,title --jq '.[] | "\( .url ) - \( .createdAt | fromdateiso8601 | strftime( "%F %H:%IZ" ) ) - \( .title ) [\( .author.name )]"' ) - if [[ -n "$TMP" ]]; then - echo "Someone probably needs to merge the following PR:" - echo "$TMP" - exit 1 - fi - git fetch -q origin trunk "$R" || die "Something unexpected went wrong fetching the commit from GitHub" - if git diff --quiet origin/trunk..."$R"; then - echo "There don't seem to be any changes between that and trunk, if whoever created it has abandoned the release it should be safe to delete the branch." - exit 1 - fi - if ! git diff --quiet origin/trunk..."$R" '*/CHANGELOG.md'; then - echo "Looks like someone is in the middle of a release! Wait for them merge the changes back into trunk." - exit 1 - fi - echo "Looks like someone may be in the middle of a release! Wait for them merge the changes back into trunk, or to abandon the release." - exit 1 -fi - -# Check out and push pre-release branch -if git rev-parse --verify prerelease &>/dev/null; then - proceed_p "Existing local prerelease branch found." "Delete it?" Y - git branch -D prerelease -fi - -git checkout -b prerelease -if ! git push -u origin HEAD; then - send_tracks_event "jetpack_release_prerelease_push" '{"result": "failure"}' - die "Branch push failed. Check #jetpack-releases and make sure no one is doing a release already, then delete the branch at https://github.com/Automattic/jetpack/branches" -fi -GITBASE=$( git rev-parse --verify HEAD ) -send_tracks_event "jetpack_release_prerelease_push" '{"result": "success"}' - -# Loop through the projects and update the changelogs after building the arguments. -for PLUGIN in "${!PROJECTS[@]}"; do - yellow "Updating the changelog files for $PLUGIN." - - # Add the PR numbers to the changelog. - ARGS=('-p') - - # Add alpha and beta flags. - VERSION="${PROJECTS[$PLUGIN]}" - case $VERSION in - *-a* ) ARGS+=('-a');; - *-beta ) ARGS+=('-b');; - esac - - # Explicitly pass the version number we want so there are no surprises. - ARGS+=( '-r' "${PROJECTS[$PLUGIN]}" ) - ARGS+=("$PLUGIN"); - tools/changelogger-release.sh "${ARGS[@]}" -done - -# When it completes, wait for user to edit anything they want, then push key to continue. -read -r -s -p $'Edit all the changelog entries you want (in a separate terminal or your text editor of choice (make sure to save)).\nCheck for consistency between the different entries, and keep in mind that your plugin changelog will be used in the plugin readme file.\n\nOnce you are happy with your work, press enter to continue the release process.' -echo "" - -for PLUGIN in "${!PROJECTS[@]}"; do - # check if the plugin even has a readme.txt file. - if [[ ! -e "$BASE/projects/$PLUGIN/readme.txt" ]]; then - yellow "$PLUGIN has no readme.txt file, skipping." - continue - fi - yellow "Updating the readme.txt file for $PLUGIN." - ARGS=() - # Add alpha and beta flags. - VERSION="${PROJECTS[$PLUGIN]}" - case $VERSION in - *-a* ) ARGS+=('-a');; - *-beta ) ARGS+=('-b');; - * ) ARGS+=('-s');; - esac - pnpm jetpack release "$PLUGIN" readme "${ARGS[@]}" -done - -yellow "Committing changes." -git add --all -git commit -am "Changelog and readme.txt edits." - -# If we're releasing Jetpack and it's a beta, amend the readme.txt -if [[ -v PROJECTS["plugins/jetpack"] && "${PROJECTS[plugins/jetpack]}" == *-beta ]]; then - yellow "Releasing a beta for Jetpack, amending the readme.txt" - pnpm jetpack changelog squash plugins/jetpack readme - git commit -am "Amend readme.txt" -fi - -HEADSHA=$(git rev-parse HEAD) -yellow "Pushing changes." -git push -u origin prerelease - -yellow "Waiting for build to complete and push to mirror repos" -BUILDID= - -# If the build ID doesn't exist, try every five seconds until timeout after a minute. -TIMEOUT=$((SECONDS+60)) -while [[ $SECONDS -lt $TIMEOUT && -z "$BUILDID" ]]; do - echo "Waiting for build to become available..." - sleep 5 - BUILDID="$( gh run list -b prerelease -w Build --json event,databaseId,headSha | jq --arg HEADSHA "$HEADSHA" '.[] | select(.event=="push" and .headSha==$HEADSHA) | .databaseId' )" -done - -if [[ -z "$BUILDID" ]]; then - send_tracks_event "jetpack_release_github_build" '{"result": "not_found"}' - die "Build ID not found. Check GitHub actions to see if build on prerelease branch is running, then continue with manual steps." -fi - -yellow "Build ID found, waiting for build to complete and push to mirror repos." -if ! gh run watch "${BUILDID[0]}" --exit-status; then - send_tracks_event "jetpack_release_github_build" '{"result": "failure"}' - echo "Build failed! Check for build errors on GitHub for more information." && die -fi - -send_tracks_event "jetpack_release_github_build" '{"result": "success"}' -yellow "Build is complete." - -# Wait for new versions of any composer packages to be up. -# We expect a new version when (1) the package is touched in this release and (2) it has no change entry files remaining. -POLL_ARGS=() -cd "$BASE" -for PKGDIR in $(git -c core.quotepath=off diff --name-only "$GITBASE..HEAD" projects/packages/ | sed 's!^\(projects/packages/[^/]*\)/.*!\1!' | sort -u); do - cd "$BASE/$PKGDIR" - CHANGES_DIR=$(jq -r '.extra.changelogger["changes-dir"] // "changelog"' composer.json) - if [[ ! -d "$CHANGES_DIR" || -z "$(ls -- "$CHANGES_DIR")" ]]; then - POLL_ARGS+=( "$( jq -r .name composer.json )=$( changelogger version current )" ) - fi -done -cd "$BASE" -if [[ ${#POLL_ARGS[@]} -gt 0 ]]; then - yellow "Waiting for packagist to get updated packages..." - tools/js-tools/await-packagist-updates.mjs "${POLL_ARGS[@]}" - yellow "Packagist is updated!" -fi - -# Run tools/create-release-branch.sh to create a release branch for each project. -for PREFIX in "${PREFIXES[@]}"; do - git checkout prerelease - PROJECT=$(jq -r --arg prefix "$PREFIX" '.[$prefix] | if length == 1 then "plugins/\(first)" else empty end' <<<"$PREFIXDATA") - if [[ -n "$PROJECT" && -n "${PROJECTS[$PROJECT]}" ]]; then - VERSION="${PROJECTS[$PROJECT]}" - yellow "Creating release branch for $PROJECT $VERSION" - tools/create-release-branch.sh "$PROJECT" "$VERSION" - else - yellow "Creating release branch for $PREFIX" - tools/create-release-branch.sh "$PREFIX" - fi -done - -yellow "Release branches created!" - -yellow "Creating a PR to merge the prerelease branch into trunk." -git checkout prerelease - -# Handle any package changes merged into trunk while we were working. -git fetch -git merge origin/trunk -tools/fixup-project-versions.sh -if [[ -n "$(git status --porcelain)" ]]; then - git commit -am 'Version bumps' -fi -git push -PLUGINS_CHANGED= -for PLUGIN in "${!PROJECTS[@]}"; do - PLUGINS_CHANGED+="$(basename "$PLUGIN") ${PROJECTS[$PLUGIN]}, " -done -# Remove the trailing comma and space -PLUGINS_CHANGED=${PLUGINS_CHANGED%, } -sed "s/%RELEASED_PLUGINS%/$PLUGINS_CHANGED/g" .github/files/BACKPORT_RELEASE_CHANGES.md > .github/files/TEMP_BACKPORT_RELEASE_CHANGES.md -gh pr create --title "Backport $PLUGINS_CHANGED Changes" --body "$(cat .github/files/TEMP_BACKPORT_RELEASE_CHANGES.md)" --label "[Status] Needs Review" --repo "Automattic/jetpack" --head "$(git rev-parse --abbrev-ref HEAD)" -rm .github/files/TEMP_BACKPORT_RELEASE_CHANGES.md - -yellow "Release script complete!" - -echo '' -echo 'Next you need to merge the above PR into trunk.' - -AUTO=() -MANUALTAG=() -MANUALTAGONLY=() -MANUALPUB=() -MANUALBOTH=() -for PLUGIN in "${!PROJECTS[@]}"; do - F="$BASE/projects/$PLUGIN/composer.json" - if ! jq -e '.extra["mirror-repo"] // false' "$F" &>/dev/null; then - continue - fi - - if ! jq -e '.extra["wp-plugin-slug"] // .extra["wp-theme-slug"] // false' "$F" &>/dev/null; then - if ! jq -e '.extra["autotagger"]' "$F" &>/dev/null; then - MANUALTAGONLY+=( "$PLUGIN" ) - fi - continue - fi - - if jq -e '.extra["autotagger"]' "$F" &>/dev/null; then - if jq -e '.extra["wp-svn-autopublish"] // false' "$F" &>/dev/null; then - AUTO+=( "$PLUGIN" ) - else - MANUALPUB+=( "$PLUGIN" ) - fi - else - if jq -e '.extra["wp-svn-autopublish"] // false' "$F" &>/dev/null; then - MANUALTAG+=( "$PLUGIN" ) - else - MANUALBOTH+=( "$PLUGIN" ) - fi - fi +# Run each release step. +for ((i = CUR_STEP; i < ${#RELEASE_STEPS[@]}; i++)); do + green "Step $i: ${RELEASE_STEPS[$i]}" + "${RELEASE_STEPS[$i]}" + ((CUR_STEP+=1)) done -if [[ ${#AUTO[@]} -gt 0 ]]; then - cat <<-EOM - - For these plugins: ${AUTO[*]} - The release will shortly be tagged to GitHub and released to SVN and you can - then smoke test the release. Once ready, use \`./tools/stable-tag.sh \` - to update the stable tag, and you're done! - EOM -fi - -if [[ ${#MANUALTAGONLY[@]} -gt 0 ]]; then - cat <<-EOM - - For these plugins: ${MANUALTAGONLY[*]} - Wait for the changes to appear in the mirror repo and conduct a GitHub - release. Then you're done! - EOM -fi - -if [[ ${#MANUALTAG[@]} -gt 0 ]]; then - cat <<-EOM - - For these plugins: ${MANUALTAG[*]} - Wait for the changes to appear in the mirror repo and conduct a GitHub - release. The changes will then be automatically released to SVN and you can - then smote test the release. Once ready, use \`./tools/stable-tag.sh \` - to update the stable tag, and you're done! - EOM -fi - -if [[ ${#MANUALPUB[@]} -gt 0 ]]; then - cat <<-EOM - - For these plugins: ${MANUALPUB[*]} - The release will shortly be tagged to GitHub. Once the tag appears, deploy it - to SVN by running \`./tools/deploy-to-svn.sh \`, and smoke test. - When ready, flip the stable tag with \`./tools/stable-tag.sh \` and - you're all set. - EOM -fi - -if [[ ${#MANUALBOTH[@]} -gt 0 ]]; then - cat <<-EOM - - For these plugins: ${MANUALBOTH[*]} - Wait for the changes to appear in the mirror repo, and conduct a GitHub - release. Next, deploy the tag to SVN by running - \`./tools/deploy-to-svn.sh \`, and smoke test. When ready, flip - the stable tag with \`./tools/stable-tag.sh \` and you're all set. - EOM -fi - send_tracks_event "jetpack_release_done" From ae2a3997adb7ea420784de06ec9a61e1c8883bb3 Mon Sep 17 00:00:00 2001 From: Ben Zhu <6070516+benzhu56@users.noreply.github.com> Date: Thu, 19 Dec 2024 11:14:16 +1000 Subject: [PATCH 12/45] Add mask css rule to csstidy allow list (#40655) * Add mask css rule to allow list * Add changelog --------- Co-authored-by: Ben Zhu --- .../changelog/benz56-add-mask-css-rule-to-allowlist | 4 ++++ .../src/features/custom-css/csstidy/data.inc.php | 1 + 2 files changed, 5 insertions(+) create mode 100644 projects/packages/jetpack-mu-wpcom/changelog/benz56-add-mask-css-rule-to-allowlist diff --git a/projects/packages/jetpack-mu-wpcom/changelog/benz56-add-mask-css-rule-to-allowlist b/projects/packages/jetpack-mu-wpcom/changelog/benz56-add-mask-css-rule-to-allowlist new file mode 100644 index 0000000000000..0841f37a48c0e --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/changelog/benz56-add-mask-css-rule-to-allowlist @@ -0,0 +1,4 @@ +Significance: patch +Type: added + +CSS Tidy: add css rule mask to allowlist diff --git a/projects/packages/jetpack-mu-wpcom/src/features/custom-css/csstidy/data.inc.php b/projects/packages/jetpack-mu-wpcom/src/features/custom-css/csstidy/data.inc.php index 87163a845e502..760f24d8d2782 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/custom-css/csstidy/data.inc.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/custom-css/csstidy/data.inc.php @@ -549,6 +549,7 @@ $GLOBALS['csstidy']['all_properties']['marquee-play-count'] = 'CSS3.0'; $GLOBALS['csstidy']['all_properties']['marquee-speed'] = 'CSS3.0'; $GLOBALS['csstidy']['all_properties']['marquee-style'] = 'CSS3.0'; +$GLOBALS['csstidy']['all_properties']['mask'] = 'CSS3.0'; $GLOBALS['csstidy']['all_properties']['mask-clip'] = 'CSS3.0'; $GLOBALS['csstidy']['all_properties']['mask-composite'] = 'CSS3.0'; $GLOBALS['csstidy']['all_properties']['mask-image'] = 'CSS3.0'; From cff42cc9319a4141640c16e7c81aa881b35e9936 Mon Sep 17 00:00:00 2001 From: Bryan Elliott Date: Wed, 18 Dec 2024 22:44:49 -0500 Subject: [PATCH 13/45] My Jetpack: Add Backup 'needs-attention' status when backups are failing. (#40454) * Add red bubble alert if Backups failing. --- .../packages/my-jetpack/.phan/baseline.php | 2 +- .../components/product-card/action-button.tsx | 12 +++ .../_inc/components/product-card/index.tsx | 3 +- .../_inc/components/product-card/status.tsx | 3 + .../packages/my-jetpack/_inc/constants.ts | 1 + .../add-backup-needs-attention-status | 4 + .../my-jetpack/src/class-products.php | 2 + .../my-jetpack/src/products/class-backup.php | 97 ++++++++++++++++++- .../my-jetpack/src/products/class-product.php | 14 +++ 9 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 projects/packages/my-jetpack/changelog/add-backup-needs-attention-status diff --git a/projects/packages/my-jetpack/.phan/baseline.php b/projects/packages/my-jetpack/.phan/baseline.php index dd9d2bb32018e..50deef4b803f2 100644 --- a/projects/packages/my-jetpack/.phan/baseline.php +++ b/projects/packages/my-jetpack/.phan/baseline.php @@ -37,7 +37,7 @@ 'src/class-rest-zendesk-chat.php' => ['PhanParamTooMany'], 'src/class-wpcom-products.php' => ['PhanTypeMismatchReturnProbablyReal'], 'src/products/class-anti-spam.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchPropertyDefault'], - 'src/products/class-backup.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchPropertyDefault'], + 'src/products/class-backup.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchPropertyDefault', 'PhanTypeSuspiciousNonTraversableForeach'], 'src/products/class-boost.php' => ['PhanTypeMismatchPropertyDefault'], 'src/products/class-creator.php' => ['PhanTypeMismatchPropertyDefault', 'PhanTypeMismatchReturnProbablyReal'], 'src/products/class-crm.php' => ['PhanTypeMismatchPropertyDefault'], diff --git a/projects/packages/my-jetpack/_inc/components/product-card/action-button.tsx b/projects/packages/my-jetpack/_inc/components/product-card/action-button.tsx index 61984095e7a30..82878556ba7c6 100644 --- a/projects/packages/my-jetpack/_inc/components/product-card/action-button.tsx +++ b/projects/packages/my-jetpack/_inc/components/product-card/action-button.tsx @@ -44,6 +44,8 @@ const ActionButton: FC< ActionButtonProps > = ( { upgradeInInterstitial, isOwned, } ) => { + const troubleshootBackupsUrl = + 'https://jetpack.com/support/backup/troubleshooting-jetpack-backup/'; const [ isDropdownOpen, setIsDropdownOpen ] = useState( false ); const [ currentAction, setCurrentAction ] = useState< ComponentProps< typeof Button > >( {} ); const { detail } = useProduct( slug ); @@ -208,6 +210,16 @@ const ActionButton: FC< ActionButtonProps > = ( { PRODUCT_STATUSES.EXPIRED in primaryActionOverride && primaryActionOverride[ PRODUCT_STATUSES.EXPIRED ] ), }; + case PRODUCT_STATUSES.NEEDS_ATTENTION: + return { + ...buttonState, + href: troubleshootBackupsUrl, + variant: 'primary', + label: __( 'Troubleshoot', 'jetpack-my-jetpack' ), + ...( primaryActionOverride && + PRODUCT_STATUSES.NEEDS_ATTENTION in primaryActionOverride && + primaryActionOverride[ PRODUCT_STATUSES.NEEDS_ATTENTION ] ), + }; default: return null; } diff --git a/projects/packages/my-jetpack/_inc/components/product-card/index.tsx b/projects/packages/my-jetpack/_inc/components/product-card/index.tsx index 72b536197a895..5fbe96fd6f7e5 100644 --- a/projects/packages/my-jetpack/_inc/components/product-card/index.tsx +++ b/projects/packages/my-jetpack/_inc/components/product-card/index.tsx @@ -70,7 +70,8 @@ const ProductCard: FC< ProductCardProps > = props => { const { ownedProducts } = getMyJetpackWindowInitialState( 'lifecycleStats' ); const isOwned = ownedProducts?.includes( slug ); - const isError = status === PRODUCT_STATUSES.EXPIRED; + const isError = + status === PRODUCT_STATUSES.EXPIRED || status === PRODUCT_STATUSES.NEEDS_ATTENTION; const isWarning = status === PRODUCT_STATUSES.EXPIRING_SOON; const isAbsent = status === PRODUCT_STATUSES.ABSENT || status === PRODUCT_STATUSES.ABSENT_WITH_PLAN; diff --git a/projects/packages/my-jetpack/_inc/components/product-card/status.tsx b/projects/packages/my-jetpack/_inc/components/product-card/status.tsx index 51e6d4ed429e7..f46baca25a7d3 100644 --- a/projects/packages/my-jetpack/_inc/components/product-card/status.tsx +++ b/projects/packages/my-jetpack/_inc/components/product-card/status.tsx @@ -40,6 +40,8 @@ const getStatusLabel: StatusStateFunction = ( status, isOwned ) => { const inactiveText = __( 'Inactive', 'jetpack-my-jetpack' ); return isOwned ? needsPlanText : inactiveText; } + case PRODUCT_STATUSES.NEEDS_ATTENTION: + return __( 'Needs attention', 'jetpack-my-jetpack' ); default: return __( 'Inactive', 'jetpack-my-jetpack' ); } @@ -62,6 +64,7 @@ const getStatusClassName: StatusStateFunction = ( status, isOwned ) => { case PRODUCT_STATUSES.NEEDS_PLAN: return isOwned ? styles.warning : styles.inactive; case PRODUCT_STATUSES.EXPIRED: + case PRODUCT_STATUSES.NEEDS_ATTENTION: return styles.error; default: return styles.inactive; diff --git a/projects/packages/my-jetpack/_inc/constants.ts b/projects/packages/my-jetpack/_inc/constants.ts index af4cdacb11fe5..1503114ca4de0 100644 --- a/projects/packages/my-jetpack/_inc/constants.ts +++ b/projects/packages/my-jetpack/_inc/constants.ts @@ -41,4 +41,5 @@ export const PRODUCT_STATUSES = { CAN_UPGRADE: 'can_upgrade', EXPIRING_SOON: 'expiring', EXPIRED: 'expired', + NEEDS_ATTENTION: 'needs_attention', }; diff --git a/projects/packages/my-jetpack/changelog/add-backup-needs-attention-status b/projects/packages/my-jetpack/changelog/add-backup-needs-attention-status new file mode 100644 index 0000000000000..ba8a03a3a2ebc --- /dev/null +++ b/projects/packages/my-jetpack/changelog/add-backup-needs-attention-status @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +My Jetpack: Add 'Needs attention' status to Backup product card when Backups are failing. diff --git a/projects/packages/my-jetpack/src/class-products.php b/projects/packages/my-jetpack/src/class-products.php index 8f8681fdb2ab8..33e894329a507 100644 --- a/projects/packages/my-jetpack/src/class-products.php +++ b/projects/packages/my-jetpack/src/class-products.php @@ -29,6 +29,7 @@ class Products { const STATUS_NEEDS_PLAN = 'needs_plan'; const STATUS_NEEDS_ACTIVATION = 'needs_activation'; const STATUS_NEEDS_FIRST_SITE_CONNECTION = 'needs_first_site_connection'; + const STATUS_NEEDS_ATTENTION = 'needs_attention'; /** * List of statuses that display the module as disabled @@ -107,6 +108,7 @@ class Products { self::STATUS_NEEDS_PLAN, self::STATUS_NEEDS_ACTIVATION, self::STATUS_NEEDS_FIRST_SITE_CONNECTION, + self::STATUS_NEEDS_ATTENTION, ); /** diff --git a/projects/packages/my-jetpack/src/products/class-backup.php b/projects/packages/my-jetpack/src/products/class-backup.php index 8566a4b8738bf..bee360c09ee2a 100644 --- a/projects/packages/my-jetpack/src/products/class-backup.php +++ b/projects/packages/my-jetpack/src/products/class-backup.php @@ -1,6 +1,6 @@ 2 ), null, 'wpcom' ); + $response = Client::wpcom_json_api_request_as_blog( + sprintf( '/sites/%d/rewind', $site_id ) . '?force=wpcom', + '2', + array( 'timeout' => 2 ), + null, + 'wpcom' + ); if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { $status = new WP_Error( 'rewind_state_fetch_failed' ); @@ -200,6 +205,90 @@ private static function get_state_from_wpcom() { return $status; } + /** + * Hits the wpcom api to retrieve the last 10 backup records. + * + * @return Object|WP_Error + */ + public static function get_latest_backups() { + static $backups = null; + + if ( $backups !== null ) { + return $backups; + } + + $site_id = \Jetpack_Options::get_option( 'id' ); + $response = Client::wpcom_json_api_request_as_blog( + sprintf( '/sites/%d/rewind/backups', $site_id ) . '?force=wpcom', + '2', + array( 'timeout' => 2 ), + null, + 'wpcom' + ); + + if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { + $backups = new WP_Error( 'rewind_backups_fetch_failed' ); + return $backups; + } + + $body = wp_remote_retrieve_body( $response ); + $backups = json_decode( $body ); + return $backups; + } + + /** + * Determines whether the module/plugin/product needs the users attention. + * Typically due to some sort of error where user troubleshooting is needed. + * + * @return boolean|array + */ + public static function does_module_need_attention() { + $backup_failed_status = false; + // First check the status of Rewind for failure. + $rewind_state = self::get_state_from_wpcom(); + if ( ! is_wp_error( $rewind_state ) ) { + $backup_failure_reasons = array( + 'unknown_error', + 'no_site_found', + 'missing_plan', + 'no_connected_jetpack', + 'no_connected_jetpack_with_credentials', + 'multisite_not_supported', + 'host_not_supported', + 'vp_active_on_site', + ); + if ( $rewind_state->state === 'unavailable' && ! empty( $rewind_state->reason ) && in_array( $rewind_state->reason, $backup_failure_reasons, true ) ) { + $backup_failed_status = array( + 'status' => $rewind_state->reason, + 'last_updated' => $rewind_state->last_updated, + ); + } + } + // Next check for a failed last backup. + $latest_backups = self::get_latest_backups(); + if ( ! is_wp_error( $latest_backups ) ) { + // Get the last/latest backup record. + $last_backup = null; + foreach ( $latest_backups as $backup ) { + if ( $backup->is_backup ) { + $last_backup = $backup; + break; + } + } + + if ( $last_backup && isset( $last_backup->status ) ) { + if ( $last_backup->status === 'not-accessible' || $last_backup->status === 'error' || $last_backup->status === 'credential-error' ) { + $backup_failed_status = array( + 'status' => $last_backup->status, + 'last_updated' => $last_backup->last_updated, + ); + } + } + } + + return $backup_failed_status; + } + /** * Return product bundles list * that supports the product. diff --git a/projects/packages/my-jetpack/src/products/class-product.php b/projects/packages/my-jetpack/src/products/class-product.php index 128d00ea3307c..b2262eddd6b4a 100644 --- a/projects/packages/my-jetpack/src/products/class-product.php +++ b/projects/packages/my-jetpack/src/products/class-product.php @@ -10,6 +10,7 @@ use Automattic\Jetpack\Connection\Client; use Automattic\Jetpack\Connection\Manager as Connection_Manager; use Automattic\Jetpack\Modules; +use Automattic\Jetpack\My_Jetpack\Products\Backup; use Automattic\Jetpack\Plugins_Installer; use Automattic\Jetpack\Status; use Jetpack_Options; @@ -716,6 +717,9 @@ public static function get_status() { } elseif ( static::$requires_user_connection && ! ( new Connection_Manager() )->has_connected_owner() ) { $status = Products::STATUS_USER_CONNECTION_ERROR; } elseif ( static::has_paid_plan_for_product() ) { + if ( static::$slug === 'backup' && Backup::does_module_need_attention() ) { + $status = Products::STATUS_NEEDS_ATTENTION; + } if ( static::is_paid_plan_expired() ) { $status = Products::STATUS_EXPIRED; } elseif ( static::is_paid_plan_expiring() ) { @@ -987,4 +991,14 @@ public static function install_and_activate_standalone() { return true; } + + /** + * Determines whether the module/plugin/product needs the users attention. + * Typically due to some sort of error where user troubleshooting is needed. + * + * @return boolean + */ + public static function does_module_need_attention() { + return false; + } } From f12d3de6f331fb7a5b689cbbc297298dad45a9a8 Mon Sep 17 00:00:00 2001 From: Manzoor Wani Date: Wed, 18 Dec 2024 20:37:19 -0800 Subject: [PATCH 14/45] Move wpcom/v2/publicize/connections endpoint to publicize package (#40607) * Move wpcom/v2/publicize/connections endpoint to publicize package * Fix Fatals in Publicize base class on WPCOM * Now we can use v2 for proxy requests * Phan needs a fan because I am not * Update baseline.php * Use publicize for fields for now instead of a new class * Move initialization logic to Publicize_Setup * Clean up * Update phan baseline * Use null for the status field as default * Default external_handle to null * Return null in all cases for external_handle * Make get_username use get_external_handle * Rename rest-endpoints to rest-api * Clean up prepare_item_for_response * Update baseline.php * Use schema caching --- .../packages/publicize/.phan/baseline.php | 8 +- projects/packages/publicize/.phan/config.php | 1 + projects/packages/publicize/actions.php | 4 +- ...pcom-v2-publicize-connections-to-publicize | 4 + .../publicize/src/class-publicize-base.php | 40 ++- .../publicize/src/class-publicize-setup.php | 27 ++ .../src/rest-api/class-base-controller.php | 85 +++++ .../rest-api/class-connections-controller.php | 304 ++++++++++++++++++ projects/plugins/jetpack/.phan/baseline.php | 3 +- .../wpcom-endpoints/publicize-connections.php | 23 +- ...pcom-v2-publicize-connections-to-publicize | 4 + 11 files changed, 463 insertions(+), 40 deletions(-) create mode 100644 projects/packages/publicize/changelog/update-move-wpcom-v2-publicize-connections-to-publicize create mode 100644 projects/packages/publicize/src/rest-api/class-base-controller.php create mode 100644 projects/packages/publicize/src/rest-api/class-connections-controller.php create mode 100644 projects/plugins/jetpack/changelog/update-move-wpcom-v2-publicize-connections-to-publicize diff --git a/projects/packages/publicize/.phan/baseline.php b/projects/packages/publicize/.phan/baseline.php index 276871afd3219..ae1e8cfe766d4 100644 --- a/projects/packages/publicize/.phan/baseline.php +++ b/projects/packages/publicize/.phan/baseline.php @@ -9,17 +9,18 @@ */ return [ // # Issue statistics: - // PhanTypeMismatchArgument : 7 occurrences // PhanPluginDuplicateConditionalNullCoalescing : 6 occurrences + // PhanTypeMismatchArgument : 6 occurrences // PhanTypeMismatchArgumentNullable : 3 occurrences // PhanDeprecatedFunction : 2 occurrences + // PhanPluginMixedKeyNoKey : 2 occurrences // PhanPossiblyUndeclaredVariable : 2 occurrences // PhanTypeMismatchReturnProbablyReal : 2 occurrences // PhanTypeMissingReturn : 2 occurrences // PhanImpossibleCondition : 1 occurrence + // PhanNoopNew : 1 occurrence // PhanParamSignatureMismatch : 1 occurrence // PhanPluginDuplicateExpressionAssignmentOperation : 1 occurrence - // PhanPluginMixedKeyNoKey : 1 occurrence // PhanPluginSimplifyExpressionBool : 1 occurrence // PhanSuspiciousMagicConstant : 1 occurrence // PhanTypeMismatchArgumentNullableInternal : 1 occurrence @@ -33,10 +34,11 @@ 'src/class-connections-post-field.php' => ['PhanPluginDuplicateConditionalNullCoalescing'], 'src/class-keyring-helper.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchDefault'], 'src/class-publicize-base.php' => ['PhanImpossibleCondition', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginSimplifyExpressionBool', 'PhanSuspiciousMagicConstant', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchReturn'], - 'src/class-publicize-setup.php' => ['PhanTypeMismatchArgument'], + 'src/class-publicize-setup.php' => ['PhanNoopNew', 'PhanTypeMismatchArgument'], 'src/class-publicize-ui.php' => ['PhanPluginDuplicateExpressionAssignmentOperation', 'PhanTypeMismatchReturnProbablyReal'], 'src/class-publicize.php' => ['PhanParamSignatureMismatch', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgument', 'PhanTypeMissingReturn'], 'src/class-rest-controller.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanTypeMismatchReturnProbablyReal'], + 'src/rest-api/class-connections-controller.php' => ['PhanPluginMixedKeyNoKey'], 'src/social-image-generator/class-post-settings.php' => ['PhanPluginDuplicateConditionalNullCoalescing'], 'src/social-image-generator/class-rest-settings-controller.php' => ['PhanPluginMixedKeyNoKey'], 'src/social-image-generator/class-settings.php' => ['PhanPluginDuplicateConditionalNullCoalescing'], diff --git a/projects/packages/publicize/.phan/config.php b/projects/packages/publicize/.phan/config.php index 7030e2aa8176c..075dd16643b9e 100644 --- a/projects/packages/publicize/.phan/config.php +++ b/projects/packages/publicize/.phan/config.php @@ -24,6 +24,7 @@ __DIR__ . '/../../../plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php', // class Jetpack_Admin_Page __DIR__ . '/../../../plugins/jetpack/modules/subscriptions.php', // class Jetpack_Subscriptions __DIR__ . '/../../../plugins/jetpack/functions.global.php', // function jetpack_render_tos_blurb + __DIR__ . '/../../../plugins/jetpack/_inc/lib/core-api/load-wpcom-endpoints.php', // function wpcom_rest_api_v2_load_plugin ), ) ); diff --git a/projects/packages/publicize/actions.php b/projects/packages/publicize/actions.php index 8a1413391ae13..27748d4f9ffd0 100644 --- a/projects/packages/publicize/actions.php +++ b/projects/packages/publicize/actions.php @@ -8,12 +8,12 @@ // If WordPress's plugin API is available already, use it. If not, // drop data into `$wp_filter` for `WP_Hook::build_preinitialized_hooks()`. if ( function_exists( 'add_action' ) ) { - add_action( 'plugins_loaded', array( Automattic\Jetpack\Publicize\Publicize_Assets::class, 'configure' ), 1 ); + add_action( 'plugins_loaded', array( Automattic\Jetpack\Publicize\Publicize_Setup::class, 'pre_initialization' ), 1 ); } else { global $wp_filter; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited $wp_filter['plugins_loaded'][1][] = array( 'accepted_args' => 0, - 'function' => array( Automattic\Jetpack\Publicize\Publicize_Assets::class, 'configure' ), + 'function' => array( Automattic\Jetpack\Publicize\Publicize_Setup::class, 'pre_initialization' ), ); } diff --git a/projects/packages/publicize/changelog/update-move-wpcom-v2-publicize-connections-to-publicize b/projects/packages/publicize/changelog/update-move-wpcom-v2-publicize-connections-to-publicize new file mode 100644 index 0000000000000..9d87109f63b2c --- /dev/null +++ b/projects/packages/publicize/changelog/update-move-wpcom-v2-publicize-connections-to-publicize @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Moved wpcom/v2/publicize/connections endpoint to publicize package diff --git a/projects/packages/publicize/src/class-publicize-base.php b/projects/packages/publicize/src/class-publicize-base.php index b88bd1a6b12ca..c2e6c044cc5bf 100644 --- a/projects/packages/publicize/src/class-publicize-base.php +++ b/projects/packages/publicize/src/class-publicize-base.php @@ -497,8 +497,8 @@ public function get_profile_link( $service_name, $connection ) { return 'https://instagram.com/' . $cmeta['connection_data']['meta']['username']; } - if ( 'threads' === $service_name && isset( $connection['external_name'] ) ) { - return 'https://www.threads.net/@' . $connection['external_name']; + if ( 'threads' === $service_name && isset( $cmeta['external_name'] ) ) { + return 'https://www.threads.net/@' . $cmeta['external_name']; } if ( 'mastodon' === $service_name && isset( $cmeta['external_name'] ) ) { @@ -527,7 +527,7 @@ public function get_profile_link( $service_name, $connection ) { } $profile_url_query = wp_parse_url( $cmeta['connection_data']['meta']['profile_url'], PHP_URL_QUERY ); - $profile_url_query_args = null; + $profile_url_query_args = array(); wp_parse_str( $profile_url_query, $profile_url_query_args ); $id = null; @@ -589,17 +589,35 @@ public function get_display_name( $service_name, $connection ) { * @return string */ public function get_username( $service_name, $connection ) { + $handle = $this->get_external_handle( $service_name, $connection ); + + return $handle ?? $this->get_display_name( $service_name, $connection ); + } + + /** + * Returns the external handle for the Connection. + * + * @param string $service_name 'facebook', 'linkedin', etc. + * @param object|array $connection The Connection object (WordPress.com) or array (Jetpack). + * @return string|null + */ + public function get_external_handle( $service_name, $connection ) { $cmeta = $this->get_connection_meta( $connection ); - if ( 'mastodon' === $service_name && isset( $cmeta['external_display'] ) ) { - return $cmeta['external_display']; - } + switch ( $service_name ) { + case 'mastodon': + return $cmeta['external_display'] ?? null; - if ( isset( $cmeta['connection_data']['meta']['username'] ) ) { - return $cmeta['connection_data']['meta']['username']; - } + case 'bluesky': + case 'threads': + return $cmeta['external_name'] ?? null; - return $this->get_display_name( $service_name, $connection ); + case 'instagram-business': + return $cmeta['connection_data']['meta']['username'] ?? null; + + default: + return null; + } } /** @@ -608,7 +626,7 @@ public function get_username( $service_name, $connection ) { * @param object|array $connection The Connection object (WordPress.com) or array (Jetpack). * @return string */ - private function get_profile_picture( $connection ) { + public function get_profile_picture( $connection ) { $cmeta = $this->get_connection_meta( $connection ); if ( isset( $cmeta['profile_picture'] ) ) { diff --git a/projects/packages/publicize/src/class-publicize-setup.php b/projects/packages/publicize/src/class-publicize-setup.php index 383ef289fab5e..dc4dc5a3997c2 100644 --- a/projects/packages/publicize/src/class-publicize-setup.php +++ b/projects/packages/publicize/src/class-publicize-setup.php @@ -7,6 +7,9 @@ namespace Automattic\Jetpack\Publicize; +use Automattic\Jetpack\Publicize\REST_API\Connections_Controller; +use Automattic\Jetpack\Status\Host; + /** * The class to configure and initialize the publicize package. */ @@ -26,6 +29,30 @@ public static function configure() { add_action( 'jetpack_feature_publicize_enabled', array( __CLASS__, 'on_jetpack_feature_publicize_enabled' ) ); } + /** + * Initialization of publicize logic that should always be loaded. + */ + public static function pre_initialization() { + + $is_wpcom = ( new Host() )->is_wpcom_simple(); + + // Assets are to be loaded in all cases. + Publicize_Assets::configure(); + + $rest_controllers = array( + Connections_Controller::class, + ); + + // Load the REST controllers. + foreach ( $rest_controllers as $controller ) { + if ( $is_wpcom ) { + wpcom_rest_api_v2_load_plugin( $controller ); + } else { + new $controller(); + } + } + } + /** * To configure the publicize package, when called via the Config package. */ diff --git a/projects/packages/publicize/src/rest-api/class-base-controller.php b/projects/packages/publicize/src/rest-api/class-base-controller.php new file mode 100644 index 0000000000000..acf0aa0c78cc2 --- /dev/null +++ b/projects/packages/publicize/src/rest-api/class-base-controller.php @@ -0,0 +1,85 @@ +wpcom_is_wpcom_only_endpoint = true; + } + + /** + * Check if we are on WPCOM. + * + * @return bool + */ + public static function is_wpcom() { + return ( new Host() )->is_wpcom_simple(); + } + + /** + * Filters out data based on ?_fields= request parameter + * + * @param array $item Item to prepare. + * @param WP_REST_Request $request Full details about the request. + * + * @return WP_REST_Response filtered item + */ + public function prepare_item_for_response( $item, $request ) { + + $fields = $this->get_fields_for_response( $request ); + + $response_data = array(); + foreach ( $item as $field => $value ) { + if ( rest_is_field_included( $field, $fields ) ) { + $response_data[ $field ] = $value; + } + } + + return rest_ensure_response( $response_data ); + } + + /** + * Verify that user can access Publicize data + * + * @return true|WP_Error + */ + public function get_items_permission_check() { + global $publicize; + + if ( ! $publicize ) { + return new WP_Error( + 'publicize_not_available', + __( 'Sorry, Jetpack Social is not available on your site right now.', 'jetpack-publicize-pkg' ), + array( 'status' => rest_authorization_required_code() ) + ); + } + + if ( $publicize->current_user_can_access_publicize_data() ) { + return true; + } + + return new WP_Error( + 'invalid_user_permission_publicize', + __( 'Sorry, you are not allowed to access Jetpack Social data on this site.', 'jetpack-publicize-pkg' ), + array( 'status' => rest_authorization_required_code() ) + ); + } +} diff --git a/projects/packages/publicize/src/rest-api/class-connections-controller.php b/projects/packages/publicize/src/rest-api/class-connections-controller.php new file mode 100644 index 0000000000000..f1710bca05a93 --- /dev/null +++ b/projects/packages/publicize/src/rest-api/class-connections-controller.php @@ -0,0 +1,304 @@ +namespace = 'wpcom/v2'; + $this->rest_base = 'publicize/connections'; + + add_action( 'rest_api_init', array( $this, 'register_routes' ) ); + } + + /** + * Register the routes. + */ + public function register_routes() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base, + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permission_check' ), + 'args' => array( + 'test_connections' => array( + 'type' => 'boolean', + 'description' => __( 'Whether to test connections.', 'jetpack-publicize-pkg' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); + } + + /** + * Schema for the endpoint. + * + * @return array + */ + public function get_item_schema() { + if ( $this->schema ) { + return $this->add_additional_fields_schema( $this->schema ); + } + $deprecated_fields = array( + 'id' => array( + 'type' => 'string', + 'description' => __( 'Unique identifier for the Jetpack Social connection.', 'jetpack-publicize-pkg' ) . ' ' . sprintf( + /* translators: %s is the new field name */ + __( 'Deprecated in favor of %s.', 'jetpack-publicize-pkg' ), + 'connection_id' + ), + ), + 'username' => array( + 'type' => 'string', + 'description' => __( 'Username of the connected account.', 'jetpack-publicize-pkg' ) . ' ' . sprintf( + /* translators: %s is the new field name */ + __( 'Deprecated in favor of %s.', 'jetpack-publicize-pkg' ), + 'external_handle' + ), + ), + 'profile_display_name' => array( + 'type' => 'string', + 'description' => __( 'The name to display in the profile of the connected account.', 'jetpack-publicize-pkg' ) . ' ' . sprintf( + /* translators: %s is the new field name */ + __( 'Deprecated in favor of %s.', 'jetpack-publicize-pkg' ), + 'display_name' + ), + ), + 'global' => array( + 'type' => 'boolean', + 'description' => __( 'Is this connection available to all users?', 'jetpack-publicize-pkg' ) . ' ' . sprintf( + /* translators: %s is the new field name */ + __( 'Deprecated in favor of %s.', 'jetpack-publicize-pkg' ), + 'shared' + ), + ), + ); + + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'jetpack-publicize-connection', + 'type' => 'object', + 'properties' => array_merge( + $deprecated_fields, + array( + 'connection_id' => array( + 'type' => 'string', + 'description' => __( 'Connection ID of the connected account.', 'jetpack-publicize-pkg' ), + ), + 'display_name' => array( + 'type' => 'string', + 'description' => __( 'Display name of the connected account.', 'jetpack-publicize-pkg' ), + ), + 'external_handle' => array( + 'type' => 'string', + 'description' => __( 'The external handle or username of the connected account.', 'jetpack-publicize-pkg' ), + ), + 'external_id' => array( + 'type' => 'string', + 'description' => __( 'The external ID of the connected account.', 'jetpack-publicize-pkg' ), + ), + 'profile_link' => array( + 'type' => 'string', + 'description' => __( 'Profile link of the connected account.', 'jetpack-publicize-pkg' ), + ), + 'profile_picture' => array( + 'type' => 'string', + 'description' => __( 'URL of the profile picture of the connected account.', 'jetpack-publicize-pkg' ), + ), + 'service_label' => array( + 'type' => 'string', + 'description' => __( 'Human-readable label for the Jetpack Social service.', 'jetpack-publicize-pkg' ), + ), + 'service_name' => array( + 'type' => 'string', + 'description' => __( 'Alphanumeric identifier for the Jetpack Social service.', 'jetpack-publicize-pkg' ), + ), + 'shared' => array( + 'type' => 'boolean', + 'description' => __( 'Whether the connection is shared with other users.', 'jetpack-publicize-pkg' ), + ), + 'status' => array( + 'type' => 'string', + 'description' => __( 'The connection status.', 'jetpack-publicize-pkg' ), + 'enum' => array( + 'ok', + 'broken', + ), + ), + 'user_id' => array( + 'type' => 'integer', + 'description' => __( 'ID of the user the connection belongs to.', 'jetpack-publicize-pkg' ), + ), + ) + ), + ); + + $this->schema = $schema; + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get all connections. Meant to be called directly only on WPCOM. + * + * @param bool $run_tests Whether to run tests on the connections. + * + * @return array + */ + protected static function get_all_connections( $run_tests = false ) { + /** + * Publicize instance. + * + * @var \Automattic\Jetpack\Publicize\Publicize $publicize + */ + global $publicize; + + $items = array(); + + $test_results = $run_tests ? self::get_connections_test_status() : array(); + + foreach ( (array) $publicize->get_services( 'connected' ) as $service_name => $connections ) { + foreach ( $connections as $connection ) { + + $connection_id = $publicize->get_connection_id( $connection ); + + $connection_meta = $publicize->get_connection_meta( $connection ); + $connection_data = $connection_meta['connection_data']; + + $items[] = array( + 'connection_id' => $connection_id, + 'display_name' => $publicize->get_display_name( $service_name, $connection ), + 'external_handle' => $publicize->get_external_handle( $service_name, $connection ), + 'external_id' => $connection_meta['external_id'] ?? '', + 'profile_link' => $publicize->get_profile_link( $service_name, $connection ), + 'profile_picture' => $publicize->get_profile_picture( $connection ), + 'service_label' => Publicize::get_service_label( $service_name ), + 'service_name' => $service_name, + 'shared' => ! $connection_data['user_id'], + 'status' => $test_results[ $connection_id ] ?? null, + 'user_id' => (int) $connection_data['user_id'], + + // Deprecated fields. + 'id' => (string) $publicize->get_connection_unique_id( $connection ), + 'username' => $publicize->get_username( $service_name, $connection ), + 'profile_display_name' => ! empty( $connection_meta['profile_display_name'] ) ? $connection_meta['profile_display_name'] : '', + // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual -- We expect an integer, but do loose comparison below in case some other type is stored. + 'global' => 0 == $connection_data['user_id'], + + ); + } + } + + return $items; + } + + /** + * Get a list of publicize connections. + * + * @param bool $run_tests Whether to run tests on the connections. + * + * @return array + */ + public static function get_connections( $run_tests = false ) { + if ( self::is_wpcom() ) { + return self::get_all_connections( $run_tests ); + } + + $site_id = Manager::get_site_id( true ); + if ( ! $site_id ) { + return array(); + } + + $path = add_query_arg( + array( 'test_connections' => $run_tests ), + sprintf( '/sites/%d/publicize/connections', $site_id ) + ); + + $response = Client::wpcom_json_api_request_as_user( $path, 'v2', array( 'method' => 'GET' ) ); + + if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { + // TODO log error. + return array(); + } + + $body = wp_remote_retrieve_body( $response ); + + $items = json_decode( $body, true ); + + return $items ? $items : array(); + } + + /** + * Get list of connected Publicize connections. + * + * @param WP_REST_Request $request Full details about the request. + * + * @return WP_REST_Response suitable for 1-page collection + */ + public function get_items( $request ) { + $items = array(); + + $run_tests = $request->get_param( 'test_connections' ); + + foreach ( self::get_connections( $run_tests ) as $item ) { + $data = $this->prepare_item_for_response( $item, $request ); + + $items[] = $this->prepare_response_for_collection( $data ); + } + + $response = rest_ensure_response( $items ); + $response->header( 'X-WP-Total', (string) count( $items ) ); + $response->header( 'X-WP-TotalPages', '1' ); + + return $response; + } + + /** + * Get the connections test status. + * + * @return array + */ + protected static function get_connections_test_status() { + /** + * Publicize instance. + * + * @var \Automattic\Jetpack\Publicize\Publicize $publicize + */ + global $publicize; + + $test_results = $publicize->get_publicize_conns_test_results(); + + $test_results_map = array(); + + foreach ( $test_results as $test_result ) { + // Compare to `true` because the API returns a 'must_reauth' for LinkedIn. + $test_results_map[ $test_result['connectionID'] ] = true === $test_result['connectionTestPassed'] ? 'ok' : 'broken'; + } + + return $test_results_map; + } +} diff --git a/projects/plugins/jetpack/.phan/baseline.php b/projects/plugins/jetpack/.phan/baseline.php index d3614e00bc549..741c58a413969 100644 --- a/projects/plugins/jetpack/.phan/baseline.php +++ b/projects/plugins/jetpack/.phan/baseline.php @@ -81,7 +81,6 @@ // PhanTypeMismatchArgumentInternalProbablyReal : 2 occurrences // PhanUndeclaredClassInCallable : 2 occurrences // PhanUndeclaredClassMethod : 2 occurrences - // PhanCommentParamWithoutRealParam : 1 occurrence // PhanDeprecatedPartiallySupportedCallable : 1 occurrence // PhanEmptyForeach : 1 occurrence // PhanPluginDuplicateSwitchCase : 1 occurrence @@ -139,7 +138,7 @@ '_inc/lib/core-api/wpcom-endpoints/gutenberg-available-extensions.php' => ['PhanPluginMixedKeyNoKey'], '_inc/lib/core-api/wpcom-endpoints/memberships.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginUnreachableCode', 'PhanTypeArraySuspicious'], '_inc/lib/core-api/wpcom-endpoints/publicize-connection-test-results.php' => ['PhanPluginMixedKeyNoKey', 'PhanTypeMismatchArgument'], - '_inc/lib/core-api/wpcom-endpoints/publicize-connections.php' => ['PhanParamSignatureMismatch', 'PhanPluginMixedKeyNoKey', 'PhanTypeMismatchArgument'], + '_inc/lib/core-api/wpcom-endpoints/publicize-connections.php' => ['PhanParamSignatureMismatch', 'PhanTypeMismatchArgument'], '_inc/lib/core-api/wpcom-endpoints/publicize-services.php' => ['PhanParamSignatureMismatch', 'PhanPluginMixedKeyNoKey', 'PhanTypeMismatchArgument'], '_inc/lib/core-api/wpcom-endpoints/service-api-keys.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanTypeArraySuspicious', 'PhanTypeMismatchReturnProbablyReal'], '_inc/lib/core-api/wpcom-endpoints/trait-wpcom-rest-api-proxy-request-trait.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanUndeclaredProperty'], diff --git a/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connections.php b/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connections.php index 67fa5b25ced9e..35ffcbed109a9 100644 --- a/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connections.php +++ b/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connections.php @@ -29,32 +29,11 @@ class WPCOM_REST_API_V2_Endpoint_List_Publicize_Connections extends WP_REST_Cont */ public $wpcom_is_wpcom_only_endpoint = true; - /** - * Constructor. - */ - public function __construct() { - $this->namespace = 'wpcom/v2'; - $this->rest_base = 'publicize/connections'; - - add_action( 'rest_api_init', array( $this, 'register_routes' ) ); - } - /** * Called automatically on `rest_api_init()`. */ public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permission_check' ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) - ); + // Endpoint moved to publicize package. } /** diff --git a/projects/plugins/jetpack/changelog/update-move-wpcom-v2-publicize-connections-to-publicize b/projects/plugins/jetpack/changelog/update-move-wpcom-v2-publicize-connections-to-publicize new file mode 100644 index 0000000000000..5cb09fcc5fe9d --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-move-wpcom-v2-publicize-connections-to-publicize @@ -0,0 +1,4 @@ +Significance: patch +Type: other + +Moved wpcom/v2/publicize/connections endpoint to publicize package From 56c0fbc7c6bca58785d5a3a46ba12f83292cd9fd Mon Sep 17 00:00:00 2001 From: Bryan Elliott Date: Thu, 19 Dec 2024 00:01:28 -0500 Subject: [PATCH 15/45] My Jetpack: Add Backup 'needs-attention' red bubble and notice banner (#40512) * Add redbubble & notice when backups are failing. --- .../notice-component-minor-css-adjustment | 5 + .../components/notice/style.module.scss | 6 + .../_inc/components/info-tooltip/index.tsx | 2 + .../my-jetpack-screen/styles.module.scss | 1 + .../backup-card/index.jsx | 56 +++++- .../backup-card/style.module.scss | 42 +++++ .../protect-card/style.scss | 9 - .../product-cards-section/style.module.scss | 12 ++ .../hooks/use-notification-watcher/index.ts | 10 +- .../use-backup-needs-attention-notice.tsx | 115 ++++++++++++ .../use-get-readable-failed-backup-reason.tsx | 173 ++++++++++++++++++ .../my-jetpack/_inc/utils/apply-timezone.ts | 15 ++ ...dd-backup-redbubble-needs-attention-notice | 4 + projects/packages/my-jetpack/global.d.ts | 33 +++- .../my-jetpack/src/class-initializer.php | 33 +++- .../my-jetpack/src/class-products.php | 1 + .../my-jetpack/src/products/class-backup.php | 18 +- 17 files changed, 502 insertions(+), 33 deletions(-) create mode 100644 projects/js-packages/components/changelog/notice-component-minor-css-adjustment create mode 100644 projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-backup-needs-attention-notice.tsx create mode 100644 projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-get-readable-failed-backup-reason.tsx create mode 100644 projects/packages/my-jetpack/_inc/utils/apply-timezone.ts create mode 100644 projects/packages/my-jetpack/changelog/add-backup-redbubble-needs-attention-notice diff --git a/projects/js-packages/components/changelog/notice-component-minor-css-adjustment b/projects/js-packages/components/changelog/notice-component-minor-css-adjustment new file mode 100644 index 0000000000000..a005ea7cb6a5b --- /dev/null +++ b/projects/js-packages/components/changelog/notice-component-minor-css-adjustment @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Notice component: Minor css adjustment. + + diff --git a/projects/js-packages/components/components/notice/style.module.scss b/projects/js-packages/components/components/notice/style.module.scss index f765d25ab4566..1bf9ef4a578d2 100644 --- a/projects/js-packages/components/components/notice/style.module.scss +++ b/projects/js-packages/components/components/notice/style.module.scss @@ -62,6 +62,12 @@ display: flex; align-items: center; margin-top: 20px; + row-gap: 20px; + flex-wrap: wrap; + + @media screen and ( max-width: 600px ) { + justify-content: center; + } a { &, &:hover, &:active, &:focus { diff --git a/projects/packages/my-jetpack/_inc/components/info-tooltip/index.tsx b/projects/packages/my-jetpack/_inc/components/info-tooltip/index.tsx index be873a602847a..b4e6a62eae873 100644 --- a/projects/packages/my-jetpack/_inc/components/info-tooltip/index.tsx +++ b/projects/packages/my-jetpack/_inc/components/info-tooltip/index.tsx @@ -23,6 +23,7 @@ export const InfoTooltip: FC< Props > = ( { iconSize = 14, tracksEventName, tracksEventProps = {}, + ...rest } ) => { const { recordEvent } = useAnalytics(); const useTooltipRef = useRef< HTMLButtonElement >(); @@ -66,6 +67,7 @@ export const InfoTooltip: FC< Props > = ( { offset={ 10 } focusOnMount={ 'container' } onClose={ hideTooltip } + { ...rest } >
{ children }
diff --git a/projects/packages/my-jetpack/_inc/components/my-jetpack-screen/styles.module.scss b/projects/packages/my-jetpack/_inc/components/my-jetpack-screen/styles.module.scss index ff620626fc455..48fa729fd473c 100644 --- a/projects/packages/my-jetpack/_inc/components/my-jetpack-screen/styles.module.scss +++ b/projects/packages/my-jetpack/_inc/components/my-jetpack-screen/styles.module.scss @@ -29,6 +29,7 @@ font-size: 16px; font-weight: 600; padding: var(--spacing-base) calc(var(--spacing-base)* 3) !important; + white-space: nowrap; } // X close button diff --git a/projects/packages/my-jetpack/_inc/components/product-cards-section/backup-card/index.jsx b/projects/packages/my-jetpack/_inc/components/product-cards-section/backup-card/index.jsx index 0ab9107bf5649..03b669c4d4421 100644 --- a/projects/packages/my-jetpack/_inc/components/product-cards-section/backup-card/index.jsx +++ b/projects/packages/my-jetpack/_inc/components/product-cards-section/backup-card/index.jsx @@ -17,8 +17,10 @@ import useProduct from '../../../data/products/use-product'; import useSimpleQuery from '../../../data/use-simple-query'; import { getMyJetpackWindowInitialState } from '../../../data/utils/get-my-jetpack-window-state'; import useAnalytics from '../../../hooks/use-analytics'; +import { useGetReadableFailedBackupReason } from '../../../hooks/use-notification-watcher/use-get-readable-failed-backup-reason'; import numberFormat from '../../../utils/format-number'; import ProductCard from '../../connected-product-card'; +import { InfoTooltip } from '../../info-tooltip'; import styles from './style.module.scss'; const productSlug = PRODUCT_SLUGS.BACKUP; @@ -128,12 +130,58 @@ const getTimeSinceLastRenewableEvent = lastRewindableEventTime => { const BackupCard = props => { const { detail } = useProduct( productSlug ); const { status } = detail; + const { backup_failure: backupFailure } = + getMyJetpackWindowInitialState( 'redBubbleAlerts' ) || {}; + const { status: lastBackupStatus } = backupFailure || {}; const hasBackups = status === PRODUCT_STATUSES.ACTIVE || status === PRODUCT_STATUSES.CAN_UPGRADE; + const noDescription = () => null; - return hasBackups ? ( - - ) : ( - + const { title: errorTitle, text: errorDescription } = useGetReadableFailedBackupReason() || {}; + + if ( hasBackups ) { + return ; + } + + return ( + // eslint-disable-next-line react/jsx-no-bind + + { status === PRODUCT_STATUSES.NEEDS_ATTENTION && backupFailure && ( +
+
+ +
+
+ + { __( 'The last backup attempt failed.', 'jetpack-my-jetpack' ) } + + <> +

{ errorTitle }

+

{ errorDescription }

+

+ { __( + 'Check out our troubleshooting guide or contact your hosting provider to resolve the issue.', + 'jetpack-my-jetpack' + ) } +

+ +
+
+ + { __( 'Check out our troubleshooting guide.', 'jetpack-my-jetpack' ) } + +
+
+ ) } +
); }; diff --git a/projects/packages/my-jetpack/_inc/components/product-cards-section/backup-card/style.module.scss b/projects/packages/my-jetpack/_inc/components/product-cards-section/backup-card/style.module.scss index 42cf0f6c65494..1f3dbd21d24d8 100644 --- a/projects/packages/my-jetpack/_inc/components/product-cards-section/backup-card/style.module.scss +++ b/projects/packages/my-jetpack/_inc/components/product-cards-section/backup-card/style.module.scss @@ -56,3 +56,45 @@ .time { color: var( --jp-gray-40 ); } + +.backupWarning { + display: flex; + align-items: center; + gap: 0.25rem; + font-weight: 500; + + svg.iconError { + fill: var( --jp-red-60 ); + } +} + +.backupErrorContainer { + display: flex; + align-items: flex-start; + gap: 0.25rem; + font-size: var(--font-body-extra-small); + line-height: var(--font-title-small); + color: var(--jp-gray-50); + + .iconContainer { + padding-top: calc( var( --jp-underline-thickness) * 2 ); + > svg { + fill: var( --jp-red ); + } + } + + .errorDescription { + font-size: var( --font-label ); + font-weight: 400; + line-height: 20px; + } +} + +:global(.value-section__heading) { + display: flex; + align-items: center; + text-wrap: nowrap; + color: var(--jp-gray-100); + font-weight: 500; +} + diff --git a/projects/packages/my-jetpack/_inc/components/product-cards-section/protect-card/style.scss b/projects/packages/my-jetpack/_inc/components/product-cards-section/protect-card/style.scss index 77bb791e18b45..5592085c3a657 100644 --- a/projects/packages/my-jetpack/_inc/components/product-cards-section/protect-card/style.scss +++ b/projects/packages/my-jetpack/_inc/components/product-cards-section/protect-card/style.scss @@ -96,12 +96,3 @@ color: var(--jp-black); } } - -.info-tooltip { - &__content { - width: calc(100vw - 64px); - max-width: 340px; - min-height: 150px; - padding: 24px; - } -} \ No newline at end of file diff --git a/projects/packages/my-jetpack/_inc/components/product-cards-section/style.module.scss b/projects/packages/my-jetpack/_inc/components/product-cards-section/style.module.scss index 7be0d183cbe66..c471b95443613 100644 --- a/projects/packages/my-jetpack/_inc/components/product-cards-section/style.module.scss +++ b/projects/packages/my-jetpack/_inc/components/product-cards-section/style.module.scss @@ -66,6 +66,18 @@ line-height: var(--font-title-small); } +:global(.info-tooltip__content) { + width: calc(100vw - 64px); + max-width: 340px; + min-height: 150px; + padding: 24px; +} + +:global(.components-popover.is-expanded .info-tooltip__content) { + width: auto; + max-width: unset; +} + // Since we're adding so much info into the My Jetpack product cards, here we'll increase // the min-width of the cards to 300px, and otherwise wrap around. @media screen and (min-width: 599px) and (max-width: 1290px) { diff --git a/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/index.ts b/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/index.ts index d5055aefdf56b..0efbfe8f3da00 100644 --- a/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/index.ts +++ b/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/index.ts @@ -1,4 +1,5 @@ import { getMyJetpackWindowInitialState } from '../../data/utils/get-my-jetpack-window-state'; +import useBackupNeedsAttentionNotice from './use-backup-needs-attention-notice'; import useBadInstallNotice from './use-bad-install-notice'; import useConnectionErrorsNotice from './use-connection-errors-notice'; import useDeprecateFeatureNotice from './use-deprecate-feature-notice'; @@ -8,11 +9,12 @@ import useSiteConnectionNotice from './use-site-connection-notice'; const useNotificationWatcher = () => { const { redBubbleAlerts } = getMyJetpackWindowInitialState(); - useBadInstallNotice( redBubbleAlerts ); - useSiteConnectionNotice( redBubbleAlerts ); - useConnectionErrorsNotice(); - useDeprecateFeatureNotice( redBubbleAlerts ); useExpiringPlansNotice( redBubbleAlerts ); + useBackupNeedsAttentionNotice( redBubbleAlerts ); + useDeprecateFeatureNotice( redBubbleAlerts ); + useConnectionErrorsNotice(); + useSiteConnectionNotice( redBubbleAlerts ); + useBadInstallNotice( redBubbleAlerts ); }; export default useNotificationWatcher; diff --git a/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-backup-needs-attention-notice.tsx b/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-backup-needs-attention-notice.tsx new file mode 100644 index 0000000000000..0940ea6ff9438 --- /dev/null +++ b/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-backup-needs-attention-notice.tsx @@ -0,0 +1,115 @@ +import { Col, getRedirectUrl, Text } from '@automattic/jetpack-components'; +import { getSettings as getDateSettings, dateI18n } from '@wordpress/date'; +import { __, sprintf } from '@wordpress/i18n'; +import { useContext, useEffect, useCallback } from 'react'; +import { NOTICE_PRIORITY_HIGH } from '../../context/constants'; +import { NoticeContext } from '../../context/notices/noticeContext'; +import { applyTimezone } from '../../utils/apply-timezone'; +import preventWidows from '../../utils/prevent-widows'; +import useAnalytics from '../use-analytics'; +import { useGetReadableFailedBackupReason } from './use-get-readable-failed-backup-reason'; +import type { NoticeOptions } from '../../context/notices/types'; + +type RedBubbleAlerts = Window[ 'myJetpackInitialState' ][ 'redBubbleAlerts' ]; + +const useBackupNeedsAttentionNotice = ( redBubbleAlerts: RedBubbleAlerts ) => { + const { recordEvent } = useAnalytics(); + const { setNotice } = useContext( NoticeContext ); + + const { status, last_updated: lastUpdated } = redBubbleAlerts?.backup_failure || {}; + const { text: errorDescription } = useGetReadableFailedBackupReason() || {}; + + const { + timezone: { offset }, + } = getDateSettings() || { offset: '0' }; + // Using dateI18n() to apply internationalization and formatting. + const backupStatusLastUpdatedDate = dateI18n( + 'F jS, Y g:ia', + applyTimezone( lastUpdated, parseInt( offset ) ) + ); + + const troubleshootBackupsUrl = getRedirectUrl( 'jetpack-support-troubleshooting-backup' ); + const contactSupportUrl = getRedirectUrl( 'jetpack-support' ); + + const noticeTitle = __( 'Oops! We couldn’t back up your site', 'jetpack-my-jetpack' ); + + const onPrimaryCtaClick = useCallback( () => { + window.open( troubleshootBackupsUrl ); + recordEvent( 'jetpack_my_jetpack_backup_needs_attention_notice_primary_cta_click', { + backup_status: status, + } ); + }, [ recordEvent, status, troubleshootBackupsUrl ] ); + + const onSecondaryCtaClick = useCallback( () => { + window.open( contactSupportUrl ); + recordEvent( 'jetpack_my_jetpack_backup_needs_attention_notice_secondary_cta_click', { + backup_status: status, + } ); + }, [ recordEvent, status, contactSupportUrl ] ); + + useEffect( () => { + if ( ! redBubbleAlerts?.backup_failure ) { + return; + } + + const noticeMessage = ( + + + { preventWidows( + sprintf( + // Translators: %1$s is the date the last backup took place, i.e.- "Dec 7, 2024" + __( 'The last backup attempted on %1$s was unsuccessful.', 'jetpack-my-jetpack' ), + backupStatusLastUpdatedDate + ) + ) } + + { errorDescription && ( + { preventWidows( errorDescription as string ) } + ) } + + { preventWidows( + __( + 'Check out our troubleshooting guide or contact your hosting provider to resolve the issue.', + 'jetpack-my-jetpack' + ) + ) } + + + ); + + const noticeOptions: NoticeOptions = { + id: 'backup-needs-attention-notice', + level: 'error', + actions: [ + { + label: __( 'Read troubleshooting guide', 'jetpack-my-jetpack' ), + onClick: onPrimaryCtaClick, + noDefaultClasses: true, + }, + { + label: __( 'Contact support', 'jetpack-my-jetpack' ), + onClick: onSecondaryCtaClick, + isExternalLink: true, + }, + ], + priority: NOTICE_PRIORITY_HIGH, + }; + + setNotice( { + title: noticeTitle, + message: noticeMessage, + options: noticeOptions, + } ); + }, [ + redBubbleAlerts, + setNotice, + recordEvent, + onPrimaryCtaClick, + onSecondaryCtaClick, + noticeTitle, + backupStatusLastUpdatedDate, + errorDescription, + ] ); +}; + +export default useBackupNeedsAttentionNotice; diff --git a/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-get-readable-failed-backup-reason.tsx b/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-get-readable-failed-backup-reason.tsx new file mode 100644 index 0000000000000..23e1f2fb7b51f --- /dev/null +++ b/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-get-readable-failed-backup-reason.tsx @@ -0,0 +1,173 @@ +import { __, sprintf } from '@wordpress/i18n'; +import { useMemo, type ReactElement } from 'react'; +import { getMyJetpackWindowInitialState } from '../../data/utils/get-my-jetpack-window-state'; + +export type ReasonContent = { + title?: ReactElement | string; + text?: ReactElement | string; +}; + +/** + * Gets the translated human readable descriptions of Backup failure codes. + * + * @return {ReasonContent} An object containing each tooltip's title and text content. + */ +export function useGetReadableFailedBackupReason(): ReasonContent { + const { backup_failure: backupFailure } = + getMyJetpackWindowInitialState( 'redBubbleAlerts' ) || {}; + const { status } = backupFailure || {}; + + const reasonContent = useMemo( () => { + switch ( status ) { + // Rewind errors: + case 'missing_plan': + return { + title: __( 'Missing Backup plan', 'jetpack-my-jetpack' ), + text: __( + 'The site does not appear to have a valid Backup plan. Please purchase a Backup plan in order activate the features of Jetpack Backup.', + 'jetpack-my-jetpack' + ), + }; + case 'no_connected_jetpack': + return { + title: __( 'Not connected', 'jetpack-my-jetpack' ), + text: __( + 'The site doesn’t appear to be connected. Backup requires an active Jetpack connection in order to function properly.', + 'jetpack-my-jetpack' + ), + }; + case 'no_connected_jetpack_with_credentials': + return { + title: __( 'Not connected', 'jetpack-my-jetpack' ), + text: __( + 'The site doesn’t appear to be connected. Backup requires an active Jetpack connection in order to function properly, although successful Backups may still appear in the logs.', + 'jetpack-my-jetpack' + ), + }; + case 'vp_active_on_site': + return { + title: __( 'Backup plugin conflict', 'jetpack-my-jetpack' ), + text: __( + 'We’ve detected VaultPress is currently active on the site. VaultPress and Jetpack Backup cannot run simultaneously. In order to activate Jetpack Backup, you will first need to deactivate VaultPress.', + 'jetpack-my-jetpack' + ), + }; + case 'vp_can_transfer': + return { + title: __( 'Transfer VaultPress', 'jetpack-my-jetpack' ), + text: __( + 'We’ve detected VaultPress is currently active on the site, and we can automatically transfer it over to Jetpack Backup (Rewind), but you will need to trigger the transfer manually.', + 'jetpack-my-jetpack' + ), + }; + case 'host_not_supported': + return { + title: __( 'Host not supported', 'jetpack-my-jetpack' ), + text: __( + 'Backup doesn’t currently support the host that the site is hosted on.', + 'jetpack-my-jetpack' + ), + }; + case 'multisite_not_supported': + return { + title: __( 'Multi-site not supported', 'jetpack-my-jetpack' ), + text: __( + 'Backup can’t be activated on multi-site installations, neither the network site or its sub-sites.', + 'jetpack-my-jetpack' + ), + }; + case 'no_site_found': + return { + title: __( 'No site record', 'jetpack-my-jetpack' ), + text: __( + 'The VaultPress API could not recognize the site ID associated with your site, or multiple site ID’s are associated with the same site domain.', + 'jetpack-my-jetpack' + ), + }; + // Last backup errors: + case 'no-credentials': // This error is depreciated, now that all backups work via http only. + return { + title: __( 'No credentials found', 'jetpack-my-jetpack' ), + text: __( + 'No remote server credentials were found. Please add your website’s server credentials in Backup settings so Backup can fully function properly.', + 'jetpack-my-jetpack' + ), + }; + case 'no-credentials-atomic': // This error is depreciated, and an extreeeeemely rare edge case scenario. + return { + title: __( 'No credentials (Atomic)', 'jetpack-my-jetpack' ), + text: __( + 'There appears to be some issue with the Atomic API or a networking type issue. Please try again shortly to see if the issue has resolved.', + 'jetpack-my-jetpack' + ), + }; + case 'credential-error': + return { + title: __( 'Backup error', 'jetpack-my-jetpack' ), + text: __( + 'Although the site appears to be up and accessible, and remote server credentials are set, Backup still encountered an error during the last backup attempt.', + 'jetpack-my-jetpack' + ), + }; + case 'http-only-error': + return { + title: __( 'Backup error', 'jetpack-my-jetpack' ), + text: __( + 'Although the site appears to be up and accessible, Backup still encountered an error during the last backup attempt.', + 'jetpack-my-jetpack' + ), + }; + case 'not-accessible': + return { + title: __( 'Site unavailable', 'jetpack-my-jetpack' ), + text: __( + 'Backup was unable to access your site during the last backup attempt. This could be due to networking issues, a block from your host, or other server issues.', + 'jetpack-my-jetpack' + ), + }; + case 'Kill switch active': + case 'backup-deactivated': + return { + title: __( 'Backup is deactivated', 'jetpack-my-jetpack' ), + text: __( + 'It appear Backup has been manually deactivated, either by a site attribute or a general kill switch.', + 'jetpack-my-jetpack' + ), + }; + case 'error': + return { + title: __( 'Backup system error', 'jetpack-my-jetpack' ), + text: __( + 'Backup has encountered a general system error and was unable to complete the last backup attempt.', + 'jetpack-my-jetpack' + ), + }; + default: { + if ( ! status ) { + return { + title: null, + text: null, + }; + } + const statusTitleSplit = status.split( /[_\s-]/ ); + statusTitleSplit[ 0 ] = + statusTitleSplit[ 0 ].charAt( 0 ).toUpperCase() + statusTitleSplit[ 0 ].slice( 1 ); + const statusTitle = statusTitleSplit.join( ' ' ); + return { + title: sprintf( + // translators: %s is the error code coming from the server (formatted, i.e.- first word capitalized, hypen's removed, etc. ) i.e.- 'Invalid credentials', 'File not found', etc. + __( '%s error', 'jetpack-my-jetpack' ), + statusTitle + ), + text: sprintf( + // translators: %s is the error code coming from the server. i.e.- 'invalid-credentials', 'file-not-found', etc. + __( 'Error code: %s', 'jetpack-my-jetpack' ), + status + ), + }; + } + } + }, [ status ] ); + + return reasonContent; +} diff --git a/projects/packages/my-jetpack/_inc/utils/apply-timezone.ts b/projects/packages/my-jetpack/_inc/utils/apply-timezone.ts new file mode 100644 index 0000000000000..4a3afe7f4d698 --- /dev/null +++ b/projects/packages/my-jetpack/_inc/utils/apply-timezone.ts @@ -0,0 +1,15 @@ +import { getDate } from '@wordpress/date'; + +/** + * Applies local timezone to date (via timezone offset) + * @param {string} date - a date string with format like: 2024-12-08T14:41:45.170+00:00 + * @param {number} offset - the timezone offset in hours, like: -3 + * + * @return {Date} a JavaScript Date object + */ +export function applyTimezone( date: string, offset: number ): Date { + const dateObject = getDate( date ); + dateObject.setHours( dateObject.getHours() + offset ); + + return dateObject; +} diff --git a/projects/packages/my-jetpack/changelog/add-backup-redbubble-needs-attention-notice b/projects/packages/my-jetpack/changelog/add-backup-redbubble-needs-attention-notice new file mode 100644 index 0000000000000..80a1e18215b3f --- /dev/null +++ b/projects/packages/my-jetpack/changelog/add-backup-redbubble-needs-attention-notice @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +My Jetpack: Add red bubble and notice/banner when Backup has 'needs-attention' status. diff --git a/projects/packages/my-jetpack/global.d.ts b/projects/packages/my-jetpack/global.d.ts index d5c120766c91d..5ae0a3a54fcf6 100644 --- a/projects/packages/my-jetpack/global.d.ts +++ b/projects/packages/my-jetpack/global.d.ts @@ -22,7 +22,10 @@ type ProductStatus = | 'needs_activation' | 'needs_first_site_connection' | 'user_connection_error' - | 'can_upgrade'; + | 'can_upgrade' + | 'needs_attention' + | 'expired' + | 'expiring'; type JetpackModule = | 'anti-spam' @@ -69,6 +72,29 @@ type ScanItem = { version: string; }; +type RewindStatus = + | 'missing_plan' + | 'no_connected_jetpack' + | 'no_connected_jetpack_with_credentials' + | 'vp_active_on_site' + | 'vp_can_transfer' + | 'host_not_supported' + | 'multisite_not_supported' + | 'no_site_found'; + +type BackupStatus = + | 'started' + | 'finished' + | 'no-credentials' + | 'backups-deactivated' + | 'no-credentials-atomic' + | 'credential-error' + | 'http-only-error' + | 'not-accessible' + | 'backup-deactivated' + | 'Kill switch active' + | 'error' + | 'error-will-retry'; interface Window { myJetpackInitialState?: { siteSuffix: string; @@ -361,6 +387,11 @@ interface Window { plugin: string; }; }; + backup_failure?: { + source: 'rewind' | 'last_backup'; + status: RewindStatus | BackupStatus; + last_updated: string; + }; [ key: `${ string }--plan_expired` ]: { product_slug: string; product_name?: string; diff --git a/projects/packages/my-jetpack/src/class-initializer.php b/projects/packages/my-jetpack/src/class-initializer.php index 3d8bba78d485a..9ccb21cadaa6d 100644 --- a/projects/packages/my-jetpack/src/class-initializer.php +++ b/projects/packages/my-jetpack/src/class-initializer.php @@ -929,6 +929,7 @@ public static function add_red_bubble_alerts( array $red_bubble_slugs ) { } else { return array_merge( self::alert_if_missing_connection( $red_bubble_slugs ), + self::alert_if_last_backup_failed( $red_bubble_slugs ), self::alert_if_paid_plan_expiring( $red_bubble_slugs ) ); } @@ -983,14 +984,22 @@ public static function alert_if_paid_plan_expiring( array $red_bubble_slugs ) { if ( ! $connection->is_connected() ) { return $red_bubble_slugs; } - $product_classes = Products::get_products_classes(); + $product_classes = Products::get_products_classes(); + $not_shown_products = array( + 'scan', + 'extras', + 'ai', + 'newsletter', + 'site-accelerator', + 'related-posts', + ); $products_included_in_expiring_plan = array(); foreach ( $product_classes as $key => $product ) { // Skip these- we don't show them in My Jetpack. // ('ai' is a duplicate class of 'jetpack-ai', and therefore not needed). // See `get_product_classes() in projects/packages/my-jetpack/src/class-products.php for more info. - if ( 'scan' === $key || 'extras' === $key || 'ai' === $key ) { + if ( in_array( $key, $not_shown_products, true ) ) { continue; } @@ -1028,4 +1037,24 @@ public static function alert_if_paid_plan_expiring( array $red_bubble_slugs ) { return $red_bubble_slugs; } + + /** + * Add an alert slug if Backups are failing or having an issue. + * + * @param array $red_bubble_slugs - slugs that describe the reasons the red bubble is showing. + * @return array + */ + public static function alert_if_last_backup_failed( array $red_bubble_slugs ) { + // Make sure we're dealing with the backup product only + if ( ! Products\Backup::has_paid_plan_for_product() ) { + return $red_bubble_slugs; + } + + $backup_failed_status = Products\Backup::does_module_need_attention(); + if ( $backup_failed_status ) { + $red_bubble_slugs['backup_failure'] = $backup_failed_status; + } + + return $red_bubble_slugs; + } } diff --git a/projects/packages/my-jetpack/src/class-products.php b/projects/packages/my-jetpack/src/class-products.php index 33e894329a507..b6a96e4304ce1 100644 --- a/projects/packages/my-jetpack/src/class-products.php +++ b/projects/packages/my-jetpack/src/class-products.php @@ -67,6 +67,7 @@ class Products { self::STATUS_USER_CONNECTION_ERROR, self::STATUS_PLUGIN_ABSENT_WITH_PLAN, self::STATUS_NEEDS_PLAN, + self::STATUS_NEEDS_ATTENTION, ); /** diff --git a/projects/packages/my-jetpack/src/products/class-backup.php b/projects/packages/my-jetpack/src/products/class-backup.php index bee360c09ee2a..829044b11d5ec 100644 --- a/projects/packages/my-jetpack/src/products/class-backup.php +++ b/projects/packages/my-jetpack/src/products/class-backup.php @@ -247,19 +247,10 @@ public static function does_module_need_attention() { // First check the status of Rewind for failure. $rewind_state = self::get_state_from_wpcom(); if ( ! is_wp_error( $rewind_state ) ) { - $backup_failure_reasons = array( - 'unknown_error', - 'no_site_found', - 'missing_plan', - 'no_connected_jetpack', - 'no_connected_jetpack_with_credentials', - 'multisite_not_supported', - 'host_not_supported', - 'vp_active_on_site', - ); - if ( $rewind_state->state === 'unavailable' && ! empty( $rewind_state->reason ) && in_array( $rewind_state->reason, $backup_failure_reasons, true ) ) { + if ( $rewind_state->state !== 'active' && $rewind_state->state !== 'provisioning' && $rewind_state->state !== 'awaiting_credentials' ) { $backup_failed_status = array( - 'status' => $rewind_state->reason, + 'source' => 'rewind', + 'status' => isset( $rewind_state->reason ) && ! empty( $rewind_state->reason ) ? $rewind_state->reason : $rewind_state->state, 'last_updated' => $rewind_state->last_updated, ); } @@ -277,8 +268,9 @@ public static function does_module_need_attention() { } if ( $last_backup && isset( $last_backup->status ) ) { - if ( $last_backup->status === 'not-accessible' || $last_backup->status === 'error' || $last_backup->status === 'credential-error' ) { + if ( $last_backup->status !== 'started' && ! preg_match( '/-will-retry$/', $last_backup->status ) && $last_backup->status !== 'finished' ) { $backup_failed_status = array( + 'source' => 'last_backup', 'status' => $last_backup->status, 'last_updated' => $last_backup->last_updated, ); From 440a2342f7b360e071e50f643af02db1a3a59a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donncha=20=C3=93=20Caoimh?= <5656673+donnchawp@users.noreply.github.com> Date: Thu, 19 Dec 2024 08:19:54 +0000 Subject: [PATCH 16/45] Super Cache: fix how the plugin uses apache_request_headers (#39951) * Fix up apache_request_headers() * changelog * Fix static analysis issues * Fix the changelog message --------- Co-authored-by: Peter Petrov --- .../plugins/super-cache/.phan/baseline.php | 3 +- .../update-super-cache-get-apache-headers | 4 +++ .../plugins/super-cache/wp-cache-phase2.php | 28 ++++++++++--------- projects/plugins/super-cache/wp-cache.php | 6 ---- 4 files changed, 20 insertions(+), 21 deletions(-) create mode 100644 projects/plugins/super-cache/changelog/update-super-cache-get-apache-headers diff --git a/projects/plugins/super-cache/.phan/baseline.php b/projects/plugins/super-cache/.phan/baseline.php index bc33b588e8e44..6a814a0fb43f6 100644 --- a/projects/plugins/super-cache/.phan/baseline.php +++ b/projects/plugins/super-cache/.phan/baseline.php @@ -46,7 +46,6 @@ // PhanTypeMismatchReturn : 2 occurrences // PhanCommentParamWithoutRealParam : 1 occurrence // PhanPluginDuplicateIfCondition : 1 occurrence - // PhanRedefineFunctionInternal : 1 occurrence // PhanRedundantConditionInLoop : 1 occurrence // PhanTypeArraySuspicious : 1 occurrence // PhanTypeConversionFromArray : 1 occurrence @@ -80,7 +79,7 @@ 'tests/e2e/tools/mu-test-helpers.php' => ['PhanTypeMismatchArgument'], 'wp-cache-base.php' => ['PhanTypeMismatchArgumentNullableInternal'], 'wp-cache-phase1.php' => ['PhanRedundantConditionInGlobalScope', 'PhanTypeNonVarPassByRef'], - 'wp-cache-phase2.php' => ['PhanImpossibleCondition', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginDuplicateIfCondition', 'PhanPluginRedundantAssignment', 'PhanPluginSimplifyExpressionBool', 'PhanPluginUnreachableCode', 'PhanPossiblyUndeclaredVariable', 'PhanRedefineFunctionInternal', 'PhanRedundantCondition', 'PhanSuspiciousValueComparison', 'PhanTypeArraySuspicious', 'PhanTypeArraySuspiciousNull', 'PhanTypeArraySuspiciousNullable', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentInternal', 'PhanTypeMismatchArgumentInternalProbablyReal', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeNonVarPassByRef', 'PhanTypePossiblyInvalidDimOffset', 'PhanTypeSuspiciousNonTraversableForeach', 'PhanTypeSuspiciousStringExpression', 'PhanUndeclaredConstant', 'PhanUndeclaredVariableDim'], + 'wp-cache-phase2.php' => ['PhanImpossibleCondition', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginDuplicateIfCondition', 'PhanPluginRedundantAssignment', 'PhanPluginSimplifyExpressionBool', 'PhanPluginUnreachableCode', 'PhanPossiblyUndeclaredVariable', 'PhanRedundantCondition', 'PhanSuspiciousValueComparison', 'PhanTypeArraySuspicious', 'PhanTypeArraySuspiciousNull', 'PhanTypeArraySuspiciousNullable', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentInternal', 'PhanTypeMismatchArgumentInternalProbablyReal', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeNonVarPassByRef', 'PhanTypePossiblyInvalidDimOffset', 'PhanTypeSuspiciousNonTraversableForeach', 'PhanTypeSuspiciousStringExpression', 'PhanUndeclaredConstant', 'PhanUndeclaredVariableDim'], 'wp-cache.php' => ['PhanImpossibleCondition', 'PhanPluginDuplicateAdjacentStatement', 'PhanPluginDuplicateExpressionAssignmentOperation', 'PhanPluginNeverReturnFunction', 'PhanPluginSimplifyExpressionBool', 'PhanPossiblyUndeclaredVariable', 'PhanRedundantCondition', 'PhanRedundantConditionInLoop', 'PhanSuspiciousValueComparison', 'PhanTypeArraySuspiciousNullable', 'PhanTypeInvalidDimOffset', 'PhanTypeInvalidLeftOperandOfBitwiseOp', 'PhanTypeInvalidLeftOperandOfNumericOp', 'PhanTypeInvalidRightOperandOfAdd', 'PhanTypeInvalidRightOperandOfBitwiseOp', 'PhanTypeMismatchArgumentInternal', 'PhanTypeMismatchArgumentInternalProbablyReal', 'PhanTypeMismatchArgumentInternalReal', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchArgumentProbablyReal', 'PhanTypeNonVarPassByRef', 'PhanTypePossiblyInvalidDimOffset', 'PhanTypeSuspiciousNonTraversableForeach', 'PhanTypeSuspiciousStringExpression', 'PhanUndeclaredConstant', 'PhanUndeclaredFunction', 'PhanUndeclaredVariable', 'PhanUndeclaredVariableDim'], ], // 'directory_suppressions' => ['src/directory_name' => ['PhanIssueName1', 'PhanIssueName2']] can be manually added if needed. diff --git a/projects/plugins/super-cache/changelog/update-super-cache-get-apache-headers b/projects/plugins/super-cache/changelog/update-super-cache-get-apache-headers new file mode 100644 index 0000000000000..d43c4d6b80f59 --- /dev/null +++ b/projects/plugins/super-cache/changelog/update-super-cache-get-apache-headers @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Super Cache: Fixed the apache_request_headers fallback so it works when that command is disabled diff --git a/projects/plugins/super-cache/wp-cache-phase2.php b/projects/plugins/super-cache/wp-cache-phase2.php index 44287b4635f1e..adddbe6c0a96e 100644 --- a/projects/plugins/super-cache/wp-cache-phase2.php +++ b/projects/plugins/super-cache/wp-cache-phase2.php @@ -310,7 +310,7 @@ function wp_cache_serve_cache_file() { // don't try to match modified dates if using dynamic code. if ( $wp_cache_mfunc_enabled == 0 && $wp_supercache_304 ) { wp_cache_debug( 'wp_cache_serve_cache_file: checking age of cached vs served files.' ); - $headers = apache_request_headers(); + $headers = wpsc_apache_request_headers(); $remote_mod_time = isset( $headers['If-Modified-Since'] ) ? $headers['If-Modified-Since'] : null; if ( $remote_mod_time === null && isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) { @@ -1751,7 +1751,7 @@ function wp_cache_user_agent_is_rejected() { return false; } - $headers = apache_request_headers(); + $headers = wpsc_apache_request_headers(); if ( empty( $headers['User-Agent'] ) ) { return false; } @@ -3582,23 +3582,25 @@ function wpsc_is_get_query() { return $is_get_query; } -if ( ! function_exists( 'apache_request_headers' ) ) { - /** - * A fallback for get request headers. - * Based on comments from http://php.net/manual/en/function.apache-request-headers.php - * - * @return array List of request headers - */ - function apache_request_headers() { - $headers = array(); +/** + * A fallback for get request headers. + * Based on comments from http://php.net/manual/en/function.apache-request-headers.php + * + * @return array List of request headers + */ +function wpsc_apache_request_headers() { + if ( ! function_exists( 'apache_request_headers' ) || ! is_callable( 'apache_request_headers' ) ) { + $headers = array(); foreach ( array_keys( $_SERVER ) as $skey ) { if ( str_starts_with( $skey, 'HTTP_' ) ) { $header = implode( '-', array_map( 'ucfirst', array_slice( explode( '_', strtolower( $skey ) ), 1 ) ) ); $headers[ $header ] = $_SERVER[ $skey ]; } } - - return $headers; + } else { + $headers = apache_request_headers(); } + + return $headers; } diff --git a/projects/plugins/super-cache/wp-cache.php b/projects/plugins/super-cache/wp-cache.php index 97347ef8bd543..5aa1c630b8af9 100644 --- a/projects/plugins/super-cache/wp-cache.php +++ b/projects/plugins/super-cache/wp-cache.php @@ -1676,8 +1676,6 @@ function wp_cache_sanitize_value($text, & $array) { function wp_cache_update_rejected_ua() { global $cache_rejected_user_agent, $wp_cache_config_file, $valid_nonce; - if ( !function_exists( 'apache_request_headers' ) ) return; - if ( isset( $_POST[ 'wp_rejected_user_agent' ] ) && $valid_nonce ) { $_POST[ 'wp_rejected_user_agent' ] = str_replace( ' ', '___', $_POST[ 'wp_rejected_user_agent' ] ); $text = str_replace( '___', ' ', wp_cache_sanitize_value( $_POST[ 'wp_rejected_user_agent' ], $cache_rejected_user_agent ) ); @@ -1692,10 +1690,6 @@ function wp_cache_update_rejected_ua() { function wpsc_edit_rejected_ua() { global $cache_rejected_user_agent; - if ( ! function_exists( 'apache_request_headers' ) ) { - return; - } - $admin_url = admin_url( 'options-general.php?page=wpsupercache' ); wp_cache_update_rejected_ua(); wpsc_render_partial( From 129f0de5ccecd14a1e53b7180bf16ed019207dba Mon Sep 17 00:00:00 2001 From: Richard Ortiz Date: Thu, 19 Dec 2024 10:10:56 +0100 Subject: [PATCH 17/45] Duplicated views: add untangled comments to include list (#40649) * Added the comments page to the list of untangled pages under the experiment * changelog * Added notice to the comments section * We now use the clean title * Improved image * Edited and improved image --- .../changelog/add-untangled-comments-experiment | 4 ++++ .../screens/edit-comments-php.webp | Bin 0 -> 64250 bytes .../wpcom-admin-interface.php | 7 +++++-- 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 projects/packages/jetpack-mu-wpcom/changelog/add-untangled-comments-experiment create mode 100644 projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/screens/edit-comments-php.webp diff --git a/projects/packages/jetpack-mu-wpcom/changelog/add-untangled-comments-experiment b/projects/packages/jetpack-mu-wpcom/changelog/add-untangled-comments-experiment new file mode 100644 index 0000000000000..ac7a04cbe6b38 --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/changelog/add-untangled-comments-experiment @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Added the comments page to the list of untangled pages under the experiment diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/screens/edit-comments-php.webp b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/screens/edit-comments-php.webp new file mode 100644 index 0000000000000000000000000000000000000000..e552a79e58657b638802281af1686b29b1857485 GIT binary patch literal 64250 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 ccic?wF9nZv#Uz?<^oJCu`8mh8 plugins_url( 'screens/' . sanitize_title( $current_screen ) . '.webp', __FILE__ ), - 'title' => $title, + 'title' => $clean_title, 'screen' => $current_screen, 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'dismissNonce' => wp_create_nonce( 'wpcom_dismiss_removed_calypso_screen_notice' ), From 354fbd46b5f4dbc5e87e3e24a2df4a7dadbe500e Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Thu, 19 Dec 2024 15:20:03 +0200 Subject: [PATCH 18/45] Promote with Blaze: Purge cache on Atomic sites when site visibility changes (#40650) * Promote with Blaze: Purge cache on Atomic sites when site visibility changes * Linting * Linting... * Enable the quicklink from wpcomsh * Fix linting * Add guard * Remove changelog for Jetpack --- .../changelog/fix-atomic-promote-with-blaze | 4 ++ .../plugins/wpcomsh/feature-plugins/blaze.php | 54 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 projects/plugins/wpcomsh/changelog/fix-atomic-promote-with-blaze diff --git a/projects/plugins/wpcomsh/changelog/fix-atomic-promote-with-blaze b/projects/plugins/wpcomsh/changelog/fix-atomic-promote-with-blaze new file mode 100644 index 0000000000000..8841c588231a2 --- /dev/null +++ b/projects/plugins/wpcomsh/changelog/fix-atomic-promote-with-blaze @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Purge the cache when the site visibility changes on Atomic sites diff --git a/projects/plugins/wpcomsh/feature-plugins/blaze.php b/projects/plugins/wpcomsh/feature-plugins/blaze.php index 1c269f7e9fe43..a680f185664bb 100644 --- a/projects/plugins/wpcomsh/feature-plugins/blaze.php +++ b/projects/plugins/wpcomsh/feature-plugins/blaze.php @@ -6,6 +6,8 @@ * @package wpcomsh */ +use Automattic\Jetpack\Connection\Manager as Jetpack_Connection; + /** * Activate the Blaze module * If you use a version of Jetpack that supports it, @@ -61,5 +63,57 @@ function wpcomsh_activate_blaze_module_on_launching( $old_value, $new_value ) { if ( $blog_public === 1 ) { wpcomsh_activate_blaze_module(); } + + return $new_value; } add_filter( 'update_option_blog_public', 'wpcomsh_activate_blaze_module_on_launching', 10, 2 ); + +/** + * Delete the transient for the given site id. + * + * @return void + */ +function wpcomsh_blaze_purge_transient_cache() { + $site_id = Jetpack_Connection::get_site_id(); + + if ( is_wp_error( $site_id ) ) { + return; + } + + $transient = 'jetpack_blaze_site_supports_blaze_' . $site_id; + delete_transient( $transient ); +} + +/** + * Delete the caching transient when coming soon is changed. + */ +add_action( + 'pre_update_option_wpcom_public_coming_soon', + function ( $option ) { + wpcomsh_blaze_purge_transient_cache(); + return $option; + } +); + +/** + * Delete the caching transient when the blog visibility option changes. + */ +add_action( + 'pre_update_option_blog_public', + function ( $option ) { + wpcomsh_blaze_purge_transient_cache(); + return $option; + } +); + +/** + * On Atomic sites the Promote with Blaze option is enabled. + * + * @phan-suppress PhanUndeclaredFunctionInCallable -- jetpack_blaze_post_row_actions_disable is part of jetpack. + */ +add_action( + 'jetpack_modules_loaded', + function () { + remove_filter( 'jetpack_blaze_post_row_actions_enable', 'jetpack_blaze_post_row_actions_disable' ); + } +); From ff26ecb6c6ac8876b9562205034b437a9e8efe87 Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Thu, 19 Dec 2024 15:25:53 +0200 Subject: [PATCH 19/45] RDV: Remove the wpcom_admin_interface hook for the admin_menu hook (#40669) * RDV: Remove the wpcom_admin_interface hook for the admin_menu hook * Remove the alias functions with calls directly to get_option --- .../changelog/fix-wp-admin-rdv | 4 ++++ .../wpcom-admin-bar/wpcom-admin-bar.php | 2 +- .../wpcom-admin-interface.php | 15 +++++++++++++++ .../wpcom-admin-menu/wpcom-admin-menu.php | 19 +++---------------- .../wpcom-sidebar-notice.php | 2 +- .../features/wpcom-themes/wpcom-themes.php | 2 +- .../masterbar/changelog/fix-wp-admin-rdv | 4 ++++ .../src/admin-menu/class-admin-menu.php | 2 +- .../admin-menu/class-atomic-admin-menu.php | 12 ++++++------ .../src/admin-menu/class-base-admin-menu.php | 15 --------------- 10 files changed, 36 insertions(+), 41 deletions(-) create mode 100644 projects/packages/jetpack-mu-wpcom/changelog/fix-wp-admin-rdv create mode 100644 projects/packages/masterbar/changelog/fix-wp-admin-rdv diff --git a/projects/packages/jetpack-mu-wpcom/changelog/fix-wp-admin-rdv b/projects/packages/jetpack-mu-wpcom/changelog/fix-wp-admin-rdv new file mode 100644 index 0000000000000..cc90987517731 --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/changelog/fix-wp-admin-rdv @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Exclude the wpcom_admin_interface from the admin_menu action diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-bar/wpcom-admin-bar.php b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-bar/wpcom-admin-bar.php index a4e006a51ce38..575a7e3218f49 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-bar/wpcom-admin-bar.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-bar/wpcom-admin-bar.php @@ -263,7 +263,7 @@ function wpcom_replace_edit_profile_menu_to_me( $wp_admin_bar ) { * @return string Name of the admin bar class. */ function wpcom_custom_wpcom_admin_bar_class( $wp_admin_bar_class ) { - if ( ! wpcom_is_using_default_admin_menu() ) { + if ( get_option( 'wpcom_admin_interface' ) === 'wp-admin' ) { return $wp_admin_bar_class; } diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/wpcom-admin-interface.php b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/wpcom-admin-interface.php index e6a7caecc799e..91e2394b86a7b 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/wpcom-admin-interface.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-interface/wpcom-admin-interface.php @@ -194,6 +194,21 @@ function wpcom_admin_get_user_option_jetpack( $value ) { add_filter( 'get_user_option_jetpack_admin_menu_preferred_views', 'wpcom_admin_get_user_option_jetpack' ); add_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option', 10 ); +add_action( + 'admin_menu', + function () { + remove_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option' ); + }, + PHP_INT_MIN +); + +add_action( + 'admin_menu', + function () { + add_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option', 10 ); + }, + PHP_INT_MAX +); /** * Hides the "View" switcher on WP Admin screens enforced by the "Remove duplicate views" experiment. */ diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-menu/wpcom-admin-menu.php b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-menu/wpcom-admin-menu.php index aafe2e0edb12c..a44371e89ec14 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-menu/wpcom-admin-menu.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-admin-menu/wpcom-admin-menu.php @@ -33,24 +33,11 @@ function current_user_has_wpcom_account() { return $has_account; } -/** - * Check if the user has the default (Calypso) Admin menu. - * - * @return bool - */ -function wpcom_is_using_default_admin_menu() { - remove_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option' ); - $option = get_option( 'wpcom_admin_interface' ) !== 'wp-admin'; - add_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option', 10 ); - - return $option; -} - /** * Adds a Hosting menu. */ function wpcom_add_hosting_menu() { - if ( wpcom_is_using_default_admin_menu() ) { + if ( get_option( 'wpcom_admin_interface' ) !== 'wp-admin' ) { return; } @@ -162,7 +149,7 @@ function wpcom_add_hosting_menu() { function wpcom_add_jetpack_submenu() { $is_simple_site = defined( 'IS_WPCOM' ) && IS_WPCOM; $is_atomic_site = ! $is_simple_site; - $uses_wp_admin_interface = ! wpcom_is_using_default_admin_menu(); + $uses_wp_admin_interface = get_option( 'wpcom_admin_interface' ) === 'wp-admin'; if ( ! $uses_wp_admin_interface ) { return; @@ -392,7 +379,7 @@ function wpcom_add_plugins_menu() { global $menu; $is_simple_site = defined( 'IS_WPCOM' ) && IS_WPCOM; $is_atomic_site = ! $is_simple_site; - $uses_wp_admin_interface = ! wpcom_is_using_default_admin_menu(); + $uses_wp_admin_interface = get_option( 'wpcom_admin_interface' ) === 'wp-admin'; if ( $is_simple_site ) { $has_plugins_menu = false; diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-sidebar-notice/wpcom-sidebar-notice.php b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-sidebar-notice/wpcom-sidebar-notice.php index d8ce8b474ddd2..90b1dd2898ff6 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-sidebar-notice/wpcom-sidebar-notice.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-sidebar-notice/wpcom-sidebar-notice.php @@ -10,7 +10,7 @@ use Automattic\Jetpack\Connection\Manager as Connection_Manager; use Automattic\Jetpack\Jetpack_Mu_Wpcom; -if ( wpcom_is_using_default_admin_menu() ) { +if ( get_option( 'wpcom_admin_interface' ) !== 'wp-admin' ) { return; } diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/wpcom-themes.php b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/wpcom-themes.php index f5932690ed893..6d6ede007345a 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/wpcom-themes.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-themes/wpcom-themes.php @@ -56,7 +56,7 @@ function wpcom_themes_show_banner() { * Registers an "Appearance > Theme Showcase" menu. */ function wpcom_themes_add_theme_showcase_menu() { - if ( wpcom_is_using_default_admin_menu() ) { + if ( get_option( 'wpcom_admin_interface' ) !== 'wp-admin' ) { return; } diff --git a/projects/packages/masterbar/changelog/fix-wp-admin-rdv b/projects/packages/masterbar/changelog/fix-wp-admin-rdv new file mode 100644 index 0000000000000..cc90987517731 --- /dev/null +++ b/projects/packages/masterbar/changelog/fix-wp-admin-rdv @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Exclude the wpcom_admin_interface from the admin_menu action diff --git a/projects/packages/masterbar/src/admin-menu/class-admin-menu.php b/projects/packages/masterbar/src/admin-menu/class-admin-menu.php index eb0c7f3cdd7eb..3b0085f29391d 100644 --- a/projects/packages/masterbar/src/admin-menu/class-admin-menu.php +++ b/projects/packages/masterbar/src/admin-menu/class-admin-menu.php @@ -356,7 +356,7 @@ public function add_tools_menu() { // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539. add_submenu_page( 'tools.php', esc_attr__( 'Marketing', 'jetpack-masterbar' ), __( 'Marketing', 'jetpack-masterbar' ), 'publish_posts', 'https://wordpress.com/marketing/tools/' . $this->domain, null, 0 ); - if ( $this->is_using_default_admin_menu() ) { + if ( ! $this->use_wp_admin_interface() ) { // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539. add_submenu_page( 'tools.php', esc_attr__( 'Monetize', 'jetpack-masterbar' ), __( 'Monetize', 'jetpack-masterbar' ), 'manage_options', 'https://wordpress.com/earn/' . $this->domain, null, 1 ); } diff --git a/projects/packages/masterbar/src/admin-menu/class-atomic-admin-menu.php b/projects/packages/masterbar/src/admin-menu/class-atomic-admin-menu.php index c58244fd06a2c..017891701b8c5 100644 --- a/projects/packages/masterbar/src/admin-menu/class-atomic-admin-menu.php +++ b/projects/packages/masterbar/src/admin-menu/class-atomic-admin-menu.php @@ -47,7 +47,7 @@ function () { ); // Add notices to the settings pages when there is a Calypso page available. - if ( get_option( 'wpcom_admin_interface' ) === 'wp-admin' ) { + if ( $this->use_wp_admin_interface() ) { add_action( 'current_screen', array( $this, 'add_settings_page_notice' ) ); } } @@ -79,7 +79,7 @@ public function reregister_menu_items() { $this->remove_gutenberg_menu(); // We don't need the `My Mailboxes` when the interface is set to wp-admin or the site is a staging site, - if ( $this->is_using_default_admin_menu() && ! get_option( 'wpcom_is_staging_site' ) ) { + if ( ! $this->use_wp_admin_interface() && ! get_option( 'wpcom_is_staging_site' ) ) { $this->add_my_mailboxes_menu(); } @@ -132,7 +132,7 @@ public function add_users_menu() { $this->update_submenus( $slug, $submenus_to_update ); } - if ( $this->is_using_default_admin_menu() ) { + if ( ! $this->use_wp_admin_interface() ) { // The 'Subscribers' menu exists in the Jetpack menu for Classic wp-admin interface, so only add it for non-wp-admin interfaces. // // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539. add_submenu_page( 'users.php', esc_attr__( 'Subscribers', 'jetpack-masterbar' ), __( 'Subscribers', 'jetpack-masterbar' ), 'list_users', 'https://wordpress.com/subscribers/' . $this->domain, null ); @@ -322,7 +322,7 @@ public function get_upsell_nudge() { */ public function add_jetpack_menu() { // This is supposed to be the same as class-admin-menu but with a different position specified for the Jetpack menu. - if ( ! $this->is_using_default_admin_menu() ) { + if ( $this->use_wp_admin_interface() ) { parent::create_jetpack_menu( 2, false ); } else { parent::add_jetpack_menu(); @@ -445,7 +445,7 @@ public function add_options_menu() { // Hide Settings > Performance when the interface is set to wp-admin. // This is due to these settings are mostly also available in Jetpack > Settings, in the Performance tab. - if ( ! $this->is_using_default_admin_menu() ) { + if ( $this->use_wp_admin_interface() ) { $this->hide_submenu_page( 'options-general.php', 'https://wordpress.com/settings/performance/' . $this->domain ); } } @@ -457,7 +457,7 @@ public function add_tools_menu() { parent::add_tools_menu(); // Link the Tools menu to Available Tools when the interface is set to wp-admin. - if ( ! $this->is_using_default_admin_menu() ) { + if ( $this->use_wp_admin_interface() ) { // @phan-suppress-next-line PhanTypeMismatchArgumentProbablyReal -- Core should ideally document null for no-callback arg. https://core.trac.wordpress.org/ticket/52539. add_submenu_page( 'tools.php', esc_attr__( 'Available Tools', 'jetpack-masterbar' ), __( 'Available Tools', 'jetpack-masterbar' ), 'edit_posts', 'tools.php', null, 0 ); } diff --git a/projects/packages/masterbar/src/admin-menu/class-base-admin-menu.php b/projects/packages/masterbar/src/admin-menu/class-base-admin-menu.php index 65400fff1d1bc..dfc5ccb3954c1 100644 --- a/projects/packages/masterbar/src/admin-menu/class-base-admin-menu.php +++ b/projects/packages/masterbar/src/admin-menu/class-base-admin-menu.php @@ -756,21 +756,6 @@ public function use_wp_admin_interface() { return 'wp-admin' === get_option( 'wpcom_admin_interface' ); } - /** - * Check if the user has the default (Calypso) Admin menu. - * - * @return bool - */ - public function is_using_default_admin_menu() { - remove_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option' ); - $option = get_option( 'wpcom_admin_interface' ) !== 'wp-admin'; - if ( function_exists( 'wpcom_admin_interface_pre_get_option' ) ) { - add_filter( 'pre_option_wpcom_admin_interface', 'wpcom_admin_interface_pre_get_option', 10 ); - } - - return $option; - } - /** * Create the desired menu output. */ From b3ee2c2bf4f9020dfa3c61fc7e54cd0b794cc3a7 Mon Sep 17 00:00:00 2001 From: Miguel Torres <1233880+mmtr@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:50:23 +0100 Subject: [PATCH 20/45] Post categories: Add quick action to change the default category (#40667) --- .../add-set-default-category-quick-action | 4 + .../src/class-jetpack-mu-wpcom.php | 1 + .../post-categories/quick-actions.php | 87 +++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 projects/packages/jetpack-mu-wpcom/changelog/add-set-default-category-quick-action create mode 100644 projects/packages/jetpack-mu-wpcom/src/features/post-categories/quick-actions.php diff --git a/projects/packages/jetpack-mu-wpcom/changelog/add-set-default-category-quick-action b/projects/packages/jetpack-mu-wpcom/changelog/add-set-default-category-quick-action new file mode 100644 index 0000000000000..562cea91dca9a --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/changelog/add-set-default-category-quick-action @@ -0,0 +1,4 @@ +Significance: patch +Type: added + +Post categories: Add quick action to change default category diff --git a/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php b/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php index 26cf4192d604a..89597cf7ce895 100644 --- a/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php +++ b/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php @@ -107,6 +107,7 @@ public static function load_features() { require_once __DIR__ . '/features/import-customizations/import-customizations.php'; require_once __DIR__ . '/features/marketplace-products-updater/class-marketplace-products-updater.php'; require_once __DIR__ . '/features/media/heif-support.php'; + require_once __DIR__ . '/features/post-categories/quick-actions.php'; require_once __DIR__ . '/features/site-editor-dashboard-link/site-editor-dashboard-link.php'; require_once __DIR__ . '/features/wpcom-admin-dashboard/wpcom-admin-dashboard.php'; require_once __DIR__ . '/features/wpcom-block-editor/class-jetpack-wpcom-block-editor.php'; diff --git a/projects/packages/jetpack-mu-wpcom/src/features/post-categories/quick-actions.php b/projects/packages/jetpack-mu-wpcom/src/features/post-categories/quick-actions.php new file mode 100644 index 0000000000000..3259f07466dca --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/src/features/post-categories/quick-actions.php @@ -0,0 +1,87 @@ +term_id === $default_category ) { + return $actions; + } + + $action = 'set-default'; + + $link = add_query_arg( array( $action => $category->term_id ) ); + $link = wp_nonce_url( $link, $action . '_' . $category->term_id ); + + $actions[ $action ] = sprintf( + '%3$s', + esc_url( $link ), + /* translators: category name */ + esc_attr( sprintf( __( 'Set “%s” as the default category', 'jetpack-mu-wpcom' ), $category->name ) ), + esc_html( __( 'Set as default', 'jetpack-mu-wpcom' ) ) + ); + return $actions; +} +add_filter( 'category_row_actions', 'wpcom_add_set_default_category_quick_action', 10, 2 ); + +/** + * Changes the default post category. + */ +function wpcom_set_default_category() { + if ( ! isset( $_GET['taxonomy'] ) || 'category' !== sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ) ) { + return; + } + + if ( ! current_user_can( 'manage_options' ) ) { + return; + } + + $action = 'set-default'; + + if ( ! isset( $_GET[ $action ] ) ) { + return; + } + + $category_id = sanitize_text_field( wp_unslash( $_GET[ $action ] ) ); + if ( ! is_numeric( $category_id ) ) { + return; + } + + check_admin_referer( $action . '_' . $category_id ); + + $category = get_category( (int) $category_id ); + if ( is_wp_error( $category ) || ! $category ) { + return; + } + + update_option( 'default_category', $category->term_id ); + + add_action( + 'admin_notices', + function () { + wp_admin_notice( + __( 'Default category changed successfully.', 'jetpack-mu-wpcom' ), + array( + 'type' => 'success', + 'dismissible' => true, + ) + ); + } + ); +} +add_action( 'load-edit-tags.php', 'wpcom_set_default_category' ); From b0015a6680899ce9a964e36e3a4d7726a6234ce7 Mon Sep 17 00:00:00 2001 From: Dylan Munson <65001528+CodeyGuyDylan@users.noreply.github.com> Date: Thu, 19 Dec 2024 09:04:03 -0700 Subject: [PATCH 21/45] Remove/old welcome banner code (#40671) * Remove old welcome banner code * changelog --- .../assets/images/site-cards.png | Bin 179712 -> 0 bytes .../_inc/components/welcome-banner/index.jsx | 94 ------------------ .../stories/broken/index.stories.js | 18 ---- .../welcome-banner/style.module.scss | 75 -------------- .../changelog/remove-old-welcome-banner-code | 5 + 5 files changed, 5 insertions(+), 187 deletions(-) delete mode 100644 projects/packages/my-jetpack/_inc/components/welcome-banner/assets/images/site-cards.png delete mode 100644 projects/packages/my-jetpack/_inc/components/welcome-banner/index.jsx delete mode 100644 projects/packages/my-jetpack/_inc/components/welcome-banner/stories/broken/index.stories.js delete mode 100644 projects/packages/my-jetpack/_inc/components/welcome-banner/style.module.scss create mode 100644 projects/packages/my-jetpack/changelog/remove-old-welcome-banner-code diff --git a/projects/packages/my-jetpack/_inc/components/welcome-banner/assets/images/site-cards.png b/projects/packages/my-jetpack/_inc/components/welcome-banner/assets/images/site-cards.png deleted file mode 100644 index 83e562ede663c0bd77cd92602acfc4488f2e832c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179712 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 YZ%B=!PGCsM$LC)N6({gqUF?hq~d&W?#_V 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ξkHY$8_D{8od4kaG4Ayc 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 IM6N<$f+C%xg#Z8m diff --git a/projects/packages/my-jetpack/_inc/components/welcome-banner/index.jsx b/projects/packages/my-jetpack/_inc/components/welcome-banner/index.jsx deleted file mode 100644 index c40848b4610d7..0000000000000 --- a/projects/packages/my-jetpack/_inc/components/welcome-banner/index.jsx +++ /dev/null @@ -1,94 +0,0 @@ -import { Container, Col, Button, Text } from '@automattic/jetpack-components'; -import { __ } from '@wordpress/i18n'; -import { close } from '@wordpress/icons'; -import { useEffect, useCallback, useState } from 'react'; -import { MyJetpackRoutes } from '../../constants'; -import useWelcomeBanner from '../../data/welcome-banner/use-welcome-banner'; -import useAnalytics from '../../hooks/use-analytics'; -import useMyJetpackConnection from '../../hooks/use-my-jetpack-connection'; -import useMyJetpackNavigate from '../../hooks/use-my-jetpack-navigate'; -import { CardWrapper } from '../card'; -import styles from './style.module.scss'; - -/** - * Component that renders the Welcome banner on My Jetpack. - * - * @return {object} The WelcomeBanner component. - */ -const WelcomeBanner = () => { - const { recordEvent } = useAnalytics(); - const { isWelcomeBannerVisible, dismissWelcomeBanner } = useWelcomeBanner(); - const { isRegistered, isUserConnected } = useMyJetpackConnection(); - const navigateToConnectionPage = useMyJetpackNavigate( MyJetpackRoutes.Connection ); - const [ bannerVisible, setBannerVisible ] = useState( isWelcomeBannerVisible ); - const shouldDisplayConnectionButton = ! isRegistered || ! isUserConnected; - - useEffect( () => { - if ( bannerVisible ) { - recordEvent( 'jetpack_myjetpack_welcome_banner_view' ); - } - }, [ bannerVisible, recordEvent ] ); - - const onDismissClick = useCallback( () => { - recordEvent( 'jetpack_myjetpack_welcome_banner_dismiss_click' ); - setBannerVisible( false ); - dismissWelcomeBanner(); - }, [ recordEvent, dismissWelcomeBanner ] ); - - const onFinishConnectionClick = useCallback( () => { - recordEvent( 'jetpack_myjetpack_welcome_banner_finish_connection_click' ); - navigateToConnectionPage(); - }, [ recordEvent, navigateToConnectionPage ] ); - - if ( ! bannerVisible ) { - return null; - } - - return ( - - - - - - - { __( 'Welcome to Jetpack!', 'jetpack-my-jetpack' ) } - - - { __( - 'Jetpack is a suite of security, performance, and growth tools made for WordPress sites by the WordPress experts.', - 'jetpack-my-jetpack' - ) } - - - { __( - 'It’s the ultimate toolkit for best-in-class websites, with everything you need to grow your business. Choose a plan below to get started.', - 'jetpack-my-jetpack' - ) } - - { shouldDisplayConnectionButton && ( - - ) } - - - - -