--- a/wp/wp-includes/post.php Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-includes/post.php Fri Sep 05 18:40:08 2025 +0200
@@ -75,9 +75,9 @@
'labels' => array(
'name' => _x( 'Media', 'post type general name' ),
'name_admin_bar' => _x( 'Media', 'add new from admin bar' ),
- 'add_new' => _x( 'Add New', 'add new media' ),
+ 'add_new' => __( 'Add New Media File' ),
'edit_item' => __( 'Edit Media' ),
- 'view_item' => __( 'View Attachment Page' ),
+ 'view_item' => ( '1' === get_option( 'wp_attachment_pages_enabled' ) ) ? __( 'View Attachment Page' ) : __( 'View Media File' ),
'attributes' => __( 'Attachment Attributes' ),
),
'public' => true,
@@ -202,7 +202,7 @@
'labels' => array(
'name' => _x( 'Changesets', 'post type general name' ),
'singular_name' => _x( 'Changeset', 'post type singular name' ),
- 'add_new' => _x( 'Add New', 'Customize Changeset' ),
+ 'add_new' => __( 'Add New Changeset' ),
'add_new_item' => __( 'Add New Changeset' ),
'new_item' => __( 'New Changeset' ),
'edit_item' => __( 'Edit Changeset' ),
@@ -282,25 +282,26 @@
'wp_block',
array(
'labels' => array(
- 'name' => _x( 'Reusable blocks', 'post type general name' ),
- 'singular_name' => _x( 'Reusable block', 'post type singular name' ),
- 'add_new' => _x( 'Add New', 'Reusable block' ),
- 'add_new_item' => __( 'Add new Reusable block' ),
- 'new_item' => __( 'New Reusable block' ),
- 'edit_item' => __( 'Edit Reusable block' ),
- 'view_item' => __( 'View Reusable block' ),
- 'all_items' => __( 'All Reusable blocks' ),
- 'search_items' => __( 'Search Reusable blocks' ),
- 'not_found' => __( 'No reusable blocks found.' ),
- 'not_found_in_trash' => __( 'No reusable blocks found in Trash.' ),
- 'filter_items_list' => __( 'Filter reusable blocks list' ),
- 'items_list_navigation' => __( 'Reusable blocks list navigation' ),
- 'items_list' => __( 'Reusable blocks list' ),
- 'item_published' => __( 'Reusable block published.' ),
- 'item_published_privately' => __( 'Reusable block published privately.' ),
- 'item_reverted_to_draft' => __( 'Reusable block reverted to draft.' ),
- 'item_scheduled' => __( 'Reusable block scheduled.' ),
- 'item_updated' => __( 'Reusable block updated.' ),
+ 'name' => _x( 'Patterns', 'post type general name' ),
+ 'singular_name' => _x( 'Pattern', 'post type singular name' ),
+ 'add_new' => __( 'Add New Pattern' ),
+ 'add_new_item' => __( 'Add New Pattern' ),
+ 'new_item' => __( 'New Pattern' ),
+ 'edit_item' => __( 'Edit Block Pattern' ),
+ 'view_item' => __( 'View Pattern' ),
+ 'view_items' => __( 'View Patterns' ),
+ 'all_items' => __( 'All Patterns' ),
+ 'search_items' => __( 'Search Patterns' ),
+ 'not_found' => __( 'No patterns found.' ),
+ 'not_found_in_trash' => __( 'No patterns found in Trash.' ),
+ 'filter_items_list' => __( 'Filter patterns list' ),
+ 'items_list_navigation' => __( 'Patterns list navigation' ),
+ 'items_list' => __( 'Patterns list' ),
+ 'item_published' => __( 'Pattern published.' ),
+ 'item_published_privately' => __( 'Pattern published privately.' ),
+ 'item_reverted_to_draft' => __( 'Pattern reverted to draft.' ),
+ 'item_scheduled' => __( 'Pattern scheduled.' ),
+ 'item_updated' => __( 'Pattern updated.' ),
),
'public' => false,
'_builtin' => true, /* internal use only. don't use this when registering your own post type. */
@@ -319,25 +320,37 @@
'edit_posts' => 'edit_posts',
'edit_published_posts' => 'edit_published_posts',
'delete_published_posts' => 'delete_published_posts',
+ // Enables trashing draft posts as well.
+ 'delete_posts' => 'delete_posts',
'edit_others_posts' => 'edit_others_posts',
'delete_others_posts' => 'delete_others_posts',
),
'map_meta_cap' => true,
'supports' => array(
'title',
+ 'excerpt',
'editor',
'revisions',
+ 'custom-fields',
),
)
);
+ $template_edit_link = 'site-editor.php?' . build_query(
+ array(
+ 'postType' => '%s',
+ 'postId' => '%s',
+ 'canvas' => 'edit',
+ )
+ );
+
register_post_type(
'wp_template',
array(
- 'labels' => array(
+ 'labels' => array(
'name' => _x( 'Templates', 'post type general name' ),
'singular_name' => _x( 'Template', 'post type singular name' ),
- 'add_new' => _x( 'Add New', 'Template' ),
+ 'add_new' => __( 'Add New Template' ),
'add_new_item' => __( 'Add New Template' ),
'new_item' => __( 'New Template' ),
'edit_item' => __( 'Edit Template' ),
@@ -353,19 +366,24 @@
'filter_items_list' => __( 'Filter templates list' ),
'items_list_navigation' => __( 'Templates list navigation' ),
'items_list' => __( 'Templates list' ),
+ 'item_updated' => __( 'Template updated.' ),
),
- 'description' => __( 'Templates to include in your theme.' ),
- 'public' => false,
- '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
- 'has_archive' => false,
- 'show_ui' => false,
- 'show_in_menu' => false,
- 'show_in_rest' => true,
- 'rewrite' => false,
- 'rest_base' => 'templates',
- 'rest_controller_class' => 'WP_REST_Templates_Controller',
- 'capability_type' => array( 'template', 'templates' ),
- 'capabilities' => array(
+ 'description' => __( 'Templates to include in your theme.' ),
+ 'public' => false,
+ '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
+ '_edit_link' => $template_edit_link, /* internal use only. don't use this when registering your own post type. */
+ 'has_archive' => false,
+ 'show_ui' => false,
+ 'show_in_menu' => false,
+ 'show_in_rest' => true,
+ 'rewrite' => false,
+ 'rest_base' => 'templates',
+ 'rest_controller_class' => 'WP_REST_Templates_Controller',
+ 'autosave_rest_controller_class' => 'WP_REST_Template_Autosaves_Controller',
+ 'revisions_rest_controller_class' => 'WP_REST_Template_Revisions_Controller',
+ 'late_route_registration' => true,
+ 'capability_type' => array( 'template', 'templates' ),
+ 'capabilities' => array(
'create_posts' => 'edit_theme_options',
'delete_posts' => 'edit_theme_options',
'delete_others_posts' => 'edit_theme_options',
@@ -379,8 +397,8 @@
'read' => 'edit_theme_options',
'read_private_posts' => 'edit_theme_options',
),
- 'map_meta_cap' => true,
- 'supports' => array(
+ 'map_meta_cap' => true,
+ 'supports' => array(
'title',
'slug',
'excerpt',
@@ -394,10 +412,10 @@
register_post_type(
'wp_template_part',
array(
- 'labels' => array(
+ 'labels' => array(
'name' => _x( 'Template Parts', 'post type general name' ),
'singular_name' => _x( 'Template Part', 'post type singular name' ),
- 'add_new' => _x( 'Add New', 'Template Part' ),
+ 'add_new' => __( 'Add New Template Part' ),
'add_new_item' => __( 'Add New Template Part' ),
'new_item' => __( 'New Template Part' ),
'edit_item' => __( 'Edit Template Part' ),
@@ -413,19 +431,24 @@
'filter_items_list' => __( 'Filter template parts list' ),
'items_list_navigation' => __( 'Template parts list navigation' ),
'items_list' => __( 'Template parts list' ),
+ 'item_updated' => __( 'Template part updated.' ),
),
- 'description' => __( 'Template parts to include in your templates.' ),
- 'public' => false,
- '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
- 'has_archive' => false,
- 'show_ui' => false,
- 'show_in_menu' => false,
- 'show_in_rest' => true,
- 'rewrite' => false,
- 'rest_base' => 'template-parts',
- 'rest_controller_class' => 'WP_REST_Templates_Controller',
- 'map_meta_cap' => true,
- 'capabilities' => array(
+ 'description' => __( 'Template parts to include in your templates.' ),
+ 'public' => false,
+ '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
+ '_edit_link' => $template_edit_link, /* internal use only. don't use this when registering your own post type. */
+ 'has_archive' => false,
+ 'show_ui' => false,
+ 'show_in_menu' => false,
+ 'show_in_rest' => true,
+ 'rewrite' => false,
+ 'rest_base' => 'template-parts',
+ 'rest_controller_class' => 'WP_REST_Templates_Controller',
+ 'autosave_rest_controller_class' => 'WP_REST_Template_Autosaves_Controller',
+ 'revisions_rest_controller_class' => 'WP_REST_Template_Revisions_Controller',
+ 'late_route_registration' => true,
+ 'map_meta_cap' => true,
+ 'capabilities' => array(
'create_posts' => 'edit_theme_options',
'delete_posts' => 'edit_theme_options',
'delete_others_posts' => 'edit_theme_options',
@@ -439,7 +462,7 @@
'read' => 'edit_theme_options',
'read_private_posts' => 'edit_theme_options',
),
- 'supports' => array(
+ 'supports' => array(
'title',
'slug',
'excerpt',
@@ -453,14 +476,19 @@
register_post_type(
'wp_global_styles',
array(
- 'label' => _x( 'Global Styles', 'post type general name' ),
- 'description' => __( 'Global styles to include in themes.' ),
- 'public' => false,
- '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
- 'show_ui' => false,
- 'show_in_rest' => false,
- 'rewrite' => false,
- 'capabilities' => array(
+ 'label' => _x( 'Global Styles', 'post type general name' ),
+ 'description' => __( 'Global styles to include in themes.' ),
+ 'public' => false,
+ '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
+ '_edit_link' => '/site-editor.php?canvas=edit', /* internal use only. don't use this when registering your own post type. */
+ 'show_ui' => false,
+ 'show_in_rest' => true,
+ 'rewrite' => false,
+ 'rest_base' => 'global-styles',
+ 'rest_controller_class' => 'WP_REST_Global_Styles_Controller',
+ 'revisions_rest_controller_class' => 'WP_REST_Global_Styles_Revisions_Controller',
+ 'late_route_registration' => true,
+ 'capabilities' => array(
'read' => 'edit_theme_options',
'create_posts' => 'edit_theme_options',
'edit_posts' => 'edit_theme_options',
@@ -469,14 +497,24 @@
'edit_others_posts' => 'edit_theme_options',
'delete_others_posts' => 'edit_theme_options',
),
- 'map_meta_cap' => true,
- 'supports' => array(
+ 'map_meta_cap' => true,
+ 'supports' => array(
'title',
'editor',
'revisions',
),
)
);
+ // Disable autosave endpoints for global styles.
+ remove_post_type_support( 'wp_global_styles', 'autosave' );
+
+ $navigation_post_edit_link = 'site-editor.php?' . build_query(
+ array(
+ 'postId' => '%s',
+ 'postType' => 'wp_navigation',
+ 'canvas' => 'edit',
+ )
+ );
register_post_type(
'wp_navigation',
@@ -484,7 +522,7 @@
'labels' => array(
'name' => _x( 'Navigation Menus', 'post type general name' ),
'singular_name' => _x( 'Navigation Menu', 'post type singular name' ),
- 'add_new' => _x( 'Add New', 'Navigation Menu' ),
+ 'add_new' => __( 'Add New Navigation Menu' ),
'add_new_item' => __( 'Add New Navigation Menu' ),
'new_item' => __( 'New Navigation Menu' ),
'edit_item' => __( 'Edit Navigation Menu' ),
@@ -504,6 +542,7 @@
'description' => __( 'Navigation menus that can be inserted into your site.' ),
'public' => false,
'_builtin' => true, /* internal use only. don't use this when registering your own post type. */
+ '_edit_link' => $navigation_post_edit_link, /* internal use only. don't use this when registering your own post type. */
'has_archive' => false,
'show_ui' => true,
'show_in_menu' => false,
@@ -534,6 +573,70 @@
)
);
+ register_post_type(
+ 'wp_font_family',
+ array(
+ 'labels' => array(
+ 'name' => __( 'Font Families' ),
+ 'singular_name' => __( 'Font Family' ),
+ ),
+ 'public' => false,
+ '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
+ 'hierarchical' => false,
+ 'capabilities' => array(
+ 'read' => 'edit_theme_options',
+ 'read_private_posts' => 'edit_theme_options',
+ 'create_posts' => 'edit_theme_options',
+ 'publish_posts' => 'edit_theme_options',
+ 'edit_posts' => 'edit_theme_options',
+ 'edit_others_posts' => 'edit_theme_options',
+ 'edit_published_posts' => 'edit_theme_options',
+ 'delete_posts' => 'edit_theme_options',
+ 'delete_others_posts' => 'edit_theme_options',
+ 'delete_published_posts' => 'edit_theme_options',
+ ),
+ 'map_meta_cap' => true,
+ 'query_var' => false,
+ 'rewrite' => false,
+ 'show_in_rest' => true,
+ 'rest_base' => 'font-families',
+ 'rest_controller_class' => 'WP_REST_Font_Families_Controller',
+ 'supports' => array( 'title' ),
+ )
+ );
+
+ register_post_type(
+ 'wp_font_face',
+ array(
+ 'labels' => array(
+ 'name' => __( 'Font Faces' ),
+ 'singular_name' => __( 'Font Face' ),
+ ),
+ 'public' => false,
+ '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
+ 'hierarchical' => false,
+ 'capabilities' => array(
+ 'read' => 'edit_theme_options',
+ 'read_private_posts' => 'edit_theme_options',
+ 'create_posts' => 'edit_theme_options',
+ 'publish_posts' => 'edit_theme_options',
+ 'edit_posts' => 'edit_theme_options',
+ 'edit_others_posts' => 'edit_theme_options',
+ 'edit_published_posts' => 'edit_theme_options',
+ 'delete_posts' => 'edit_theme_options',
+ 'delete_others_posts' => 'edit_theme_options',
+ 'delete_published_posts' => 'edit_theme_options',
+ ),
+ 'map_meta_cap' => true,
+ 'query_var' => false,
+ 'rewrite' => false,
+ 'show_in_rest' => true,
+ 'rest_base' => 'font-families/(?P<font_family_id>[\d]+)/font-faces',
+ 'rest_controller_class' => 'WP_REST_Font_Faces_Controller',
+ 'supports' => array( 'title' ),
+ )
+ );
+
register_post_status(
'publish',
array(
@@ -703,28 +806,27 @@
}
/**
- * Retrieve attached file path based on attachment ID.
- *
- * By default the path will go through the 'get_attached_file' filter, but
- * passing a true to the $unfiltered argument of get_attached_file() will
- * return the file path unfiltered.
- *
- * The function works by getting the single post meta name, named
- * '_wp_attached_file' and returning it. This is a convenience function to
- * prevent looking up the meta name and provide a mechanism for sending the
- * attached filename through a filter.
+ * Retrieves attached file path based on attachment ID.
+ *
+ * By default the path will go through the {@see 'get_attached_file'} filter, but
+ * passing `true` to the `$unfiltered` argument will return the file path unfiltered.
+ *
+ * The function works by retrieving the `_wp_attached_file` post meta value.
+ * This is a convenience function to prevent looking up the meta name and provide
+ * a mechanism for sending the attached filename through a filter.
*
* @since 2.0.0
*
* @param int $attachment_id Attachment ID.
- * @param bool $unfiltered Optional. Whether to apply filters. Default false.
+ * @param bool $unfiltered Optional. Whether to skip the {@see 'get_attached_file'} filter.
+ * Default false.
* @return string|false The file path to where the attached file should be, false otherwise.
*/
function get_attached_file( $attachment_id, $unfiltered = false ) {
$file = get_post_meta( $attachment_id, '_wp_attached_file', true );
// If the file is relative, prepend upload dir.
- if ( $file && 0 !== strpos( $file, '/' ) && ! preg_match( '|^.:\\\|', $file ) ) {
+ if ( $file && ! str_starts_with( $file, '/' ) && ! preg_match( '|^.:\\\|', $file ) ) {
$uploads = wp_get_upload_dir();
if ( false === $uploads['error'] ) {
$file = $uploads['basedir'] . "/$file";
@@ -747,7 +849,7 @@
}
/**
- * Update attachment file path based on attachment ID.
+ * Updates attachment file path based on attachment ID.
*
* Used to update the file path of the attachment, which uses post meta name
* '_wp_attached_file' to store the path of the attachment.
@@ -782,7 +884,7 @@
}
/**
- * Return relative path to an uploaded file.
+ * Returns relative path to an uploaded file.
*
* The path is relative to the current upload dir.
*
@@ -796,7 +898,7 @@
$new_path = $path;
$uploads = wp_get_upload_dir();
- if ( 0 === strpos( $new_path, $uploads['basedir'] ) ) {
+ if ( str_starts_with( $new_path, $uploads['basedir'] ) ) {
$new_path = str_replace( $uploads['basedir'], '', $new_path );
$new_path = ltrim( $new_path, '/' );
}
@@ -813,7 +915,7 @@
}
/**
- * Retrieve all children of the post parent ID.
+ * Retrieves all children of the post parent ID.
*
* Normally, without any enhancements, the children would apply to pages. In the
* context of the inner workings of WordPress, pages, posts, and attachments
@@ -861,7 +963,7 @@
* @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
* correspond to a WP_Post object, an associative array, or a numeric array,
* respectively. Default OBJECT.
- * @return WP_Post[]|int[] Array of post objects or post IDs.
+ * @return WP_Post[]|array[]|int[] Array of post objects, arrays, or IDs, depending on `$output`.
*/
function get_children( $args = '', $output = OBJECT ) {
$kids = array();
@@ -922,7 +1024,7 @@
}
/**
- * Get extended entry info (<!--more-->).
+ * Gets extended entry info (<!--more-->).
*
* There should not be any space after the second dash and before the word
* 'more'. There can be text or space(s) after the word 'more', but won't be
@@ -1056,7 +1158,7 @@
}
/**
- * Retrieve data from a post field based on Post ID.
+ * Retrieves data from a post field based on Post ID.
*
* Examples of the post field will be, 'post_type', 'post_status', 'post_content',
* etc and based off of the post object property or key names.
@@ -1090,7 +1192,7 @@
}
/**
- * Retrieve the mime type of an attachment based on the ID.
+ * Retrieves the mime type of an attachment based on the ID.
*
* This function can be used with any post type, but it makes more sense with
* attachments.
@@ -1111,7 +1213,7 @@
}
/**
- * Retrieve the post status based on the post ID.
+ * Retrieves the post status based on the post ID.
*
* If the post ID is of an attachment, then the parent post status will be given
* instead.
@@ -1122,7 +1224,10 @@
* @return string|false Post status on success, false on failure.
*/
function get_post_status( $post = null ) {
- $post = get_post( $post );
+ // Normalize the post object if necessary, skip normalization if called from get_sample_permalink().
+ if ( ! $post instanceof WP_Post || ! isset( $post->filter ) || 'sample' !== $post->filter ) {
+ $post = get_post( $post );
+ }
if ( ! is_object( $post ) ) {
return false;
@@ -1144,6 +1249,7 @@
} elseif ( 'trash' === get_post_status( $post->post_parent ) ) {
// Get parent status prior to trashing.
$post_status = get_post_meta( $post->post_parent, '_wp_trash_meta_status', true );
+
if ( ! $post_status ) {
// Assume publish as above.
$post_status = 'publish';
@@ -1178,7 +1284,7 @@
}
/**
- * Retrieve all of the WordPress supported post statuses.
+ * Retrieves all of the WordPress supported post statuses.
*
* Posts have a limited set of valid status values, this provides the
* post_status values and descriptions.
@@ -1199,7 +1305,7 @@
}
/**
- * Retrieve all of the WordPress support page statuses.
+ * Retrieves all of the WordPress support page statuses.
*
* Pages have a limited set of valid status values, this provides the
* post_status values and descriptions.
@@ -1219,12 +1325,12 @@
}
/**
- * Return statuses for privacy requests.
+ * Returns statuses for privacy requests.
*
* @since 4.9.6
* @access private
*
- * @return array
+ * @return string[] Array of privacy request status labels keyed by their status.
*/
function _wp_privacy_statuses() {
return array(
@@ -1236,7 +1342,7 @@
}
/**
- * Register a post status. Do not use before init.
+ * Registers a post status. Do not use before init.
*
* A simple function for creating or modifying a post status based on the
* parameters given. The function will accept an array (second optional
@@ -1254,8 +1360,10 @@
*
* @type bool|string $label A descriptive name for the post status marked
* for translation. Defaults to value of $post_status.
- * @type bool|array $label_count Descriptive text to use for nooped plurals.
- * Default array of $label, twice.
+ * @type array|false $label_count Nooped plural text from _n_noop() to provide the singular
+ * and plural forms of the label for counts. Default false
+ * which means the `$label` argument will be used for both
+ * the singular and plural forms of this label.
* @type bool $exclude_from_search Whether to exclude posts with this post status
* from search results. Default is value of $internal.
* @type bool $_builtin Whether the status is built-in. Core-use only.
@@ -1356,7 +1464,7 @@
}
if ( false === $args->label_count ) {
- // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralSingle,WordPress.WP.I18n.NonSingularStringLiteralPlural
+ // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralSingular,WordPress.WP.I18n.NonSingularStringLiteralPlural
$args->label_count = _n_noop( $args->label, $args->label );
}
@@ -1366,7 +1474,7 @@
}
/**
- * Retrieve a post status object by name.
+ * Retrieves a post status object by name.
*
* @since 3.0.0
*
@@ -1388,7 +1496,7 @@
}
/**
- * Get a list of post statuses.
+ * Gets a list of post statuses.
*
* @since 3.0.0
*
@@ -1413,7 +1521,7 @@
}
/**
- * Whether the post type is hierarchical.
+ * Determines whether the post type is hierarchical.
*
* A false return value might also mean that the post type does not exist.
*
@@ -1492,7 +1600,7 @@
}
/**
- * Get a list of all registered post type objects.
+ * Gets a list of all registered post type objects.
*
* @since 2.9.0
*
@@ -1502,7 +1610,7 @@
*
* @param array|string $args Optional. An array of key => value arguments to match against
* the post type objects. Default empty array.
- * @param string $output Optional. The type of output to return. Accepts post type 'names'
+ * @param string $output Optional. The type of output to return. Either 'names'
* or 'objects'. Default 'names'.
* @param string $operator Optional. The logical operation to perform. 'or' means only one
* element from the array needs to match; 'and' means all elements
@@ -1544,91 +1652,97 @@
*
* @global array $wp_post_types List of post types.
*
- * @param string $post_type Post type key. Must not exceed 20 characters and may
- * only contain lowercase alphanumeric characters, dashes,
- * and underscores. See sanitize_key().
+ * @param string $post_type Post type key. Must not exceed 20 characters and may only contain
+ * lowercase alphanumeric characters, dashes, and underscores. See sanitize_key().
* @param array|string $args {
* Array or string of arguments for registering a post type.
*
- * @type string $label Name of the post type shown in the menu. Usually plural.
- * Default is value of $labels['name'].
- * @type string[] $labels An array of labels for this post type. If not set, post
- * labels are inherited for non-hierarchical types and page
- * labels for hierarchical ones. See get_post_type_labels() for a full
- * list of supported labels.
- * @type string $description A short descriptive summary of what the post type is.
- * Default empty.
- * @type bool $public Whether a post type is intended for use publicly either via
- * the admin interface or by front-end users. While the default
- * settings of $exclude_from_search, $publicly_queryable, $show_ui,
- * and $show_in_nav_menus are inherited from $public, each does not
- * rely on this relationship and controls a very specific intention.
- * Default false.
- * @type bool $hierarchical Whether the post type is hierarchical (e.g. page). Default false.
- * @type bool $exclude_from_search Whether to exclude posts with this post type from front end search
- * results. Default is the opposite value of $public.
- * @type bool $publicly_queryable Whether queries can be performed on the front end for the post type
- * as part of parse_request(). Endpoints would include:
- * * ?post_type={post_type_key}
- * * ?{post_type_key}={single_post_slug}
- * * ?{post_type_query_var}={single_post_slug}
- * If not set, the default is inherited from $public.
- * @type bool $show_ui Whether to generate and allow a UI for managing this post type in the
- * admin. Default is value of $public.
- * @type bool|string $show_in_menu Where to show the post type in the admin menu. To work, $show_ui
- * must be true. If true, the post type is shown in its own top level
- * menu. If false, no menu is shown. If a string of an existing top
- * level menu ('tools.php' or 'edit.php?post_type=page', for example), the
- * post type will be placed as a sub-menu of that.
- * Default is value of $show_ui.
- * @type bool $show_in_nav_menus Makes this post type available for selection in navigation menus.
- * Default is value of $public.
- * @type bool $show_in_admin_bar Makes this post type available via the admin bar. Default is value
- * of $show_in_menu.
- * @type bool $show_in_rest Whether to include the post type in the REST API. Set this to true
- * for the post type to be available in the block editor.
- * @type string $rest_base To change the base URL of REST API route. Default is $post_type.
- * @type string $rest_namespace To change the namespace URL of REST API route. Default is wp/v2.
- * @type string $rest_controller_class REST API controller class name. Default is 'WP_REST_Posts_Controller'.
- * @type int $menu_position The position in the menu order the post type should appear. To work,
- * $show_in_menu must be true. Default null (at the bottom).
- * @type string $menu_icon The URL to the icon to be used for this menu. Pass a base64-encoded
- * SVG using a data URI, which will be colored to match the color scheme
- * -- this should begin with 'data:image/svg+xml;base64,'. Pass the name
- * of a Dashicons helper class to use a font icon, e.g.
- * 'dashicons-chart-pie'. Pass 'none' to leave div.wp-menu-image empty
- * so an icon can be added via CSS. Defaults to use the posts icon.
- * @type string|array $capability_type The string to use to build the read, edit, and delete capabilities.
- * May be passed as an array to allow for alternative plurals when using
- * this argument as a base to construct the capabilities, e.g.
- * array('story', 'stories'). Default 'post'.
- * @type string[] $capabilities Array of capabilities for this post type. $capability_type is used
- * as a base to construct capabilities by default.
- * See get_post_type_capabilities().
- * @type bool $map_meta_cap Whether to use the internal default meta capability handling.
- * Default false.
- * @type array $supports Core feature(s) the post type supports. Serves as an alias for calling
- * add_post_type_support() directly. Core features include 'title',
- * 'editor', 'comments', 'revisions', 'trackbacks', 'author', 'excerpt',
- * 'page-attributes', 'thumbnail', 'custom-fields', and 'post-formats'.
- * Additionally, the 'revisions' feature dictates whether the post type
- * will store revisions, and the 'comments' feature dictates whether the
- * comments count will show on the edit screen. A feature can also be
- * specified as an array of arguments to provide additional information
- * about supporting that feature.
- * Example: `array( 'my_feature', array( 'field' => 'value' ) )`.
- * Default is an array containing 'title' and 'editor'.
- * @type callable $register_meta_box_cb Provide a callback function that sets up the meta boxes for the
- * edit form. Do remove_meta_box() and add_meta_box() calls in the
- * callback. Default null.
- * @type string[] $taxonomies An array of taxonomy identifiers that will be registered for the
- * post type. Taxonomies can be registered later with register_taxonomy()
- * or register_taxonomy_for_object_type().
- * Default empty array.
- * @type bool|string $has_archive Whether there should be post type archives, or if a string, the
- * archive slug to use. Will generate the proper rewrite rules if
- * $rewrite is enabled. Default false.
- * @type bool|array $rewrite {
+ * @type string $label Name of the post type shown in the menu. Usually plural.
+ * Default is value of $labels['name'].
+ * @type string[] $labels An array of labels for this post type. If not set, post
+ * labels are inherited for non-hierarchical types and page
+ * labels for hierarchical ones. See get_post_type_labels() for a full
+ * list of supported labels.
+ * @type string $description A short descriptive summary of what the post type is.
+ * Default empty.
+ * @type bool $public Whether a post type is intended for use publicly either via
+ * the admin interface or by front-end users. While the default
+ * settings of $exclude_from_search, $publicly_queryable, $show_ui,
+ * and $show_in_nav_menus are inherited from $public, each does not
+ * rely on this relationship and controls a very specific intention.
+ * Default false.
+ * @type bool $hierarchical Whether the post type is hierarchical (e.g. page). Default false.
+ * @type bool $exclude_from_search Whether to exclude posts with this post type from front end search
+ * results. Default is the opposite value of $public.
+ * @type bool $publicly_queryable Whether queries can be performed on the front end for the post type
+ * as part of parse_request(). Endpoints would include:
+ * * ?post_type={post_type_key}
+ * * ?{post_type_key}={single_post_slug}
+ * * ?{post_type_query_var}={single_post_slug}
+ * If not set, the default is inherited from $public.
+ * @type bool $show_ui Whether to generate and allow a UI for managing this post type in the
+ * admin. Default is value of $public.
+ * @type bool|string $show_in_menu Where to show the post type in the admin menu. To work, $show_ui
+ * must be true. If true, the post type is shown in its own top level
+ * menu. If false, no menu is shown. If a string of an existing top
+ * level menu ('tools.php' or 'edit.php?post_type=page', for example), the
+ * post type will be placed as a sub-menu of that.
+ * Default is value of $show_ui.
+ * @type bool $show_in_nav_menus Makes this post type available for selection in navigation menus.
+ * Default is value of $public.
+ * @type bool $show_in_admin_bar Makes this post type available via the admin bar. Default is value
+ * of $show_in_menu.
+ * @type bool $show_in_rest Whether to include the post type in the REST API. Set this to true
+ * for the post type to be available in the block editor.
+ * @type string $rest_base To change the base URL of REST API route. Default is $post_type.
+ * @type string $rest_namespace To change the namespace URL of REST API route. Default is wp/v2.
+ * @type string $rest_controller_class REST API controller class name. Default is 'WP_REST_Posts_Controller'.
+ * @type string|bool $autosave_rest_controller_class REST API controller class name. Default is 'WP_REST_Autosaves_Controller'.
+ * @type string|bool $revisions_rest_controller_class REST API controller class name. Default is 'WP_REST_Revisions_Controller'.
+ * @type bool $late_route_registration A flag to direct the REST API controllers for autosave / revisions
+ * should be registered before/after the post type controller.
+ * @type int $menu_position The position in the menu order the post type should appear. To work,
+ * $show_in_menu must be true. Default null (at the bottom).
+ * @type string $menu_icon The URL to the icon to be used for this menu. Pass a base64-encoded
+ * SVG using a data URI, which will be colored to match the color scheme
+ * -- this should begin with 'data:image/svg+xml;base64,'. Pass the name
+ * of a Dashicons helper class to use a font icon, e.g.
+ * 'dashicons-chart-pie'. Pass 'none' to leave div.wp-menu-image empty
+ * so an icon can be added via CSS. Defaults to use the posts icon.
+ * @type string|array $capability_type The string to use to build the read, edit, and delete capabilities.
+ * May be passed as an array to allow for alternative plurals when using
+ * this argument as a base to construct the capabilities, e.g.
+ * array('story', 'stories'). Default 'post'.
+ * @type string[] $capabilities Array of capabilities for this post type. $capability_type is used
+ * as a base to construct capabilities by default.
+ * See get_post_type_capabilities().
+ * @type bool $map_meta_cap Whether to use the internal default meta capability handling.
+ * Default false.
+ * @type array|false $supports Core feature(s) the post type supports. Serves as an alias for calling
+ * add_post_type_support() directly. Core features include 'title',
+ * 'editor', 'comments', 'revisions', 'trackbacks', 'author', 'excerpt',
+ * 'page-attributes', 'thumbnail', 'custom-fields', and 'post-formats'.
+ * Additionally, the 'revisions' feature dictates whether the post type
+ * will store revisions, the 'autosave' feature dictates whether the post type
+ * will be autosaved, and the 'comments' feature dictates whether the
+ * comments count will show on the edit screen. For backward compatibility reasons,
+ * adding 'editor' support implies 'autosave' support too. A feature can also be
+ * specified as an array of arguments to provide additional information
+ * about supporting that feature.
+ * Example: `array( 'my_feature', array( 'field' => 'value' ) )`.
+ * If false, no features will be added.
+ * Default is an array containing 'title' and 'editor'.
+ * @type callable $register_meta_box_cb Provide a callback function that sets up the meta boxes for the
+ * edit form. Do remove_meta_box() and add_meta_box() calls in the
+ * callback. Default null.
+ * @type string[] $taxonomies An array of taxonomy identifiers that will be registered for the
+ * post type. Taxonomies can be registered later with register_taxonomy()
+ * or register_taxonomy_for_object_type().
+ * Default empty array.
+ * @type bool|string $has_archive Whether there should be post type archives, or if a string, the
+ * archive slug to use. Will generate the proper rewrite rules if
+ * $rewrite is enabled. Default false.
+ * @type bool|array $rewrite {
* Triggers the handling of rewrites for this post type. To prevent rewrite, set to false.
* Defaults to true, using $post_type as slug. To specify rewrite rules, an array can be
* passed with any of these keys:
@@ -1643,32 +1757,32 @@
* inherits from $permalink_epmask. If not specified and permalink_epmask
* is not set, defaults to EP_PERMALINK.
* }
- * @type string|bool $query_var Sets the query_var key for this post type. Defaults to $post_type
- * key. If false, a post type cannot be loaded at
- * ?{query_var}={post_slug}. If specified as a string, the query
- * ?{query_var_string}={post_slug} will be valid.
- * @type bool $can_export Whether to allow this post type to be exported. Default true.
- * @type bool $delete_with_user Whether to delete posts of this type when deleting a user.
- * * If true, posts of this type belonging to the user will be moved
- * to Trash when the user is deleted.
- * * If false, posts of this type belonging to the user will *not*
- * be trashed or deleted.
- * * If not set (the default), posts are trashed if post type supports
- * the 'author' feature. Otherwise posts are not trashed or deleted.
- * Default null.
- * @type array $template Array of blocks to use as the default initial state for an editor
- * session. Each item should be an array containing block name and
- * optional attributes. Default empty array.
- * @type string|false $template_lock Whether the block template should be locked if $template is set.
- * * If set to 'all', the user is unable to insert new blocks,
- * move existing blocks and delete blocks.
- * * If set to 'insert', the user is able to move existing blocks
- * but is unable to insert new blocks and delete blocks.
- * Default false.
- * @type bool $_builtin FOR INTERNAL USE ONLY! True if this post type is a native or
- * "built-in" post_type. Default false.
- * @type string $_edit_link FOR INTERNAL USE ONLY! URL segment to use for edit link of
- * this post type. Default 'post.php?post=%d'.
+ * @type string|bool $query_var Sets the query_var key for this post type. Defaults to $post_type
+ * key. If false, a post type cannot be loaded at
+ * ?{query_var}={post_slug}. If specified as a string, the query
+ * ?{query_var_string}={post_slug} will be valid.
+ * @type bool $can_export Whether to allow this post type to be exported. Default true.
+ * @type bool $delete_with_user Whether to delete posts of this type when deleting a user.
+ * * If true, posts of this type belonging to the user will be moved
+ * to Trash when the user is deleted.
+ * * If false, posts of this type belonging to the user will *not*
+ * be trashed or deleted.
+ * * If not set (the default), posts are trashed if post type supports
+ * the 'author' feature. Otherwise posts are not trashed or deleted.
+ * Default null.
+ * @type array $template Array of blocks to use as the default initial state for an editor
+ * session. Each item should be an array containing block name and
+ * optional attributes. Default empty array.
+ * @type string|false $template_lock Whether the block template should be locked if $template is set.
+ * * If set to 'all', the user is unable to insert new blocks,
+ * move existing blocks and delete blocks.
+ * * If set to 'insert', the user is able to move existing blocks
+ * but is unable to insert new blocks and delete blocks.
+ * Default false.
+ * @type bool $_builtin FOR INTERNAL USE ONLY! True if this post type is a native or
+ * "built-in" post_type. Default false.
+ * @type string $_edit_link FOR INTERNAL USE ONLY! URL segment to use for edit link of
+ * this post type. Default 'post.php?post=%d'.
* }
* @return WP_Post_Type|WP_Error The registered post type object on success,
* WP_Error object on failure.
@@ -1776,7 +1890,7 @@
}
/**
- * Build an object with all post type capabilities out of a post type object
+ * Builds an object with all post type capabilities out of a post type object
*
* Post type capabilities use the 'capability_type' argument as a base, if the
* capability is not set in the 'capabilities' argument array or if the
@@ -1881,7 +1995,7 @@
}
/**
- * Store or return a list of post type meta caps for map_meta_cap().
+ * Stores or returns a list of post type meta caps for map_meta_cap().
*
* @since 3.1.0
* @access private
@@ -1908,9 +2022,7 @@
* - `name` - General name for the post type, usually plural. The same and overridden
* by `$post_type_object->label`. Default is 'Posts' / 'Pages'.
* - `singular_name` - Name for one object of this post type. Default is 'Post' / 'Page'.
- * - `add_new` - Default is 'Add New' for both hierarchical and non-hierarchical types.
- * When internationalizing this string, please use a {@link https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#disambiguation-by-context gettext context}
- * matching your post type. Example: `_x( 'Add New', 'product', 'textdomain' );`.
+ * - `add_new` - Label for adding a new item. Default is 'Add New Post' / 'Add New Page'.
* - `add_new_item` - Label for adding a new singular item. Default is 'Add New Post' / 'Add New Page'.
* - `edit_item` - Label for editing a singular item. Default is 'Edit Post' / 'Edit Page'.
* - `new_item` - Label for the new item page title. Default is 'New Post' / 'New Page'.
@@ -1944,6 +2056,7 @@
* Default is 'Post published privately.' / 'Page published privately.'
* - `item_reverted_to_draft` - Label used when an item is switched to a draft.
* Default is 'Post reverted to draft.' / 'Page reverted to draft.'
+ * - `item_trashed` - Label used when an item is moved to Trash. Default is 'Post trashed.' / 'Page trashed.'
* - `item_scheduled` - Label used when an item is scheduled for publishing. Default is 'Post scheduled.' /
* 'Page scheduled.'
* - `item_updated` - Label used when an item is updated. Default is 'Post updated.' / 'Page updated.'
@@ -1967,6 +2080,10 @@
* `item_scheduled`, and `item_updated` labels.
* @since 5.7.0 Added the `filter_by_date` label.
* @since 5.8.0 Added the `item_link` and `item_link_description` labels.
+ * @since 6.3.0 Added the `item_trashed` label.
+ * @since 6.4.0 Changed default values for the `add_new` label to include the type of content.
+ * This matches `add_new_item` and provides more context for better accessibility.
+ * @since 6.6.0 Added the `template_name` label.
*
* @access private
*
@@ -1980,6 +2097,11 @@
$labels = _get_custom_object_labels( $post_type_object, $nohier_vs_hier_defaults );
+ if ( ! isset( $post_type_object->labels->template_name ) && isset( $post_type_object->labels->singular_name ) ) {
+ /* translators: %s: Post type name. */
+ $labels->template_name = sprintf( __( 'Single item: %s' ), $post_type_object->labels->singular_name );
+ }
+
$post_type = $post_type_object->name;
$default_labels = clone $labels;
@@ -2011,55 +2133,59 @@
}
/**
- * Build an object with custom-something object (post type, taxonomy) labels
+ * Builds an object with custom-something object (post type, taxonomy) labels
* out of a custom-something object
*
* @since 3.0.0
* @access private
*
- * @param object $object A custom-something object.
+ * @param object $data_object A custom-something object.
* @param array $nohier_vs_hier_defaults Hierarchical vs non-hierarchical default labels.
* @return object Object containing labels for the given custom-something object.
*/
-function _get_custom_object_labels( $object, $nohier_vs_hier_defaults ) {
- $object->labels = (array) $object->labels;
-
- if ( isset( $object->label ) && empty( $object->labels['name'] ) ) {
- $object->labels['name'] = $object->label;
- }
-
- if ( ! isset( $object->labels['singular_name'] ) && isset( $object->labels['name'] ) ) {
- $object->labels['singular_name'] = $object->labels['name'];
- }
-
- if ( ! isset( $object->labels['name_admin_bar'] ) ) {
- $object->labels['name_admin_bar'] = isset( $object->labels['singular_name'] ) ? $object->labels['singular_name'] : $object->name;
- }
-
- if ( ! isset( $object->labels['menu_name'] ) && isset( $object->labels['name'] ) ) {
- $object->labels['menu_name'] = $object->labels['name'];
- }
-
- if ( ! isset( $object->labels['all_items'] ) && isset( $object->labels['menu_name'] ) ) {
- $object->labels['all_items'] = $object->labels['menu_name'];
- }
-
- if ( ! isset( $object->labels['archives'] ) && isset( $object->labels['all_items'] ) ) {
- $object->labels['archives'] = $object->labels['all_items'];
+function _get_custom_object_labels( $data_object, $nohier_vs_hier_defaults ) {
+ $data_object->labels = (array) $data_object->labels;
+
+ if ( isset( $data_object->label ) && empty( $data_object->labels['name'] ) ) {
+ $data_object->labels['name'] = $data_object->label;
+ }
+
+ if ( ! isset( $data_object->labels['singular_name'] ) && isset( $data_object->labels['name'] ) ) {
+ $data_object->labels['singular_name'] = $data_object->labels['name'];
+ }
+
+ if ( ! isset( $data_object->labels['name_admin_bar'] ) ) {
+ $data_object->labels['name_admin_bar'] =
+ isset( $data_object->labels['singular_name'] )
+ ? $data_object->labels['singular_name']
+ : $data_object->name;
+ }
+
+ if ( ! isset( $data_object->labels['menu_name'] ) && isset( $data_object->labels['name'] ) ) {
+ $data_object->labels['menu_name'] = $data_object->labels['name'];
+ }
+
+ if ( ! isset( $data_object->labels['all_items'] ) && isset( $data_object->labels['menu_name'] ) ) {
+ $data_object->labels['all_items'] = $data_object->labels['menu_name'];
+ }
+
+ if ( ! isset( $data_object->labels['archives'] ) && isset( $data_object->labels['all_items'] ) ) {
+ $data_object->labels['archives'] = $data_object->labels['all_items'];
}
$defaults = array();
foreach ( $nohier_vs_hier_defaults as $key => $value ) {
- $defaults[ $key ] = $object->hierarchical ? $value[1] : $value[0];
- }
- $labels = array_merge( $defaults, $object->labels );
- $object->labels = (object) $object->labels;
+ $defaults[ $key ] = $data_object->hierarchical ? $value[1] : $value[0];
+ }
+
+ $labels = array_merge( $defaults, $data_object->labels );
+ $data_object->labels = (object) $data_object->labels;
return (object) $labels;
}
/**
- * Add submenus for post types.
+ * Adds submenus for post types.
*
* @access private
* @since 3.1.0
@@ -2084,7 +2210,8 @@
* 'thumbnail', 'custom-fields', and 'post-formats'.
*
* Additionally, the 'revisions' feature dictates whether the post type will
- * store revisions, and the 'comments' feature dictates whether the comments
+ * store revisions, the 'autosave' feature dictates whether the post type
+ * will be autosaved, and the 'comments' feature dictates whether the comments
* count will show on the edit screen.
*
* A third, optional parameter can also be passed along with a feature to provide
@@ -2125,7 +2252,7 @@
}
/**
- * Remove support for a feature from a post type.
+ * Removes support for a feature from a post type.
*
* @since 3.0.0
*
@@ -2141,7 +2268,7 @@
}
/**
- * Get all the post type features
+ * Gets all the post type features
*
* @since 3.4.0
*
@@ -2161,7 +2288,7 @@
}
/**
- * Check a post type's support for a given feature.
+ * Checks a post type's support for a given feature.
*
* @since 3.0.0
*
@@ -2200,7 +2327,7 @@
}
/**
- * Update the post type for the post ID.
+ * Updates the post type for the post ID.
*
* The page or post cache will be cleaned for the post ID.
*
@@ -2241,6 +2368,7 @@
function is_post_type_viewable( $post_type ) {
if ( is_scalar( $post_type ) ) {
$post_type = get_post_type_object( $post_type );
+
if ( ! $post_type ) {
return false;
}
@@ -2270,7 +2398,7 @@
}
/**
- * Determine whether a post status is considered "viewable".
+ * Determines whether a post status is considered "viewable".
*
* For built-in post statuses such as publish and private, the 'public' value will be evaluated.
* For all others, the 'publicly_queryable' value will be used.
@@ -2284,6 +2412,7 @@
function is_post_status_viewable( $post_status ) {
if ( is_scalar( $post_status ) ) {
$post_status = get_post_status_object( $post_status );
+
if ( ! $post_status ) {
return false;
}
@@ -2317,7 +2446,7 @@
}
/**
- * Determine whether a post is publicly viewable.
+ * Determines whether a post is publicly viewable.
*
* Posts are considered publicly viewable if both the post status and post type
* are viewable.
@@ -2406,9 +2535,8 @@
$parsed_args['ignore_sticky_posts'] = true;
$parsed_args['no_found_rows'] = true;
- $get_posts = new WP_Query;
+ $get_posts = new WP_Query();
return $get_posts->query( $parsed_args );
-
}
//
@@ -2563,7 +2691,7 @@
}
/**
- * Retrieve post meta fields, based on post ID.
+ * Retrieves post meta fields, based on post ID.
*
* The post meta fields are retrieved from the cache where possible,
* so the function is optimized to be called more than once.
@@ -2577,6 +2705,7 @@
*/
function get_post_custom( $post_id = 0 ) {
$post_id = absint( $post_id );
+
if ( ! $post_id ) {
$post_id = get_the_ID();
}
@@ -2585,7 +2714,7 @@
}
/**
- * Retrieve meta field names for a post.
+ * Retrieves meta field names for a post.
*
* If there are no meta fields, then nothing (null) will be returned.
*
@@ -2608,7 +2737,7 @@
}
/**
- * Retrieve values for a custom post field.
+ * Retrieves values for a custom post field.
*
* The parameters must not be considered optional. All of the post meta fields
* will be retrieved and only the meta field key values returned.
@@ -2752,7 +2881,7 @@
}
$prefixed = false;
- if ( false !== strpos( $field, 'post_' ) ) {
+ if ( str_contains( $field, 'post_' ) ) {
$prefixed = true;
$field_no_prefix = str_replace( 'post_', '', $field );
}
@@ -2881,7 +3010,7 @@
}
/**
- * Make a post sticky.
+ * Makes a post sticky.
*
* Sticky posts should be displayed at the top of the front page.
*
@@ -2918,7 +3047,7 @@
}
/**
- * Un-stick a post.
+ * Un-sticks a post.
*
* Sticky posts should be displayed at the top of the front page.
*
@@ -2962,7 +3091,7 @@
}
/**
- * Return the cache key for wp_count_posts() based on the passed arguments.
+ * Returns the cache key for wp_count_posts() based on the passed arguments.
*
* @since 3.9.0
* @access private
@@ -2986,7 +3115,7 @@
}
/**
- * Count number of posts of a post type and if user has permissions to view.
+ * Counts number of posts of a post type and if user has permissions to view.
*
* This function provides an efficient method of finding the amount of post's
* type a blog has. Another method is to count the amount of items in
@@ -3002,13 +3131,14 @@
*
* @param string $type Optional. Post type to retrieve count. Default 'post'.
* @param string $perm Optional. 'readable' or empty. Default empty.
- * @return stdClass Number of posts for each status.
+ * @return stdClass An object containing the number of posts for each status,
+ * or an empty object if the post type does not exist.
*/
function wp_count_posts( $type = 'post', $perm = '' ) {
global $wpdb;
if ( ! post_type_exists( $type ) ) {
- return new stdClass;
+ return new stdClass();
}
$cache_key = _count_posts_cache_key( $type, $perm );
@@ -3051,7 +3181,7 @@
wp_cache_set( $cache_key, $counts, 'counts' );
/**
- * Modify returned post counts by status for the current post type.
+ * Filters the post counts by status for the current post type.
*
* @since 3.7.0
*
@@ -3065,7 +3195,7 @@
}
/**
- * Count number of attachments for the mime type(s).
+ * Counts number of attachments for the mime type(s).
*
* If you set the optional mime_type parameter, then an array will still be
* returned, but will only have the item you are looking for. It does not give
@@ -3083,17 +3213,27 @@
function wp_count_attachments( $mime_type = '' ) {
global $wpdb;
- $and = wp_post_mime_type_where( $mime_type );
- $count = $wpdb->get_results( "SELECT post_mime_type, COUNT( * ) AS num_posts FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' $and GROUP BY post_mime_type", ARRAY_A );
-
- $counts = array();
- foreach ( (array) $count as $row ) {
- $counts[ $row['post_mime_type'] ] = $row['num_posts'];
- }
- $counts['trash'] = $wpdb->get_var( "SELECT COUNT( * ) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status = 'trash' $and" );
+ $cache_key = sprintf(
+ 'attachments%s',
+ ! empty( $mime_type ) ? ':' . str_replace( '/', '_', implode( '-', (array) $mime_type ) ) : ''
+ );
+
+ $counts = wp_cache_get( $cache_key, 'counts' );
+ if ( false == $counts ) {
+ $and = wp_post_mime_type_where( $mime_type );
+ $count = $wpdb->get_results( "SELECT post_mime_type, COUNT( * ) AS num_posts FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' $and GROUP BY post_mime_type", ARRAY_A );
+
+ $counts = array();
+ foreach ( (array) $count as $row ) {
+ $counts[ $row['post_mime_type'] ] = $row['num_posts'];
+ }
+ $counts['trash'] = $wpdb->get_var( "SELECT COUNT( * ) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status = 'trash' $and" );
+
+ wp_cache_set( $cache_key, (object) $counts, 'counts' );
+ }
/**
- * Modify returned attachment counts by mime type.
+ * Filters the attachment counts by mime type.
*
* @since 3.7.0
*
@@ -3105,7 +3245,7 @@
}
/**
- * Get default post mime types.
+ * Gets default post mime types.
*
* @since 2.9.0
* @since 5.3.0 Added the 'Documents', 'Spreadsheets', and 'Archives' mime type groups.
@@ -3209,16 +3349,16 @@
}
/**
- * Check a MIME-Type against a list.
- *
- * If the wildcard_mime_types parameter is a string, it must be comma separated
- * list. If the real_mime_types is a string, it is also comma separated to
+ * Checks a MIME-Type against a list.
+ *
+ * If the `$wildcard_mime_types` parameter is a string, it must be comma separated
+ * list. If the `$real_mime_types` is a string, it is also comma separated to
* create the list.
*
* @since 2.5.0
*
- * @param string|string[] $wildcard_mime_types Mime types, e.g. audio/mpeg or image (same as image/*)
- * or flash (same as *flash*).
+ * @param string|string[] $wildcard_mime_types Mime types, e.g. `audio/mpeg`, `image` (same as `image/*`),
+ * or `flash` (same as `*flash*`).
* @param string|string[] $real_mime_types Real post mime type values.
* @return array array(wildcard=>array(real types)).
*/
@@ -3241,7 +3381,7 @@
$patternses[][ $type ] = "^$regex$";
- if ( false === strpos( $mime, '/' ) ) {
+ if ( ! str_contains( $mime, '/' ) ) {
$patternses[][ $type ] = "^$regex/";
$patternses[][ $type ] = $regex;
}
@@ -3265,7 +3405,7 @@
}
/**
- * Convert MIME types into SQL.
+ * Converts MIME types into SQL.
*
* @since 2.5.0
*
@@ -3282,7 +3422,7 @@
$post_mime_types = array_map( 'trim', explode( ',', $post_mime_types ) );
}
- $wheres = array();
+ $where_clauses = array();
foreach ( (array) $post_mime_types as $mime_type ) {
$mime_type = preg_replace( '/\s/', '', $mime_type );
@@ -3298,7 +3438,7 @@
$mime_pattern = "$mime_group/$mime_subgroup";
} else {
$mime_pattern = preg_replace( '/[^-*.a-zA-Z0-9]/', '', $mime_type );
- if ( false === strpos( $mime_pattern, '*' ) ) {
+ if ( ! str_contains( $mime_pattern, '*' ) ) {
$mime_pattern .= '/*';
}
}
@@ -3309,22 +3449,22 @@
return '';
}
- if ( false !== strpos( $mime_pattern, '%' ) ) {
- $wheres[] = empty( $table_alias ) ? "post_mime_type LIKE '$mime_pattern'" : "$table_alias.post_mime_type LIKE '$mime_pattern'";
+ if ( str_contains( $mime_pattern, '%' ) ) {
+ $where_clauses[] = empty( $table_alias ) ? "post_mime_type LIKE '$mime_pattern'" : "$table_alias.post_mime_type LIKE '$mime_pattern'";
} else {
- $wheres[] = empty( $table_alias ) ? "post_mime_type = '$mime_pattern'" : "$table_alias.post_mime_type = '$mime_pattern'";
- }
- }
-
- if ( ! empty( $wheres ) ) {
- $where = ' AND (' . implode( ' OR ', $wheres ) . ') ';
+ $where_clauses[] = empty( $table_alias ) ? "post_mime_type = '$mime_pattern'" : "$table_alias.post_mime_type = '$mime_pattern'";
+ }
+ }
+
+ if ( ! empty( $where_clauses ) ) {
+ $where = ' AND (' . implode( ' OR ', $where_clauses ) . ') ';
}
return $where;
}
/**
- * Trash or delete a post or page.
+ * Trashes or deletes a post or page.
*
* When the post and page is permanently deleted, everything that is tied to
* it is deleted also. This includes comments, post meta fields, and terms
@@ -3339,15 +3479,15 @@
* @see wp_delete_attachment()
* @see wp_trash_post()
*
- * @param int $postid Optional. Post ID. Default 0.
+ * @param int $post_id Optional. Post ID. Default 0.
* @param bool $force_delete Optional. Whether to bypass Trash and force deletion.
* Default false.
* @return WP_Post|false|null Post data on success, false or null on failure.
*/
-function wp_delete_post( $postid = 0, $force_delete = false ) {
+function wp_delete_post( $post_id = 0, $force_delete = false ) {
global $wpdb;
- $post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d", $postid ) );
+ $post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d", $post_id ) );
if ( ! $post ) {
return $post;
@@ -3355,12 +3495,15 @@
$post = get_post( $post );
- if ( ! $force_delete && ( 'post' === $post->post_type || 'page' === $post->post_type ) && 'trash' !== get_post_status( $postid ) && EMPTY_TRASH_DAYS ) {
- return wp_trash_post( $postid );
+ if ( ! $force_delete
+ && ( 'post' === $post->post_type || 'page' === $post->post_type )
+ && 'trash' !== get_post_status( $post_id ) && EMPTY_TRASH_DAYS
+ ) {
+ return wp_trash_post( $post_id );
}
if ( 'attachment' === $post->post_type ) {
- return wp_delete_attachment( $postid, $force_delete );
+ return wp_delete_attachment( $post_id, $force_delete );
}
/**
@@ -3368,7 +3511,7 @@
*
* @since 4.4.0
*
- * @param WP_Post|false|null $delete Whether to go forward with deletion. @TODO description
+ * @param WP_Post|false|null $delete Whether to go forward with deletion.
* @param WP_Post $post Post object.
* @param bool $force_delete Whether to bypass the Trash.
*/
@@ -3385,30 +3528,39 @@
*
* @see wp_delete_post()
*
- * @param int $postid Post ID.
- * @param WP_Post $post Post object.
+ * @param int $post_id Post ID.
+ * @param WP_Post $post Post object.
*/
- do_action( 'before_delete_post', $postid, $post );
-
- delete_post_meta( $postid, '_wp_trash_meta_status' );
- delete_post_meta( $postid, '_wp_trash_meta_time' );
-
- wp_delete_object_term_relationships( $postid, get_object_taxonomies( $post->post_type ) );
+ do_action( 'before_delete_post', $post_id, $post );
+
+ delete_post_meta( $post_id, '_wp_trash_meta_status' );
+ delete_post_meta( $post_id, '_wp_trash_meta_time' );
+
+ wp_delete_object_term_relationships( $post_id, get_object_taxonomies( $post->post_type ) );
$parent_data = array( 'post_parent' => $post->post_parent );
- $parent_where = array( 'post_parent' => $postid );
+ $parent_where = array( 'post_parent' => $post_id );
if ( is_post_type_hierarchical( $post->post_type ) ) {
// Point children of this page to its parent, also clean the cache of affected children.
- $children_query = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_parent = %d AND post_type = %s", $postid, $post->post_type );
- $children = $wpdb->get_results( $children_query );
+ $children_query = $wpdb->prepare(
+ "SELECT * FROM $wpdb->posts WHERE post_parent = %d AND post_type = %s",
+ $post_id,
+ $post->post_type
+ );
+
+ $children = $wpdb->get_results( $children_query );
+
if ( $children ) {
$wpdb->update( $wpdb->posts, $parent_data, $parent_where + array( 'post_type' => $post->post_type ) );
}
}
// Do raw query. wp_get_post_revisions() is filtered.
- $revision_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'revision'", $postid ) );
+ $revision_ids = $wpdb->get_col(
+ $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'revision'", $post_id )
+ );
+
// Use wp_delete_post (via wp_delete_post_revision) again. Ensures any meta/misplaced data gets cleaned up.
foreach ( $revision_ids as $revision_id ) {
wp_delete_post_revision( $revision_id );
@@ -3419,14 +3571,20 @@
wp_defer_comment_counting( true );
- $comment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d ORDER BY comment_ID DESC", $postid ) );
+ $comment_ids = $wpdb->get_col(
+ $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d ORDER BY comment_ID DESC", $post_id )
+ );
+
foreach ( $comment_ids as $comment_id ) {
wp_delete_comment( $comment_id, true );
}
wp_defer_comment_counting( false );
- $post_meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $postid ) );
+ $post_meta_ids = $wpdb->get_col(
+ $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d ", $post_id )
+ );
+
foreach ( $post_meta_ids as $mid ) {
delete_metadata_by_mid( 'post', $mid );
}
@@ -3434,15 +3592,28 @@
/**
* Fires immediately before a post is deleted from the database.
*
+ * The dynamic portion of the hook name, `$post->post_type`, refers to
+ * the post type slug.
+ *
+ * @since 6.6.0
+ *
+ * @param int $post_id Post ID.
+ * @param WP_Post $post Post object.
+ */
+ do_action( "delete_post_{$post->post_type}", $post_id, $post );
+
+ /**
+ * Fires immediately before a post is deleted from the database.
+ *
* @since 1.2.0
* @since 5.5.0 Added the `$post` parameter.
*
- * @param int $postid Post ID.
- * @param WP_Post $post Post object.
+ * @param int $post_id Post ID.
+ * @param WP_Post $post Post object.
*/
- do_action( 'delete_post', $postid, $post );
-
- $result = $wpdb->delete( $wpdb->posts, array( 'ID' => $postid ) );
+ do_action( 'delete_post', $post_id, $post );
+
+ $result = $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) );
if ( ! $result ) {
return false;
}
@@ -3450,13 +3621,26 @@
/**
* Fires immediately after a post is deleted from the database.
*
+ * The dynamic portion of the hook name, `$post->post_type`, refers to
+ * the post type slug.
+ *
+ * @since 6.6.0
+ *
+ * @param int $post_id Post ID.
+ * @param WP_Post $post Post object.
+ */
+ do_action( "deleted_post_{$post->post_type}", $post_id, $post );
+
+ /**
+ * Fires immediately after a post is deleted from the database.
+ *
* @since 2.2.0
* @since 5.5.0 Added the `$post` parameter.
*
- * @param int $postid Post ID.
- * @param WP_Post $post Post object.
+ * @param int $post_id Post ID.
+ * @param WP_Post $post Post object.
*/
- do_action( 'deleted_post', $postid, $post );
+ do_action( 'deleted_post', $post_id, $post );
clean_post_cache( $post );
@@ -3466,7 +3650,7 @@
}
}
- wp_clear_scheduled_hook( 'publish_future_post', array( $postid ) );
+ wp_clear_scheduled_hook( 'publish_future_post', array( $post_id ) );
/**
* Fires after a post is deleted, at the conclusion of wp_delete_post().
@@ -3476,16 +3660,16 @@
*
* @see wp_delete_post()
*
- * @param int $postid Post ID.
- * @param WP_Post $post Post object.
+ * @param int $post_id Post ID.
+ * @param WP_Post $post Post object.
*/
- do_action( 'after_delete_post', $postid, $post );
+ do_action( 'after_delete_post', $post_id, $post );
return $post;
}
/**
- * Reset the page_on_front, show_on_front, and page_for_post settings when
+ * Resets the page_on_front, show_on_front, and page_for_post settings when
* a linked page is deleted or trashed.
*
* Also ensures the post is no longer sticky.
@@ -3516,7 +3700,7 @@
}
/**
- * Move a post or page to the Trash
+ * Moves a post or page to the Trash
*
* If Trash is disabled, the post or page is permanently deleted.
*
@@ -3543,15 +3727,19 @@
return false;
}
+ $previous_status = $post->post_status;
+
/**
* Filters whether a post trashing should take place.
*
* @since 4.9.0
- *
- * @param bool|null $trash Whether to go forward with trashing.
- * @param WP_Post $post Post object.
+ * @since 6.3.0 Added the `$previous_status` parameter.
+ *
+ * @param bool|null $trash Whether to go forward with trashing.
+ * @param WP_Post $post Post object.
+ * @param string $previous_status The status of the post about to be trashed.
*/
- $check = apply_filters( 'pre_trash_post', null, $post );
+ $check = apply_filters( 'pre_trash_post', null, $post, $previous_status );
if ( null !== $check ) {
return $check;
@@ -3561,12 +3749,14 @@
* Fires before a post is sent to the Trash.
*
* @since 3.3.0
- *
- * @param int $post_id Post ID.
+ * @since 6.3.0 Added the `$previous_status` parameter.
+ *
+ * @param int $post_id Post ID.
+ * @param string $previous_status The status of the post about to be trashed.
*/
- do_action( 'wp_trash_post', $post_id );
-
- add_post_meta( $post_id, '_wp_trash_meta_status', $post->post_status );
+ do_action( 'wp_trash_post', $post_id, $previous_status );
+
+ add_post_meta( $post_id, '_wp_trash_meta_status', $previous_status );
add_post_meta( $post_id, '_wp_trash_meta_time', time() );
$post_updated = wp_update_post(
@@ -3586,10 +3776,12 @@
* Fires after a post is sent to the Trash.
*
* @since 2.9.0
- *
- * @param int $post_id Post ID.
+ * @since 6.3.0 Added the `$previous_status` parameter.
+ *
+ * @param int $post_id Post ID.
+ * @param string $previous_status The status of the post at the point where it was trashed.
*/
- do_action( 'trashed_post', $post_id );
+ do_action( 'trashed_post', $post_id, $previous_status );
return $post;
}
@@ -3623,7 +3815,7 @@
* Filters whether a post untrashing should take place.
*
* @since 4.9.0
- * @since 5.6.0 The `$previous_status` parameter was added.
+ * @since 5.6.0 Added the `$previous_status` parameter.
*
* @param bool|null $untrash Whether to go forward with untrashing.
* @param WP_Post $post Post object.
@@ -3638,7 +3830,7 @@
* Fires before a post is restored from the Trash.
*
* @since 2.9.0
- * @since 5.6.0 The `$previous_status` parameter was added.
+ * @since 5.6.0 Added the `$previous_status` parameter.
*
* @param int $post_id Post ID.
* @param string $previous_status The status of the post at the point where it was trashed.
@@ -3684,7 +3876,7 @@
* Fires after a post is restored from the Trash.
*
* @since 2.9.0
- * @since 5.6.0 The `$previous_status` parameter was added.
+ * @since 5.6.0 Added the `$previous_status` parameter.
*
* @param int $post_id Post ID.
* @param string $previous_status The status of the post at the point where it was trashed.
@@ -3756,7 +3948,7 @@
}
/**
- * Restore comments for a post from the Trash.
+ * Restores comments for a post from the Trash.
*
* @since 2.9.0
*
@@ -3798,7 +3990,7 @@
}
foreach ( $group_by_status as $status => $comments ) {
- // Sanity check. This shouldn't happen.
+ // Confidence check. This shouldn't happen.
if ( 'post-trashed' === $status ) {
$status = '0';
}
@@ -3821,7 +4013,7 @@
}
/**
- * Retrieve the list of categories for a post.
+ * Retrieves the list of categories for a post.
*
* Compatibility layer for themes and plugins. Also an easy layer of abstraction
* away from the complexity of the taxonomy layer.
@@ -3850,7 +4042,7 @@
}
/**
- * Retrieve the tags for a post.
+ * Retrieves the tags for a post.
*
* There is only one default for this function, called 'fields' and by default
* is set to 'all'. There are other defaults that can be overridden in
@@ -3898,7 +4090,7 @@
}
/**
- * Retrieve a number of recent posts.
+ * Retrieves a number of recent posts.
*
* @since 1.0.0
*
@@ -3947,11 +4139,10 @@
}
return $results ? $results : false;
-
-}
-
-/**
- * Insert or update a post.
+}
+
+/**
+ * Inserts or update a post.
*
* If the $postarr parameter has 'ID' set to a value, then post will be updated.
*
@@ -3995,10 +4186,6 @@
* Default empty.
* @type string $pinged Space or carriage return-separated list of URLs that have
* been pinged. Default empty.
- * @type string $post_modified The date when the post was last modified. Default is
- * the current time.
- * @type string $post_modified_gmt The date when the post was last modified in the GMT
- * timezone. Default is the current time.
* @type int $post_parent Set this for the post it belongs to, if any. Default 0.
* @type int $menu_order The order the post should be displayed in. Default 0.
* @type string $post_mime_type The mime type of the post. Default empty.
@@ -4017,6 +4204,7 @@
* child terms can have the same names with different parent terms,
* so the only way to connect them is using ID. Default empty.
* @type array $meta_input Array of post meta values keyed by their post meta key. Default empty.
+ * @type string $page_template Page template to use.
* }
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
* @param bool $fire_after_hooks Optional. Whether to fire the after insert hooks. Default true.
@@ -4059,7 +4247,7 @@
$postarr = sanitize_post( $postarr, 'db' );
// Are we updating or creating?
- $post_ID = 0;
+ $post_id = 0;
$update = false;
$guid = $postarr['guid'];
@@ -4067,8 +4255,8 @@
$update = true;
// Get the post ID and GUID.
- $post_ID = $postarr['ID'];
- $post_before = get_post( $post_ID );
+ $post_id = $postarr['ID'];
+ $post_before = get_post( $post_id );
if ( is_null( $post_before ) ) {
if ( $wp_error ) {
@@ -4077,8 +4265,8 @@
return 0;
}
- $guid = get_post_field( 'guid', $post_ID );
- $previous_status = get_post_field( 'post_status', $post_ID );
+ $guid = get_post_field( 'guid', $post_id );
+ $previous_status = get_post_field( 'post_status', $post_id );
} else {
$previous_status = 'new';
$post_before = null;
@@ -4136,6 +4324,8 @@
if ( ! empty( $postarr['post_category'] ) ) {
// Filter out empty terms.
$post_category = array_filter( $postarr['post_category'] );
+ } elseif ( $update && ! isset( $postarr['post_category'] ) ) {
+ $post_category = $post_before->post_category;
}
// Make sure we set a valid category.
@@ -4153,12 +4343,14 @@
*
* For new posts check the primitive capability, for updates check the meta capability.
*/
- $post_type_object = get_post_type_object( $post_type );
-
- if ( ! $update && 'pending' === $post_status && ! current_user_can( $post_type_object->cap->publish_posts ) ) {
- $post_name = '';
- } elseif ( $update && 'pending' === $post_status && ! current_user_can( 'publish_post', $post_ID ) ) {
- $post_name = '';
+ if ( 'pending' === $post_status ) {
+ $post_type_object = get_post_type_object( $post_type );
+
+ if ( ! $update && $post_type_object && ! current_user_can( $post_type_object->cap->publish_posts ) ) {
+ $post_name = '';
+ } elseif ( $update && ! current_user_can( 'publish_post', $post_id ) ) {
+ $post_name = '';
+ }
}
/*
@@ -4175,9 +4367,12 @@
// On updates, we need to check to see if it's using the old, fixed sanitization context.
$check_name = sanitize_title( $post_name, '', 'old-save' );
- if ( $update && strtolower( urlencode( $post_name ) ) == $check_name && get_post_field( 'post_name', $post_ID ) == $check_name ) {
+ if ( $update
+ && strtolower( urlencode( $post_name ) ) === $check_name
+ && get_post_field( 'post_name', $post_id ) === $check_name
+ ) {
$post_name = $check_name;
- } else { // new post, or slug has changed.
+ } else { // New post, or slug has changed.
$post_name = sanitize_title( $post_name );
}
}
@@ -4187,6 +4382,7 @@
* if none are provided, the date will be set to now.
*/
$post_date = wp_resolve_post_date( $postarr['post_date'], $postarr['post_date_gmt'] );
+
if ( ! $post_date ) {
if ( $wp_error ) {
return new WP_Error( 'invalid_date', __( 'Invalid date.' ) );
@@ -4269,7 +4465,7 @@
$new_postarr = array_merge(
array(
- 'ID' => $post_ID,
+ 'ID' => $post_id,
),
compact( array_diff( array_keys( $defaults ), array( 'context', 'filter' ) ) )
);
@@ -4280,21 +4476,21 @@
* @since 3.1.0
*
* @param int $post_parent Post parent ID.
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param array $new_postarr Array of parsed post data.
* @param array $postarr Array of sanitized, but otherwise unmodified post data.
*/
- $post_parent = apply_filters( 'wp_insert_post_parent', $post_parent, $post_ID, $new_postarr, $postarr );
+ $post_parent = apply_filters( 'wp_insert_post_parent', $post_parent, $post_id, $new_postarr, $postarr );
/*
* If the post is being untrashed and it has a desired slug stored in post meta,
* reassign it.
*/
if ( 'trash' === $previous_status && 'trash' !== $post_status ) {
- $desired_post_slug = get_post_meta( $post_ID, '_wp_desired_post_slug', true );
+ $desired_post_slug = get_post_meta( $post_id, '_wp_desired_post_slug', true );
if ( $desired_post_slug ) {
- delete_post_meta( $post_ID, '_wp_desired_post_slug' );
+ delete_post_meta( $post_id, '_wp_desired_post_slug' );
$post_name = $desired_post_slug;
}
}
@@ -4308,27 +4504,49 @@
*
* @param bool $add_trashed_suffix Whether to attempt to add the suffix.
* @param string $post_name The name of the post being updated.
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
*/
- $add_trashed_suffix = apply_filters( 'add_trashed_suffix_to_trashed_posts', true, $post_name, $post_ID );
+ $add_trashed_suffix = apply_filters( 'add_trashed_suffix_to_trashed_posts', true, $post_name, $post_id );
if ( $add_trashed_suffix ) {
- wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_ID );
+ wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_id );
}
}
// When trashing an existing post, change its slug to allow non-trashed posts to use it.
if ( 'trash' === $post_status && 'trash' !== $previous_status && 'new' !== $previous_status ) {
- $post_name = wp_add_trashed_suffix_to_post_name_for_post( $post_ID );
- }
-
- $post_name = wp_unique_post_slug( $post_name, $post_ID, $post_status, $post_type, $post_parent );
+ $post_name = wp_add_trashed_suffix_to_post_name_for_post( $post_id );
+ }
+
+ $post_name = wp_unique_post_slug( $post_name, $post_id, $post_status, $post_type, $post_parent );
// Don't unslash.
$post_mime_type = isset( $postarr['post_mime_type'] ) ? $postarr['post_mime_type'] : '';
// Expected_slashed (everything!).
- $data = compact( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_content_filtered', 'post_title', 'post_excerpt', 'post_status', 'post_type', 'comment_status', 'ping_status', 'post_password', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_parent', 'menu_order', 'post_mime_type', 'guid' );
+ $data = compact(
+ 'post_author',
+ 'post_date',
+ 'post_date_gmt',
+ 'post_content',
+ 'post_content_filtered',
+ 'post_title',
+ 'post_excerpt',
+ 'post_status',
+ 'post_type',
+ 'comment_status',
+ 'ping_status',
+ 'post_password',
+ 'post_name',
+ 'to_ping',
+ 'pinged',
+ 'post_modified',
+ 'post_modified_gmt',
+ 'post_parent',
+ 'menu_order',
+ 'post_mime_type',
+ 'guid'
+ );
$emoji_fields = array( 'post_title', 'post_content', 'post_excerpt' );
@@ -4375,7 +4593,7 @@
}
$data = wp_unslash( $data );
- $where = array( 'ID' => $post_ID );
+ $where = array( 'ID' => $post_id );
if ( $update ) {
/**
@@ -4383,10 +4601,10 @@
*
* @since 2.5.0
*
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param array $data Array of unslashed post data.
*/
- do_action( 'pre_post_update', $post_ID, $data );
+ do_action( 'pre_post_update', $post_id, $data );
if ( false === $wpdb->update( $wpdb->posts, $data, $where ) ) {
if ( $wp_error ) {
@@ -4425,25 +4643,25 @@
}
}
- $post_ID = (int) $wpdb->insert_id;
-
- // Use the newly generated $post_ID.
- $where = array( 'ID' => $post_ID );
+ $post_id = (int) $wpdb->insert_id;
+
+ // Use the newly generated $post_id.
+ $where = array( 'ID' => $post_id );
}
if ( empty( $data['post_name'] ) && ! in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ), true ) ) {
- $data['post_name'] = wp_unique_post_slug( sanitize_title( $data['post_title'], $post_ID ), $post_ID, $data['post_status'], $post_type, $post_parent );
+ $data['post_name'] = wp_unique_post_slug( sanitize_title( $data['post_title'], $post_id ), $post_id, $data['post_status'], $post_type, $post_parent );
$wpdb->update( $wpdb->posts, array( 'post_name' => $data['post_name'] ), $where );
- clean_post_cache( $post_ID );
+ clean_post_cache( $post_id );
}
if ( is_object_in_taxonomy( $post_type, 'category' ) ) {
- wp_set_post_categories( $post_ID, $post_category );
+ wp_set_post_categories( $post_id, $post_category );
}
if ( isset( $postarr['tags_input'] ) && is_object_in_taxonomy( $post_type, 'post_tag' ) ) {
- wp_set_post_tags( $post_ID, $postarr['tags_input'] );
+ wp_set_post_tags( $post_id, $postarr['tags_input'] );
}
// Add default term for all associated custom taxonomies.
@@ -4458,7 +4676,7 @@
}
// Passed custom taxonomy list overwrites the existing list if not empty.
- $terms = wp_get_object_terms( $post_ID, $taxonomy, array( 'fields' => 'ids' ) );
+ $terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'ids' ) );
if ( ! empty( $terms ) && empty( $postarr['tax_input'][ $taxonomy ] ) ) {
$postarr['tax_input'][ $taxonomy ] = $terms;
}
@@ -4490,31 +4708,31 @@
}
if ( current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
- wp_set_post_terms( $post_ID, $tags, $taxonomy );
+ wp_set_post_terms( $post_id, $tags, $taxonomy );
}
}
}
if ( ! empty( $postarr['meta_input'] ) ) {
foreach ( $postarr['meta_input'] as $field => $value ) {
- update_post_meta( $post_ID, $field, $value );
- }
- }
-
- $current_guid = get_post_field( 'guid', $post_ID );
+ update_post_meta( $post_id, $field, $value );
+ }
+ }
+
+ $current_guid = get_post_field( 'guid', $post_id );
// Set GUID.
if ( ! $update && '' === $current_guid ) {
- $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_ID ) ), $where );
+ $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_id ) ), $where );
}
if ( 'attachment' === $postarr['post_type'] ) {
if ( ! empty( $postarr['file'] ) ) {
- update_attached_file( $post_ID, $postarr['file'] );
+ update_attached_file( $post_id, $postarr['file'] );
}
if ( ! empty( $postarr['context'] ) ) {
- add_post_meta( $post_ID, '_wp_attachment_context', $postarr['context'], true );
+ add_post_meta( $post_id, '_wp_attachment_context', $postarr['context'], true );
}
}
@@ -4523,9 +4741,9 @@
$thumbnail_support = current_theme_supports( 'post-thumbnails', $post_type ) && post_type_supports( $post_type, 'thumbnail' ) || 'revision' === $post_type;
if ( ! $thumbnail_support && 'attachment' === $post_type && $post_mime_type ) {
- if ( wp_attachment_is( 'audio', $post_ID ) ) {
+ if ( wp_attachment_is( 'audio', $post_id ) ) {
$thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' );
- } elseif ( wp_attachment_is( 'video', $post_ID ) ) {
+ } elseif ( wp_attachment_is( 'video', $post_id ) ) {
$thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' );
}
}
@@ -4533,16 +4751,16 @@
if ( $thumbnail_support ) {
$thumbnail_id = (int) $postarr['_thumbnail_id'];
if ( -1 === $thumbnail_id ) {
- delete_post_thumbnail( $post_ID );
+ delete_post_thumbnail( $post_id );
} else {
- set_post_thumbnail( $post_ID, $thumbnail_id );
+ set_post_thumbnail( $post_id, $thumbnail_id );
}
}
}
- clean_post_cache( $post_ID );
-
- $post = get_post( $post_ID );
+ clean_post_cache( $post_id );
+
+ $post = get_post( $post_id );
if ( ! empty( $postarr['page_template'] ) ) {
$post->page_template = $postarr['page_template'];
@@ -4553,9 +4771,9 @@
return new WP_Error( 'invalid_page_template', __( 'Invalid page template.' ) );
}
- update_post_meta( $post_ID, '_wp_page_template', 'default' );
+ update_post_meta( $post_id, '_wp_page_template', 'default' );
} else {
- update_post_meta( $post_ID, '_wp_page_template', $postarr['page_template'] );
+ update_post_meta( $post_id, '_wp_page_template', $postarr['page_template'] );
}
}
@@ -4568,22 +4786,22 @@
*
* @since 2.0.0
*
- * @param int $post_ID Attachment ID.
+ * @param int $post_id Attachment ID.
*/
- do_action( 'edit_attachment', $post_ID );
-
- $post_after = get_post( $post_ID );
+ do_action( 'edit_attachment', $post_id );
+
+ $post_after = get_post( $post_id );
/**
* Fires once an existing attachment has been updated.
*
* @since 4.4.0
*
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param WP_Post $post_after Post object following the update.
* @param WP_Post $post_before Post object before the update.
*/
- do_action( 'attachment_updated', $post_ID, $post_after, $post_before );
+ do_action( 'attachment_updated', $post_id, $post_after, $post_before );
} else {
/**
@@ -4591,12 +4809,12 @@
*
* @since 2.0.0
*
- * @param int $post_ID Attachment ID.
+ * @param int $post_id Attachment ID.
*/
- do_action( 'add_attachment', $post_ID );
- }
-
- return $post_ID;
+ do_action( 'add_attachment', $post_id );
+ }
+
+ return $post_id;
}
if ( $update ) {
@@ -4613,33 +4831,33 @@
*
* @since 5.1.0
*
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param WP_Post $post Post object.
*/
- do_action( "edit_post_{$post->post_type}", $post_ID, $post );
+ do_action( "edit_post_{$post->post_type}", $post_id, $post );
/**
* Fires once an existing post has been updated.
*
* @since 1.2.0
*
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param WP_Post $post Post object.
*/
- do_action( 'edit_post', $post_ID, $post );
-
- $post_after = get_post( $post_ID );
+ do_action( 'edit_post', $post_id, $post );
+
+ $post_after = get_post( $post_id );
/**
* Fires once an existing post has been updated.
*
* @since 3.0.0
*
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param WP_Post $post_after Post object following the update.
* @param WP_Post $post_before Post object before the update.
*/
- do_action( 'post_updated', $post_ID, $post_after, $post_before );
+ do_action( 'post_updated', $post_id, $post_after, $post_before );
}
/**
@@ -4655,43 +4873,43 @@
*
* @since 3.7.0
*
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param WP_Post $post Post object.
* @param bool $update Whether this is an existing post being updated.
*/
- do_action( "save_post_{$post->post_type}", $post_ID, $post, $update );
+ do_action( "save_post_{$post->post_type}", $post_id, $post, $update );
/**
* Fires once a post has been saved.
*
* @since 1.5.0
*
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param WP_Post $post Post object.
* @param bool $update Whether this is an existing post being updated.
*/
- do_action( 'save_post', $post_ID, $post, $update );
+ do_action( 'save_post', $post_id, $post, $update );
/**
* Fires once a post has been saved.
*
* @since 2.0.0
*
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param WP_Post $post Post object.
* @param bool $update Whether this is an existing post being updated.
*/
- do_action( 'wp_insert_post', $post_ID, $post, $update );
+ do_action( 'wp_insert_post', $post_id, $post, $update );
if ( $fire_after_hooks ) {
wp_after_insert_post( $post, $update, $post_before );
}
- return $post_ID;
-}
-
-/**
- * Update a post with new post data.
+ return $post_id;
+}
+
+/**
+ * Updates a post with new post data.
*
* The date does not have to be set for drafts. You can set the date and it will
* not be overridden.
@@ -4776,7 +4994,7 @@
}
/**
- * Publish a post by transitioning the post status.
+ * Publishes a post by transitioning the post status.
*
* @since 2.1.0
*
@@ -4853,17 +5071,17 @@
}
/**
- * Publish future post and make sure post ID has future post status.
+ * Publishes future post and make sure post ID has future post status.
*
* Invoked by cron 'publish_future_post' event. This safeguard prevents cron
* from publishing drafts, etc.
*
* @since 2.5.0
*
- * @param int|WP_Post $post_id Post ID or post object.
- */
-function check_and_publish_future_post( $post_id ) {
- $post = get_post( $post_id );
+ * @param int|WP_Post $post Post ID or post object.
+ */
+function check_and_publish_future_post( $post ) {
+ $post = get_post( $post );
if ( ! $post ) {
return;
@@ -4877,13 +5095,13 @@
// Uh oh, someone jumped the gun!
if ( $time > time() ) {
- wp_clear_scheduled_hook( 'publish_future_post', array( $post_id ) ); // Clear anything else in the system.
- wp_schedule_single_event( $time, 'publish_future_post', array( $post_id ) );
+ wp_clear_scheduled_hook( 'publish_future_post', array( $post->ID ) ); // Clear anything else in the system.
+ wp_schedule_single_event( $time, 'publish_future_post', array( $post->ID ) );
return;
}
// wp_publish_post() returns no meaningful value.
- wp_publish_post( $post_id );
+ wp_publish_post( $post->ID );
}
/**
@@ -4896,8 +5114,8 @@
*
* @since 5.7.0
*
- * @param string $post_date The date in mysql format.
- * @param string $post_date_gmt The GMT date in mysql format.
+ * @param string $post_date The date in mysql format (`Y-m-d H:i:s`).
+ * @param string $post_date_gmt The GMT date in mysql format (`Y-m-d H:i:s`).
* @return string|false A valid Gregorian-calendar date string, or false on failure.
*/
function wp_resolve_post_date( $post_date = '', $post_date_gmt = '' ) {
@@ -4911,9 +5129,9 @@
}
// Validate the date.
- $month = substr( $post_date, 5, 2 );
- $day = substr( $post_date, 8, 2 );
- $year = substr( $post_date, 0, 4 );
+ $month = (int) substr( $post_date, 5, 2 );
+ $day = (int) substr( $post_date, 8, 2 );
+ $year = (int) substr( $post_date, 0, 4 );
$valid_date = wp_checkdate( $month, $day, $year, $post_date );
@@ -4932,13 +5150,13 @@
* @global WP_Rewrite $wp_rewrite WordPress rewrite component.
*
* @param string $slug The desired slug (post_name).
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param string $post_status No uniqueness checks are made if the post is still draft or pending.
* @param string $post_type Post type.
* @param int $post_parent Post parent ID.
* @return string Unique slug for the post, based on $post_name (with a -1, -2, etc. suffix)
*/
-function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent ) {
+function wp_unique_post_slug( $slug, $post_id, $post_status, $post_type, $post_parent ) {
if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ), true )
|| ( 'inherit' === $post_status && 'revision' === $post_type ) || 'user_request' === $post_type
) {
@@ -4955,12 +5173,12 @@
*
* @param string|null $override_slug Short-circuit return value.
* @param string $slug The desired slug (post_name).
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param string $post_status The post status.
* @param string $post_type Post type.
* @param int $post_parent Post parent ID.
*/
- $override_slug = apply_filters( 'pre_wp_unique_post_slug', null, $slug, $post_ID, $post_status, $post_type, $post_parent );
+ $override_slug = apply_filters( 'pre_wp_unique_post_slug', null, $slug, $post_id, $post_status, $post_type, $post_parent );
if ( null !== $override_slug ) {
return $override_slug;
}
@@ -4977,7 +5195,7 @@
if ( 'attachment' === $post_type ) {
// Attachment slugs must be unique across all types.
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1";
- $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) );
+ $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_id ) );
/**
* Filters whether the post slug would make a bad attachment slug.
@@ -4996,8 +5214,8 @@
$suffix = 2;
do {
$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
- $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_ID ) );
- $suffix++;
+ $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_id ) );
+ ++$suffix;
} while ( $post_name_check );
$slug = $alt_post_name;
}
@@ -5011,7 +5229,7 @@
* namespace than posts so page slugs are allowed to overlap post slugs.
*/
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1";
- $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID, $post_parent ) );
+ $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_id, $post_parent ) );
/**
* Filters whether the post slug would make a bad hierarchical post slug.
@@ -5033,17 +5251,17 @@
$suffix = 2;
do {
$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
- $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID, $post_parent ) );
- $suffix++;
+ $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_id, $post_parent ) );
+ ++$suffix;
} while ( $post_name_check );
$slug = $alt_post_name;
}
} else {
// Post slugs must be unique across all posts.
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1";
- $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) );
-
- $post = get_post( $post_ID );
+ $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_id ) );
+
+ $post = get_post( $post_id );
// Prevent new post slugs that could result in URLs that conflict with date archives.
$conflicts_with_date_archive = false;
@@ -5089,8 +5307,8 @@
$suffix = 2;
do {
$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
- $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID ) );
- $suffix++;
+ $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_id ) );
+ ++$suffix;
} while ( $post_name_check );
$slug = $alt_post_name;
}
@@ -5102,17 +5320,17 @@
* @since 3.3.0
*
* @param string $slug The post slug.
- * @param int $post_ID Post ID.
+ * @param int $post_id Post ID.
* @param string $post_status The post status.
* @param string $post_type Post type.
* @param int $post_parent Post parent ID
* @param string $original_slug The original post slug.
*/
- return apply_filters( 'wp_unique_post_slug', $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug );
-}
-
-/**
- * Truncate a post slug.
+ return apply_filters( 'wp_unique_post_slug', $slug, $post_id, $post_status, $post_type, $post_parent, $original_slug );
+}
+
+/**
+ * Truncates a post slug.
*
* @since 3.6.0
* @access private
@@ -5137,7 +5355,7 @@
}
/**
- * Add tags to a post.
+ * Adds tags to a post.
*
* @see wp_set_post_tags()
*
@@ -5153,7 +5371,7 @@
}
/**
- * Set the tags for a post.
+ * Sets the tags for a post.
*
* @since 2.3.0
*
@@ -5171,14 +5389,14 @@
}
/**
- * Set the terms for a post.
+ * Sets the terms for a post.
*
* @since 2.8.0
*
* @see wp_set_object_terms()
*
* @param int $post_id Optional. The Post ID. Does not default to the ID of the global $post.
- * @param string|array $tags Optional. An array of terms to set for the post, or a string of terms
+ * @param string|array $terms Optional. An array of terms to set for the post, or a string of terms
* separated by commas. Hierarchical taxonomies must always pass IDs rather
* than names so that children with the same names but different parents
* aren't confused. Default empty.
@@ -5187,23 +5405,23 @@
* replace the terms with the new terms. Default false.
* @return array|false|WP_Error Array of term taxonomy IDs of affected terms. WP_Error or false on failure.
*/
-function wp_set_post_terms( $post_id = 0, $tags = '', $taxonomy = 'post_tag', $append = false ) {
+function wp_set_post_terms( $post_id = 0, $terms = '', $taxonomy = 'post_tag', $append = false ) {
$post_id = (int) $post_id;
if ( ! $post_id ) {
return false;
}
- if ( empty( $tags ) ) {
- $tags = array();
- }
-
- if ( ! is_array( $tags ) ) {
+ if ( empty( $terms ) ) {
+ $terms = array();
+ }
+
+ if ( ! is_array( $terms ) ) {
$comma = _x( ',', 'tag delimiter' );
if ( ',' !== $comma ) {
- $tags = str_replace( $comma, ',', $tags );
- }
- $tags = explode( ',', trim( $tags, " \n\t\r\0\x0B," ) );
+ $terms = str_replace( $comma, ',', $terms );
+ }
+ $terms = explode( ',', trim( $terms, " \n\t\r\0\x0B," ) );
}
/*
@@ -5211,20 +5429,20 @@
* children with the same names but different parents aren't confused.
*/
if ( is_taxonomy_hierarchical( $taxonomy ) ) {
- $tags = array_unique( array_map( 'intval', $tags ) );
- }
-
- return wp_set_object_terms( $post_id, $tags, $taxonomy, $append );
-}
-
-/**
- * Set categories for a post.
+ $terms = array_unique( array_map( 'intval', $terms ) );
+ }
+
+ return wp_set_object_terms( $post_id, $terms, $taxonomy, $append );
+}
+
+/**
+ * Sets categories for a post.
*
* If no categories are provided, the default category is used.
*
* @since 2.1.0
*
- * @param int $post_ID Optional. The Post ID. Does not default to the ID
+ * @param int $post_id Optional. The Post ID. Does not default to the ID
* of the global $post. Default 0.
* @param int[]|int $post_categories Optional. List of category IDs, or the ID of a single category.
* Default empty array.
@@ -5232,10 +5450,10 @@
* If false, replace the categories with the new categories.
* @return array|false|WP_Error Array of term taxonomy IDs of affected categories. WP_Error or false on failure.
*/
-function wp_set_post_categories( $post_ID = 0, $post_categories = array(), $append = false ) {
- $post_ID = (int) $post_ID;
- $post_type = get_post_type( $post_ID );
- $post_status = get_post_status( $post_ID );
+function wp_set_post_categories( $post_id = 0, $post_categories = array(), $append = false ) {
+ $post_id = (int) $post_id;
+ $post_type = get_post_type( $post_id );
+ $post_status = get_post_status( $post_id );
// If $post_categories isn't already an array, make it one.
$post_categories = (array) $post_categories;
@@ -5266,7 +5484,7 @@
return true;
}
- return wp_set_post_terms( $post_ID, $post_categories, 'category', $append );
+ return wp_set_post_terms( $post_id, $post_categories, 'category', $append );
}
/**
@@ -5373,6 +5591,7 @@
*/
function wp_after_insert_post( $post, $update, $post_before ) {
$post = get_post( $post );
+
if ( ! $post ) {
return;
}
@@ -5398,22 +5617,22 @@
//
/**
- * Add a URL to those already pinged.
+ * Adds a URL to those already pinged.
*
* @since 1.5.0
- * @since 4.7.0 `$post_id` can be a WP_Post object.
+ * @since 4.7.0 `$post` can be a WP_Post object.
* @since 4.7.0 `$uri` can be an array of URIs.
*
* @global wpdb $wpdb WordPress database abstraction object.
*
- * @param int|WP_Post $post_id Post object or ID.
- * @param string|array $uri Ping URI or array of URIs.
+ * @param int|WP_Post $post Post ID or post object.
+ * @param string|array $uri Ping URI or array of URIs.
* @return int|false How many rows were updated.
*/
-function add_ping( $post_id, $uri ) {
+function add_ping( $post, $uri ) {
global $wpdb;
- $post = get_post( $post_id );
+ $post = get_post( $post );
if ( ! $post ) {
return false;
@@ -5444,7 +5663,7 @@
}
/**
- * Retrieve enclosures already enclosed for a post.
+ * Retrieves enclosures already enclosed for a post.
*
* @since 1.5.0
*
@@ -5480,17 +5699,17 @@
}
/**
- * Retrieve URLs already pinged for a post.
+ * Retrieves URLs already pinged for a post.
*
* @since 1.5.0
*
- * @since 4.7.0 `$post_id` can be a WP_Post object.
- *
- * @param int|WP_Post $post_id Post ID or object.
+ * @since 4.7.0 `$post` can be a WP_Post object.
+ *
+ * @param int|WP_Post $post Post ID or object.
* @return string[]|false Array of URLs already pinged for the given post, false if the post is not found.
*/
-function get_pung( $post_id ) {
- $post = get_post( $post_id );
+function get_pung( $post ) {
+ $post = get_post( $post );
if ( ! $post ) {
return false;
@@ -5510,16 +5729,16 @@
}
/**
- * Retrieve URLs that need to be pinged.
+ * Retrieves URLs that need to be pinged.
*
* @since 1.5.0
- * @since 4.7.0 `$post_id` can be a WP_Post object.
- *
- * @param int|WP_Post $post_id Post Object or ID
+ * @since 4.7.0 `$post` can be a WP_Post object.
+ *
+ * @param int|WP_Post $post Post ID or post object.
* @return string[]|false List of URLs yet to ping.
*/
-function get_to_ping( $post_id ) {
- $post = get_post( $post_id );
+function get_to_ping( $post ) {
+ $post = get_post( $post );
if ( ! $post ) {
return false;
@@ -5539,7 +5758,7 @@
}
/**
- * Do trackbacks for a list of URLs.
+ * Does trackbacks for a list of URLs.
*
* @since 1.0.0
*
@@ -5571,7 +5790,7 @@
//
/**
- * Get a list of page IDs.
+ * Gets a list of page IDs.
*
* @since 2.0.0
*
@@ -5632,7 +5851,7 @@
$hash = md5( $page_path . serialize( $post_type ) );
$cache_key = "get_page_by_path:$hash:$last_changed";
- $cached = wp_cache_get( $cache_key, 'posts' );
+ $cached = wp_cache_get( $cache_key, 'post-queries' );
if ( false !== $cached ) {
// Special case: '0' is a bad `$page_path`.
if ( '0' === $cached || 0 === $cached ) {
@@ -5681,7 +5900,7 @@
* ensuring each matches the post ancestry.
*/
while ( 0 != $p->post_parent && isset( $pages[ $p->post_parent ] ) ) {
- $count++;
+ ++$count;
$parent = $pages[ $p->post_parent ];
if ( ! isset( $revparts[ $count ] ) || $parent->post_name != $revparts[ $count ] ) {
break;
@@ -5689,7 +5908,7 @@
$p = $parent;
}
- if ( 0 == $p->post_parent && count( $revparts ) == $count + 1 && $p->post_name == $revparts[ $count ] ) {
+ if ( 0 == $p->post_parent && count( $revparts ) === $count + 1 && $p->post_name == $revparts[ $count ] ) {
$foundid = $page->ID;
if ( $page->post_type == $post_type ) {
break;
@@ -5699,7 +5918,7 @@
}
// We cache misses as well as hits.
- wp_cache_set( $cache_key, $foundid, 'posts' );
+ wp_cache_set( $cache_key, $foundid, 'post-queries' );
if ( $foundid ) {
return get_post( $foundid, $output );
@@ -5709,74 +5928,15 @@
}
/**
- * Retrieve a page given its title.
- *
- * If more than one post uses the same title, the post with the smallest ID will be returned.
- * Be careful: in case of more than one post having the same title, it will check the oldest
- * publication date, not the smallest ID.
- *
- * Because this function uses the MySQL '=' comparison, $page_title will usually be matched
- * as case-insensitive with default collation.
- *
- * @since 2.1.0
- * @since 3.0.0 The `$post_type` parameter was added.
- *
- * @global wpdb $wpdb WordPress database abstraction object.
- *
- * @param string $page_title Page title.
- * @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
- * correspond to a WP_Post object, an associative array, or a numeric array,
- * respectively. Default OBJECT.
- * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
- * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
- */
-function get_page_by_title( $page_title, $output = OBJECT, $post_type = 'page' ) {
- global $wpdb;
-
- if ( is_array( $post_type ) ) {
- $post_type = esc_sql( $post_type );
- $post_type_in_string = "'" . implode( "','", $post_type ) . "'";
- $sql = $wpdb->prepare(
- "
- SELECT ID
- FROM $wpdb->posts
- WHERE post_title = %s
- AND post_type IN ($post_type_in_string)
- ",
- $page_title
- );
- } else {
- $sql = $wpdb->prepare(
- "
- SELECT ID
- FROM $wpdb->posts
- WHERE post_title = %s
- AND post_type = %s
- ",
- $page_title,
- $post_type
- );
- }
-
- $page = $wpdb->get_var( $sql );
-
- if ( $page ) {
- return get_post( $page, $output );
- }
-
- return null;
-}
-
-/**
- * Identify descendants of a given page ID in a list of page objects.
+ * Identifies descendants of a given page ID in a list of page objects.
*
* Descendants are identified from the `$pages` array passed to the function. No database queries are performed.
*
* @since 1.5.1
*
- * @param int $page_id Page ID.
- * @param array $pages List of page objects from which descendants should be identified.
- * @return array List of page children.
+ * @param int $page_id Page ID.
+ * @param WP_Post[] $pages List of page objects from which descendants should be identified.
+ * @return WP_Post[] List of page children.
*/
function get_page_children( $page_id, $pages ) {
// Build a hash of ID -> children.
@@ -5808,7 +5968,7 @@
}
/**
- * Order the pages with children under parents in a flat list.
+ * Orders the pages with children under parents in a flat list.
*
* It uses auxiliary structure to hold parent-children relationships and
* runs in O(N) complexity
@@ -5837,7 +5997,7 @@
}
/**
- * Traverse and return all the nested children post names of a root page.
+ * Traverses and return all the nested children post names of a root page.
*
* $children contains parent-children relations
*
@@ -5860,7 +6020,7 @@
}
/**
- * Build the URI path for a page.
+ * Builds the URI path for a page.
*
* Sub pages will be in the "directory" under the parent page post name.
*
@@ -5900,11 +6060,10 @@
}
/**
- * Retrieve an array of pages (or hierarchical post type items).
- *
- * @global wpdb $wpdb WordPress database abstraction object.
+ * Retrieves an array of pages (or hierarchical post type items).
*
* @since 1.5.0
+ * @since 6.3.0 Use WP_Query internally.
*
* @param array|string $args {
* Optional. Array or string of arguments to retrieve pages.
@@ -5939,13 +6098,11 @@
* @type string|array $post_status A comma-separated list or array of post statuses to include.
* Default 'publish'.
* }
- * @return WP_Post[]|int[]|false Array of pages (or hierarchical post type items). Boolean false if the
- * specified post type is not hierarchical or the specified status is not
- * supported by the post type.
+ * @return WP_Post[]|false Array of pages (or hierarchical post type items). Boolean false if the
+ * specified post type is not hierarchical or the specified status is not
+ * supported by the post type.
*/
function get_pages( $args = array() ) {
- global $wpdb;
-
$defaults = array(
'child_of' => 0,
'sort_order' => 'ASC',
@@ -5994,50 +6151,35 @@
return false;
}
- // $args can be whatever, only use the args defined in defaults to compute the key.
- $key = md5( serialize( wp_array_slice_assoc( $parsed_args, array_keys( $defaults ) ) ) );
- $last_changed = wp_cache_get_last_changed( 'posts' );
-
- $cache_key = "get_pages:$key:$last_changed";
- $cache = wp_cache_get( $cache_key, 'posts' );
- if ( false !== $cache ) {
- _prime_post_caches( $cache, false, false );
-
- // Convert to WP_Post instances.
- $pages = array_map( 'get_post', $cache );
- /** This filter is documented in wp-includes/post.php */
- $pages = apply_filters( 'get_pages', $pages, $parsed_args );
-
- return $pages;
- }
-
- $inclusions = '';
+ $query_args = array(
+ 'orderby' => 'post_title',
+ 'order' => 'ASC',
+ 'post__not_in' => wp_parse_id_list( $exclude ),
+ 'meta_key' => $meta_key,
+ 'meta_value' => $meta_value,
+ 'posts_per_page' => -1,
+ 'offset' => $offset,
+ 'post_type' => $parsed_args['post_type'],
+ 'post_status' => $post_status,
+ 'update_post_term_cache' => false,
+ 'update_post_meta_cache' => false,
+ 'ignore_sticky_posts' => true,
+ 'no_found_rows' => true,
+ );
+
if ( ! empty( $parsed_args['include'] ) ) {
- $child_of = 0; // Ignore child_of, parent, exclude, meta_key, and meta_value params if using include.
- $parent = -1;
- $exclude = '';
- $meta_key = '';
- $meta_value = '';
- $hierarchical = false;
- $incpages = wp_parse_id_list( $parsed_args['include'] );
- if ( ! empty( $incpages ) ) {
- $inclusions = ' AND ID IN (' . implode( ',', $incpages ) . ')';
- }
- }
-
- $exclusions = '';
- if ( ! empty( $exclude ) ) {
- $expages = wp_parse_id_list( $exclude );
- if ( ! empty( $expages ) ) {
- $exclusions = ' AND ID NOT IN (' . implode( ',', $expages ) . ')';
- }
- }
-
- $author_query = '';
+ $child_of = 0; // Ignore child_of, parent, exclude, meta_key, and meta_value params if using include.
+ $parent = -1;
+ unset( $query_args['post__not_in'], $query_args['meta_key'], $query_args['meta_value'] );
+ $hierarchical = false;
+ $query_args['post__in'] = wp_parse_id_list( $parsed_args['include'] );
+ }
+
if ( ! empty( $parsed_args['authors'] ) ) {
$post_authors = wp_parse_list( $parsed_args['authors'] );
if ( ! empty( $post_authors ) ) {
+ $query_args['author__in'] = array();
foreach ( $post_authors as $post_author ) {
// Do we have an author id or an author login?
if ( 0 == (int) $post_author ) {
@@ -6050,136 +6192,61 @@
}
$post_author = $post_author->ID;
}
-
- if ( '' === $author_query ) {
- $author_query = $wpdb->prepare( ' post_author = %d ', $post_author );
- } else {
- $author_query .= $wpdb->prepare( ' OR post_author = %d ', $post_author );
- }
- }
- if ( '' !== $author_query ) {
- $author_query = " AND ($author_query)";
+ $query_args['author__in'][] = (int) $post_author;
}
}
}
- $join = '';
- $where = "$exclusions $inclusions ";
- if ( '' !== $meta_key || '' !== $meta_value ) {
- $join = " LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )";
-
- // meta_key and meta_value might be slashed.
- $meta_key = wp_unslash( $meta_key );
- $meta_value = wp_unslash( $meta_value );
- if ( '' !== $meta_key ) {
- $where .= $wpdb->prepare( " AND $wpdb->postmeta.meta_key = %s", $meta_key );
- }
- if ( '' !== $meta_value ) {
- $where .= $wpdb->prepare( " AND $wpdb->postmeta.meta_value = %s", $meta_value );
- }
- }
-
if ( is_array( $parent ) ) {
- $post_parent__in = implode( ',', array_map( 'absint', (array) $parent ) );
+ $post_parent__in = array_map( 'absint', (array) $parent );
if ( ! empty( $post_parent__in ) ) {
- $where .= " AND post_parent IN ($post_parent__in)";
+ $query_args['post_parent__in'] = $post_parent__in;
}
} elseif ( $parent >= 0 ) {
- $where .= $wpdb->prepare( ' AND post_parent = %d ', $parent );
- }
-
- if ( 1 === count( $post_status ) ) {
- $where_post_type = $wpdb->prepare( 'post_type = %s AND post_status = %s', $parsed_args['post_type'], reset( $post_status ) );
- } else {
- $post_status = implode( "', '", $post_status );
- $where_post_type = $wpdb->prepare( "post_type = %s AND post_status IN ('$post_status')", $parsed_args['post_type'] );
- }
-
- $orderby_array = array();
- $allowed_keys = array(
- 'author',
- 'post_author',
- 'date',
- 'post_date',
- 'title',
- 'post_title',
- 'name',
- 'post_name',
- 'modified',
- 'post_modified',
- 'modified_gmt',
- 'post_modified_gmt',
- 'menu_order',
- 'parent',
- 'post_parent',
- 'ID',
- 'rand',
- 'comment_count',
+ $query_args['post_parent'] = $parent;
+ }
+
+ /*
+ * Maintain backward compatibility for `sort_column` key.
+ * Additionally to `WP_Query`, it has been supporting the `post_modified_gmt` field, so this logic will translate
+ * it to `post_modified` which should result in the same order given the two dates in the fields match.
+ */
+ $orderby = wp_parse_list( $parsed_args['sort_column'] );
+ $orderby = array_map(
+ static function ( $orderby_field ) {
+ $orderby_field = trim( $orderby_field );
+ if ( 'post_modified_gmt' === $orderby_field || 'modified_gmt' === $orderby_field ) {
+ $orderby_field = str_replace( '_gmt', '', $orderby_field );
+ }
+ return $orderby_field;
+ },
+ $orderby
);
-
- foreach ( explode( ',', $parsed_args['sort_column'] ) as $orderby ) {
- $orderby = trim( $orderby );
- if ( ! in_array( $orderby, $allowed_keys, true ) ) {
- continue;
- }
-
- switch ( $orderby ) {
- case 'menu_order':
- break;
- case 'ID':
- $orderby = "$wpdb->posts.ID";
- break;
- case 'rand':
- $orderby = 'RAND()';
- break;
- case 'comment_count':
- $orderby = "$wpdb->posts.comment_count";
- break;
- default:
- if ( 0 === strpos( $orderby, 'post_' ) ) {
- $orderby = "$wpdb->posts." . $orderby;
- } else {
- $orderby = "$wpdb->posts.post_" . $orderby;
- }
- }
-
- $orderby_array[] = $orderby;
-
- }
- $sort_column = ! empty( $orderby_array ) ? implode( ',', $orderby_array ) : "$wpdb->posts.post_title";
-
- $sort_order = strtoupper( $parsed_args['sort_order'] );
- if ( '' !== $sort_order && ! in_array( $sort_order, array( 'ASC', 'DESC' ), true ) ) {
- $sort_order = 'ASC';
- }
-
- $query = "SELECT * FROM $wpdb->posts $join WHERE ($where_post_type) $where ";
- $query .= $author_query;
- $query .= ' ORDER BY ' . $sort_column . ' ' . $sort_order;
+ if ( $orderby ) {
+ $query_args['orderby'] = array_fill_keys( $orderby, $parsed_args['sort_order'] );
+ }
+
+ $order = $parsed_args['sort_order'];
+ if ( $order ) {
+ $query_args['order'] = $order;
+ }
if ( ! empty( $number ) ) {
- $query .= ' LIMIT ' . $offset . ',' . $number;
- }
-
- $pages = $wpdb->get_results( $query );
-
- if ( empty( $pages ) ) {
- wp_cache_set( $cache_key, array(), 'posts' );
-
- /** This filter is documented in wp-includes/post.php */
- $pages = apply_filters( 'get_pages', array(), $parsed_args );
-
- return $pages;
- }
-
- // Sanitize before caching so it'll only get done once.
- $num_pages = count( $pages );
- for ( $i = 0; $i < $num_pages; $i++ ) {
- $pages[ $i ] = sanitize_post( $pages[ $i ], 'raw' );
- }
-
- // Update cache.
- update_post_cache( $pages );
+ $query_args['posts_per_page'] = $number;
+ }
+
+ /**
+ * Filters query arguments passed to WP_Query in get_pages.
+ *
+ * @since 6.3.0
+ *
+ * @param array $query_args Array of arguments passed to WP_Query.
+ * @param array $parsed_args Array of get_pages() arguments.
+ */
+ $query_args = apply_filters( 'get_pages_query_args', $query_args, $parsed_args );
+
+ $pages = new WP_Query();
+ $pages = $pages->query( $query_args );
if ( $child_of || $hierarchical ) {
$pages = get_page_children( $child_of, $pages );
@@ -6202,16 +6269,6 @@
}
}
- $page_structure = array();
- foreach ( $pages as $page ) {
- $page_structure[] = $page->ID;
- }
-
- wp_cache_set( $cache_key, $page_structure, 'posts' );
-
- // Convert to WP_Post instances.
- $pages = array_map( 'get_post', $pages );
-
/**
* Filters the retrieved list of pages.
*
@@ -6240,10 +6297,10 @@
* @return bool True on success, false on failure.
*/
function is_local_attachment( $url ) {
- if ( strpos( $url, home_url() ) === false ) {
+ if ( ! str_contains( $url, home_url() ) ) {
return false;
}
- if ( strpos( $url, home_url( '/?attachment_id=' ) ) !== false ) {
+ if ( str_contains( $url, home_url( '/?attachment_id=' ) ) ) {
return true;
}
@@ -6258,7 +6315,7 @@
}
/**
- * Insert an attachment.
+ * Inserts an attachment.
*
* If you set the 'ID' in the $args parameter, it will mean that you are
* updating and attempt to update the attachment. You can also set the
@@ -6278,13 +6335,13 @@
* @see wp_insert_post()
*
* @param string|array $args Arguments for inserting an attachment.
- * @param string|false $file Optional. Filename.
- * @param int $parent Optional. Parent post ID.
+ * @param string|false $file Optional. Filename. Default false.
+ * @param int $parent_post_id Optional. Parent post ID or 0 for no parent. Default 0.
* @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
* @param bool $fire_after_hooks Optional. Whether to fire the after insert hooks. Default true.
* @return int|WP_Error The attachment ID on success. The value 0 or WP_Error on failure.
*/
-function wp_insert_attachment( $args, $file = false, $parent = 0, $wp_error = false, $fire_after_hooks = true ) {
+function wp_insert_attachment( $args, $file = false, $parent_post_id = 0, $wp_error = false, $fire_after_hooks = true ) {
$defaults = array(
'file' => $file,
'post_parent' => 0,
@@ -6292,8 +6349,8 @@
$data = wp_parse_args( $args, $defaults );
- if ( ! empty( $parent ) ) {
- $data['post_parent'] = $parent;
+ if ( ! empty( $parent_post_id ) ) {
+ $data['post_parent'] = $parent_post_id;
}
$data['post_type'] = 'attachment';
@@ -6302,7 +6359,7 @@
}
/**
- * Trash or delete an attachment.
+ * Trashes or deletes an attachment.
*
* When an attachment is permanently deleted, the file will also be removed.
* Deletion removes all post meta fields, taxonomy, comments, etc. associated
@@ -6344,7 +6401,7 @@
*
* @since 5.5.0
*
- * @param WP_Post|false|null $delete Whether to go forward with deletion. @TODO description
+ * @param WP_Post|false|null $delete Whether to go forward with deletion.
* @param WP_Post $post Post object.
* @param bool $force_delete Whether to bypass the Trash.
*/
@@ -6506,6 +6563,7 @@
* Retrieves attachment metadata for attachment ID.
*
* @since 2.1.0
+ * @since 6.0.0 The `$filesize` value was added to the returned array.
*
* @param int $attachment_id Attachment post ID. Defaults to global $post.
* @param bool $unfiltered Optional. If true, filters are not run. Default false.
@@ -6590,7 +6648,7 @@
}
/**
- * Retrieve the URL for an attachment.
+ * Retrieves the URL for an attachment.
*
* @since 2.1.0
*
@@ -6622,10 +6680,10 @@
$uploads = wp_get_upload_dir();
if ( $uploads && false === $uploads['error'] ) {
// Check that the upload base exists in the file location.
- if ( 0 === strpos( $file, $uploads['basedir'] ) ) {
+ if ( str_starts_with( $file, $uploads['basedir'] ) ) {
// Replace file location with url location.
$url = str_replace( $uploads['basedir'], $uploads['baseurl'], $file );
- } elseif ( false !== strpos( $file, 'wp-content/uploads' ) ) {
+ } elseif ( str_contains( $file, 'wp-content/uploads' ) ) {
// Get the directory name relative to the basedir (back compat for pre-2.7 uploads).
$url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $file ) ) . wp_basename( $file );
} else {
@@ -6699,87 +6757,36 @@
}
/**
- * Retrieve thumbnail for an attachment.
+ * Retrieves URL for an attachment thumbnail.
*
* @since 2.1.0
- *
- * @param int $post_id Optional. Attachment ID. Default is the ID of the global `$post`.
- * @return string|false Thumbnail file path on success, false on failure.
- */
-function wp_get_attachment_thumb_file( $post_id = 0 ) {
- $post_id = (int) $post_id;
- $post = get_post( $post_id );
-
- if ( ! $post ) {
- return false;
- }
-
- $imagedata = wp_get_attachment_metadata( $post->ID );
- if ( ! is_array( $imagedata ) ) {
- return false;
- }
-
- $file = get_attached_file( $post->ID );
-
- if ( ! empty( $imagedata['thumb'] ) ) {
- $thumbfile = str_replace( wp_basename( $file ), $imagedata['thumb'], $file );
- if ( file_exists( $thumbfile ) ) {
- /**
- * Filters the attachment thumbnail file path.
- *
- * @since 2.1.0
- *
- * @param string $thumbfile File path to the attachment thumbnail.
- * @param int $post_id Attachment ID.
- */
- return apply_filters( 'wp_get_attachment_thumb_file', $thumbfile, $post->ID );
- }
- }
- return false;
-}
-
-/**
- * Retrieve URL for an attachment thumbnail.
- *
- * @since 2.1.0
+ * @since 6.1.0 Changed to use wp_get_attachment_image_url().
*
* @param int $post_id Optional. Attachment ID. Default is the ID of the global `$post`.
* @return string|false Thumbnail URL on success, false on failure.
*/
function wp_get_attachment_thumb_url( $post_id = 0 ) {
$post_id = (int) $post_id;
- $post = get_post( $post_id );
-
- if ( ! $post ) {
- return false;
- }
-
- $url = wp_get_attachment_url( $post->ID );
- if ( ! $url ) {
+
+ /*
+ * This uses image_downsize() which also looks for the (very) old format $image_meta['thumb']
+ * when the newer format $image_meta['sizes']['thumbnail'] doesn't exist.
+ */
+ $thumbnail_url = wp_get_attachment_image_url( $post_id, 'thumbnail' );
+
+ if ( empty( $thumbnail_url ) ) {
return false;
}
- $sized = image_downsize( $post_id, 'thumbnail' );
- if ( $sized ) {
- return $sized[0];
- }
-
- $thumb = wp_get_attachment_thumb_file( $post->ID );
- if ( ! $thumb ) {
- return false;
- }
-
- $url = str_replace( wp_basename( $url ), wp_basename( $thumb ), $url );
-
/**
* Filters the attachment thumbnail URL.
*
* @since 2.1.0
*
- * @param string $url URL for the attachment thumbnail.
- * @param int $post_id Attachment ID.
+ * @param string $thumbnail_url URL for the attachment thumbnail.
+ * @param int $post_id Attachment ID.
*/
- return apply_filters( 'wp_get_attachment_thumb_url', $url, $post->ID );
+ return apply_filters( 'wp_get_attachment_thumb_url', $thumbnail_url, $post_id );
}
/**
@@ -6787,9 +6794,9 @@
*
* @since 4.2.0
*
- * @param string $type Attachment type. Accepts 'image', 'audio', or 'video'.
+ * @param string $type Attachment type. Accepts `image`, `audio`, `video`, or a file extension.
* @param int|WP_Post $post Optional. Attachment ID or object. Default is global $post.
- * @return bool True if one of the accepted types, false otherwise.
+ * @return bool True if an accepted type or a matching file extension, false otherwise.
*/
function wp_attachment_is( $type, $post = null ) {
$post = get_post( $post );
@@ -6804,7 +6811,7 @@
return false;
}
- if ( 0 === strpos( $post->post_mime_type, $type . '/' ) ) {
+ if ( str_starts_with( $post->post_mime_type, $type . '/' ) ) {
return true;
}
@@ -6822,7 +6829,7 @@
switch ( $type ) {
case 'image':
- $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp' );
+ $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp', 'avif' );
return in_array( $ext, $image_exts, true );
case 'audio':
@@ -6855,18 +6862,25 @@
}
/**
- * Retrieve the icon for a MIME type or attachment.
+ * Retrieves the icon for a MIME type or attachment.
*
* @since 2.1.0
- *
- * @param string|int $mime MIME type or attachment ID.
+ * @since 6.5.0 Added the `$preferred_ext` parameter.
+ *
+ * @param string|int $mime MIME type or attachment ID.
+ * @param string $preferred_ext File format to prefer in return. Default '.png'.
* @return string|false Icon, false otherwise.
*/
-function wp_mime_type_icon( $mime = 0 ) {
+function wp_mime_type_icon( $mime = 0, $preferred_ext = '.png' ) {
if ( ! is_numeric( $mime ) ) {
$icon = wp_cache_get( "mime_type_icon_$mime" );
}
+ // Check if preferred file format variable is present and is a validly formatted file extension.
+ if ( ! empty( $preferred_ext ) && is_string( $preferred_ext ) && ! str_starts_with( $preferred_ext, '.' ) ) {
+ $preferred_ext = '.' . strtolower( $preferred_ext );
+ }
+
$post_id = 0;
if ( empty( $icon ) ) {
$post_mimes = array();
@@ -6922,6 +6936,7 @@
*/
$dirs = apply_filters( 'icon_dirs', array( $icon_dir => $icon_dir_uri ) );
$icon_files = array();
+ $all_icons = array();
while ( $dirs ) {
$keys = array_keys( $dirs );
$dir = array_shift( $keys );
@@ -6930,22 +6945,29 @@
if ( $dh ) {
while ( false !== $file = readdir( $dh ) ) {
$file = wp_basename( $file );
- if ( '.' === substr( $file, 0, 1 ) ) {
+ if ( str_starts_with( $file, '.' ) ) {
continue;
}
$ext = strtolower( substr( $file, -4 ) );
- if ( ! in_array( $ext, array( '.png', '.gif', '.jpg' ), true ) ) {
+ if ( ! in_array( $ext, array( '.svg', '.png', '.gif', '.jpg' ), true ) ) {
if ( is_dir( "$dir/$file" ) ) {
$dirs[ "$dir/$file" ] = "$uri/$file";
}
continue;
}
- $icon_files[ "$dir/$file" ] = "$uri/$file";
+ $all_icons[ "$dir/$file" ] = "$uri/$file";
+ if ( $ext === $preferred_ext ) {
+ $icon_files[ "$dir/$file" ] = "$uri/$file";
+ }
}
closedir( $dh );
}
}
+ // If directory only contained icons of a non-preferred format, return those.
+ if ( empty( $icon_files ) ) {
+ $icon_files = $all_icons;
+ }
wp_cache_add( 'icon_files', $icon_files, 'default', 600 );
}
@@ -6993,7 +7015,7 @@
}
/**
- * Check for changed slugs for published post objects and save the old slug.
+ * Checks for changed slugs for published post objects and save the old slug.
*
* The function is used when a post object of any type is updated,
* by comparing the current and previous post objects.
@@ -7008,8 +7030,8 @@
* @since 2.1.0
*
* @param int $post_id Post ID.
- * @param WP_Post $post The Post Object
- * @param WP_Post $post_before The Previous Post Object
+ * @param WP_Post $post The post object.
+ * @param WP_Post $post_before The previous post object.
*/
function wp_check_for_changed_slugs( $post_id, $post, $post_before ) {
// Don't bother if it hasn't changed.
@@ -7036,7 +7058,7 @@
}
/**
- * Check for changed dates for published post objects and save the old date.
+ * Checks for changed dates for published post objects and save the old date.
*
* The function is used when a post object of any type is updated,
* by comparing the current and previous post objects.
@@ -7051,8 +7073,8 @@
* @since 4.9.3
*
* @param int $post_id Post ID.
- * @param WP_Post $post The Post Object
- * @param WP_Post $post_before The Previous Post Object
+ * @param WP_Post $post The post object.
+ * @param WP_Post $post_before The previous post object.
*/
function wp_check_for_changed_dates( $post_id, $post, $post_before ) {
$previous_date = gmdate( 'Y-m-d', strtotime( $post_before->post_date ) );
@@ -7082,7 +7104,7 @@
}
/**
- * Retrieve the private post SQL based on capability.
+ * Retrieves the private post SQL based on capability.
*
* This function provides a standardized way to appropriately select on the
* post_status of a post type. The function will return a piece of SQL code
@@ -7100,7 +7122,7 @@
}
/**
- * Retrieve the post SQL based on capability, author, and type.
+ * Retrieves the post SQL based on capability, author, and type.
*
* @since 3.0.0
* @since 4.3.0 Introduced the ability to pass an array of post types to `$post_type`.
@@ -7128,6 +7150,7 @@
$post_type_clauses = array();
foreach ( $post_types as $post_type ) {
$post_type_obj = get_post_type_object( $post_type );
+
if ( ! $post_type_obj ) {
continue;
}
@@ -7142,12 +7165,14 @@
* @param string $cap Capability.
*/
$cap = apply_filters_deprecated( 'pub_priv_sql_capability', array( '' ), '3.2.0' );
+
if ( ! $cap ) {
$cap = current_user_can( $post_type_obj->cap->read_private_posts );
}
// Only need to check the cap if $public_only is false.
$post_status_sql = "post_status = 'publish'";
+
if ( false === $public_only ) {
if ( $cap ) {
// Does the user have the capability to view private posts? Guess so.
@@ -7220,7 +7245,7 @@
}
/**
- * Get the most recent time that a post on the site was modified.
+ * Gets the most recent time that a post on the site was modified.
*
* The server timezone is the default and is the difference between GMT and
* server time. The 'blog' value is just when the last post was modified.
@@ -7391,6 +7416,7 @@
}
wp_cache_delete( $post->ID, 'posts' );
+ wp_cache_delete( 'post_parent:' . (string) $post->ID, 'posts' );
wp_cache_delete( $post->ID, 'post_meta' );
clean_object_term_cache( $post->ID, $post->post_type );
@@ -7420,15 +7446,15 @@
do_action( 'clean_page_cache', $post->ID );
}
- wp_cache_set( 'last_changed', microtime(), 'posts' );
-}
-
-/**
- * Call major cache updating functions for list of Post objects.
+ wp_cache_set_posts_last_changed();
+}
+
+/**
+ * Updates post, term, and metadata caches for a list of post objects.
*
* @since 1.5.0
*
- * @param WP_Post[] $posts Array of Post objects
+ * @param WP_Post[] $posts Array of post objects (passed by reference).
* @param string $post_type Optional. Post type. Default 'post'.
* @param bool $update_term_cache Optional. Whether to update the term cache. Default true.
* @param bool $update_meta_cache Optional. Whether to update the meta cache. Default true.
@@ -7475,7 +7501,48 @@
}
/**
- * Updates metadata cache for list of post IDs.
+ * Updates post author user caches for a list of post objects.
+ *
+ * @since 6.1.0
+ *
+ * @param WP_Post[] $posts Array of post objects.
+ */
+function update_post_author_caches( $posts ) {
+ /*
+ * cache_users() is a pluggable function so is not available prior
+ * to the `plugins_loaded` hook firing. This is to ensure against
+ * fatal errors when the function is not available.
+ */
+ if ( ! function_exists( 'cache_users' ) ) {
+ return;
+ }
+
+ $author_ids = wp_list_pluck( $posts, 'post_author' );
+ $author_ids = array_map( 'absint', $author_ids );
+ $author_ids = array_unique( array_filter( $author_ids ) );
+
+ cache_users( $author_ids );
+}
+
+/**
+ * Updates parent post caches for a list of post objects.
+ *
+ * @since 6.1.0
+ *
+ * @param WP_Post[] $posts Array of post objects.
+ */
+function update_post_parent_caches( $posts ) {
+ $parent_ids = wp_list_pluck( $posts, 'post_parent' );
+ $parent_ids = array_map( 'absint', $parent_ids );
+ $parent_ids = array_unique( array_filter( $parent_ids ) );
+
+ if ( ! empty( $parent_ids ) ) {
+ _prime_post_caches( $parent_ids, false );
+ }
+}
+
+/**
+ * Updates metadata cache for a list of post IDs.
*
* Performs SQL query to retrieve the metadata for the post IDs and updates the
* metadata cache for the posts. Therefore, the functions, which call this
@@ -7657,14 +7724,16 @@
*/
function wp_get_post_parent_id( $post = null ) {
$post = get_post( $post );
+
if ( ! $post || is_wp_error( $post ) ) {
return false;
}
+
return (int) $post->post_parent;
}
/**
- * Check the given subset of the post hierarchy for hierarchy loops.
+ * Checks the given subset of the post hierarchy for hierarchy loops.
*
* Prevents loops from forming and breaks those that it finds. Attached
* to the {@see 'wp_insert_post_parent'} filter.
@@ -7674,37 +7743,37 @@
* @see wp_find_hierarchy_loop()
*
* @param int $post_parent ID of the parent for the post we're checking.
- * @param int $post_ID ID of the post we're checking.
+ * @param int $post_id ID of the post we're checking.
* @return int The new post_parent for the post, 0 otherwise.
*/
-function wp_check_post_hierarchy_for_loops( $post_parent, $post_ID ) {
+function wp_check_post_hierarchy_for_loops( $post_parent, $post_id ) {
// Nothing fancy here - bail.
if ( ! $post_parent ) {
return 0;
}
// New post can't cause a loop.
- if ( ! $post_ID ) {
+ if ( ! $post_id ) {
return $post_parent;
}
// Can't be its own parent.
- if ( $post_parent == $post_ID ) {
+ if ( $post_parent == $post_id ) {
return 0;
}
// Now look for larger loops.
- $loop = wp_find_hierarchy_loop( 'wp_get_post_parent_id', $post_ID, $post_parent );
+ $loop = wp_find_hierarchy_loop( 'wp_get_post_parent_id', $post_id, $post_parent );
if ( ! $loop ) {
return $post_parent; // No loop.
}
// Setting $post_parent to the given value causes a loop.
- if ( isset( $loop[ $post_ID ] ) ) {
+ if ( isset( $loop[ $post_id ] ) ) {
return 0;
}
- // There's a loop, but it doesn't contain $post_ID. Break the loop.
+ // There's a loop, but it doesn't contain $post_id. Break the loop.
foreach ( array_keys( $loop ) as $loop_member ) {
wp_update_post(
array(
@@ -7756,7 +7825,7 @@
}
/**
- * Delete auto-drafts for new posts that are > 7 days old.
+ * Deletes auto-drafts for new posts that are > 7 days old.
*
* @since 3.4.0
*
@@ -7778,11 +7847,11 @@
*
* @since 4.5.0
*
- * @param array $posts Array of WP_Post objects.
+ * @param WP_Post[] $posts Array of WP_Post objects.
*/
function wp_queue_posts_for_term_meta_lazyload( $posts ) {
$post_type_taxonomies = array();
- $term_ids = array();
+ $prime_post_terms = array();
foreach ( $posts as $post ) {
if ( ! ( $post instanceof WP_Post ) ) {
continue;
@@ -7793,26 +7862,36 @@
}
foreach ( $post_type_taxonomies[ $post->post_type ] as $taxonomy ) {
- // Term cache should already be primed by `update_post_term_cache()`.
- $terms = get_object_term_cache( $post->ID, $taxonomy );
- if ( false !== $terms ) {
- foreach ( $terms as $term ) {
- if ( ! in_array( $term->term_id, $term_ids, true ) ) {
- $term_ids[] = $term->term_id;
+ $prime_post_terms[ $taxonomy ][] = $post->ID;
+ }
+ }
+
+ $term_ids = array();
+ if ( $prime_post_terms ) {
+ foreach ( $prime_post_terms as $taxonomy => $post_ids ) {
+ $cached_term_ids = wp_cache_get_multiple( $post_ids, "{$taxonomy}_relationships" );
+ if ( is_array( $cached_term_ids ) ) {
+ $cached_term_ids = array_filter( $cached_term_ids );
+ foreach ( $cached_term_ids as $_term_ids ) {
+ // Backward compatibility for if a plugin is putting objects into the cache, rather than IDs.
+ foreach ( $_term_ids as $term_id ) {
+ if ( is_numeric( $term_id ) ) {
+ $term_ids[] = (int) $term_id;
+ } elseif ( isset( $term_id->term_id ) ) {
+ $term_ids[] = (int) $term_id->term_id;
+ }
}
}
}
}
- }
-
- if ( $term_ids ) {
- $lazyloader = wp_metadata_lazyloader();
- $lazyloader->queue_objects( 'term', $term_ids );
- }
-}
-
-/**
- * Update the custom taxonomies' term counts when a post's status is changed.
+ $term_ids = array_unique( $term_ids );
+ }
+
+ wp_lazyload_term_meta( $term_ids );
+}
+
+/**
+ * Updates the custom taxonomies' term counts when a post's status is changed.
*
* For example, default posts term counts (for custom taxonomies) don't include
* private / draft posts.
@@ -7836,13 +7915,15 @@
* Adds any posts from the given IDs to the cache that do not already exist in cache.
*
* @since 3.4.0
- * @access private
- *
- * @see update_post_caches()
+ * @since 6.1.0 This function is no longer marked as "private".
+ *
+ * @see update_post_cache()
+ * @see update_postmeta_cache()
+ * @see update_object_term_cache()
*
* @global wpdb $wpdb WordPress database abstraction object.
*
- * @param array $ids ID list.
+ * @param int[] $ids ID list.
* @param bool $update_term_cache Optional. Whether to update the term cache. Default true.
* @param bool $update_meta_cache Optional. Whether to update the meta cache. Default true.
*/
@@ -7853,7 +7934,67 @@
if ( ! empty( $non_cached_ids ) ) {
$fresh_posts = $wpdb->get_results( sprintf( "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE ID IN (%s)", implode( ',', $non_cached_ids ) ) );
- update_post_caches( $fresh_posts, 'any', $update_term_cache, $update_meta_cache );
+ if ( $fresh_posts ) {
+ // Despite the name, update_post_cache() expects an array rather than a single post.
+ update_post_cache( $fresh_posts );
+ }
+ }
+
+ if ( $update_meta_cache ) {
+ update_postmeta_cache( $ids );
+ }
+
+ if ( $update_term_cache ) {
+ $post_types = array_map( 'get_post_type', $ids );
+ $post_types = array_unique( $post_types );
+ update_object_term_cache( $ids, $post_types );
+ }
+}
+
+/**
+ * Prime the cache containing the parent ID of various post objects.
+ *
+ * @since 6.4.0
+ *
+ * @global wpdb $wpdb WordPress database abstraction object.
+ *
+ * @param int[] $ids ID list.
+ */
+function _prime_post_parent_id_caches( array $ids ) {
+ global $wpdb;
+
+ $ids = array_filter( $ids, '_validate_cache_id' );
+ $ids = array_unique( array_map( 'intval', $ids ), SORT_NUMERIC );
+
+ if ( empty( $ids ) ) {
+ return;
+ }
+
+ $cache_keys = array();
+ foreach ( $ids as $id ) {
+ $cache_keys[ $id ] = 'post_parent:' . (string) $id;
+ }
+
+ $cached_data = wp_cache_get_multiple( array_values( $cache_keys ), 'posts' );
+
+ $non_cached_ids = array();
+ foreach ( $cache_keys as $id => $cache_key ) {
+ if ( false === $cached_data[ $cache_key ] ) {
+ $non_cached_ids[] = $id;
+ }
+ }
+
+ if ( ! empty( $non_cached_ids ) ) {
+ $fresh_posts = $wpdb->get_results( sprintf( "SELECT $wpdb->posts.ID, $wpdb->posts.post_parent FROM $wpdb->posts WHERE ID IN (%s)", implode( ',', $non_cached_ids ) ) );
+
+ if ( $fresh_posts ) {
+ $post_parent_data = array();
+ foreach ( $fresh_posts as $fresh_post ) {
+ $post_parent_data[ 'post_parent:' . (string) $fresh_post->ID ] = (int) $fresh_post->post_parent;
+ }
+
+ wp_cache_add_multiple( $post_parent_data, 'posts' );
+ }
}
}
@@ -7869,16 +8010,16 @@
* @access private
*
* @param string $post_name Post slug.
- * @param int $post_ID Optional. Post ID that should be ignored. Default 0.
- */
-function wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_ID = 0 ) {
+ * @param int $post_id Optional. Post ID that should be ignored. Default 0.
+ */
+function wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_id = 0 ) {
$trashed_posts_with_desired_slug = get_posts(
array(
'name' => $post_name,
'post_status' => 'trash',
'post_type' => 'any',
'nopaging' => true,
- 'post__not_in' => array( $post_ID ),
+ 'post__not_in' => array( $post_id ),
)
);
@@ -7900,6 +8041,8 @@
* @since 4.5.0
* @access private
*
+ * @global wpdb $wpdb WordPress database abstraction object.
+ *
* @param WP_Post $post The post.
* @return string New slug for the post.
*/
@@ -7908,7 +8051,7 @@
$post = get_post( $post );
- if ( '__trashed' === substr( $post->post_name, -9 ) ) {
+ if ( str_ends_with( $post->post_name, '__trashed' ) ) {
return $post->post_name;
}
add_post_meta( $post->ID, '_wp_desired_post_slug', $post->post_name );
@@ -7919,59 +8062,43 @@
}
/**
- * Filters the SQL clauses of an attachment query to include filenames.
- *
- * @since 4.7.0
- * @access private
- *
- * @global wpdb $wpdb WordPress database abstraction object.
- *
- * @param string[] $clauses An array including WHERE, GROUP BY, JOIN, ORDER BY,
- * DISTINCT, fields (SELECT), and LIMITS clauses.
- * @return string[] The modified array of clauses.
- */
-function _filter_query_attachment_filenames( $clauses ) {
- global $wpdb;
- remove_filter( 'posts_clauses', __FUNCTION__ );
-
- // Add a LEFT JOIN of the postmeta table so we don't trample existing JOINs.
- $clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND sq1.meta_key = '_wp_attached_file' )";
-
- $clauses['groupby'] = "{$wpdb->posts}.ID";
-
- $clauses['where'] = preg_replace(
- "/\({$wpdb->posts}.post_content (NOT LIKE|LIKE) (\'[^']+\')\)/",
- '$0 OR ( sq1.meta_value $1 $2 )',
- $clauses['where']
- );
-
- return $clauses;
-}
-
-/**
* Sets the last changed time for the 'posts' cache group.
*
* @since 5.0.0
*/
function wp_cache_set_posts_last_changed() {
- wp_cache_set( 'last_changed', microtime(), 'posts' );
-}
-
-/**
- * Get all available post MIME types for a given post type.
+ wp_cache_set_last_changed( 'posts' );
+}
+
+/**
+ * Gets all available post MIME types for a given post type.
*
* @since 2.5.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param string $type
- * @return mixed
+ * @return string[] An array of MIME types.
*/
function get_available_post_mime_types( $type = 'attachment' ) {
global $wpdb;
- $types = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s", $type ) );
- return $types;
+ /**
+ * Filters the list of available post MIME types for the given post type.
+ *
+ * @since 6.4.0
+ *
+ * @param string[]|null $mime_types An array of MIME types. Default null.
+ * @param string $type The post type name. Usually 'attachment' but can be any post type.
+ */
+ $mime_types = apply_filters( 'pre_get_available_post_mime_types', null, $type );
+
+ if ( ! is_array( $mime_types ) ) {
+ $mime_types = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s AND post_mime_type != ''", $type ) );
+ }
+
+ // Remove nulls from returned $mime_types.
+ return array_values( array_filter( $mime_types ) );
}
/**
@@ -8015,7 +8142,7 @@
}
/**
- * Retrieve the URL to an original attachment image.
+ * Retrieves the URL to an original attachment image.
*
* Similar to `wp_get_attachment_url()` however some images may have been
* processed after uploading. In this case this function returns the URL
@@ -8057,7 +8184,7 @@
}
/**
- * Filter callback which sets the status of an untrashed post to its previous status.
+ * Filters callback which sets the status of an untrashed post to its previous status.
*
* This can be used as a callback on the `wp_untrash_post_status` filter.
*
@@ -8071,3 +8198,100 @@
function wp_untrash_post_set_previous_status( $new_status, $post_id, $previous_status ) {
return $previous_status;
}
+
+/**
+ * Returns whether the post can be edited in the block editor.
+ *
+ * @since 5.0.0
+ * @since 6.1.0 Moved to wp-includes from wp-admin.
+ *
+ * @param int|WP_Post $post Post ID or WP_Post object.
+ * @return bool Whether the post can be edited in the block editor.
+ */
+function use_block_editor_for_post( $post ) {
+ $post = get_post( $post );
+
+ if ( ! $post ) {
+ return false;
+ }
+
+ // We're in the meta box loader, so don't use the block editor.
+ if ( is_admin() && isset( $_GET['meta-box-loader'] ) ) {
+ check_admin_referer( 'meta-box-loader', 'meta-box-loader-nonce' );
+ return false;
+ }
+
+ $use_block_editor = use_block_editor_for_post_type( $post->post_type );
+
+ /**
+ * Filters whether a post is able to be edited in the block editor.
+ *
+ * @since 5.0.0
+ *
+ * @param bool $use_block_editor Whether the post can be edited or not.
+ * @param WP_Post $post The post being checked.
+ */
+ return apply_filters( 'use_block_editor_for_post', $use_block_editor, $post );
+}
+
+/**
+ * Returns whether a post type is compatible with the block editor.
+ *
+ * The block editor depends on the REST API, and if the post type is not shown in the
+ * REST API, then it won't work with the block editor.
+ *
+ * @since 5.0.0
+ * @since 6.1.0 Moved to wp-includes from wp-admin.
+ *
+ * @param string $post_type The post type.
+ * @return bool Whether the post type can be edited with the block editor.
+ */
+function use_block_editor_for_post_type( $post_type ) {
+ if ( ! post_type_exists( $post_type ) ) {
+ return false;
+ }
+
+ if ( ! post_type_supports( $post_type, 'editor' ) ) {
+ return false;
+ }
+
+ $post_type_object = get_post_type_object( $post_type );
+ if ( $post_type_object && ! $post_type_object->show_in_rest ) {
+ return false;
+ }
+
+ /**
+ * Filters whether a post is able to be edited in the block editor.
+ *
+ * @since 5.0.0
+ *
+ * @param bool $use_block_editor Whether the post type can be edited or not. Default true.
+ * @param string $post_type The post type being checked.
+ */
+ return apply_filters( 'use_block_editor_for_post_type', true, $post_type );
+}
+
+/**
+ * Registers any additional post meta fields.
+ *
+ * @since 6.3.0 Adds `wp_pattern_sync_status` meta field to the wp_block post type so an unsynced option can be added.
+ *
+ * @link https://github.com/WordPress/gutenberg/pull/51144
+ */
+function wp_create_initial_post_meta() {
+ register_post_meta(
+ 'wp_block',
+ 'wp_pattern_sync_status',
+ array(
+ 'sanitize_callback' => 'sanitize_text_field',
+ 'single' => true,
+ 'type' => 'string',
+ 'show_in_rest' => array(
+ 'schema' => array(
+ 'type' => 'string',
+ 'enum' => array( 'partial', 'unsynced' ),
+ ),
+ ),
+ )
+ );
+}