: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Filters the mime type icon.
* @param string $icon Path to the mime type icon.
* @param string $mime Mime type.
* @param int $post_id Attachment ID. Will equal 0 if the function passed
return apply_filters( 'wp_mime_type_icon', $icon, $mime, $post_id );
* Checks for changed slugs for published post objects and save the old slug.
* The function is used when a post object of any type is updated,
* by comparing the current and previous post objects.
* If the slug was changed and not already part of the old slugs then it will be
* added to the post meta field ('_wp_old_slug') for storing old slugs for that
* The most logically usage of this function is redirecting changed post objects, so
* that those that linked to an changed post will be redirected to the new post.
* @param int $post_id Post ID.
* @param WP_Post $post The post object.
* @param WP_Post $post_before The previous post object.
function wp_check_for_changed_slugs( $post_id, $post, $post_before ) {
// Don't bother if it hasn't changed.
if ( $post->post_name == $post_before->post_name ) {
// 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 ) ) {
$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, 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, true ) ) {
delete_post_meta( $post_id, '_wp_old_slug', $post->post_name );
* Checks for changed dates for published post objects and save the old date.
* The function is used when a post object of any type is updated,
* by comparing the current and previous post objects.
* If the date was changed and not already part of the old dates then it will be
* added to the post meta field ('_wp_old_date') for storing old dates for that
* The most logically usage of this function is redirecting changed post objects, so
* that those that linked to an changed post will be redirected to the new post.
* @param int $post_id Post ID.
* @param WP_Post $post The post object.
* @param WP_Post $post_before The previous post object.
function wp_check_for_changed_dates( $post_id, $post, $post_before ) {
$previous_date = gmdate( 'Y-m-d', strtotime( $post_before->post_date ) );
$new_date = gmdate( 'Y-m-d', strtotime( $post->post_date ) );
// Don't bother if it hasn't changed.
if ( $new_date == $previous_date ) {
// 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 ) ) {
$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, 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, true ) ) {
delete_post_meta( $post_id, '_wp_old_date', $new_date );
* Retrieves the private post SQL based on capability.
* This function provides a standardized way to appropriately select on the
* post_status of a post type. The function will return a piece of SQL code
* that can be added to a WHERE clause; this SQL is constructed to allow all
* published posts, and all private posts to which the user has access.
* @since 4.3.0 Added the ability to pass an array to `$post_type`.
* @param string|array $post_type Single post type or an array of post types. Currently only supports 'post' or 'page'.
* @return string SQL code that can be added to a where clause.
function get_private_posts_cap_sql( $post_type ) {
return get_posts_by_author_sql( $post_type, false );
* Retrieves the post SQL based on capability, author, and type.
* @since 4.3.0 Introduced the ability to pass an array of post types to `$post_type`.
* @see get_private_posts_cap_sql()
* @global wpdb $wpdb WordPress database abstraction object.
* @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 ) {
if ( is_array( $post_type ) ) {
$post_types = $post_type;
$post_types = array( $post_type );
$post_type_clauses = array();
foreach ( $post_types as $post_type ) {
$post_type_obj = get_post_type_object( $post_type );
if ( ! $post_type_obj ) {
* Filters the capability to read private posts for a custom post type
* when generating SQL for getting posts by author.
* @deprecated 3.2.0 The hook transitioned from "somewhat useless" to "totally useless".
* @param string $cap Capability.
$cap = apply_filters_deprecated( 'pub_priv_sql_capability', array( '' ), '3.2.0' );
$cap = current_user_can( $post_type_obj->cap->read_private_posts );
// Only need to check the cap if $public_only is false.
$post_status_sql = "post_status = 'publish'";
if ( false === $public_only ) {
// Does the user have the capability to view private posts? Guess so.
$post_status_sql .= " OR post_status = 'private'";
} elseif ( is_user_logged_in() ) {
// Users can view their own private posts.
$id = get_current_user_id();
if ( null === $post_author || ! $full ) {
$post_status_sql .= " OR post_status = 'private' AND post_author = $id";
} elseif ( $id == (int) $post_author ) {
$post_status_sql .= " OR post_status = 'private'";
$post_type_clauses[] = "( post_type = '" . $post_type . "' AND ( $post_status_sql ) )";
if ( empty( $post_type_clauses ) ) {
return $full ? 'WHERE 1 = 0' : '1 = 0';
$sql = '( ' . implode( ' OR ', $post_type_clauses ) . ' )';
if ( null !== $post_author ) {
$sql .= $wpdb->prepare( ' AND post_author = %d', $post_author );
* 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.
* @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_date` field, which proxies to the timezone set for the site.
* 'gmt' uses the `post_date_gmt` field.
* @param string $post_type Optional. The post type to check. Default 'any'.
* @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 most recent time that a post on the site was published.
* @since 5.5.0 Added the `$post_type` parameter.
* @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', $lastpostdate, $timezone, $post_type );
* Gets the most recent time that a post on the site was modified.
* The server timezone is the default and is the difference between GMT and
* server time. The 'blog' value is just when the last post was modified.
* The 'gmt' is when the last post was modified in GMT time.
* @since 4.4.0 The `$post_type` argument was added.
* @param string $timezone Optional. The timezone for the timestamp. See get_lastpostdate()
* for information on accepted values.
* @param string $post_type Optional. The post type to check. Default 'any'.
* @return string The timestamp in 'Y-m-d H:i:s' format, or false on failure.
function get_lastpostmodified( $timezone = 'server', $post_type = 'any' ) {
* Pre-filter the return value of get_lastpostmodified() before the query is run.
* @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, $post_type );
if ( $lastpostdate > $lastpostmodified ) {
$lastpostmodified = $lastpostdate;
* Filters the most recent time that a post on the site was modified.
* @since 5.5.0 Added the `$post_type` parameter.
* @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, $post_type );
* Gets the timestamp of the last time any post was modified or published.
* @since 4.4.0 The `$post_type` argument was added.
* @global wpdb $wpdb WordPress database abstraction object.
* @param string $timezone The timezone for the timestamp. See get_lastpostdate().
* 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 in 'Y-m-d H:i:s' format, or false on failure.
function _get_last_post_time( $timezone, $field, $post_type = 'any' ) {
if ( ! in_array( $field, array( 'date', 'modified' ), true ) ) {
$timezone = strtolower( $timezone );
$key = "lastpost{$field}:$timezone";
if ( 'any' !== $post_type ) {
$key .= ':' . sanitize_key( $post_type );
$date = wp_cache_get( $key, 'timeinfo' );
if ( 'any' === $post_type ) {
$post_types = get_post_types( array( 'public' => true ) );
array_walk( $post_types, array( $wpdb, 'escape_by_ref' ) );
$post_types = "'" . implode( "', '", $post_types ) . "'";
$post_types = "'" . sanitize_key( $post_type ) . "'";
$date = $wpdb->get_var( "SELECT post_{$field}_gmt FROM $wpdb->posts WHERE post_status = 'publish' AND post_type IN ({$post_types}) ORDER BY post_{$field}_gmt DESC LIMIT 1" );
$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" );
$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" );
wp_cache_set( $key, $date, 'timeinfo' );
* Updates posts in cache.
* @param WP_Post[] $posts Array of post objects (passed by reference).
function update_post_cache( &$posts ) {
foreach ( $posts as $post ) {
if ( empty( $post->filter ) || 'raw' !== $post->filter ) {
$post = sanitize_post( $post, 'raw' );
$data[ $post->ID ] = $post;
wp_cache_add_multiple( $data, 'posts' );
* Will clean the post in the cache.
* Cleaning means delete from the cache of the post. Will call to clean the term
* object cache associated with the post ID.
* This function not run if $_wp_suspend_cache_invalidation is not empty. See
* wp_suspend_cache_invalidation().
* @global bool $_wp_suspend_cache_invalidation
* @param int|WP_Post $post Post ID or post object to remove from the cache.
function clean_post_cache( $post ) {
global $_wp_suspend_cache_invalidation;
if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
$post = get_post( $post );
wp_cache_delete( $post->ID, 'posts' );
wp_cache_delete( 'post_parent:' . (string) $post->ID, 'posts' );
wp_cache_delete( $post->ID, 'post_meta' );
clean_object_term_cache( $post->ID, $post->post_type );
wp_cache_delete( 'wp_get_archives', 'general' );
* Fires immediately after the given post's cache is cleaned.
* @param int $post_id Post ID.
* @param WP_Post $post Post object.
do_action( 'clean_post_cache', $post->ID, $post );
if ( 'page' === $post->post_type ) {
wp_cache_delete( 'all_page_ids', 'posts' );
* Fires immediately after the given page's cache is cleaned.
* @param int $post_id Post ID.
do_action( 'clean_page_cache', $post->ID );
wp_cache_set_posts_last_changed();
* Updates post, term, and metadata caches for a list of post objects.
* @param WP_Post[] $posts Array of post objects (passed by reference).
* @param string $post_type Optional. Post type. Default 'post'.
* @param bool $update_term_cache Optional. Whether to update the term cache. Default true.
* @param bool $update_meta_cache Optional. Whether to update the meta cache. Default true.
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.
update_post_cache( $posts );
foreach ( $posts as $post ) {
if ( $update_term_cache ) {
if ( is_array( $post_type ) ) {
} elseif ( 'any' === $post_type ) {
// Just use the post_types in the supplied posts.
foreach ( $posts as $post ) {
$ptypes[] = $post->post_type;
$ptypes = array_unique( $ptypes );
$ptypes = array( $post_type );
if ( ! empty( $ptypes ) ) {
update_object_term_cache( $post_ids, $ptypes );
if ( $update_meta_cache ) {
update_postmeta_cache( $post_ids );