Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilize the PreSavePost and SavePost filters #64198

Merged
merged 3 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 8 additions & 15 deletions packages/edit-post/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
privateApis as editorPrivateApis,
} from '@wordpress/editor';
import deprecated from '@wordpress/deprecated';
import { addFilter } from '@wordpress/hooks';
import { addAction } from '@wordpress/hooks';
import { store as coreStore } from '@wordpress/core-data';

/**
Expand Down Expand Up @@ -478,21 +478,14 @@ export const initializeMetaBoxes =
metaBoxesInitialized = true;

// Save metaboxes on save completion, except for autosaves.
addFilter(
'editor.__unstableSavePost',
addAction(
'editor.savePost',
'core/edit-post/save-metaboxes',
( previous, options ) =>
previous.then( () => {
if ( options.isAutosave ) {
return;
}

if ( ! select.hasMetaBoxes() ) {
return;
}

return dispatch.requestMetaBoxUpdates();
} )
async ( options ) => {
if ( ! options.isAutosave && select.hasMetaBoxes() ) {
await dispatch.requestMetaBoxUpdates();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning here previously didn't make much sense, and that's why we're removing it, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously we were returning a promise, so that the next filter can .then on it. Now this is all handled by the async runner: it will ensure that the next handler runs only after the previous one finished and succeeded.

That's also why this hook is no longer a filter, but an action. Action handlers don't return anything.

}
}
);

dispatch( {
Expand Down
37 changes: 26 additions & 11 deletions packages/editor/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import {
import { store as noticesStore } from '@wordpress/notices';
import { store as coreStore } from '@wordpress/core-data';
import { store as blockEditorStore } from '@wordpress/block-editor';
import { applyFilters } from '@wordpress/hooks';
import {
applyFilters,
applyFiltersAsync,
doActionAsync,
} from '@wordpress/hooks';
import { store as preferencesStore } from '@wordpress/preferences';
import { __ } from '@wordpress/i18n';

Expand Down Expand Up @@ -184,7 +188,7 @@ export const savePost =
}

const previousRecord = select.getCurrentPost();
const edits = {
let edits = {
id: previousRecord.id,
...registry
.select( coreStore )
Expand All @@ -199,9 +203,9 @@ export const savePost =

let error = false;
try {
error = await applyFilters(
'editor.__unstablePreSavePost',
Promise.resolve( false ),
edits = await applyFiltersAsync(
'editor.preSavePost',
edits,
options
);
} catch ( err ) {
Expand Down Expand Up @@ -236,14 +240,25 @@ export const savePost =
);
}

// Run the hook with legacy unstable name for backward compatibility
if ( ! error ) {
await applyFilters(
'editor.__unstableSavePost',
Promise.resolve(),
options
).catch( ( err ) => {
try {
await applyFilters(
'editor.__unstableSavePost',
Promise.resolve(),
options
);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If anyone ever registers an editor.__unstableSavePost legacy filter, I'd like to log a deprecated warning. But not sure how to do that. Did anyone do something similar before?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't seem like it'd be as effective as a deprecation message on a call to addFilter, but core has this PHP function, so replicating it might be the way to go - https://developer.wordpress.org/reference/functions/apply_filters_deprecated/

There's no JS equivalent unfortunately, so it'd need to be implemented in the hooks package, which makes this a bit more involved. 😅

I guess the reason it's not handled on add_filter in core is the deprecation messages would have to be added within the add_filter function?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, apply_filters_deprecated is exactly what I need 🙂 It does nothing when no filter is registered, but complains otherwise.

It needs to be added to @wordpress/hooks first, but why not, I'm already adding async filters anyway. Seems that the hooks package will get a nice upgrade in 6.7.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a apply_filters_deprecated port to JS will make a lot of sense in the package, especially as we deprecate filters/actions in the future. Work for another PR of course 😉 It doesn't seem like the unstable hook was used anywhere (I've checked extensively on wpdirectory.net and a few more places)

} catch ( err ) {
error = err;
} );
}
}

if ( ! error ) {
try {
await doActionAsync( 'editor.savePost', options );
} catch ( err ) {
error = err;
}
}
dispatch( { type: 'REQUEST_POST_UPDATE_FINISH', options } );

Expand Down
Loading