_wp_keep_alive_customize_changeset_dependent_auto_drafts()
概述
此函数用于管理自定义器变更集(customize_changeset)相关的自动草稿文章,防止它们被过早垃圾回收。它根据变更集的状态变化,调整依赖的自动草稿文章的 post_date 或状态。
关键要点
- 当变更集保持为 auto-draft 状态时,保持依赖文章的 post_date 不变,以确保它们与变更集同时被 wp_delete_auto_drafts() 垃圾回收。
- 当变更集变为 draft 状态时,将依赖的自动草稿文章更新为 draft 状态,并设置远未来的 post_date,以防止垃圾回收,同时允许在发布前在管理界面编辑。
- 如果变更集被移至 trash 状态,则立即将相关的 customization drafts 文章移至垃圾箱,以从管理界面移除可见性。
- 函数处理依赖于 nav_menus_created_posts 数据中的文章 ID,仅影响状态为 auto-draft 的文章。
代码示例
function _wp_keep_alive_customize_changeset_dependent_auto_drafts( $new_status, $old_status, $post ) {
global $wpdb;
unset( $old_status );
// Short-circuit if not a changeset or if the changeset was published.
if ( 'customize_changeset' !== $post->post_type || 'publish' === $new_status ) {
return;
}
$data = json_decode( $post->post_content, true );
if ( empty( $data['nav_menus_created_posts']['value'] ) ) {
return;
}
if ( 'trash' === $new_status ) {
foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) {
if ( ! empty( $post_id ) && 'draft' === get_post_status( $post_id ) ) {
wp_trash_post( $post_id );
}
}
return;
}
$post_args = array();
if ( 'auto-draft' === $new_status ) {
$post_args['post_date'] = $post->post_date;
} else {
$post_args['post_status'] = 'draft';
}
foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) {
if ( empty( $post_id ) || 'auto-draft' !== get_post_status( $post_id ) ) {
continue;
}
$wpdb->update(
$wpdb->posts,
$post_args,
array( 'ID' => $post_id )
);
clean_post_cache( $post_id );
}
}注意事项
- 此函数仅在 WordPress 4.8.0 及更高版本中可用。
- 它依赖于变更集的 post_content 中包含 nav_menus_created_posts 数据,否则会提前返回。
- 使用 wpdb::update() 直接更新数据库,并调用 clean_post_cache() 清理缓存,确保数据一致性。
- 相关函数包括 wp_delete_auto_drafts()、wp_trash_post() 和 get_post_status(),用于辅助垃圾回收和状态管理。
Makes sure that auto-draft posts get their post_date bumped or status changed to draft to prevent premature garbage-collection.
Description
When a changeset is updated but remains an auto-draft, ensure the post_date for the auto-draft posts remains the same so that it will be garbage-collected at the same time by wp_delete_auto_drafts(). Otherwise, if the changeset is updated to be a draft then update the posts to have a far-future post_date so that they will never be garbage collected unless the changeset post itself is deleted.
When a changeset is updated to be a persistent draft or to be scheduled for publishing, then transition any dependent auto-drafts to a draft status so that they likewise will not be garbage-collected but also so that they can be edited in the admin before publishing since there is not yet a post/page editing flow in the Customizer. See #39752.
See also
Parameters
$new_statusstringrequired-
Transition to this post status.
$old_statusstringrequired-
Previous post status.
$postWP_Postrequired-
Post data.
Source
function _wp_keep_alive_customize_changeset_dependent_auto_drafts( $new_status, $old_status, $post ) {
global $wpdb;
unset( $old_status );
// Short-circuit if not a changeset or if the changeset was published.
if ( 'customize_changeset' !== $post->post_type || 'publish' === $new_status ) {
return;
}
$data = json_decode( $post->post_content, true );
if ( empty( $data['nav_menus_created_posts']['value'] ) ) {
return;
}
/*
* Actually, in lieu of keeping alive, trash any customization drafts here if the changeset itself is
* getting trashed. This is needed because when a changeset transitions to a draft, then any of the
* dependent auto-draft post/page stubs will also get transitioned to customization drafts which
* are then visible in the WP Admin. We cannot wait for the deletion of the changeset in which
* _wp_delete_customize_changeset_dependent_auto_drafts() will be called, since they need to be
* trashed to remove from visibility immediately.
*/
if ( 'trash' === $new_status ) {
foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) {
if ( ! empty( $post_id ) && 'draft' === get_post_status( $post_id ) ) {
wp_trash_post( $post_id );
}
}
return;
}
$post_args = array();
if ( 'auto-draft' === $new_status ) {
/*
* Keep the post date for the post matching the changeset
* so that it will not be garbage-collected before the changeset.
*/
$post_args['post_date'] = $post->post_date; // Note wp_delete_auto_drafts() only looks at this date.
} else {
/*
* Since the changeset no longer has an auto-draft (and it is not published)
* it is now a persistent changeset, a long-lived draft, and so any
* associated auto-draft posts should likewise transition into having a draft
* status. These drafts will be treated differently than regular drafts in
* that they will be tied to the given changeset. The publish meta box is
* replaced with a notice about how the post is part of a set of customized changes
* which will be published when the changeset is published.
*/
$post_args['post_status'] = 'draft';
}
foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) {
if ( empty( $post_id ) || 'auto-draft' !== get_post_status( $post_id ) ) {
continue;
}
$wpdb->update(
$wpdb->posts,
$post_args,
array( 'ID' => $post_id )
);
clean_post_cache( $post_id );
}
}
Changelog
| Version | Description |
|---|---|
| 4.8.0 | Introduced. |