diff -r 3d4e9c994f10 -r a86126ab1dd4 wp/wp-includes/post.php
--- a/wp/wp-includes/post.php Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-includes/post.php Tue Dec 15 13:49:49 2020 +0100
@@ -7,7 +7,7 @@
*/
//
-// Post Type Registration
+// Post Type registration.
//
/**
@@ -30,6 +30,7 @@
'capability_type' => 'post',
'map_meta_cap' => true,
'menu_position' => 5,
+ 'menu_icon' => 'dashicons-admin-post',
'hierarchical' => false,
'rewrite' => false,
'query_var' => false,
@@ -54,6 +55,7 @@
'capability_type' => 'page',
'map_meta_cap' => true,
'menu_position' => 20,
+ 'menu_icon' => 'dashicons-admin-page',
'hierarchical' => true,
'rewrite' => false,
'query_var' => false,
@@ -85,6 +87,7 @@
'create_posts' => 'upload_files',
),
'map_meta_cap' => true,
+ 'menu_icon' => 'dashicons-admin-media',
'hierarchical' => false,
'rewrite' => false,
'query_var' => false,
@@ -312,7 +315,11 @@
'label' => _x( 'Published', 'post status' ),
'public' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Published (%s)', 'Published (%s)' ),
+ /* translators: %s: Number of published posts. */
+ 'label_count' => _n_noop(
+ 'Published (%s)',
+ 'Published (%s)'
+ ),
)
);
@@ -322,27 +329,41 @@
'label' => _x( 'Scheduled', 'post status' ),
'protected' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Scheduled (%s)', 'Scheduled (%s)' ),
+ /* translators: %s: Number of scheduled posts. */
+ 'label_count' => _n_noop(
+ 'Scheduled (%s)',
+ 'Scheduled (%s)'
+ ),
)
);
register_post_status(
'draft',
array(
- 'label' => _x( 'Draft', 'post status' ),
- 'protected' => true,
- '_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Draft (%s)', 'Drafts (%s)' ),
+ 'label' => _x( 'Draft', 'post status' ),
+ 'protected' => true,
+ '_builtin' => true, /* internal use only. */
+ /* translators: %s: Number of draft posts. */
+ 'label_count' => _n_noop(
+ 'Draft (%s)',
+ 'Drafts (%s)'
+ ),
+ 'date_floating' => true,
)
);
register_post_status(
'pending',
array(
- 'label' => _x( 'Pending', 'post status' ),
- 'protected' => true,
- '_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Pending (%s)', 'Pending (%s)' ),
+ 'label' => _x( 'Pending', 'post status' ),
+ 'protected' => true,
+ '_builtin' => true, /* internal use only. */
+ /* translators: %s: Number of pending posts. */
+ 'label_count' => _n_noop(
+ 'Pending (%s)',
+ 'Pending (%s)'
+ ),
+ 'date_floating' => true,
)
);
@@ -352,7 +373,11 @@
'label' => _x( 'Private', 'post status' ),
'private' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Private (%s)', 'Private (%s)' ),
+ /* translators: %s: Number of private posts. */
+ 'label_count' => _n_noop(
+ 'Private (%s)',
+ 'Private (%s)'
+ ),
)
);
@@ -362,7 +387,11 @@
'label' => _x( 'Trash', 'post status' ),
'internal' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Trash (%s)', 'Trash (%s)' ),
+ /* translators: %s: Number of trashed posts. */
+ 'label_count' => _n_noop(
+ 'Trash (%s)',
+ 'Trash (%s)'
+ ),
'show_in_admin_status_list' => true,
)
);
@@ -370,9 +399,10 @@
register_post_status(
'auto-draft',
array(
- 'label' => 'auto-draft',
- 'internal' => true,
- '_builtin' => true, /* internal use only. */
+ 'label' => 'auto-draft',
+ 'internal' => true,
+ '_builtin' => true, /* internal use only. */
+ 'date_floating' => true,
)
);
@@ -392,7 +422,11 @@
'label' => _x( 'Pending', 'request status' ),
'internal' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Pending (%s)', 'Pending (%s)' ),
+ /* translators: %s: Number of pending requests. */
+ 'label_count' => _n_noop(
+ 'Pending (%s)',
+ 'Pending (%s)'
+ ),
'exclude_from_search' => false,
)
);
@@ -403,7 +437,11 @@
'label' => _x( 'Confirmed', 'request status' ),
'internal' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Confirmed (%s)', 'Confirmed (%s)' ),
+ /* translators: %s: Number of confirmed requests. */
+ 'label_count' => _n_noop(
+ 'Confirmed (%s)',
+ 'Confirmed (%s)'
+ ),
'exclude_from_search' => false,
)
);
@@ -414,7 +452,11 @@
'label' => _x( 'Failed', 'request status' ),
'internal' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Failed (%s)', 'Failed (%s)' ),
+ /* translators: %s: Number of failed requests. */
+ 'label_count' => _n_noop(
+ 'Failed (%s)',
+ 'Failed (%s)'
+ ),
'exclude_from_search' => false,
)
);
@@ -425,7 +467,11 @@
'label' => _x( 'Completed', 'request status' ),
'internal' => true,
'_builtin' => true, /* internal use only. */
- 'label_count' => _n_noop( 'Completed (%s)', 'Completed (%s)' ),
+ /* translators: %s: Number of completed requests. */
+ 'label_count' => _n_noop(
+ 'Completed (%s)',
+ 'Completed (%s)'
+ ),
'exclude_from_search' => false,
)
);
@@ -453,8 +499,11 @@
$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 ) && ( ( $uploads = wp_get_upload_dir() ) && false === $uploads['error'] ) ) {
- $file = $uploads['basedir'] . "/$file";
+ if ( $file && 0 !== strpos( $file, '/' ) && ! preg_match( '|^.:\\\|', $file ) ) {
+ $uploads = wp_get_upload_dir();
+ if ( false === $uploads['error'] ) {
+ $file = $uploads['basedir'] . "/$file";
+ }
}
if ( $unfiltered ) {
@@ -466,8 +515,8 @@
*
* @since 2.1.0
*
- * @param string $file Path to attached file.
- * @param int $attachment_id Attachment ID.
+ * @param string|false $file The file path to where the attached file should be, false otherwise.
+ * @param int $attachment_id Attachment ID.
*/
return apply_filters( 'get_attached_file', $file, $attachment_id );
}
@@ -499,7 +548,8 @@
*/
$file = apply_filters( 'update_attached_file', $file, $attachment_id );
- if ( $file = _wp_relative_upload_path( $file ) ) {
+ $file = _wp_relative_upload_path( $file );
+ if ( $file ) {
return update_post_meta( $attachment_id, '_wp_attached_file', $file );
} else {
return delete_post_meta( $attachment_id, '_wp_attached_file' );
@@ -580,13 +630,13 @@
* @see get_posts()
* @todo Check validity of description.
*
- * @global WP_Post $post
+ * @global WP_Post $post Global post object.
*
* @param mixed $args Optional. User defined arguments for replacing the defaults. Default empty.
- * @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 array Array of children, where the type of each element is determined by $output parameter.
- * Empty array on failure.
+ * @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.
*/
function get_children( $args = '', $output = OBJECT ) {
$kids = array();
@@ -609,15 +659,15 @@
'post_parent' => 0,
);
- $r = wp_parse_args( $args, $defaults );
-
- $children = get_posts( $r );
+ $parsed_args = wp_parse_args( $args, $defaults );
+
+ $children = get_posts( $parsed_args );
if ( ! $children ) {
return $kids;
}
- if ( ! empty( $r['fields'] ) ) {
+ if ( ! empty( $parsed_args['fields'] ) ) {
return $children;
}
@@ -627,15 +677,15 @@
$kids[ $child->ID ] = $children[ $key ];
}
- if ( $output == OBJECT ) {
+ if ( OBJECT == $output ) {
return $kids;
- } elseif ( $output == ARRAY_A ) {
+ } elseif ( ARRAY_A == $output ) {
$weeuns = array();
foreach ( (array) $kids as $kid ) {
$weeuns[ $kid->ID ] = get_object_vars( $kids[ $kid->ID ] );
}
return $weeuns;
- } elseif ( $output == ARRAY_N ) {
+ } elseif ( ARRAY_N == $output ) {
$babes = array();
foreach ( (array) $kids as $kid ) {
$babes[ $kid->ID ] = array_values( get_object_vars( $kids[ $kid->ID ] ) );
@@ -660,10 +710,16 @@
* @since 1.0.0
*
* @param string $post Post content.
- * @return array Post before ('main'), after ('extended'), and custom read more ('more_text').
+ * @return string[] {
+ * Extended entry info.
+ *
+ * @type string $main Content before the more tag.
+ * @type string $extended Content after the more tag.
+ * @type string $more_text Custom read more text, or empty string.
+ * }
*/
function get_extended( $post ) {
- //Match the new style more links.
+ // Match the new style more links.
if ( preg_match( '//', $post, $matches ) ) {
list($main, $extended) = explode( $matches[0], $post, 2 );
$more_text = $matches[1];
@@ -673,7 +729,7 @@
$more_text = '';
}
- // leading and trailing whitespace.
+ // Leading and trailing whitespace.
$main = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $main );
$extended = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $extended );
$more_text = preg_replace( '/^[\s]*(.*)[\s]*$/', '\\1', $more_text );
@@ -693,11 +749,12 @@
*
* @since 1.5.1
*
- * @global WP_Post $post
+ * @global WP_Post $post Global post object.
*
* @param int|WP_Post|null $post Optional. Post ID or post object. Defaults to global $post.
- * @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 $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 $filter Optional. Type of filter to apply. Accepts 'raw', 'edit', 'db',
* or 'display'. Default 'raw'.
* @return WP_Post|array|null Type corresponding to $output on success or null on failure.
@@ -714,7 +771,7 @@
if ( empty( $post->filter ) ) {
$_post = sanitize_post( $post, 'raw' );
$_post = new WP_Post( $_post );
- } elseif ( 'raw' == $post->filter ) {
+ } elseif ( 'raw' === $post->filter ) {
$_post = new WP_Post( $post );
} else {
$_post = WP_Post::get_instance( $post->ID );
@@ -729,9 +786,9 @@
$_post = $_post->filter( $filter );
- if ( $output == ARRAY_A ) {
+ if ( ARRAY_A == $output ) {
return $_post->to_array();
- } elseif ( $output == ARRAY_N ) {
+ } elseif ( ARRAY_N == $output ) {
return array_values( $_post->to_array() );
}
@@ -744,7 +801,7 @@
* @since 2.5.0
*
* @param int|WP_Post $post Post ID or post object.
- * @return array Ancestor IDs or empty array if none are found.
+ * @return int[] Ancestor IDs or empty array if none are found.
*/
function get_post_ancestors( $post ) {
$post = get_post( $post );
@@ -755,15 +812,17 @@
$ancestors = array();
- $id = $ancestors[] = $post->post_parent;
+ $id = $post->post_parent;
+ $ancestors[] = $id;
while ( $ancestor = get_post( $id ) ) {
// Loop detection: If the ancestor has been seen before, break.
- if ( empty( $ancestor->post_parent ) || ( $ancestor->post_parent == $post->ID ) || in_array( $ancestor->post_parent, $ancestors ) ) {
+ if ( empty( $ancestor->post_parent ) || ( $ancestor->post_parent == $post->ID ) || in_array( $ancestor->post_parent, $ancestors, true ) ) {
break;
}
- $id = $ancestors[] = $ancestor->post_parent;
+ $id = $ancestor->post_parent;
+ $ancestors[] = $id;
}
return $ancestors;
@@ -842,20 +901,20 @@
return false;
}
- if ( 'attachment' == $post->post_type ) {
- if ( 'private' == $post->post_status ) {
+ if ( 'attachment' === $post->post_type ) {
+ if ( 'private' === $post->post_status ) {
return 'private';
}
// Unattached attachments are assumed to be published.
- if ( ( 'inherit' == $post->post_status ) && ( 0 == $post->post_parent ) ) {
+ if ( ( 'inherit' === $post->post_status ) && ( 0 == $post->post_parent ) ) {
return 'publish';
}
// Inherit status from the parent.
if ( $post->post_parent && ( $post->ID != $post->post_parent ) ) {
$parent_post_status = get_post_status( $post->post_parent );
- if ( 'trash' == $parent_post_status ) {
+ if ( 'trash' === $parent_post_status ) {
return get_post_meta( $post->post_parent, '_wp_trash_meta_status', true );
} else {
return $parent_post_status;
@@ -882,7 +941,7 @@
*
* @since 2.5.0
*
- * @return array List of post statuses.
+ * @return string[] Array of post status labels keyed by their status.
*/
function get_post_statuses() {
$status = array(
@@ -903,7 +962,7 @@
*
* @since 2.5.0
*
- * @return array List of page statuses.
+ * @return string[] Array of page status labels keyed by their status.
*/
function get_page_statuses() {
$status = array(
@@ -925,10 +984,10 @@
*/
function _wp_privacy_statuses() {
return array(
- 'request-pending' => __( 'Pending' ), // Pending confirmation from user.
- 'request-confirmed' => __( 'Confirmed' ), // User has confirmed the action.
- 'request-failed' => __( 'Failed' ), // User failed to confirm the action.
- 'request-completed' => __( 'Completed' ), // Admin has handled the request.
+ 'request-pending' => _x( 'Pending', 'request status' ), // Pending confirmation from user.
+ 'request-confirmed' => _x( 'Confirmed', 'request status' ), // User has confirmed the action.
+ 'request-failed' => _x( 'Failed', 'request status' ), // User failed to confirm the action.
+ 'request-completed' => _x( 'Completed', 'request status' ), // Admin has handled the request.
);
}
@@ -942,16 +1001,17 @@
* Arguments prefixed with an _underscore shouldn't be used by plugins and themes.
*
* @since 3.0.0
+ *
* @global array $wp_post_statuses Inserts new post status object into the list
*
- * @param string $post_status Name of the post status.
+ * @param string $post_status Name of the post status.
* @param array|string $args {
* Optional. Array or string of post status arguments.
*
* @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
+ * Default array of $label, twice.
* @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.
@@ -967,11 +1027,14 @@
* @type bool $publicly_queryable Whether posts with this status should be publicly-
* queryable. Default is value of $public.
* @type bool $show_in_admin_all_list Whether to include posts in the edit listing for
- * their post type. Default is value of $internal.
+ * their post type. Default is the opposite value
+ * of $internal.
* @type bool $show_in_admin_status_list Show in the list of statuses with post counts at
* the top of the edit listings,
* e.g. All (12) | Published (9) | My Custom Status (2)
- * Default is value of $internal.
+ * Default is the opposite value of $internal.
+ * @type bool $date_floating Whether the post has a floating creation date.
+ * Default to false.
* }
* @return object
*/
@@ -995,6 +1058,7 @@
'publicly_queryable' => null,
'show_in_admin_status_list' => null,
'show_in_admin_all_list' => null,
+ 'date_floating' => null,
);
$args = wp_parse_args( $args, $defaults );
$args = (object) $args;
@@ -1039,6 +1103,10 @@
$args->show_in_admin_status_list = ! $args->internal;
}
+ if ( null === $args->date_floating ) {
+ $args->date_floating = false;
+ }
+
if ( false === $args->label ) {
$args->label = $post_status;
}
@@ -1095,7 +1163,7 @@
function get_post_stati( $args = array(), $output = 'names', $operator = 'and' ) {
global $wp_post_statuses;
- $field = ( 'names' == $output ) ? 'name' : false;
+ $field = ( 'names' === $output ) ? 'name' : false;
return wp_filter_object_list( $wp_post_statuses, $args, $operator, $field );
}
@@ -1148,7 +1216,8 @@
* @return string|false Post type on success, false on failure.
*/
function get_post_type( $post = null ) {
- if ( $post = get_post( $post ) ) {
+ $post = get_post( $post );
+ if ( $post ) {
return $post->post_type;
}
@@ -1199,7 +1268,7 @@
function get_post_types( $args = array(), $output = 'names', $operator = 'and' ) {
global $wp_post_types;
- $field = ( 'names' == $output ) ? 'name' : false;
+ $field = ( 'names' === $output ) ? 'name' : false;
return wp_filter_object_list( $wp_post_types, $args, $operator, $field );
}
@@ -1225,12 +1294,13 @@
* @since 4.6.0 Post type object returned is now an instance of `WP_Post_Type`.
* @since 4.7.0 Introduced `show_in_rest`, `rest_base` and `rest_controller_class`
* arguments to register the post type in REST API.
- *
+ * @since 5.3.0 The `supports` argument will now accept an array of arguments for a feature.
+ * .
* @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.
*
@@ -1259,17 +1329,18 @@
* 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 $show_in_menu Where to show the post type in the admin menu. To work, $show_ui
+ * @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 (eg. 'tools.php' or 'edit.php?post_type=page'), 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 $public.
+ * 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 add the post type route in the REST API 'wp/v2' namespace.
+ * @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_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,
@@ -1295,8 +1366,11 @@
* '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. Defaults is an array
- * containing 'title' and 'editor'.
+ * 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.
@@ -1328,7 +1402,7 @@
* ?{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
+ * posts of this type belonging to the user will be moved to Trash
* when then 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('author'). Otherwise posts
@@ -1338,7 +1412,8 @@
* @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, or an error object.
+ * @return WP_Post_Type|WP_Error The registered post type object on success,
+ * WP_Error object on failure.
*/
function register_post_type( $post_type, $args = array() ) {
global $wp_post_types;
@@ -1347,7 +1422,7 @@
$wp_post_types = array();
}
- // Sanitize post type name
+ // Sanitize post type name.
$post_type = sanitize_key( $post_type );
if ( empty( $post_type ) || strlen( $post_type ) > 20 ) {
@@ -1437,7 +1512,7 @@
* Otherwise, an 's' will be added to the value for the plural form. After
* registration, capability_type will always be a string of the singular value.
*
- * By default, seven keys are accepted as part of the capabilities array:
+ * By default, eight keys are accepted as part of the capabilities array:
*
* - edit_post, read_post, and delete_post are meta capabilities, which are then
* generally mapped to corresponding primitive capabilities depending on the
@@ -1449,17 +1524,17 @@
* - edit_others_posts - Controls whether objects of this type owned by other users
* can be edited. If the post type does not support an author, then this will
* behave like edit_posts.
+ * - delete_posts - Controls whether objects of this post type can be deleted.
* - publish_posts - Controls publishing objects of this post type.
* - read_private_posts - Controls whether private objects can be read.
*
- * These four primitive capabilities are checked in core in various locations.
- * There are also seven other primitive capabilities which are not referenced
+ * These five primitive capabilities are checked in core in various locations.
+ * There are also six other primitive capabilities which are not referenced
* directly in core, except in map_meta_cap(), which takes the three aforementioned
* meta capabilities and translates them into one or more primitive capabilities
* that must then be checked against the user or role, depending on the context.
*
* - read - Controls whether objects of this post type can be read.
- * - delete_posts - Controls whether objects of this post type can be deleted.
* - delete_private_posts - Controls whether private objects can be deleted.
* - delete_published_posts - Controls whether published objects can be deleted.
* - delete_others_posts - Controls whether objects owned by other users can be
@@ -1473,6 +1548,7 @@
* argument set to true (default is false).
*
* @since 3.0.0
+ * @since 5.4.0 'delete_posts' is included in default capabilities.
*
* @see register_post_type()
* @see map_meta_cap()
@@ -1489,13 +1565,14 @@
list( $singular_base, $plural_base ) = $args->capability_type;
$default_capabilities = array(
- // Meta capabilities
+ // Meta capabilities.
'edit_post' => 'edit_' . $singular_base,
'read_post' => 'read_' . $singular_base,
'delete_post' => 'delete_' . $singular_base,
// Primitive capabilities used outside of map_meta_cap():
'edit_posts' => 'edit_' . $plural_base,
'edit_others_posts' => 'edit_others_' . $plural_base,
+ 'delete_posts' => 'delete_' . $plural_base,
'publish_posts' => 'publish_' . $plural_base,
'read_private_posts' => 'read_private_' . $plural_base,
);
@@ -1504,7 +1581,6 @@
if ( $args->map_meta_cap ) {
$default_capabilities_for_mapping = array(
'read' => 'read',
- 'delete_posts' => 'delete_' . $plural_base,
'delete_private_posts' => 'delete_private_' . $plural_base,
'delete_published_posts' => 'delete_published_' . $plural_base,
'delete_others_posts' => 'delete_others_' . $plural_base,
@@ -1537,13 +1613,13 @@
*
* @global array $post_type_meta_caps Used to store meta capabilities.
*
- * @param array $capabilities Post type meta capabilities.
+ * @param string[] $capabilities Post type meta capabilities.
*/
function _post_type_meta_capabilities( $capabilities = null ) {
global $post_type_meta_caps;
foreach ( $capabilities as $core => $custom ) {
- if ( in_array( $core, array( 'read_post', 'delete_post', 'edit_post' ) ) ) {
+ if ( in_array( $core, array( 'read_post', 'delete_post', 'edit_post' ), true ) ) {
$post_type_meta_caps[ $custom ] = $core;
}
}
@@ -1558,7 +1634,7 @@
* 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://codex.wordpress.org/I18n_for_WordPress_Developers#Disambiguation_by_context gettext context}
+ * 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_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'.
@@ -1567,7 +1643,7 @@
* - `view_items` - Label for viewing post type archives. Default is 'View Posts' / 'View Pages'.
* - `search_items` - Label for searching plural items. Default is 'Search Posts' / 'Search Pages'.
* - `not_found` - Label used when no items are found. Default is 'No posts found' / 'No pages found'.
- * - `not_found_in_trash` - Label used when no items are in the trash. Default is 'No posts found in Trash' /
+ * - `not_found_in_trash` - Label used when no items are in the Trash. Default is 'No posts found in Trash' /
* 'No pages found in Trash'.
* - `parent_item_colon` - Label used to prefix parents of hierarchical items. Not used on non-hierarchical
* post types. Default is 'Parent Page:'.
@@ -1577,7 +1653,7 @@
* - `insert_into_item` - Label for the media frame button. Default is 'Insert into post' / 'Insert into page'.
* - `uploaded_to_this_item` - Label for the media frame filter. Default is 'Uploaded to this post' /
* 'Uploaded to this page'.
- * - `featured_image` - Label for the Featured Image meta box title. Default is 'Featured Image'.
+ * - `featured_image` - Label for the featured image meta box title. Default is 'Featured image'.
* - `set_featured_image` - Label for setting the featured image. Default is 'Set featured image'.
* - `remove_featured_image` - Label for removing the featured image. Default is 'Remove featured image'.
* - `use_featured_image` - Label in the media frame for using a featured image. Default is 'Use as featured image'.
@@ -1635,7 +1711,7 @@
'attributes' => array( __( 'Post Attributes' ), __( 'Page Attributes' ) ),
'insert_into_item' => array( __( 'Insert into post' ), __( 'Insert into page' ) ),
'uploaded_to_this_item' => array( __( 'Uploaded to this post' ), __( 'Uploaded to this page' ) ),
- 'featured_image' => array( _x( 'Featured Image', 'post' ), _x( 'Featured Image', 'page' ) ),
+ 'featured_image' => array( _x( 'Featured image', 'post' ), _x( 'Featured image', 'page' ) ),
'set_featured_image' => array( _x( 'Set featured image', 'post' ), _x( 'Set featured image', 'page' ) ),
'remove_featured_image' => array( _x( 'Remove featured image', 'post' ), _x( 'Remove featured image', 'page' ) ),
'use_featured_image' => array( _x( 'Use as featured image', 'post' ), _x( 'Use as featured image', 'page' ) ),
@@ -1734,7 +1810,7 @@
foreach ( get_post_types( array( 'show_ui' => true ) ) as $ptype ) {
$ptype_obj = get_post_type_object( $ptype );
// Sub-menus only.
- if ( ! $ptype_obj->show_in_menu || $ptype_obj->show_in_menu === true ) {
+ if ( ! $ptype_obj->show_in_menu || true === $ptype_obj->show_in_menu ) {
continue;
}
add_submenu_page( $ptype_obj->show_in_menu, $ptype_obj->labels->name, $ptype_obj->labels->all_items, $ptype_obj->cap->edit_posts, "edit.php?post_type=$ptype" );
@@ -1742,7 +1818,7 @@
}
/**
- * Register support of certain features for a post type.
+ * Registers support of certain features for a post type.
*
* All core features are directly associated with a functional area of the edit
* screen, such as the editor or a meta box. Features include: 'title', 'editor',
@@ -1753,23 +1829,39 @@
* store revisions, 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
+ * additional information about supporting that feature.
+ *
+ * Example usage:
+ *
+ * add_post_type_support( 'my_post_type', 'comments' );
+ * add_post_type_support( 'my_post_type', array(
+ * 'author', 'excerpt',
+ * ) );
+ * add_post_type_support( 'my_post_type', 'my_feature', array(
+ * 'field' => 'value',
+ * ) );
+ *
* @since 3.0.0
+ * @since 5.3.0 Formalized the existing and already documented `...$args` parameter
+ * by adding it to the function signature.
*
* @global array $_wp_post_type_features
*
* @param string $post_type The post type for which to add the feature.
* @param string|array $feature The feature being added, accepts an array of
* feature strings or a single string.
- */
-function add_post_type_support( $post_type, $feature ) {
+ * @param mixed ...$args Optional extra arguments to pass along with certain features.
+ */
+function add_post_type_support( $post_type, $feature, ...$args ) {
global $_wp_post_type_features;
$features = (array) $feature;
foreach ( $features as $feature ) {
- if ( func_num_args() == 2 ) {
+ if ( $args ) {
+ $_wp_post_type_features[ $post_type ][ $feature ] = $args;
+ } else {
$_wp_post_type_features[ $post_type ][ $feature ] = true;
- } else {
- $_wp_post_type_features[ $post_type ][ $feature ] = array_slice( func_get_args(), 2 );
}
}
}
@@ -1839,7 +1931,7 @@
* only one element from the array needs to match; 'and'
* means all elements must match; 'not' means no elements may
* match. Default 'and'.
- * @return array A list of post type names.
+ * @return string[] A list of post type names.
*/
function get_post_types_by_support( $feature, $operator = 'and' ) {
global $_wp_post_type_features;
@@ -1936,34 +2028,34 @@
'suppress_filters' => true,
);
- $r = wp_parse_args( $args, $defaults );
- if ( empty( $r['post_status'] ) ) {
- $r['post_status'] = ( 'attachment' == $r['post_type'] ) ? 'inherit' : 'publish';
- }
- if ( ! empty( $r['numberposts'] ) && empty( $r['posts_per_page'] ) ) {
- $r['posts_per_page'] = $r['numberposts'];
- }
- if ( ! empty( $r['category'] ) ) {
- $r['cat'] = $r['category'];
- }
- if ( ! empty( $r['include'] ) ) {
- $incposts = wp_parse_id_list( $r['include'] );
- $r['posts_per_page'] = count( $incposts ); // only the number of posts included
- $r['post__in'] = $incposts;
- } elseif ( ! empty( $r['exclude'] ) ) {
- $r['post__not_in'] = wp_parse_id_list( $r['exclude'] );
- }
-
- $r['ignore_sticky_posts'] = true;
- $r['no_found_rows'] = true;
+ $parsed_args = wp_parse_args( $args, $defaults );
+ if ( empty( $parsed_args['post_status'] ) ) {
+ $parsed_args['post_status'] = ( 'attachment' === $parsed_args['post_type'] ) ? 'inherit' : 'publish';
+ }
+ if ( ! empty( $parsed_args['numberposts'] ) && empty( $parsed_args['posts_per_page'] ) ) {
+ $parsed_args['posts_per_page'] = $parsed_args['numberposts'];
+ }
+ if ( ! empty( $parsed_args['category'] ) ) {
+ $parsed_args['cat'] = $parsed_args['category'];
+ }
+ if ( ! empty( $parsed_args['include'] ) ) {
+ $incposts = wp_parse_id_list( $parsed_args['include'] );
+ $parsed_args['posts_per_page'] = count( $incposts ); // Only the number of posts included.
+ $parsed_args['post__in'] = $incposts;
+ } elseif ( ! empty( $parsed_args['exclude'] ) ) {
+ $parsed_args['post__not_in'] = wp_parse_id_list( $parsed_args['exclude'] );
+ }
+
+ $parsed_args['ignore_sticky_posts'] = true;
+ $parsed_args['no_found_rows'] = true;
$get_posts = new WP_Query;
- return $get_posts->query( $r );
+ return $get_posts->query( $parsed_args );
}
//
-// Post meta functions
+// Post meta functions.
//
/**
@@ -2001,8 +2093,9 @@
*
* @param int $post_id Post ID.
* @param string $meta_key Metadata name.
- * @param mixed $meta_value Optional. Metadata value. Must be serializable if
- * non-scalar. Default empty.
+ * @param mixed $meta_value Optional. Metadata value. If provided,
+ * rows will only be removed that match the value.
+ * Must be serializable if non-scalar. Default empty.
* @return bool True on success, false on failure.
*/
function delete_post_meta( $post_id, $meta_key, $meta_value = '' ) {
@@ -2021,12 +2114,13 @@
* @since 1.5.0
*
* @param int $post_id Post ID.
- * @param string $key Optional. The meta key to retrieve. By default, returns
- * data for all keys. Default empty.
- * @param bool $single Optional. If true, returns only the first value for the specified meta key.
- * This parameter has no effect if $key is not specified. Default false.
- * @return mixed Will be an array if $single is false. Will be value of the meta
- * field if $single is true.
+ * @param string $key Optional. The meta key to retrieve. By default,
+ * returns data for all keys. Default empty.
+ * @param bool $single Optional. Whether to return a single value.
+ * This parameter has no effect if $key is not specified.
+ * Default false.
+ * @return mixed An array if $single is false. The value of the meta field
+ * if $single is true. False for an invalid $post_id.
*/
function get_post_meta( $post_id, $key = '', $single = false ) {
return get_metadata( 'post', $post_id, $key, $single );
@@ -2048,8 +2142,11 @@
* @param string $meta_key Metadata key.
* @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
* @param mixed $prev_value Optional. Previous value to check before updating.
- * @return int|bool The new meta field ID if a field with the given key didn't exist and was
- * therefore added, true on successful update, false on failure.
+ * If specified, only update existing metadata entries with
+ * this value. Otherwise, update all entries. Default empty.
+ * @return int|bool Meta ID if the key didn't exist, true on successful update,
+ * false on failure or if the value passed to the function
+ * is the same as the one that is already in the database.
*/
function update_post_meta( $post_id, $meta_key, $meta_value, $prev_value = '' ) {
// Make sure meta is added to the post, not a revision.
@@ -2143,7 +2240,8 @@
return;
}
- if ( $keys = array_keys( $custom ) ) {
+ $keys = array_keys( $custom );
+ if ( $keys ) {
return $keys;
}
}
@@ -2194,15 +2292,22 @@
$stickies = get_option( 'sticky_posts' );
- if ( ! is_array( $stickies ) ) {
- return false;
- }
-
- if ( in_array( $post_id, $stickies ) ) {
- return true;
- }
-
- return false;
+ if ( is_array( $stickies ) ) {
+ $stickies = array_map( 'intval', $stickies );
+ $is_sticky = in_array( $post_id, $stickies, true );
+ } else {
+ $is_sticky = false;
+ }
+
+ /**
+ * Filters whether a post is sticky.
+ *
+ * @since 5.3.0
+ *
+ * @param bool $is_sticky Whether a post is sticky.
+ * @param int $post_id Post ID.
+ */
+ return apply_filters( 'is_sticky', $is_sticky, $post_id );
}
/**
@@ -2252,7 +2357,7 @@
}
/**
- * Sanitize post field based on context.
+ * Sanitizes a post field based on context.
*
* Possible context values are: 'raw', 'edit', 'db', 'display', 'attribute' and
* 'js'. The 'display' context is used by default. 'attribute' and 'js' contexts
@@ -2264,24 +2369,24 @@
* @param string $field The Post Object field name.
* @param mixed $value The Post Object value.
* @param int $post_id Post ID.
- * @param string $context Optional. How to sanitize post fields. Looks for 'raw', 'edit',
+ * @param string $context Optional. How to sanitize the field. Possible values are 'raw', 'edit',
* 'db', 'display', 'attribute' and 'js'. Default 'display'.
* @return mixed Sanitized value.
*/
function sanitize_post_field( $field, $value, $post_id, $context = 'display' ) {
$int_fields = array( 'ID', 'post_parent', 'menu_order' );
- if ( in_array( $field, $int_fields ) ) {
+ if ( in_array( $field, $int_fields, true ) ) {
$value = (int) $value;
}
// Fields which contain arrays of integers.
$array_int_fields = array( 'ancestors' );
- if ( in_array( $field, $array_int_fields ) ) {
+ if ( in_array( $field, $array_int_fields, true ) ) {
$value = array_map( 'absint', $value );
return $value;
}
- if ( 'raw' == $context ) {
+ if ( 'raw' === $context ) {
return $value;
}
@@ -2291,7 +2396,7 @@
$field_no_prefix = str_replace( 'post_', '', $field );
}
- if ( 'edit' == $context ) {
+ if ( 'edit' === $context ) {
$format_to_edit = array( 'post_content', 'post_excerpt', 'post_title', 'post_password' );
if ( $prefixed ) {
@@ -2325,8 +2430,8 @@
$value = apply_filters( "edit_post_{$field}", $value, $post_id );
}
- if ( in_array( $field, $format_to_edit ) ) {
- if ( 'post_content' == $field ) {
+ if ( in_array( $field, $format_to_edit, true ) ) {
+ if ( 'post_content' === $field ) {
$value = format_to_edit( $value, user_can_richedit() );
} else {
$value = format_to_edit( $value );
@@ -2334,7 +2439,7 @@
} else {
$value = esc_attr( $value );
}
- } elseif ( 'db' == $context ) {
+ } elseif ( 'db' === $context ) {
if ( $prefixed ) {
/**
@@ -2391,7 +2496,7 @@
* @param mixed $value Value of the prefixed post field.
* @param int $post_id Post ID.
* @param string $context Context for how to sanitize the field. Possible
- * values include 'raw', 'edit', 'db', 'display',
+ * values include 'edit', 'display',
* 'attribute' and 'js'.
*/
$value = apply_filters( "{$field}", $value, $post_id, $context );
@@ -2399,9 +2504,9 @@
$value = apply_filters( "post_{$field}", $value, $post_id, $context );
}
- if ( 'attribute' == $context ) {
+ if ( 'attribute' === $context ) {
$value = esc_attr( $value );
- } elseif ( 'js' == $context ) {
+ } elseif ( 'js' === $context ) {
$value = esc_js( $value );
}
}
@@ -2419,13 +2524,16 @@
* @param int $post_id Post ID.
*/
function stick_post( $post_id ) {
+ $post_id = (int) $post_id;
$stickies = get_option( 'sticky_posts' );
if ( ! is_array( $stickies ) ) {
- $stickies = array( $post_id );
- }
-
- if ( ! in_array( $post_id, $stickies ) ) {
+ $stickies = array();
+ }
+
+ $stickies = array_map( 'intval', $stickies );
+
+ if ( ! in_array( $post_id, $stickies, true ) ) {
$stickies[] = $post_id;
}
@@ -2453,17 +2561,20 @@
* @param int $post_id Post ID.
*/
function unstick_post( $post_id ) {
+ $post_id = (int) $post_id;
$stickies = get_option( 'sticky_posts' );
if ( ! is_array( $stickies ) ) {
return;
}
- if ( ! in_array( $post_id, $stickies ) ) {
+ $stickies = array_map( 'intval', $stickies );
+
+ if ( ! in_array( $post_id, $stickies, true ) ) {
return;
}
- $offset = array_search( $post_id, $stickies );
+ $offset = array_search( $post_id, $stickies, true );
if ( false === $offset ) {
return;
}
@@ -2496,12 +2607,15 @@
*/
function _count_posts_cache_key( $type = 'post', $perm = '' ) {
$cache_key = 'posts-' . $type;
- if ( 'readable' == $perm && is_user_logged_in() ) {
+
+ if ( 'readable' === $perm && is_user_logged_in() ) {
$post_type_object = get_post_type_object( $type );
+
if ( $post_type_object && ! current_user_can( $post_type_object->cap->read_private_posts ) ) {
$cache_key .= '_' . $perm . '_' . get_current_user_id();
}
}
+
return $cache_key;
}
@@ -2535,12 +2649,20 @@
$counts = wp_cache_get( $cache_key, 'counts' );
if ( false !== $counts ) {
+ // We may have cached this before every status was registered.
+ foreach ( get_post_stati() as $status ) {
+ if ( ! isset( $counts->{$status} ) ) {
+ $counts->{$status} = 0;
+ }
+ }
+
/** This filter is documented in wp-includes/post.php */
return apply_filters( 'wp_count_posts', $counts, $type, $perm );
}
$query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s";
- if ( 'readable' == $perm && is_user_logged_in() ) {
+
+ if ( 'readable' === $perm && is_user_logged_in() ) {
$post_type_object = get_post_type_object( $type );
if ( ! current_user_can( $post_type_object->cap->read_private_posts ) ) {
$query .= $wpdb->prepare(
@@ -2549,6 +2671,7 @@
);
}
}
+
$query .= ' GROUP BY post_status';
$results = (array) $wpdb->get_results( $wpdb->prepare( $query, $type ), ARRAY_A );
@@ -2620,16 +2743,96 @@
* Get default post mime types.
*
* @since 2.9.0
+ * @since 5.3.0 Added the 'Documents', 'Spreadsheets', and 'Archives' mime type groups.
*
* @return array List of post mime types.
*/
function get_post_mime_types() {
- $post_mime_types = array( // array( adj, noun )
- 'image' => array( __( 'Images' ), __( 'Manage Images' ), _n_noop( 'Image (%s)', 'Images (%s)' ) ),
- 'audio' => array( __( 'Audio' ), __( 'Manage Audio' ), _n_noop( 'Audio (%s)', 'Audio (%s)' ) ),
- 'video' => array( __( 'Video' ), __( 'Manage Video' ), _n_noop( 'Video (%s)', 'Video (%s)' ) ),
+ $post_mime_types = array( // array( adj, noun )
+ 'image' => array(
+ __( 'Images' ),
+ __( 'Manage Images' ),
+ /* translators: %s: Number of images. */
+ _n_noop(
+ 'Image (%s)',
+ 'Images (%s)'
+ ),
+ ),
+ 'audio' => array(
+ __( 'Audio' ),
+ __( 'Manage Audio' ),
+ /* translators: %s: Number of audio files. */
+ _n_noop(
+ 'Audio (%s)',
+ 'Audio (%s)'
+ ),
+ ),
+ 'video' => array(
+ __( 'Video' ),
+ __( 'Manage Video' ),
+ /* translators: %s: Number of video files. */
+ _n_noop(
+ 'Video (%s)',
+ 'Video (%s)'
+ ),
+ ),
+ 'document' => array(
+ __( 'Documents' ),
+ __( 'Manage Documents' ),
+ /* translators: %s: Number of documents. */
+ _n_noop(
+ 'Document (%s)',
+ 'Documents (%s)'
+ ),
+ ),
+ 'spreadsheet' => array(
+ __( 'Spreadsheets' ),
+ __( 'Manage Spreadsheets' ),
+ /* translators: %s: Number of spreadsheets. */
+ _n_noop(
+ 'Spreadsheet (%s)',
+ 'Spreadsheets (%s)'
+ ),
+ ),
+ 'archive' => array(
+ _x( 'Archives', 'file type group' ),
+ __( 'Manage Archives' ),
+ /* translators: %s: Number of archives. */
+ _n_noop(
+ 'Archive (%s)',
+ 'Archives (%s)'
+ ),
+ ),
);
+ $ext_types = wp_get_ext_types();
+ $mime_types = wp_get_mime_types();
+
+ foreach ( $post_mime_types as $group => $labels ) {
+ if ( in_array( $group, array( 'image', 'audio', 'video' ), true ) ) {
+ continue;
+ }
+
+ if ( ! isset( $ext_types[ $group ] ) ) {
+ unset( $post_mime_types[ $group ] );
+ continue;
+ }
+
+ $group_mime_types = array();
+ foreach ( $ext_types[ $group ] as $extension ) {
+ foreach ( $mime_types as $exts => $mime ) {
+ if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
+ $group_mime_types[] = $mime;
+ break;
+ }
+ }
+ }
+ $group_mime_types = implode( ',', array_unique( $group_mime_types ) );
+
+ $post_mime_types[ $group_mime_types ] = $labels;
+ unset( $post_mime_types[ $group ] );
+ }
+
/**
* Filters the default list of post mime types.
*
@@ -2669,8 +2872,10 @@
foreach ( (array) $wildcard_mime_types as $type ) {
$mimes = array_map( 'trim', explode( ',', $type ) );
foreach ( $mimes as $mime ) {
- $regex = str_replace( '__wildcard__', $wild, preg_quote( str_replace( '*', '__wildcard__', $mime ) ) );
+ $regex = str_replace( '__wildcard__', $wild, preg_quote( str_replace( '*', '__wildcard__', $mime ) ) );
+
$patternses[][ $type ] = "^$regex$";
+
if ( false === strpos( $mime, '/' ) ) {
$patternses[][ $type ] = "^$regex/";
$patternses[][ $type ] = $regex;
@@ -2682,12 +2887,15 @@
foreach ( $patternses as $patterns ) {
foreach ( $patterns as $type => $pattern ) {
foreach ( (array) $real_mime_types as $real ) {
- if ( preg_match( "#$pattern#", $real ) && ( empty( $matches[ $type ] ) || false === array_search( $real, $matches[ $type ] ) ) ) {
+ if ( preg_match( "#$pattern#", $real )
+ && ( empty( $matches[ $type ] ) || false === array_search( $real, $matches[ $type ], true ) )
+ ) {
$matches[ $type ][] = $real;
}
}
}
}
+
return $matches;
}
@@ -2732,7 +2940,7 @@
$mime_pattern = preg_replace( '/\*+/', '%', $mime_pattern );
- if ( in_array( $mime_type, $wildcards ) ) {
+ if ( in_array( $mime_type, $wildcards, true ) ) {
return '';
}
@@ -2742,9 +2950,11 @@
$wheres[] = empty( $table_alias ) ? "post_mime_type = '$mime_pattern'" : "$table_alias.post_mime_type = '$mime_pattern'";
}
}
+
if ( ! empty( $wheres ) ) {
$where = ' AND (' . join( ' OR ', $wheres ) . ') ';
}
+
return $where;
}
@@ -2755,8 +2965,8 @@
* it is deleted also. This includes comments, post meta fields, and terms
* associated with the post.
*
- * The post or page is moved to trash instead of permanently deleted unless
- * trash is disabled, item is already in the trash, or $force_delete is true.
+ * The post or page is moved to Trash instead of permanently deleted unless
+ * Trash is disabled, item is already in the Trash, or $force_delete is true.
*
* @since 1.0.0
*
@@ -2765,7 +2975,7 @@
* @see wp_trash_post()
*
* @param int $postid Optional. Post ID. Default 0.
- * @param bool $force_delete Optional. Whether to bypass trash and force deletion.
+ * @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.
*/
@@ -2793,9 +3003,9 @@
*
* @since 4.4.0
*
- * @param bool $delete Whether to go forward with deletion.
- * @param WP_Post $post Post object.
- * @param bool $force_delete Whether to bypass the trash.
+ * @param bool|null $delete Whether to go forward with deletion.
+ * @param WP_Post $post Post object.
+ * @param bool $force_delete Whether to bypass the Trash.
*/
$check = apply_filters( 'pre_delete_post', null, $post, $force_delete );
if ( null !== $check ) {
@@ -2806,12 +3016,14 @@
* Fires before a post is deleted, at the start of wp_delete_post().
*
* @since 3.2.0
+ * @since 5.5.0 Added the `$post` parameter.
*
* @see wp_delete_post()
*
- * @param int $postid Post ID.
+ * @param int $postid Post ID.
+ * @param WP_Post $post Post object.
*/
- do_action( 'before_delete_post', $postid );
+ do_action( 'before_delete_post', $postid, $post );
delete_post_meta( $postid, '_wp_trash_meta_status' );
delete_post_meta( $postid, '_wp_trash_meta_time' );
@@ -2858,10 +3070,13 @@
* 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 int $postid Post ID.
+ * @param WP_Post $post Post object.
*/
- do_action( 'delete_post', $postid );
+ do_action( 'delete_post', $postid, $post );
+
$result = $wpdb->delete( $wpdb->posts, array( 'ID' => $postid ) );
if ( ! $result ) {
return false;
@@ -2871,10 +3086,12 @@
* 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 int $postid Post ID.
+ * @param WP_Post $post Post object.
*/
- do_action( 'deleted_post', $postid );
+ do_action( 'deleted_post', $postid, $post );
clean_post_cache( $post );
@@ -2890,12 +3107,14 @@
* Fires after a post is deleted, at the conclusion of wp_delete_post().
*
* @since 3.2.0
+ * @since 5.5.0 Added the `$post` parameter.
*
* @see wp_delete_post()
*
- * @param int $postid Post ID.
+ * @param int $postid Post ID.
+ * @param WP_Post $post Post object.
*/
- do_action( 'after_delete_post', $postid );
+ do_action( 'after_delete_post', $postid, $post );
return $post;
}
@@ -2913,26 +3132,28 @@
*/
function _reset_front_page_settings_for_post( $post_id ) {
$post = get_post( $post_id );
- if ( 'page' == $post->post_type ) {
+
+ if ( 'page' === $post->post_type ) {
/*
- * If the page is defined in option page_on_front or post_for_posts,
- * adjust the corresponding options.
- */
+ * If the page is defined in option page_on_front or post_for_posts,
+ * adjust the corresponding options.
+ */
if ( get_option( 'page_on_front' ) == $post->ID ) {
update_option( 'show_on_front', 'posts' );
update_option( 'page_on_front', 0 );
}
if ( get_option( 'page_for_posts' ) == $post->ID ) {
- delete_option( 'page_for_posts', 0 );
+ update_option( 'page_for_posts', 0 );
}
}
+
unstick_post( $post->ID );
}
/**
* Move a post or page to the Trash
*
- * If trash is disabled, the post or page is permanently deleted.
+ * If Trash is disabled, the post or page is permanently deleted.
*
* @since 2.9.0
*
@@ -2962,8 +3183,8 @@
*
* @since 4.9.0
*
- * @param bool $trash Whether to go forward with trashing.
- * @param WP_Post $post Post object.
+ * @param bool|null $trash Whether to go forward with trashing.
+ * @param WP_Post $post Post object.
*/
$check = apply_filters( 'pre_trash_post', null, $post );
if ( null !== $check ) {
@@ -2971,7 +3192,7 @@
}
/**
- * Fires before a post is sent to the trash.
+ * Fires before a post is sent to the Trash.
*
* @since 3.3.0
*
@@ -2982,17 +3203,21 @@
add_post_meta( $post_id, '_wp_trash_meta_status', $post->post_status );
add_post_meta( $post_id, '_wp_trash_meta_time', time() );
- wp_update_post(
+ $post_updated = wp_update_post(
array(
'ID' => $post_id,
'post_status' => 'trash',
)
);
+ if ( ! $post_updated ) {
+ return false;
+ }
+
wp_trash_post_comments( $post_id );
/**
- * Fires after a post is sent to the trash.
+ * Fires after a post is sent to the Trash.
*
* @since 2.9.0
*
@@ -3027,8 +3252,8 @@
*
* @since 4.9.0
*
- * @param bool $untrash Whether to go forward with untrashing.
- * @param WP_Post $post Post object.
+ * @param bool|null $untrash Whether to go forward with untrashing.
+ * @param WP_Post $post Post object.
*/
$check = apply_filters( 'pre_untrash_post', null, $post );
if ( null !== $check ) {
@@ -3036,7 +3261,7 @@
}
/**
- * Fires before a post is restored from the trash.
+ * Fires before a post is restored from the Trash.
*
* @since 2.9.0
*
@@ -3049,17 +3274,21 @@
delete_post_meta( $post_id, '_wp_trash_meta_status' );
delete_post_meta( $post_id, '_wp_trash_meta_time' );
- wp_update_post(
+ $post_updated = wp_update_post(
array(
'ID' => $post_id,
'post_status' => $post_status,
)
);
+ if ( ! $post_updated ) {
+ return false;
+ }
+
wp_untrash_post_comments( $post_id );
/**
- * Fires after a post is restored from the trash.
+ * Fires after a post is restored from the Trash.
*
* @since 2.9.0
*
@@ -3071,7 +3300,7 @@
}
/**
- * Moves comments for a post to the trash.
+ * Moves comments for a post to the Trash.
*
* @since 2.9.0
*
@@ -3091,7 +3320,7 @@
$post_id = $post->ID;
/**
- * Fires before comments are sent to the trash.
+ * Fires before comments are sent to the Trash.
*
* @since 2.9.0
*
@@ -3117,7 +3346,7 @@
clean_comment_cache( array_keys( $statuses ) );
/**
- * Fires after comments are sent to the trash.
+ * Fires after comments are sent to the Trash.
*
* @since 2.9.0
*
@@ -3130,7 +3359,7 @@
}
/**
- * Restore comments for a post from the trash.
+ * Restore comments for a post from the Trash.
*
* @since 2.9.0
*
@@ -3156,7 +3385,7 @@
}
/**
- * Fires before comments are restored for a post from the trash.
+ * Fires before comments are restored for a post from the Trash.
*
* @since 2.9.0
*
@@ -3172,7 +3401,7 @@
foreach ( $group_by_status as $status => $comments ) {
// Sanity check. This shouldn't happen.
- if ( 'post-trashed' == $status ) {
+ if ( 'post-trashed' === $status ) {
$status = '0';
}
$comments_in = implode( ', ', array_map( 'intval', $comments ) );
@@ -3184,7 +3413,7 @@
delete_post_meta( $post_id, '_wp_trash_meta_comments_status' );
/**
- * Fires after comments are restored for a post from the trash.
+ * Fires after comments are restored for a post from the Trash.
*
* @since 2.9.0
*
@@ -3209,7 +3438,7 @@
* See WP_Term_Query::__construct() for supported arguments.
* @return array|WP_Error List of categories. If the `$fields` argument passed via `$args` is 'all' or
* 'all_with_object_id', an array of WP_Term objects will be returned. If `$fields`
- * is 'ids', an array of category ids. If `$fields` is 'names', an array of category names.
+ * is 'ids', an array of category IDs. If `$fields` is 'names', an array of category names.
* WP_Error object if 'category' taxonomy doesn't exist.
*/
function wp_get_post_categories( $post_id = 0, $args = array() ) {
@@ -3278,10 +3507,11 @@
* @see get_posts()
*
* @param array $args Optional. Arguments to retrieve posts. Default empty array.
- * @param string $output Optional. The required return type. One of OBJECT or ARRAY_A, which correspond to
- * a WP_Post object or an associative array, respectively. Default ARRAY_A.
- * @return array|false Array of recent posts, where the type of each element is determined by $output parameter.
- * Empty array on failure.
+ * @param string $output Optional. The required return type. One of OBJECT or ARRAY_A, which
+ * correspond to a WP_Post object or an associative array, respectively.
+ * Default ARRAY_A.
+ * @return array|false Array of recent posts, where the type of each element is determined
+ * by the `$output` parameter. Empty array on failure.
*/
function wp_get_recent_posts( $args = array(), $output = ARRAY_A ) {
@@ -3306,9 +3536,9 @@
'suppress_filters' => true,
);
- $r = wp_parse_args( $args, $defaults );
-
- $results = get_posts( $r );
+ $parsed_args = wp_parse_args( $args, $defaults );
+
+ $results = get_posts( $parsed_args );
// Backward compatibility. Prior to 3.1 expected posts to be returned in array.
if ( ARRAY_A == $output ) {
@@ -3385,6 +3615,9 @@
function wp_insert_post( $postarr, $wp_error = false ) {
global $wpdb;
+ // Capture original pre-sanitized array for passing into filters.
+ $unsanitized_postarr = $postarr;
+
$user_id = get_current_user_id();
$defaults = array(
@@ -3424,6 +3657,7 @@
// Get the post ID and GUID.
$post_ID = $postarr['ID'];
$post_before = get_post( $post_ID );
+
if ( is_null( $post_before ) ) {
if ( $wp_error ) {
return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) );
@@ -3442,6 +3676,7 @@
$post_title = $postarr['post_title'];
$post_content = $postarr['post_content'];
$post_excerpt = $postarr['post_excerpt'];
+
if ( isset( $postarr['post_name'] ) ) {
$post_name = $postarr['post_name'];
} elseif ( $update ) {
@@ -3462,8 +3697,8 @@
* 1. The post type supports the title, editor, and excerpt fields
* 2. The title, editor, and excerpt fields are all empty
*
- * Returning a truthy value to the filter will effectively short-circuit
- * the new post being inserted, returning 0. If $wp_error is true, a WP_Error
+ * Returning a truthy value from the filter will effectively short-circuit
+ * the new post being inserted and return 0. If $wp_error is true, a WP_Error
* will be returned instead.
*
* @since 3.3.0
@@ -3480,6 +3715,7 @@
}
$post_status = empty( $postarr['post_status'] ) ? 'draft' : $postarr['post_status'];
+
if ( 'attachment' === $post_type && ! in_array( $post_status, array( 'inherit', 'private', 'trash', 'auto-draft' ), true ) ) {
$post_status = 'inherit';
}
@@ -3490,9 +3726,9 @@
}
// Make sure we set a valid category.
- if ( empty( $post_category ) || 0 == count( $post_category ) || ! is_array( $post_category ) ) {
+ if ( empty( $post_category ) || 0 === count( $post_category ) || ! is_array( $post_category ) ) {
// 'post' requires at least one category.
- if ( 'post' == $post_type && 'auto-draft' != $post_status ) {
+ if ( 'post' === $post_type && 'auto-draft' !== $post_status ) {
$post_category = array( get_option( 'default_category' ) );
} else {
$post_category = array();
@@ -3517,7 +3753,7 @@
* an empty post name.
*/
if ( empty( $post_name ) ) {
- if ( ! in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) {
+ if ( ! in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ), true ) ) {
$post_name = sanitize_title( $post_title );
} else {
$post_name = '';
@@ -3525,6 +3761,7 @@
} else {
// 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 ) {
$post_name = $check_name;
} else { // new post, or slug has changed.
@@ -3536,8 +3773,8 @@
* If the post date is empty (due to having been new or a draft) and status
* is not 'draft' or 'pending', set date to now.
*/
- if ( empty( $postarr['post_date'] ) || '0000-00-00 00:00:00' == $postarr['post_date'] ) {
- if ( empty( $postarr['post_date_gmt'] ) || '0000-00-00 00:00:00' == $postarr['post_date_gmt'] ) {
+ if ( empty( $postarr['post_date'] ) || '0000-00-00 00:00:00' === $postarr['post_date'] ) {
+ if ( empty( $postarr['post_date_gmt'] ) || '0000-00-00 00:00:00' === $postarr['post_date_gmt'] ) {
$post_date = current_time( 'mysql' );
} else {
$post_date = get_date_from_gmt( $postarr['post_date_gmt'] );
@@ -3559,8 +3796,8 @@
}
}
- if ( empty( $postarr['post_date_gmt'] ) || '0000-00-00 00:00:00' == $postarr['post_date_gmt'] ) {
- if ( ! in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) {
+ if ( empty( $postarr['post_date_gmt'] ) || '0000-00-00 00:00:00' === $postarr['post_date_gmt'] ) {
+ if ( ! in_array( $post_status, get_post_stati( array( 'date_floating' => true ) ), true ) ) {
$post_date_gmt = get_gmt_from_date( $post_date );
} else {
$post_date_gmt = '0000-00-00 00:00:00';
@@ -3569,7 +3806,7 @@
$post_date_gmt = $postarr['post_date_gmt'];
}
- if ( $update || '0000-00-00 00:00:00' == $post_date ) {
+ if ( $update || '0000-00-00 00:00:00' === $post_date ) {
$post_modified = current_time( 'mysql' );
$post_modified_gmt = current_time( 'mysql', 1 );
} else {
@@ -3578,14 +3815,14 @@
}
if ( 'attachment' !== $post_type ) {
- if ( 'publish' == $post_status ) {
- $now = gmdate( 'Y-m-d H:i:59' );
- if ( mysql2date( 'U', $post_date_gmt, false ) > mysql2date( 'U', $now, false ) ) {
+ $now = gmdate( 'Y-m-d H:i:s' );
+
+ if ( 'publish' === $post_status ) {
+ if ( strtotime( $post_date_gmt ) - strtotime( $now ) >= MINUTE_IN_SECONDS ) {
$post_status = 'future';
}
- } elseif ( 'future' == $post_status ) {
- $now = gmdate( 'Y-m-d H:i:59' );
- if ( mysql2date( 'U', $post_date_gmt, false ) <= mysql2date( 'U', $now, false ) ) {
+ } elseif ( 'future' === $post_status ) {
+ if ( strtotime( $post_date_gmt ) - strtotime( $now ) < MINUTE_IN_SECONDS ) {
$post_status = 'publish';
}
}
@@ -3621,7 +3858,7 @@
}
$post_password = isset( $postarr['post_password'] ) ? $postarr['post_password'] : '';
- if ( 'private' == $post_status ) {
+ if ( 'private' === $post_status ) {
$post_password = '';
}
@@ -3656,6 +3893,7 @@
*/
if ( 'trash' === $previous_status && 'trash' !== $post_status ) {
$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' );
$post_name = $desired_post_slug;
@@ -3664,7 +3902,20 @@
// If a trashed post has the desired slug, change it and let this post have it.
if ( 'trash' !== $post_status && $post_name ) {
- wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_ID );
+ /**
+ * Filters whether or not to add a `__trashed` suffix to trashed posts that match the name of the updated post.
+ *
+ * @since 5.4.0
+ *
+ * @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.
+ */
+ $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 );
+ }
}
// When trashing an existing post, change its slug to allow non-trashed posts to use it.
@@ -3685,6 +3936,7 @@
foreach ( $emoji_fields as $emoji_field ) {
if ( isset( $data[ $emoji_field ] ) ) {
$charset = $wpdb->get_col_charset( $wpdb->posts, $emoji_field );
+
if ( 'utf8' === $charset ) {
$data[ $emoji_field ] = wp_encode_emoji( $data[ $emoji_field ] );
}
@@ -3696,22 +3948,29 @@
* Filters attachment post data before it is updated in or added to the database.
*
* @since 3.9.0
+ * @since 5.4.1 `$unsanitized_postarr` argument added.
*
- * @param array $data An array of sanitized attachment post data.
- * @param array $postarr An array of unsanitized attachment post data.
+ * @param array $data An array of slashed, sanitized, and processed attachment post data.
+ * @param array $postarr An array of slashed and sanitized attachment post data, but not processed.
+ * @param array $unsanitized_postarr An array of slashed yet *unsanitized* and unprocessed attachment post data
+ * as originally passed to wp_insert_post().
*/
- $data = apply_filters( 'wp_insert_attachment_data', $data, $postarr );
+ $data = apply_filters( 'wp_insert_attachment_data', $data, $postarr, $unsanitized_postarr );
} else {
/**
* Filters slashed post data just before it is inserted into the database.
*
* @since 2.7.0
+ * @since 5.4.1 `$unsanitized_postarr` argument added.
*
- * @param array $data An array of slashed post data.
- * @param array $postarr An array of sanitized, but otherwise unmodified post data.
+ * @param array $data An array of slashed, sanitized, and processed post data.
+ * @param array $postarr An array of sanitized (and slashed) but otherwise unmodified post data.
+ * @param array $unsanitized_postarr An array of slashed yet *unsanitized* and unprocessed post data as
+ * originally passed to wp_insert_post().
*/
- $data = apply_filters( 'wp_insert_post_data', $data, $postarr );
- }
+ $data = apply_filters( 'wp_insert_post_data', $data, $postarr, $unsanitized_postarr );
+ }
+
$data = wp_unslash( $data );
$where = array( 'ID' => $post_ID );
@@ -3725,9 +3984,16 @@
* @param array $data Array of unslashed post data.
*/
do_action( 'pre_post_update', $post_ID, $data );
+
if ( false === $wpdb->update( $wpdb->posts, $data, $where ) ) {
if ( $wp_error ) {
- return new WP_Error( 'db_update_error', __( 'Could not update post in the database' ), $wpdb->last_error );
+ if ( 'attachment' === $post_type ) {
+ $message = __( 'Could not update attachment in the database.' );
+ } else {
+ $message = __( 'Could not update post in the database.' );
+ }
+
+ return new WP_Error( 'db_update_error', $message, $wpdb->last_error );
} else {
return 0;
}
@@ -3736,25 +4002,35 @@
// If there is a suggested ID, use it if not already present.
if ( ! empty( $import_id ) ) {
$import_id = (int) $import_id;
+
if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE ID = %d", $import_id ) ) ) {
$data['ID'] = $import_id;
}
}
+
if ( false === $wpdb->insert( $wpdb->posts, $data ) ) {
if ( $wp_error ) {
- return new WP_Error( 'db_insert_error', __( 'Could not insert post into the database' ), $wpdb->last_error );
+ if ( 'attachment' === $post_type ) {
+ $message = __( 'Could not insert attachment into the database.' );
+ } else {
+ $message = __( 'Could not insert post into the database.' );
+ }
+
+ return new WP_Error( 'db_insert_error', $message, $wpdb->last_error );
} else {
return 0;
}
}
+
$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' ) ) ) {
+ 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 );
+
$wpdb->update( $wpdb->posts, array( 'post_name' => $data['post_name'] ), $where );
clean_post_cache( $post_ID );
}
@@ -3767,12 +4043,40 @@
wp_set_post_tags( $post_ID, $postarr['tags_input'] );
}
+ // Add default term for all associated custom taxonomies.
+ if ( 'auto-draft' !== $post_status ) {
+ foreach ( get_object_taxonomies( $post_type, 'object' ) as $taxonomy => $tax_object ) {
+
+ if ( ! empty( $tax_object->default_term ) ) {
+
+ // Filter out empty terms.
+ if ( isset( $postarr['tax_input'] ) && is_array( $postarr['tax_input'][ $taxonomy ] ) ) {
+ $postarr['tax_input'][ $taxonomy ] = array_filter( $postarr['tax_input'][ $taxonomy ] );
+ }
+
+ // Passed custom taxonomy list overwrites the existing list if not empty.
+ $terms = wp_get_object_terms( $post_ID, $taxonomy, array( 'fields' => 'ids' ) );
+ if ( ! empty( $terms ) && empty( $postarr['tax_input'][ $taxonomy ] ) ) {
+ $postarr['tax_input'][ $taxonomy ] = $terms;
+ }
+
+ if ( empty( $postarr['tax_input'][ $taxonomy ] ) ) {
+ $default_term_id = get_option( 'default_term_' . $taxonomy );
+ if ( ! empty( $default_term_id ) ) {
+ $postarr['tax_input'][ $taxonomy ] = array( (int) $default_term_id );
+ }
+ }
+ }
+ }
+ }
+
// New-style support for all custom taxonomies.
if ( ! empty( $postarr['tax_input'] ) ) {
foreach ( $postarr['tax_input'] as $taxonomy => $tags ) {
$taxonomy_obj = get_taxonomy( $taxonomy );
+
if ( ! $taxonomy_obj ) {
- /* translators: %s: taxonomy name */
+ /* translators: %s: Taxonomy name. */
_doing_it_wrong( __FUNCTION__, sprintf( __( 'Invalid taxonomy: %s.' ), $taxonomy ), '4.4.0' );
continue;
}
@@ -3781,6 +4085,7 @@
if ( is_array( $tags ) ) {
$tags = array_filter( $tags );
}
+
if ( current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
wp_set_post_terms( $post_ID, $tags, $taxonomy );
}
@@ -3796,7 +4101,7 @@
$current_guid = get_post_field( 'guid', $post_ID );
// Set GUID.
- if ( ! $update && '' == $current_guid ) {
+ if ( ! $update && '' === $current_guid ) {
$wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_ID ) ), $where );
}
@@ -3813,6 +4118,7 @@
// Set or remove featured image.
if ( isset( $postarr['_thumbnail_id'] ) ) {
$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 ) ) {
$thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' );
@@ -3838,10 +4144,12 @@
if ( ! empty( $postarr['page_template'] ) ) {
$post->page_template = $postarr['page_template'];
$page_templates = wp_get_theme()->get_page_templates( $post );
- if ( 'default' != $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) {
+
+ if ( 'default' !== $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) {
if ( $wp_error ) {
return new WP_Error( 'invalid_page_template', __( 'Invalid page template.' ) );
}
+
update_post_meta( $post_ID, '_wp_page_template', 'default' );
} else {
update_post_meta( $post_ID, '_wp_page_template', $postarr['page_template'] );
@@ -3860,6 +4168,7 @@
* @param int $post_ID Attachment ID.
*/
do_action( 'edit_attachment', $post_ID );
+
$post_after = get_post( $post_ID );
/**
@@ -3935,7 +4244,7 @@
*
* @param int $post_ID Post ID.
* @param WP_Post $post Post object.
- * @param bool $update Whether this is an existing post being updated or not.
+ * @param bool $update Whether this is an existing post being updated.
*/
do_action( "save_post_{$post->post_type}", $post_ID, $post, $update );
@@ -3946,7 +4255,7 @@
*
* @param int $post_ID Post ID.
* @param WP_Post $post Post object.
- * @param bool $update Whether this is an existing post being updated or not.
+ * @param bool $update Whether this is an existing post being updated.
*/
do_action( 'save_post', $post_ID, $post, $update );
@@ -3957,7 +4266,7 @@
*
* @param int $post_ID Post ID.
* @param WP_Post $post Post object.
- * @param bool $update Whether this is an existing post being updated or not.
+ * @param bool $update Whether this is an existing post being updated.
*/
do_action( 'wp_insert_post', $post_ID, $post, $update );
@@ -3975,7 +4284,7 @@
* @param array|object $postarr Optional. Post data. Arrays are expected to be escaped,
* objects are not. Default array.
* @param bool $wp_error Optional. Allow return of WP_Error on failure. Default false.
- * @return int|WP_Error The value 0 or WP_Error on failure. The post ID on success.
+ * @return int|WP_Error The post ID on success. The value 0 or WP_Error on failure.
*/
function wp_update_post( $postarr = array(), $wp_error = false ) {
if ( is_object( $postarr ) ) {
@@ -3999,15 +4308,18 @@
// Passed post category list overwrites existing category list if not empty.
if ( isset( $postarr['post_category'] ) && is_array( $postarr['post_category'] )
- && 0 != count( $postarr['post_category'] ) ) {
+ && count( $postarr['post_category'] ) > 0
+ ) {
$post_cats = $postarr['post_category'];
} else {
$post_cats = $post['post_category'];
}
// Drafts shouldn't be assigned a date unless explicitly done so by the user.
- if ( isset( $post['post_status'] ) && in_array( $post['post_status'], array( 'draft', 'pending', 'auto-draft' ) ) && empty( $postarr['edit_date'] ) &&
- ( '0000-00-00 00:00:00' == $post['post_date_gmt'] ) ) {
+ if ( isset( $post['post_status'] )
+ && in_array( $post['post_status'], array( 'draft', 'pending', 'auto-draft' ), true )
+ && empty( $postarr['edit_date'] ) && ( '0000-00-00 00:00:00' === $post['post_date_gmt'] )
+ ) {
$clear_date = true;
} else {
$clear_date = false;
@@ -4021,10 +4333,24 @@
$postarr['post_date_gmt'] = '';
}
- if ( $postarr['post_type'] == 'attachment' ) {
+ if ( 'attachment' === $postarr['post_type'] ) {
return wp_insert_attachment( $postarr, false, 0, $wp_error );
}
+ // Discard 'tags_input' parameter if it's the same as existing post tags.
+ if ( isset( $postarr['tags_input'] ) && is_object_in_taxonomy( $postarr['post_type'], 'post_tag' ) ) {
+ $tags = get_the_terms( $postarr['ID'], 'post_tag' );
+ $tag_names = array();
+
+ if ( $tags && ! is_wp_error( $tags ) ) {
+ $tag_names = wp_list_pluck( $tags, 'name' );
+ }
+
+ if ( $postarr['tags_input'] === $tag_names ) {
+ unset( $postarr['tags_input'] );
+ }
+ }
+
return wp_insert_post( $postarr, $wp_error );
}
@@ -4040,11 +4366,12 @@
function wp_publish_post( $post ) {
global $wpdb;
- if ( ! $post = get_post( $post ) ) {
+ $post = get_post( $post );
+ if ( ! $post ) {
return;
}
- if ( 'publish' == $post->post_status ) {
+ if ( 'publish' === $post->post_status ) {
return;
}
@@ -4089,7 +4416,7 @@
return;
}
- if ( 'future' != $post->post_status ) {
+ if ( 'future' !== $post->post_status ) {
return;
}
@@ -4097,7 +4424,7 @@
// 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_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;
}
@@ -4111,8 +4438,8 @@
*
* @since 2.8.0
*
- * @global wpdb $wpdb WordPress database abstraction object.
- * @global WP_Rewrite $wp_rewrite
+ * @global wpdb $wpdb WordPress database abstraction object.
+ * @global WP_Rewrite $wp_rewrite WordPress rewrite component.
*
* @param string $slug The desired slug (post_name).
* @param int $post_ID Post ID.
@@ -4122,7 +4449,9 @@
* @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 ) {
- if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) || ( 'inherit' == $post_status && 'revision' == $post_type ) || 'user_request' === $post_type ) {
+ if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ), true )
+ || ( 'inherit' === $post_status && 'revision' === $post_type ) || 'user_request' === $post_type
+ ) {
return $slug;
}
@@ -4134,12 +4463,12 @@
*
* @since 5.1.0
*
- * @param string $override_slug Short-circuit return value.
- * @param string $slug The desired slug (post_name).
- * @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|null $override_slug Short-circuit return value.
+ * @param string $slug The desired slug (post_name).
+ * @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 );
if ( null !== $override_slug ) {
@@ -4155,7 +4484,7 @@
$feeds = array();
}
- if ( 'attachment' == $post_type ) {
+ 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 ) );
@@ -4168,7 +4497,12 @@
* @param bool $bad_slug Whether the slug would be bad as an attachment slug.
* @param string $slug The post slug.
*/
- if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug ) ) {
+ $is_bad_attachment_slug = apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug );
+
+ if ( $post_name_check
+ || in_array( $slug, $feeds, true ) || 'embed' === $slug
+ || $is_bad_attachment_slug
+ ) {
$suffix = 2;
do {
$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
@@ -4178,7 +4512,7 @@
$slug = $alt_post_name;
}
} elseif ( is_post_type_hierarchical( $post_type ) ) {
- if ( 'nav_menu_item' == $post_type ) {
+ if ( 'nav_menu_item' === $post_type ) {
return $slug;
}
@@ -4199,7 +4533,13 @@
* @param string $post_type Post type.
* @param int $post_parent Post parent ID.
*/
- if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug ) || apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent ) ) {
+ $is_bad_hierarchical_slug = apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent );
+
+ if ( $post_name_check
+ || in_array( $slug, $feeds, true ) || 'embed' === $slug
+ || preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug )
+ || $is_bad_hierarchical_slug
+ ) {
$suffix = 2;
do {
$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
@@ -4213,25 +4553,30 @@
$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 );
+
// Prevent new post slugs that could result in URLs that conflict with date archives.
- $post = get_post( $post_ID );
$conflicts_with_date_archive = false;
- if ( 'post' === $post_type && ( ! $post || $post->post_name !== $slug ) && preg_match( '/^[0-9]+$/', $slug ) && $slug_num = intval( $slug ) ) {
- $permastructs = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) );
- $postname_index = array_search( '%postname%', $permastructs );
-
- /*
- * Potential date clashes are as follows:
- *
- * - Any integer in the first permastruct position could be a year.
- * - An integer between 1 and 12 that follows 'year' conflicts with 'monthnum'.
- * - An integer between 1 and 31 that follows 'monthnum' conflicts with 'day'.
- */
- if ( 0 === $postname_index ||
- ( $postname_index && '%year%' === $permastructs[ $postname_index - 1 ] && 13 > $slug_num ) ||
- ( $postname_index && '%monthnum%' === $permastructs[ $postname_index - 1 ] && 32 > $slug_num )
- ) {
- $conflicts_with_date_archive = true;
+ if ( 'post' === $post_type && ( ! $post || $post->post_name !== $slug ) && preg_match( '/^[0-9]+$/', $slug ) ) {
+ $slug_num = intval( $slug );
+
+ if ( $slug_num ) {
+ $permastructs = array_values( array_filter( explode( '/', get_option( 'permalink_structure' ) ) ) );
+ $postname_index = array_search( '%postname%', $permastructs, true );
+
+ /*
+ * Potential date clashes are as follows:
+ *
+ * - Any integer in the first permastruct position could be a year.
+ * - An integer between 1 and 12 that follows 'year' conflicts with 'monthnum'.
+ * - An integer between 1 and 31 that follows 'monthnum' conflicts with 'day'.
+ */
+ if ( 0 === $postname_index ||
+ ( $postname_index && '%year%' === $permastructs[ $postname_index - 1 ] && 13 > $slug_num ) ||
+ ( $postname_index && '%monthnum%' === $permastructs[ $postname_index - 1 ] && 32 > $slug_num )
+ ) {
+ $conflicts_with_date_archive = true;
+ }
}
}
@@ -4244,7 +4589,13 @@
* @param string $slug The post slug.
* @param string $post_type Post type.
*/
- if ( $post_name_check || in_array( $slug, $feeds ) || 'embed' === $slug || $conflicts_with_date_archive || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
+ $is_bad_flat_slug = apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type );
+
+ if ( $post_name_check
+ || in_array( $slug, $feeds, true ) || 'embed' === $slug
+ || $conflicts_with_date_archive
+ || $is_bad_flat_slug
+ ) {
$suffix = 2;
do {
$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
@@ -4379,8 +4730,7 @@
/**
* Set categories for a post.
*
- * If the post categories parameter is not set, then the default category is
- * going used.
+ * If no categories are provided, the default category is used.
*
* @since 2.1.0
*
@@ -4396,16 +4746,33 @@
$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:
+
+ // If $post_categories isn't already an array, make it one.
$post_categories = (array) $post_categories;
+
if ( empty( $post_categories ) ) {
- if ( 'post' == $post_type && 'auto-draft' != $post_status ) {
+ /**
+ * Filters post types (in addition to 'post') that require a default category.
+ *
+ * @since 5.5.0
+ *
+ * @param string[] $post_types An array of post type names. Default empty array.
+ */
+ $default_category_post_types = apply_filters( 'default_category_post_types', array() );
+
+ // Regular posts always require a default category.
+ $default_category_post_types = array_merge( $default_category_post_types, array( 'post' ) );
+
+ if ( in_array( $post_type, $default_category_post_types, true )
+ && is_object_in_taxonomy( $post_type, 'category' )
+ && 'auto-draft' !== $post_status
+ ) {
$post_categories = array( get_option( 'default_category' ) );
$append = false;
} else {
$post_categories = array();
}
- } elseif ( 1 == count( $post_categories ) && '' == reset( $post_categories ) ) {
+ } elseif ( 1 === count( $post_categories ) && '' === reset( $post_categories ) ) {
return true;
}
@@ -4534,7 +4901,7 @@
* @since 1.5.0
*
* @param int $post_id Post ID.
- * @return array List of enclosures.
+ * @return string[] Array of enclosures for the given post.
*/
function get_enclosed( $post_id ) {
$custom_fields = get_post_custom( $post_id );
@@ -4544,7 +4911,7 @@
}
foreach ( $custom_fields as $key => $val ) {
- if ( 'enclosure' != $key || ! is_array( $val ) ) {
+ if ( 'enclosure' !== $key || ! is_array( $val ) ) {
continue;
}
foreach ( $val as $enc ) {
@@ -4558,8 +4925,8 @@
*
* @since 2.0.0
*
- * @param array $pung Array of enclosures for the given post.
- * @param int $post_id Post ID.
+ * @param string[] $pung Array of enclosures for the given post.
+ * @param int $post_id Post ID.
*/
return apply_filters( 'get_enclosed', $pung, $post_id );
}
@@ -4600,7 +4967,7 @@
* @since 4.7.0 `$post_id` can be a WP_Post object.
*
* @param int|WP_Post $post_id Post Object or ID
- * @return array
+ * @return string[]|false List of URLs yet to ping.
*/
function get_to_ping( $post_id ) {
$post = get_post( $post_id );
@@ -4617,7 +4984,7 @@
*
* @since 2.0.0
*
- * @param array $to_ping List of URLs yet to ping.
+ * @param string[] $to_ping List of URLs yet to ping.
*/
return apply_filters( 'get_to_ping', $to_ping );
}
@@ -4651,7 +5018,7 @@
}
//
-// Page functions
+// Page functions.
//
/**
@@ -4661,7 +5028,7 @@
*
* @global wpdb $wpdb WordPress database abstraction object.
*
- * @return array List of page IDs.
+ * @return string[] List of page IDs as strings.
*/
function get_all_page_ids() {
global $wpdb;
@@ -4683,12 +5050,13 @@
* @since 1.5.1
* @deprecated 3.5.0 Use get_post()
*
- * @param mixed $page Page object or page ID. Passed by reference.
- * @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 $filter Optional. How the return value should be filtered. Accepts 'raw',
- * 'edit', 'db', 'display'. Default 'raw'.
- * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
+ * @param int|WP_Post $page Page object or page ID. Passed by reference.
+ * @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 $filter Optional. How the return value should be filtered. Accepts 'raw',
+ * 'edit', 'db', 'display'. Default 'raw'.
+ * @return WP_Post|array|null WP_Post or array on success, null on failure.
*/
function get_page( $page, $output = OBJECT, $filter = 'raw' ) {
return get_post( $page, $output, $filter );
@@ -4702,8 +5070,9 @@
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param string $page_path Page path.
- * @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 $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.
*/
@@ -4762,7 +5131,7 @@
* Loop through the given path parts from right to left,
* ensuring each matches the post ancestry.
*/
- while ( $p->post_parent != 0 && isset( $pages[ $p->post_parent ] ) ) {
+ while ( 0 != $p->post_parent && isset( $pages[ $p->post_parent ] ) ) {
$count++;
$parent = $pages[ $p->post_parent ];
if ( ! isset( $revparts[ $count ] ) || $parent->post_name != $revparts[ $count ] ) {
@@ -4771,7 +5140,7 @@
$p = $parent;
}
- if ( $p->post_parent == 0 && $count + 1 == count( $revparts ) && $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;
@@ -4791,13 +5160,22 @@
/**
* 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 $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.
*/
@@ -4884,9 +5262,9 @@
*
* @since 2.0.0
*
- * @param array $pages Posts array (passed by reference).
- * @param int $page_id Optional. Parent page ID. Default 0.
- * @return array A list arranged by hierarchy. Children immediately follow their parents.
+ * @param WP_Post[] $pages Posts array (passed by reference).
+ * @param int $page_id Optional. Parent page ID. Default 0.
+ * @return string[] Array of post names keyed by ID and arranged by hierarchy. Children immediately follow their parents.
*/
function get_page_hierarchy( &$pages, $page_id = 0 ) {
if ( empty( $pages ) ) {
@@ -4915,9 +5293,9 @@
*
* @see _page_traverse_name()
*
- * @param int $page_id Page ID.
- * @param array $children Parent-children relations (passed by reference).
- * @param array $result Result (passed by reference).
+ * @param int $page_id Page ID.
+ * @param array $children Parent-children relations (passed by reference).
+ * @param string[] $result Array of page names keyed by ID (passed by reference).
*/
function _page_traverse_name( $page_id, &$children, &$result ) {
if ( isset( $children[ $page_id ] ) ) {
@@ -4934,7 +5312,7 @@
* Sub pages will be in the "directory" under the parent page post name.
*
* @since 1.5.0
- * @since 4.6.0 Converted the `$page` parameter to optional.
+ * @since 4.6.0 The `$page` parameter was made optional.
*
* @param WP_Post|object|int $page Optional. Page ID or WP_Post object. Default is global $post.
* @return string|false Page URI, false on error.
@@ -5031,21 +5409,21 @@
'post_status' => 'publish',
);
- $r = wp_parse_args( $args, $defaults );
-
- $number = (int) $r['number'];
- $offset = (int) $r['offset'];
- $child_of = (int) $r['child_of'];
- $hierarchical = $r['hierarchical'];
- $exclude = $r['exclude'];
- $meta_key = $r['meta_key'];
- $meta_value = $r['meta_value'];
- $parent = $r['parent'];
- $post_status = $r['post_status'];
+ $parsed_args = wp_parse_args( $args, $defaults );
+
+ $number = (int) $parsed_args['number'];
+ $offset = (int) $parsed_args['offset'];
+ $child_of = (int) $parsed_args['child_of'];
+ $hierarchical = $parsed_args['hierarchical'];
+ $exclude = $parsed_args['exclude'];
+ $meta_key = $parsed_args['meta_key'];
+ $meta_value = $parsed_args['meta_value'];
+ $parent = $parsed_args['parent'];
+ $post_status = $parsed_args['post_status'];
// Make sure the post type is hierarchical.
$hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) );
- if ( ! in_array( $r['post_type'], $hierarchical_post_types ) ) {
+ if ( ! in_array( $parsed_args['post_type'], $hierarchical_post_types, true ) ) {
return false;
}
@@ -5062,7 +5440,7 @@
}
// $args can be whatever, only use the args defined in defaults to compute the key.
- $key = md5( serialize( wp_array_slice_assoc( $r, array_keys( $defaults ) ) ) );
+ $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";
@@ -5071,19 +5449,19 @@
// 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, $r );
+ $pages = apply_filters( 'get_pages', $pages, $parsed_args );
return $pages;
}
$inclusions = '';
- if ( ! empty( $r['include'] ) ) {
- $child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include
+ 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( $r['include'] );
+ $incpages = wp_parse_id_list( $parsed_args['include'] );
if ( ! empty( $incpages ) ) {
$inclusions = ' AND ID IN (' . implode( ',', $incpages ) . ')';
}
@@ -5098,12 +5476,12 @@
}
$author_query = '';
- if ( ! empty( $r['authors'] ) ) {
- $post_authors = wp_parse_list( $r['authors'] );
+ if ( ! empty( $parsed_args['authors'] ) ) {
+ $post_authors = wp_parse_list( $parsed_args['authors'] );
if ( ! empty( $post_authors ) ) {
foreach ( $post_authors as $post_author ) {
- //Do we have an author id or an author login?
+ // Do we have an author id or an author login?
if ( 0 == intval( $post_author ) ) {
$post_author = get_user_by( 'login', $post_author );
if ( empty( $post_author ) ) {
@@ -5115,13 +5493,13 @@
$post_author = $post_author->ID;
}
- if ( '' == $author_query ) {
+ 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 ) {
+ if ( '' !== $author_query ) {
$author_query = " AND ($author_query)";
}
}
@@ -5132,7 +5510,7 @@
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 and meta_value might be slashed.
$meta_key = wp_unslash( $meta_key );
$meta_value = wp_unslash( $meta_value );
if ( '' !== $meta_key ) {
@@ -5152,11 +5530,11 @@
$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', $r['post_type'], reset( $post_status ) );
+ 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')", $r['post_type'] );
+ $where_post_type = $wpdb->prepare( "post_type = %s AND post_status IN ('$post_status')", $parsed_args['post_type'] );
}
$orderby_array = array();
@@ -5181,9 +5559,9 @@
'comment_count',
);
- foreach ( explode( ',', $r['sort_column'] ) as $orderby ) {
+ foreach ( explode( ',', $parsed_args['sort_column'] ) as $orderby ) {
$orderby = trim( $orderby );
- if ( ! in_array( $orderby, $allowed_keys ) ) {
+ if ( ! in_array( $orderby, $allowed_keys, true ) ) {
continue;
}
@@ -5212,8 +5590,8 @@
}
$sort_column = ! empty( $orderby_array ) ? implode( ',', $orderby_array ) : "$wpdb->posts.post_title";
- $sort_order = strtoupper( $r['sort_order'] );
- if ( '' !== $sort_order && ! in_array( $sort_order, array( 'ASC', 'DESC' ) ) ) {
+ $sort_order = strtoupper( $parsed_args['sort_order'] );
+ if ( '' !== $sort_order && ! in_array( $sort_order, array( 'ASC', 'DESC' ), true ) ) {
$sort_order = 'ASC';
}
@@ -5231,7 +5609,7 @@
wp_cache_set( $cache_key, array(), 'posts' );
/** This filter is documented in wp-includes/post.php */
- $pages = apply_filters( 'get_pages', array(), $r );
+ $pages = apply_filters( 'get_pages', array(), $parsed_args );
return $pages;
}
@@ -5248,8 +5626,8 @@
$pages = get_page_children( $child_of, $pages );
}
- if ( ! empty( $r['exclude_tree'] ) ) {
- $exclude = wp_parse_id_list( $r['exclude_tree'] );
+ if ( ! empty( $parsed_args['exclude_tree'] ) ) {
+ $exclude = wp_parse_id_list( $parsed_args['exclude_tree'] );
foreach ( $exclude as $id ) {
$children = get_page_children( $id, $pages );
foreach ( $children as $child ) {
@@ -5259,7 +5637,7 @@
$num_pages = count( $pages );
for ( $i = 0; $i < $num_pages; $i++ ) {
- if ( in_array( $pages[ $i ]->ID, $exclude ) ) {
+ if ( in_array( $pages[ $i ]->ID, $exclude, true ) ) {
unset( $pages[ $i ] );
}
}
@@ -5272,7 +5650,7 @@
wp_cache_set( $cache_key, $page_structure, 'posts' );
- // Convert to WP_Post instances
+ // Convert to WP_Post instances.
$pages = array_map( 'get_post', $pages );
/**
@@ -5280,14 +5658,14 @@
*
* @since 2.1.0
*
- * @param array $pages List of pages to retrieve.
- * @param array $r Array of get_pages() arguments.
+ * @param WP_Post[] $pages Array of page objects.
+ * @param array $parsed_args Array of get_pages() arguments.
*/
- return apply_filters( 'get_pages', $pages, $r );
+ return apply_filters( 'get_pages', $pages, $parsed_args );
}
//
-// Attachment functions
+// Attachment functions.
//
/**
@@ -5309,9 +5687,11 @@
if ( strpos( $url, home_url( '/?attachment_id=' ) ) !== false ) {
return true;
}
- if ( $id = url_to_postid( $url ) ) {
+
+ $id = url_to_postid( $url );
+ if ( $id ) {
$post = get_post( $id );
- if ( 'attachment' == $post->post_type ) {
+ if ( 'attachment' === $post->post_type ) {
return true;
}
}
@@ -5367,15 +5747,15 @@
* Deletion removes all post meta fields, taxonomy, comments, etc. associated
* with the attachment (except the main post).
*
- * The attachment is moved to the trash instead of permanently deleted unless trash
- * for media is disabled, item is already in the trash, or $force_delete is true.
+ * The attachment is moved to the Trash instead of permanently deleted unless Trash
+ * for media is disabled, item is already in the Trash, or $force_delete is true.
*
* @since 2.0.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param int $post_id Attachment ID.
- * @param bool $force_delete Optional. Whether to bypass trash and force deletion.
+ * @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.
*/
@@ -5398,6 +5778,20 @@
return wp_trash_post( $post_id );
}
+ /**
+ * Filters whether an attachment deletion should take place.
+ *
+ * @since 5.5.0
+ *
+ * @param bool|null $delete Whether to go forward with deletion.
+ * @param WP_Post $post Post object.
+ * @param bool $force_delete Whether to bypass the Trash.
+ */
+ $check = apply_filters( 'pre_delete_attachment', null, $post, $force_delete );
+ if ( null !== $check ) {
+ return $check;
+ }
+
delete_post_meta( $post_id, '_wp_trash_meta_status' );
delete_post_meta( $post_id, '_wp_trash_meta_time' );
@@ -5413,10 +5807,12 @@
* Fires before an attachment is deleted, at the start of wp_delete_attachment().
*
* @since 2.0.0
+ * @since 5.5.0 Added the `$post` parameter.
*
- * @param int $post_id Attachment ID.
+ * @param int $post_id Attachment ID.
+ * @param WP_Post $post Post object.
*/
- do_action( 'delete_attachment', $post_id );
+ do_action( 'delete_attachment', $post_id, $post );
wp_delete_object_term_relationships( $post_id, array( 'category', 'post_tag' ) );
wp_delete_object_term_relationships( $post_id, get_object_taxonomies( $post->post_type ) );
@@ -5439,13 +5835,13 @@
}
/** This action is documented in wp-includes/post.php */
- do_action( 'delete_post', $post_id );
+ do_action( 'delete_post', $post_id, $post );
$result = $wpdb->delete( $wpdb->posts, array( 'ID' => $post_id ) );
if ( ! $result ) {
return false;
}
/** This action is documented in wp-includes/post.php */
- do_action( 'deleted_post', $post_id );
+ do_action( 'deleted_post', $post_id, $post );
wp_delete_attachment_files( $post_id, $meta, $backup_sizes, $file );
@@ -5475,6 +5871,7 @@
// Don't delete the thumb if another attachment uses it.
if ( ! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like( $meta['thumb'] ) . '%', $post_id ) ) ) {
$thumbfile = str_replace( wp_basename( $file ), $meta['thumb'], $file );
+
if ( ! empty( $thumbfile ) ) {
$thumbfile = path_join( $uploadpath['basedir'], $thumbfile );
$thumbdir = path_join( $uploadpath['basedir'], dirname( $file ) );
@@ -5489,8 +5886,10 @@
// Remove intermediate and backup images if there are any.
if ( isset( $meta['sizes'] ) && is_array( $meta['sizes'] ) ) {
$intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) );
+
foreach ( $meta['sizes'] as $size => $sizeinfo ) {
$intermediate_file = str_replace( wp_basename( $file ), $sizeinfo['file'], $file );
+
if ( ! empty( $intermediate_file ) ) {
$intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file );
@@ -5501,10 +5900,28 @@
}
}
+ if ( ! empty( $meta['original_image'] ) ) {
+ if ( empty( $intermediate_dir ) ) {
+ $intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) );
+ }
+
+ $original_image = str_replace( wp_basename( $file ), $meta['original_image'], $file );
+
+ if ( ! empty( $original_image ) ) {
+ $original_image = path_join( $uploadpath['basedir'], $original_image );
+
+ if ( ! wp_delete_file_from_directory( $original_image, $intermediate_dir ) ) {
+ $deleted = false;
+ }
+ }
+ }
+
if ( is_array( $backup_sizes ) ) {
$del_dir = path_join( $uploadpath['basedir'], dirname( $meta['file'] ) );
+
foreach ( $backup_sizes as $size ) {
$del_file = path_join( dirname( $meta['file'] ), $size['file'] );
+
if ( ! empty( $del_file ) ) {
$del_file = path_join( $uploadpath['basedir'], $del_file );
@@ -5523,17 +5940,28 @@
}
/**
- * Retrieve attachment meta field for attachment ID.
+ * Retrieves attachment metadata for attachment ID.
*
* @since 2.1.0
*
* @param int $attachment_id Attachment post ID. Defaults to global $post.
* @param bool $unfiltered Optional. If true, filters are not run. Default false.
- * @return mixed Attachment meta field. False on failure.
+ * @return array|false {
+ * Attachment metadata. False on failure.
+ *
+ * @type int $width The width of the attachment.
+ * @type int $height The height of the attachment.
+ * @type string $file The file path relative to `wp-content/uploads`.
+ * @type array $sizes Keys are size slugs, each value is an array containing
+ * 'file', 'width', 'height', and 'mime-type'.
+ * @type array $image_meta Image metadata.
+ * }
*/
function wp_get_attachment_metadata( $attachment_id = 0, $unfiltered = false ) {
$attachment_id = (int) $attachment_id;
- if ( ! $post = get_post( $attachment_id ) ) {
+
+ $post = get_post( $attachment_id );
+ if ( ! $post ) {
return false;
}
@@ -5556,7 +5984,7 @@
}
/**
- * Update metadata for an attachment.
+ * Updates metadata for an attachment.
*
* @since 2.1.0
*
@@ -5566,7 +5994,9 @@
*/
function wp_update_attachment_metadata( $attachment_id, $data ) {
$attachment_id = (int) $attachment_id;
- if ( ! $post = get_post( $attachment_id ) ) {
+
+ $post = get_post( $attachment_id );
+ if ( ! $post ) {
return false;
}
@@ -5578,7 +6008,8 @@
* @param array $data Array of updated attachment meta data.
* @param int $attachment_id Attachment post ID.
*/
- if ( $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID ) ) {
+ $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID );
+ if ( $data ) {
return update_post_meta( $post->ID, '_wp_attachment_metadata', $data );
} else {
return delete_post_meta( $post->ID, '_wp_attachment_metadata' );
@@ -5597,25 +6028,29 @@
*/
function wp_get_attachment_url( $attachment_id = 0 ) {
$attachment_id = (int) $attachment_id;
- if ( ! $post = get_post( $attachment_id ) ) {
+
+ $post = get_post( $attachment_id );
+ if ( ! $post ) {
return false;
}
- if ( 'attachment' != $post->post_type ) {
+ if ( 'attachment' !== $post->post_type ) {
return false;
}
$url = '';
// Get attached file.
- if ( $file = get_post_meta( $post->ID, '_wp_attached_file', true ) ) {
+ $file = get_post_meta( $post->ID, '_wp_attached_file', true );
+ if ( $file ) {
// Get upload directory.
- if ( ( $uploads = wp_get_upload_dir() ) && false === $uploads['error'] ) {
+ $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'] ) ) {
// Replace file location with url location.
$url = str_replace( $uploads['basedir'], $uploads['baseurl'], $file );
} elseif ( false !== strpos( $file, 'wp-content/uploads' ) ) {
- // Get the directory name relative to the basedir (back compat for pre-2.7 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 {
// It's a newly-uploaded file, therefore $file is relative to the basedir.
@@ -5664,7 +6099,8 @@
*/
function wp_get_attachment_caption( $post_id = 0 ) {
$post_id = (int) $post_id;
- if ( ! $post = get_post( $post_id ) ) {
+ $post = get_post( $post_id );
+ if ( ! $post ) {
return false;
}
@@ -5695,25 +6131,31 @@
*/
function wp_get_attachment_thumb_file( $post_id = 0 ) {
$post_id = (int) $post_id;
- if ( ! $post = get_post( $post_id ) ) {
+ $post = get_post( $post_id );
+ if ( ! $post ) {
return false;
}
- if ( ! is_array( $imagedata = wp_get_attachment_metadata( $post->ID ) ) ) {
+
+ $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 ) ) && 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 );
+ 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;
}
@@ -5728,10 +6170,13 @@
*/
function wp_get_attachment_thumb_url( $post_id = 0 ) {
$post_id = (int) $post_id;
- if ( ! $post = get_post( $post_id ) ) {
+ $post = get_post( $post_id );
+ if ( ! $post ) {
return false;
}
- if ( ! $url = wp_get_attachment_url( $post->ID ) ) {
+
+ $url = wp_get_attachment_url( $post->ID );
+ if ( ! $url ) {
return false;
}
@@ -5740,7 +6185,8 @@
return $sized[0];
}
- if ( ! $thumb = wp_get_attachment_thumb_file( $post->ID ) ) {
+ $thumb = wp_get_attachment_thumb_file( $post->ID );
+ if ( ! $thumb ) {
return false;
}
@@ -5767,11 +6213,13 @@
* @return bool True if one of the accepted types, false otherwise.
*/
function wp_attachment_is( $type, $post = null ) {
- if ( ! $post = get_post( $post ) ) {
+ $post = get_post( $post );
+ if ( ! $post ) {
return false;
}
- if ( ! $file = get_attached_file( $post->ID ) ) {
+ $file = get_attached_file( $post->ID );
+ if ( ! $file ) {
return false;
}
@@ -5793,13 +6241,13 @@
switch ( $type ) {
case 'image':
$image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
- return in_array( $ext, $image_exts );
+ return in_array( $ext, $image_exts, true );
case 'audio':
- return in_array( $ext, wp_get_audio_extensions() );
+ return in_array( $ext, wp_get_audio_extensions(), true );
case 'video':
- return in_array( $ext, wp_get_video_extensions() );
+ return in_array( $ext, wp_get_video_extensions(), true );
default:
return $type === $ext;
@@ -5825,7 +6273,7 @@
}
/**
- * Retrieve the icon for a MIME type.
+ * Retrieve the icon for a MIME type or attachment.
*
* @since 2.1.0
*
@@ -5842,13 +6290,15 @@
$post_mimes = array();
if ( is_numeric( $mime ) ) {
$mime = (int) $mime;
- if ( $post = get_post( $mime ) ) {
+ $post = get_post( $mime );
+ if ( $post ) {
$post_id = (int) $post->ID;
$file = get_attached_file( $post_id );
$ext = preg_replace( '/^.+?\.([^.]+)$/', '$1', $file );
if ( ! empty( $ext ) ) {
$post_mimes[] = $ext;
- if ( $ext_type = wp_ext2type( $ext ) ) {
+ $ext_type = wp_ext2type( $ext );
+ if ( $ext_type ) {
$post_mimes[] = $ext_type;
}
}
@@ -5882,11 +6332,11 @@
$icon_dir_uri = apply_filters( 'icon_dir_uri', includes_url( 'images/media' ) );
/**
- * Filters the list of icon directory URIs.
+ * Filters the array of icon directory URIs.
*
* @since 2.5.0
*
- * @param array $uris List of icon directory URIs.
+ * @param string[] $uris Array of icon directory URIs keyed by directory absolute path.
*/
$dirs = apply_filters( 'icon_dirs', array( $icon_dir => $icon_dir_uri ) );
$icon_files = array();
@@ -5894,13 +6344,16 @@
$keys = array_keys( $dirs );
$dir = array_shift( $keys );
$uri = array_shift( $dirs );
- if ( $dh = opendir( $dir ) ) {
+ $dh = opendir( $dir );
+ if ( $dh ) {
while ( false !== $file = readdir( $dh ) ) {
$file = wp_basename( $file );
- if ( substr( $file, 0, 1 ) == '.' ) {
+ if ( '.' === substr( $file, 0, 1 ) ) {
continue;
}
- if ( ! in_array( strtolower( substr( $file, -4 ) ), array( '.png', '.gif', '.jpg' ) ) ) {
+
+ $ext = strtolower( substr( $file, -4 ) );
+ if ( ! in_array( $ext, array( '.png', '.gif', '.jpg' ), true ) ) {
if ( is_dir( "$dir/$file" ) ) {
$dirs[ "$dir/$file" ] = "$uri/$file";
}
@@ -5990,12 +6443,12 @@
$old_slugs = (array) get_post_meta( $post_id, '_wp_old_slug' );
// If we haven't added this old slug before, add it now.
- if ( ! empty( $post_before->post_name ) && ! in_array( $post_before->post_name, $old_slugs ) ) {
+ if ( ! empty( $post_before->post_name ) && ! in_array( $post_before->post_name, $old_slugs, true ) ) {
add_post_meta( $post_id, '_wp_old_slug', $post_before->post_name );
}
// If the new slug was used previously, delete it from the list.
- if ( in_array( $post->post_name, $old_slugs ) ) {
+ if ( in_array( $post->post_name, $old_slugs, true ) ) {
delete_post_meta( $post_id, '_wp_old_slug', $post->post_name );
}
}
@@ -6020,23 +6473,28 @@
* @param WP_Post $post_before The Previous Post Object
*/
function wp_check_for_changed_dates( $post_id, $post, $post_before ) {
- $previous_date = date( 'Y-m-d', strtotime( $post_before->post_date ) );
- $new_date = date( 'Y-m-d', strtotime( $post->post_date ) );
+ $previous_date = gmdate( 'Y-m-d', strtotime( $post_before->post_date ) );
+ $new_date = gmdate( 'Y-m-d', strtotime( $post->post_date ) );
+
// Don't bother if it hasn't changed.
if ( $new_date == $previous_date ) {
return;
}
+
// We're only concerned with published, non-hierarchical objects.
if ( ! ( 'publish' === $post->post_status || ( 'attachment' === get_post_type( $post ) && 'inherit' === $post->post_status ) ) || is_post_type_hierarchical( $post->post_type ) ) {
return;
}
+
$old_dates = (array) get_post_meta( $post_id, '_wp_old_date' );
+
// If we haven't added this old date before, add it now.
- if ( ! empty( $previous_date ) && ! in_array( $previous_date, $old_dates ) ) {
+ if ( ! empty( $previous_date ) && ! in_array( $previous_date, $old_dates, true ) ) {
add_post_meta( $post_id, '_wp_old_date', $previous_date );
}
+
// If the new slug was used previously, delete it from the list.
- if ( in_array( $new_date, $old_dates ) ) {
+ if ( in_array( $new_date, $old_dates, true ) ) {
delete_post_meta( $post_id, '_wp_old_date', $new_date );
}
}
@@ -6068,12 +6526,12 @@
* @see get_private_posts_cap_sql()
* @global wpdb $wpdb WordPress database abstraction object.
*
- * @param array|string $post_type Single post type or an array of post types.
- * @param bool $full Optional. Returns a full WHERE statement instead of just
- * an 'andalso' term. Default true.
- * @param int $post_author Optional. Query posts having a single author ID. Default null.
- * @param bool $public_only Optional. Only return public posts. Skips cap checks for
- * $current_user. Default false.
+ * @param string|string[] $post_type Single post type or an array of post types.
+ * @param bool $full Optional. Returns a full WHERE statement instead of just
+ * an 'andalso' term. Default true.
+ * @param int $post_author Optional. Query posts having a single author ID. Default null.
+ * @param bool $public_only Optional. Only return public posts. Skips cap checks for
+ * $current_user. Default false.
* @return string SQL WHERE code that can be added to a query.
*/
function get_posts_by_author_sql( $post_type, $full = true, $post_author = null, $public_only = false ) {
@@ -6101,7 +6559,8 @@
*
* @param string $cap Capability.
*/
- if ( ! $cap = apply_filters( 'pub_priv_sql_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 );
}
@@ -6118,8 +6577,8 @@
$post_status_sql .= " OR post_status = 'private' AND post_author = $id";
} elseif ( $id == (int) $post_author ) {
$post_status_sql .= " OR post_status = 'private'";
- } // else none
- } // else none
+ } // Else none.
+ } // Else none.
}
$post_type_clauses[] = "( post_type = '" . $post_type . "' AND ( $post_status_sql ) )";
@@ -6143,42 +6602,47 @@
}
/**
- * Retrieve the date that the last post was published.
+ * Retrieves the most recent time that a post on the site was published.
*
* The server timezone is the default and is the difference between GMT and
- * server time. The 'blog' value is the date when the last post was posted. The
- * 'gmt' is when the last post was posted in GMT formatted date.
+ * server time. The 'blog' value is the date when the last post was posted.
+ * The 'gmt' is when the last post was posted in GMT formatted date.
*
* @since 0.71
* @since 4.4.0 The `$post_type` argument was added.
*
* @param string $timezone Optional. The timezone for the timestamp. Accepts 'server', 'blog', or 'gmt'.
* 'server' uses the server's internal timezone.
- * 'blog' uses the `post_modified` field, which proxies to the timezone set for the site.
- * 'gmt' uses the `post_modified_gmt` field.
+ * 'blog' uses the `post_date` field, which proxies to the timezone set for the site.
+ * 'gmt' uses the `post_date_gmt` field.
* Default 'server'.
* @param string $post_type Optional. The post type to check. Default 'any'.
- * @return string The date of the last post.
+ * @return string The date of the last post, or false on failure.
*/
function get_lastpostdate( $timezone = 'server', $post_type = 'any' ) {
+ $lastpostdate = _get_last_post_time( $timezone, 'date', $post_type );
+
/**
- * Filters the date the last post was published.
+ * Filters the most recent time that a post on the site was published.
*
* @since 2.3.0
+ * @since 5.5.0 Added the `$post_type` parameter.
*
- * @param string $date Date the last post was published.
- * @param string $timezone Location to use for getting the post published date.
- * See get_lastpostdate() for accepted `$timezone` values.
+ * @param string|false $lastpostdate The most recent time that a post was published,
+ * in 'Y-m-d H:i:s' format. False on failure.
+ * @param string $timezone Location to use for getting the post published date.
+ * See get_lastpostdate() for accepted `$timezone` values.
+ * @param string $post_type The post type to check.
*/
- return apply_filters( 'get_lastpostdate', _get_last_post_time( $timezone, 'date', $post_type ), $timezone );
-}
-
-/**
- * Get the timestamp of the last time any post was modified.
+ return apply_filters( 'get_lastpostdate', $lastpostdate, $timezone, $post_type );
+}
+
+/**
+ * Get 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. The
- * 'gmt' is when the last post was modified in GMT time.
+ * server time. The 'blog' value is just when the last post was modified.
+ * The 'gmt' is when the last post was modified in GMT time.
*
* @since 1.2.0
* @since 4.4.0 The `$post_type` argument was added.
@@ -6187,7 +6651,7 @@
* for information on accepted values.
* Default 'server'.
* @param string $post_type Optional. The post type to check. Default 'any'.
- * @return string The timestamp.
+ * @return string The timestamp in 'Y-m-d H:i:s' format, or false on failure.
*/
function get_lastpostmodified( $timezone = 'server', $post_type = 'any' ) {
/**
@@ -6195,38 +6659,43 @@
*
* @since 4.4.0
*
- * @param string $lastpostmodified Date the last post was modified.
- * Returning anything other than false will short-circuit the function.
- * @param string $timezone Location to use for getting the post modified date.
- * See get_lastpostdate() for accepted `$timezone` values.
- * @param string $post_type The post type to check.
+ * @param string|false $lastpostmodified The most recent time that a post was modified,
+ * in 'Y-m-d H:i:s' format, or false. Returning anything
+ * other than false will short-circuit the function.
+ * @param string $timezone Location to use for getting the post modified date.
+ * See get_lastpostdate() for accepted `$timezone` values.
+ * @param string $post_type The post type to check.
*/
$lastpostmodified = apply_filters( 'pre_get_lastpostmodified', false, $timezone, $post_type );
+
if ( false !== $lastpostmodified ) {
return $lastpostmodified;
}
$lastpostmodified = _get_last_post_time( $timezone, 'modified', $post_type );
-
- $lastpostdate = get_lastpostdate( $timezone );
+ $lastpostdate = get_lastpostdate( $timezone, $post_type );
+
if ( $lastpostdate > $lastpostmodified ) {
$lastpostmodified = $lastpostdate;
}
/**
- * Filters the date the last post was modified.
+ * Filters the most recent time that a post on the site was modified.
*
* @since 2.3.0
+ * @since 5.5.0 Added the `$post_type` parameter.
*
- * @param string $lastpostmodified Date the last post was modified.
- * @param string $timezone Location to use for getting the post modified date.
- * See get_lastpostdate() for accepted `$timezone` values.
+ * @param string|false $lastpostmodified The most recent time that a post was modified,
+ * in 'Y-m-d H:i:s' format. False on failure.
+ * @param string $timezone Location to use for getting the post modified date.
+ * See get_lastpostdate() for accepted `$timezone` values.
+ * @param string $post_type The post type to check.
*/
- return apply_filters( 'get_lastpostmodified', $lastpostmodified, $timezone );
-}
-
-/**
- * Get the timestamp of the last time any post was modified or published.
+ return apply_filters( 'get_lastpostmodified', $lastpostmodified, $timezone, $post_type );
+}
+
+/**
+ * Gets the timestamp of the last time any post was modified or published.
*
* @since 3.1.0
* @since 4.4.0 The `$post_type` argument was added.
@@ -6238,12 +6707,12 @@
* for information on accepted values.
* @param string $field Post field to check. Accepts 'date' or 'modified'.
* @param string $post_type Optional. The post type to check. Default 'any'.
- * @return string|false The timestamp.
+ * @return string|false The timestamp in 'Y-m-d H:i:s' format, or false on failure.
*/
function _get_last_post_time( $timezone, $field, $post_type = 'any' ) {
global $wpdb;
- if ( ! in_array( $field, array( 'date', 'modified' ) ) ) {
+ if ( ! in_array( $field, array( 'date', 'modified' ), true ) ) {
return false;
}
@@ -6275,7 +6744,7 @@
$date = $wpdb->get_var( "SELECT post_{$field} FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1" );
break;
case 'server':
- $add_seconds_server = date( 'Z' );
+ $add_seconds_server = gmdate( 'Z' );
$date = $wpdb->get_var( "SELECT DATE_ADD(post_{$field}_gmt, INTERVAL '$add_seconds_server' SECOND) FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1" );
break;
}
@@ -6294,7 +6763,7 @@
*
* @since 1.5.1
*
- * @param array $posts Array of post objects (passed by reference).
+ * @param WP_Post[] $posts Array of post objects (passed by reference).
*/
function update_post_cache( &$posts ) {
if ( ! $posts ) {
@@ -6350,7 +6819,7 @@
*/
do_action( 'clean_post_cache', $post->ID, $post );
- if ( 'page' == $post->post_type ) {
+ if ( 'page' === $post->post_type ) {
wp_cache_delete( 'all_page_ids', 'posts' );
/**
@@ -6371,10 +6840,10 @@
*
* @since 1.5.0
*
- * @param array $posts Array of Post objects
- * @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.
+ * @param WP_Post[] $posts Array of Post objects
+ * @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.
*/
function update_post_caches( &$posts, $post_type = 'post', $update_term_cache = true, $update_meta_cache = true ) {
// No point in doing all this work if we didn't match any posts.
@@ -6396,7 +6865,7 @@
if ( $update_term_cache ) {
if ( is_array( $post_type ) ) {
$ptypes = $post_type;
- } elseif ( 'any' == $post_type ) {
+ } elseif ( 'any' === $post_type ) {
$ptypes = array();
// Just use the post_types in the supplied posts.
foreach ( $posts as $post ) {
@@ -6426,9 +6895,8 @@
*
* @since 2.1.0
*
- * @param array $post_ids List of post IDs.
- * @return array|false Returns false if there is nothing to update or an array
- * of metadata.
+ * @param int[] $post_ids Array of post IDs.
+ * @return array|false An array of metadata on success, false if there is nothing to update.
*/
function update_postmeta_cache( $post_ids ) {
return update_meta_cache( 'post', $post_ids );
@@ -6476,7 +6944,7 @@
}
//
-// Hooks
+// Hooks.
//
/**
@@ -6495,9 +6963,9 @@
function _transition_post_status( $new_status, $old_status, $post ) {
global $wpdb;
- if ( $old_status != 'publish' && $new_status == 'publish' ) {
+ if ( 'publish' !== $old_status && 'publish' === $new_status ) {
// Reset GUID if transitioning to publish and it is empty.
- if ( '' == get_the_guid( $post->ID ) ) {
+ if ( '' === get_the_guid( $post->ID ) ) {
$wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post->ID ) ), array( 'ID' => $post->ID ) );
}
@@ -6505,15 +6973,15 @@
* Fires when a post's status is transitioned from private to published.
*
* @since 1.5.0
- * @deprecated 2.3.0 Use 'private_to_publish' instead.
+ * @deprecated 2.3.0 Use {@see 'private_to_publish'} instead.
*
* @param int $post_id Post ID.
*/
- do_action( 'private_to_published', $post->ID );
+ do_action_deprecated( 'private_to_published', array( $post->ID ), '2.3.0', 'private_to_publish' );
}
// If published posts changed clear the lastpostmodified cache.
- if ( 'publish' == $new_status || 'publish' == $old_status ) {
+ if ( 'publish' === $new_status || 'publish' === $old_status ) {
foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) {
wp_cache_delete( "lastpostmodified:$timezone", 'timeinfo' );
wp_cache_delete( "lastpostdate:$timezone", 'timeinfo' );
@@ -6575,9 +7043,14 @@
}
if ( get_option( 'default_pingback_flag' ) ) {
- add_post_meta( $post_id, '_pingme', '1' );
- }
- add_post_meta( $post_id, '_encloseme', '1' );
+ add_post_meta( $post_id, '_pingme', '1', true );
+ }
+ add_post_meta( $post_id, '_encloseme', '1', true );
+
+ $to_ping = get_to_ping( $post_id );
+ if ( ! empty( $to_ping ) ) {
+ add_post_meta( $post_id, '_trackbackme', '1' );
+ }
if ( ! wp_next_scheduled( 'do_pings' ) ) {
wp_schedule_single_event( time(), 'do_pings' );
@@ -6590,7 +7063,8 @@
* @since 3.1.0
*
* @param int|WP_Post $post Post ID or post object. Defaults to global $post.
- * @return int|false Post parent ID (which can be 0 if there is no parent), or false if the post does not exist.
+ * @return int|false Post parent ID (which can be 0 if there is no parent),
+ * or false if the post does not exist.
*/
function wp_get_post_parent_id( $post ) {
$post = get_post( $post );
@@ -6631,8 +7105,9 @@
}
// Now look for larger loops.
- if ( ! $loop = wp_find_hierarchy_loop( 'wp_get_post_parent_id', $post_ID, $post_parent ) ) {
- return $post_parent; // No loop
+ $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.
@@ -6717,7 +7192,8 @@
* @param array $posts Array of WP_Post objects.
*/
function wp_queue_posts_for_term_meta_lazyload( $posts ) {
- $post_type_taxonomies = $term_ids = array();
+ $post_type_taxonomies = array();
+ $term_ids = array();
foreach ( $posts as $post ) {
if ( ! ( $post instanceof WP_Post ) ) {
continue;
@@ -6768,7 +7244,7 @@
}
/**
- * Adds any posts from the given ids to the cache that do not already exist in cache
+ * Adds any posts from the given IDs to the cache that do not already exist in cache
*
* @since 3.4.0
* @access private
@@ -6861,9 +7337,9 @@
*
* @global wpdb $wpdb WordPress database abstraction object.
*
- * @param array $clauses An array including WHERE, GROUP BY, JOIN, ORDER BY,
- * DISTINCT, fields (SELECT), and LIMITS clauses.
- * @return array The modified clauses.
+ * @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;
@@ -6908,3 +7384,85 @@
$types = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_mime_type FROM $wpdb->posts WHERE post_type = %s", $type ) );
return $types;
}
+
+/**
+ * Retrieves the path to an uploaded image file.
+ *
+ * Similar to `get_attached_file()` however some images may have been processed after uploading
+ * to make them suitable for web use. In this case the attached "full" size file is usually replaced
+ * with a scaled down version of the original image. This function always returns the path
+ * to the originally uploaded image file.
+ *
+ * @since 5.3.0
+ * @since 5.4.0 Added the `$unfiltered` parameter.
+ *
+ * @param int $attachment_id Attachment ID.
+ * @param bool $unfiltered Optional. Passed through to `get_attached_file()`. Default false.
+ * @return string|false Path to the original image file or false if the attachment is not an image.
+ */
+function wp_get_original_image_path( $attachment_id, $unfiltered = false ) {
+ if ( ! wp_attachment_is_image( $attachment_id ) ) {
+ return false;
+ }
+
+ $image_meta = wp_get_attachment_metadata( $attachment_id );
+ $image_file = get_attached_file( $attachment_id, $unfiltered );
+
+ if ( empty( $image_meta['original_image'] ) ) {
+ $original_image = $image_file;
+ } else {
+ $original_image = path_join( dirname( $image_file ), $image_meta['original_image'] );
+ }
+
+ /**
+ * Filters the path to the original image.
+ *
+ * @since 5.3.0
+ *
+ * @param string $original_image Path to original image file.
+ * @param int $attachment_id Attachment ID.
+ */
+ return apply_filters( 'wp_get_original_image_path', $original_image, $attachment_id );
+}
+
+/**
+ * Retrieve 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
+ * to the originally uploaded image file.
+ *
+ * @since 5.3.0
+ *
+ * @param int $attachment_id Attachment post ID.
+ * @return string|false Attachment image URL, false on error or if the attachment is not an image.
+ */
+function wp_get_original_image_url( $attachment_id ) {
+ if ( ! wp_attachment_is_image( $attachment_id ) ) {
+ return false;
+ }
+
+ $image_url = wp_get_attachment_url( $attachment_id );
+
+ if ( empty( $image_url ) ) {
+ return false;
+ }
+
+ $image_meta = wp_get_attachment_metadata( $attachment_id );
+
+ if ( empty( $image_meta['original_image'] ) ) {
+ $original_image_url = $image_url;
+ } else {
+ $original_image_url = path_join( dirname( $image_url ), $image_meta['original_image'] );
+ }
+
+ /**
+ * Filters the URL to the original attachment image.
+ *
+ * @since 5.3.0
+ *
+ * @param string $original_image_url URL to original image.
+ * @param int $attachment_id Attachment ID.
+ */
+ return apply_filters( 'wp_get_original_image_url', $original_image_url, $attachment_id );
+}