<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[43982] trunk: REST API: Move object type-specific metadata integrations from the wrapper functions to the low-level Meta API functions.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/43982">43982</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/43982","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>jeremyfelt</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2018-12-12 03:02:00 +0000 (Wed, 12 Dec 2018)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>REST API: Move object type-specific metadata integrations from the wrapper functions to the low-level Meta API functions.

Object type-specific actions that should happen before or after modification of metadata have so far been part of the respective wrapper functions. By using action and filter hooks, this changeset ensures they are always executed, even when calling the lower-level Meta API functions directly, which the REST API does as a prime example.

Merges <a href="https://core.trac.wordpress.org/changeset/43729">[43729]</a> to trunk.

Props flixos90, spacedmonkey.
Fixes <a href="https://core.trac.wordpress.org/ticket/44467">#44467</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludescommentphp">trunk/src/wp-includes/comment.php</a></li>
<li><a href="#trunksrcwpincludesdefaultfiltersphp">trunk/src/wp-includes/default-filters.php</a></li>
<li><a href="#trunksrcwpincludesmetaphp">trunk/src/wp-includes/meta.php</a></li>
<li><a href="#trunksrcwpincludespostphp">trunk/src/wp-includes/post.php</a></li>
<li><a href="#trunksrcwpincludestaxonomyphp">trunk/src/wp-includes/taxonomy.php</a></li>
<li><a href="#trunktestsphpunittestscommentmetaCachephp">trunk/tests/phpunit/tests/comment/metaCache.php</a></li>
<li><a href="#trunktestsphpunittestspostmetaphp">trunk/tests/phpunit/tests/post/meta.php</a></li>
<li><a href="#trunktestsphpunitteststermmetaphp">trunk/tests/phpunit/tests/term/meta.php</a></li>
</ul>

<h3>Property Changed</h3>
<ul>
<li><a href="#trunk">trunk/</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<span class="cx" style="display: block; padding: 0 10px">Index: trunk
</span><span class="cx" style="display: block; padding: 0 10px">===================================================================
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">--- trunk        2018-12-12 02:38:14 UTC (rev 43981)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+++ trunk 2018-12-12 03:02:00 UTC (rev 43982)
</ins><a id="trunk"></a>
<div class="propset"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Property changes: trunk</h4>
<pre class="diff"><span>
</span></pre></div>
<a id="svnmergeinfo"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: svn:mergeinfo</h4></div>
<span class="cx" style="display: block; padding: 0 10px"> /branches/3.3:20543
</span><span class="cx" style="display: block; padding: 0 10px"> /branches/3.4:21757
</span><span class="cx" style="display: block; padding: 0 10px"> /branches/4.9:43557
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/branches/5.0:43681-43682,43684-43687,43720,43726-43727
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/branches/5.0:43681-43682,43684-43687,43720,43726-43727,43729
</ins><span class="cx" style="display: block; padding: 0 10px"> /trunk:18512
</span><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunksrcwpincludescommentphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/comment.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/comment.php 2018-12-12 02:38:14 UTC (rev 43981)
+++ trunk/src/wp-includes/comment.php   2018-12-12 03:02:00 UTC (rev 43982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -442,11 +442,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return int|bool Meta ID on success, false on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function add_comment_meta( $comment_id, $meta_key, $meta_value, $unique = false ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $added = add_metadata( 'comment', $comment_id, $meta_key, $meta_value, $unique );
-       if ( $added ) {
-               wp_cache_set( 'last_changed', microtime(), 'comment' );
-       }
-       return $added;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return add_metadata( 'comment', $comment_id, $meta_key, $meta_value, $unique );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -465,11 +461,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return bool True on success, false on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function delete_comment_meta( $comment_id, $meta_key, $meta_value = '' ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $deleted = delete_metadata( 'comment', $comment_id, $meta_key, $meta_value );
-       if ( $deleted ) {
-               wp_cache_set( 'last_changed', microtime(), 'comment' );
-       }
-       return $deleted;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return delete_metadata( 'comment', $comment_id, $meta_key, $meta_value );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -506,11 +498,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function update_comment_meta( $comment_id, $meta_key, $meta_value, $prev_value = '' ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $updated = update_metadata( 'comment', $comment_id, $meta_key, $meta_value, $prev_value );
-       if ( $updated ) {
-               wp_cache_set( 'last_changed', microtime(), 'comment' );
-       }
-       return $updated;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return update_metadata( 'comment', $comment_id, $meta_key, $meta_value, $prev_value );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3512,3 +3500,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                'done'           => $done,
</span><span class="cx" style="display: block; padding: 0 10px">        );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Sets the last changed time for the 'comment' cache group.
+ *
+ * @since 5.0.0
+ */
+function wp_cache_set_comments_last_changed() {
+       wp_cache_set( 'last_changed', microtime(), 'comment' );
+}
</ins></span></pre></div>
<a id="trunksrcwpincludesdefaultfiltersphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/default-filters.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/default-filters.php 2018-12-12 02:38:14 UTC (rev 43981)
+++ trunk/src/wp-includes/default-filters.php   2018-12-12 03:02:00 UTC (rev 43982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -98,6 +98,29 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // Meta
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'register_meta_args', '_wp_register_meta_args_whitelist', 10, 2 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+// Post meta
+add_action( 'added_post_meta', 'wp_cache_set_posts_last_changed' );
+add_action( 'updated_post_meta', 'wp_cache_set_posts_last_changed' );
+add_action( 'deleted_post_meta', 'wp_cache_set_posts_last_changed' );
+
+// Term meta
+add_action( 'added_term_meta', 'wp_cache_set_terms_last_changed' );
+add_action( 'updated_term_meta', 'wp_cache_set_terms_last_changed' );
+add_action( 'deleted_term_meta', 'wp_cache_set_terms_last_changed' );
+add_filter( 'get_term_metadata', 'wp_check_term_meta_support_prefilter' );
+add_filter( 'add_term_metadata', 'wp_check_term_meta_support_prefilter' );
+add_filter( 'update_term_metadata', 'wp_check_term_meta_support_prefilter' );
+add_filter( 'delete_term_metadata', 'wp_check_term_meta_support_prefilter' );
+add_filter( 'get_term_metadata_by_mid', 'wp_check_term_meta_support_prefilter' );
+add_filter( 'update_term_metadata_by_mid', 'wp_check_term_meta_support_prefilter' );
+add_filter( 'delete_term_metadata_by_mid', 'wp_check_term_meta_support_prefilter' );
+add_filter( 'update_term_metadata_cache', 'wp_check_term_meta_support_prefilter' );
+
+// Comment meta
+add_action( 'added_comment_meta', 'wp_cache_set_comments_last_changed' );
+add_action( 'updated_comment_meta', 'wp_cache_set_comments_last_changed' );
+add_action( 'deleted_comment_meta', 'wp_cache_set_comments_last_changed' );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> // Places to balance tags on input
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ( array( 'content_save_pre', 'excerpt_save_pre', 'comment_save_pre', 'pre_comment_content' ) as $filter ) {
</span><span class="cx" style="display: block; padding: 0 10px">        add_filter( $filter, 'convert_invalid_entities' );
</span></span></pre></div>
<a id="trunksrcwpincludesmetaphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/meta.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/meta.php    2018-12-12 02:38:14 UTC (rev 43981)
+++ trunk/src/wp-includes/meta.php      2018-12-12 03:02:00 UTC (rev 43982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -613,6 +613,23 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $id_column = ( 'user' == $meta_type ) ? 'umeta_id' : 'meta_id';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /**
+        * Filters whether to retrieve metadata of a specific type by meta ID.
+        *
+        * The dynamic portion of the hook, `$meta_type`, refers to the meta
+        * object type (comment, post, term, or user). Returning a non-null value
+        * will effectively short-circuit the function.
+        *
+        * @since 5.0.0
+        *
+        * @param mixed $value    The value get_metadata_by_mid() should return.
+        * @param int   $meta_id  Meta ID.
+        */
+       $check = apply_filters( "get_{$meta_type}_metadata_by_mid", null, $meta_id );
+       if ( null !== $check ) {
+               return $check;
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         $meta = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE $id_column = %d", $meta_id ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( empty( $meta ) ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -660,6 +677,25 @@
</span><span class="cx" style="display: block; padding: 0 10px">        $column    = sanitize_key( $meta_type . '_id' );
</span><span class="cx" style="display: block; padding: 0 10px">        $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /**
+        * Filters whether to update metadata of a specific type by meta ID.
+        *
+        * The dynamic portion of the hook, `$meta_type`, refers to the meta
+        * object type (comment, post, term, or user). Returning a non-null value
+        * will effectively short-circuit the function.
+        *
+        * @since 5.0.0
+        *
+        * @param null|bool   $check      Whether to allow updating metadata for the given type.
+        * @param int         $meta_id    Meta ID.
+        * @param mixed       $meta_value Meta value. Must be serializable if non-scalar.
+        * @param string|bool $meta_key   Meta key, if provided.
+        */
+       $check = apply_filters( "update_{$meta_type}_metadata_by_mid", null, $meta_id, $meta_value, $meta_key );
+       if ( null !== $check ) {
+               return (bool) $check;
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         // Fetch the meta and go on if it's found.
</span><span class="cx" style="display: block; padding: 0 10px">        if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                $original_key = $meta->meta_key;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -755,6 +791,23 @@
</span><span class="cx" style="display: block; padding: 0 10px">        $column    = sanitize_key( $meta_type . '_id' );
</span><span class="cx" style="display: block; padding: 0 10px">        $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /**
+        * Filters whether to delete metadata of a specific type by meta ID.
+        *
+        * The dynamic portion of the hook, `$meta_type`, refers to the meta
+        * object type (comment, post, term, or user). Returning a non-null value
+        * will effectively short-circuit the function.
+        *
+        * @since 5.0.0
+        *
+        * @param null|bool $delete  Whether to allow metadata deletion of the given type.
+        * @param int       $meta_id Meta ID.
+        */
+       $check = apply_filters( "delete_{$meta_type}_metadata_by_mid", null, $meta_id );
+       if ( null !== $check ) {
+               return (bool) $check;
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         // Fetch the meta and go on if it's found.
</span><span class="cx" style="display: block; padding: 0 10px">        if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                $object_id = $meta->{$column};
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -841,6 +894,23 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $object_ids = array_map( 'intval', $object_ids );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /**
+        * Filters whether to update the metadata cache of a specific type.
+        *
+        * The dynamic portion of the hook, `$meta_type`, refers to the meta
+        * object type (comment, post, term, or user). Returning a non-null value
+        * will effectively short-circuit the function.
+        *
+        * @since 5.0.0
+        *
+        * @param mixed $check      Whether to allow updating the meta cache of the given type.
+        * @param array $object_ids Array of object IDs to update the meta cache for.
+        */
+       $check = apply_filters( "update_{$meta_type}_metadata_cache", null, $object_ids );
+       if ( null !== $check ) {
+               return (bool) $check;
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         $cache_key = $meta_type . '_meta';
</span><span class="cx" style="display: block; padding: 0 10px">        $ids       = array();
</span><span class="cx" style="display: block; padding: 0 10px">        $cache     = array();
</span></span></pre></div>
<a id="trunksrcwpincludespostphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/post.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/post.php    2018-12-12 02:38:14 UTC (rev 43981)
+++ trunk/src/wp-includes/post.php      2018-12-12 03:02:00 UTC (rev 43982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1906,15 +1906,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function add_post_meta( $post_id, $meta_key, $meta_value, $unique = false ) {
</span><span class="cx" style="display: block; padding: 0 10px">        // Make sure meta is added to the post, not a revision.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( $the_post = wp_is_post_revision( $post_id ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $the_post = wp_is_post_revision( $post_id );
+       if ( $the_post ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 $post_id = $the_post;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $added = add_metadata( 'post', $post_id, $meta_key, $meta_value, $unique );
-       if ( $added ) {
-               wp_cache_set( 'last_changed', microtime(), 'posts' );
-       }
-       return $added;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return add_metadata( 'post', $post_id, $meta_key, $meta_value, $unique );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1934,15 +1931,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function delete_post_meta( $post_id, $meta_key, $meta_value = '' ) {
</span><span class="cx" style="display: block; padding: 0 10px">        // Make sure meta is added to the post, not a revision.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( $the_post = wp_is_post_revision( $post_id ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $the_post = wp_is_post_revision( $post_id );
+       if ( $the_post ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 $post_id = $the_post;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $deleted = delete_metadata( 'post', $post_id, $meta_key, $meta_value );
-       if ( $deleted ) {
-               wp_cache_set( 'last_changed', microtime(), 'posts' );
-       }
-       return $deleted;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return delete_metadata( 'post', $post_id, $meta_key, $meta_value );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1981,15 +1975,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function update_post_meta( $post_id, $meta_key, $meta_value, $prev_value = '' ) {
</span><span class="cx" style="display: block; padding: 0 10px">        // Make sure meta is added to the post, not a revision.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( $the_post = wp_is_post_revision( $post_id ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $the_post = wp_is_post_revision( $post_id );
+       if ( $the_post ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 $post_id = $the_post;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $updated = update_metadata( 'post', $post_id, $meta_key, $meta_value, $prev_value );
-       if ( $updated ) {
-               wp_cache_set( 'last_changed', microtime(), 'posts' );
-       }
-       return $updated;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return update_metadata( 'post', $post_id, $meta_key, $meta_value, $prev_value );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2001,11 +1992,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return bool Whether the post meta key was deleted from the database.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function delete_post_meta_by_key( $post_meta_key ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $deleted = delete_metadata( 'post', null, $post_meta_key, '', true );
-       if ( $deleted ) {
-               wp_cache_set( 'last_changed', microtime(), 'posts' );
-       }
-       return $deleted;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return delete_metadata( 'post', null, $post_meta_key, '', true );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -6785,3 +6772,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $clauses;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Sets the last changed time for the 'posts' cache group.
+ *
+ * @since 5.0.0
+ */
+function wp_cache_set_posts_last_changed() {
+       wp_cache_set( 'last_changed', microtime(), 'posts' );
+}
</ins></span></pre></div>
<a id="trunksrcwpincludestaxonomyphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/taxonomy.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/taxonomy.php        2018-12-12 02:38:14 UTC (rev 43981)
+++ trunk/src/wp-includes/taxonomy.php  2018-12-12 03:02:00 UTC (rev 43982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1211,23 +1211,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">  *                           False on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function add_term_meta( $term_id, $meta_key, $meta_value, $unique = false ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Bail if term meta table is not installed.
-       if ( get_option( 'db_version' ) < 34370 ) {
-               return false;
-       }
-
</del><span class="cx" style="display: block; padding: 0 10px">         if ( wp_term_is_shared( $term_id ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                return new WP_Error( 'ambiguous_term_id', __( 'Term meta cannot be added to terms that are shared between taxonomies.' ), $term_id );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $added = add_metadata( 'term', $term_id, $meta_key, $meta_value, $unique );
-
-       // Bust term query cache.
-       if ( $added ) {
-               wp_cache_set( 'last_changed', microtime(), 'terms' );
-       }
-
-       return $added;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return add_metadata( 'term', $term_id, $meta_key, $meta_value, $unique );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1241,19 +1229,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return bool True on success, false on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function delete_term_meta( $term_id, $meta_key, $meta_value = '' ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Bail if term meta table is not installed.
-       if ( get_option( 'db_version' ) < 34370 ) {
-               return false;
-       }
-
-       $deleted = delete_metadata( 'term', $term_id, $meta_key, $meta_value );
-
-       // Bust term query cache.
-       if ( $deleted ) {
-               wp_cache_set( 'last_changed', microtime(), 'terms' );
-       }
-
-       return $deleted;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return delete_metadata( 'term', $term_id, $meta_key, $meta_value );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1268,11 +1244,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return mixed If `$single` is false, an array of metadata values. If `$single` is true, a single metadata value.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function get_term_meta( $term_id, $key = '', $single = false ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Bail if term meta table is not installed.
-       if ( get_option( 'db_version' ) < 34370 ) {
-               return false;
-       }
-
</del><span class="cx" style="display: block; padding: 0 10px">         return get_metadata( 'term', $term_id, $key, $single );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1293,23 +1264,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">  *                           WP_Error when term_id is ambiguous between taxonomies. False on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function update_term_meta( $term_id, $meta_key, $meta_value, $prev_value = '' ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Bail if term meta table is not installed.
-       if ( get_option( 'db_version' ) < 34370 ) {
-               return false;
-       }
-
</del><span class="cx" style="display: block; padding: 0 10px">         if ( wp_term_is_shared( $term_id ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                return new WP_Error( 'ambiguous_term_id', __( 'Term meta cannot be added to terms that are shared between taxonomies.' ), $term_id );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $updated = update_metadata( 'term', $term_id, $meta_key, $meta_value, $prev_value );
-
-       // Bust term query cache.
-       if ( $updated ) {
-               wp_cache_set( 'last_changed', microtime(), 'terms' );
-       }
-
-       return $updated;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return update_metadata( 'term', $term_id, $meta_key, $meta_value, $prev_value );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1324,11 +1283,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return array|false Returns false if there is nothing to update. Returns an array of metadata on success.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function update_termmeta_cache( $term_ids ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Bail if term meta table is not installed.
-       if ( get_option( 'db_version' ) < 34370 ) {
-               return;
-       }
-
</del><span class="cx" style="display: block; padding: 0 10px">         return update_meta_cache( 'term', $term_ids );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1343,9 +1297,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return array|false Array with meta data, or false when the meta table is not installed.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function has_term_meta( $term_id ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Bail if term meta table is not installed.
-       if ( get_option( 'db_version' ) < 34370 ) {
-               return false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $check = wp_check_term_meta_support_prefilter( null );
+       if ( null !== $check ) {
+               return $check;
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        global $wpdb;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4632,3 +4586,28 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $taxonomy->publicly_queryable;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Sets the last changed time for the 'terms' cache group.
+ *
+ * @since 5.0.0
+ */
+function wp_cache_set_terms_last_changed() {
+       wp_cache_set( 'last_changed', microtime(), 'terms' );
+}
+
+/**
+ * Aborts calls to term meta if it is not supported.
+ *
+ * @since 5.0.0
+ *
+ * @param mixed $check Skip-value for whether to proceed term meta function execution.
+ * @return mixed Original value of $check, or false if term meta is not supported.
+ */
+function wp_check_term_meta_support_prefilter( $check ) {
+       if ( get_option( 'db_version' ) < 34370 ) {
+               return false;
+       }
+
+       return $check;
+}
</ins></span></pre></div>
<a id="trunktestsphpunittestscommentmetaCachephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/comment/metaCache.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/comment/metaCache.php   2018-12-12 02:38:14 UTC (rev 43981)
+++ trunk/tests/phpunit/tests/comment/metaCache.php     2018-12-12 03:02:00 UTC (rev 43982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -224,4 +224,41 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $num_queries++;
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertSame( $num_queries, $wpdb->num_queries );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       /**
+        * @ticket 44467
+        */
+       public function test_add_metadata_sets_comments_last_changed() {
+               $comment_id = self::factory()->comment->create();
+
+               wp_cache_delete( 'last_changed', 'comment' );
+
+               $this->assertInternalType( 'integer', add_metadata( 'comment', $comment_id, 'foo', 'bar' ) );
+               $this->assertNotFalse( wp_cache_get_last_changed( 'comment' ) );
+       }
+
+       /**
+        * @ticket 44467
+        */
+       public function test_update_metadata_sets_comments_last_changed() {
+               $comment_id = self::factory()->comment->create();
+
+               wp_cache_delete( 'last_changed', 'comment' );
+
+               $this->assertInternalType( 'integer', update_metadata( 'comment', $comment_id, 'foo', 'bar' ) );
+               $this->assertNotFalse( wp_cache_get_last_changed( 'comment' ) );
+       }
+
+       /**
+        * @ticket 44467
+        */
+       public function test_delete_metadata_sets_comments_last_changed() {
+               $comment_id = self::factory()->comment->create();
+
+               update_metadata( 'comment', $comment_id, 'foo', 'bar' );
+               wp_cache_delete( 'last_changed', 'comment' );
+
+               $this->assertTrue( delete_metadata( 'comment', $comment_id, 'foo' ) );
+               $this->assertNotFalse( wp_cache_get_last_changed( 'comment' ) );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunktestsphpunittestspostmetaphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/post/meta.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/post/meta.php   2018-12-12 02:38:14 UTC (rev 43981)
+++ trunk/tests/phpunit/tests/post/meta.php     2018-12-12 03:02:00 UTC (rev 43982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -309,4 +309,41 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        array( '', 'registered_key3' ),
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       /**
+        * @ticket 44467
+        */
+       public function test_add_metadata_sets_posts_last_changed() {
+               $post_id = self::factory()->post->create();
+
+               wp_cache_delete( 'last_changed', 'posts' );
+
+               $this->assertInternalType( 'integer', add_metadata( 'post', $post_id, 'foo', 'bar' ) );
+               $this->assertNotFalse( wp_cache_get_last_changed( 'posts' ) );
+       }
+
+       /**
+        * @ticket 44467
+        */
+       public function test_update_metadata_sets_posts_last_changed() {
+               $post_id = self::factory()->post->create();
+
+               wp_cache_delete( 'last_changed', 'posts' );
+
+               $this->assertInternalType( 'integer', update_metadata( 'post', $post_id, 'foo', 'bar' ) );
+               $this->assertNotFalse( wp_cache_get_last_changed( 'posts' ) );
+       }
+
+       /**
+        * @ticket 44467
+        */
+       public function test_delete_metadata_sets_posts_last_changed() {
+               $post_id = self::factory()->post->create();
+
+               update_metadata( 'post', $post_id, 'foo', 'bar' );
+               wp_cache_delete( 'last_changed', 'posts' );
+
+               $this->assertTrue( delete_metadata( 'post', $post_id, 'foo' ) );
+               $this->assertNotFalse( wp_cache_get_last_changed( 'posts' ) );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunktestsphpunitteststermmetaphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/term/meta.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/term/meta.php   2018-12-12 02:38:14 UTC (rev 43981)
+++ trunk/tests/phpunit/tests/term/meta.php     2018-12-12 03:02:00 UTC (rev 43982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -537,4 +537,62 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        array( '', 'registered_key3' ),
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       /**
+        * @ticket 44467
+        */
+       public function test_add_metadata_sets_terms_last_changed() {
+               $term_id = self::factory()->term->create();
+
+               wp_cache_delete( 'last_changed', 'terms' );
+
+               $this->assertInternalType( 'integer', add_metadata( 'term', $term_id, 'foo', 'bar' ) );
+               $this->assertNotFalse( wp_cache_get_last_changed( 'terms' ) );
+       }
+
+       /**
+        * @ticket 44467
+        */
+       public function test_update_metadata_sets_terms_last_changed() {
+               $term_id = self::factory()->term->create();
+
+               wp_cache_delete( 'last_changed', 'terms' );
+
+               $this->assertInternalType( 'integer', update_metadata( 'term', $term_id, 'foo', 'bar' ) );
+               $this->assertNotFalse( wp_cache_get_last_changed( 'terms' ) );
+       }
+
+       /**
+        * @ticket 44467
+        */
+       public function test_delete_metadata_sets_terms_last_changed() {
+               $term_id = self::factory()->term->create();
+
+               update_metadata( 'term', $term_id, 'foo', 'bar' );
+               wp_cache_delete( 'last_changed', 'terms' );
+
+               $this->assertTrue( delete_metadata( 'term', $term_id, 'foo' ) );
+               $this->assertNotFalse( wp_cache_get_last_changed( 'terms' ) );
+       }
+
+       /**
+        * @ticket 44467
+        */
+       public function test_metadata_functions_respect_term_meta_support() {
+               $term_id = self::factory()->term->create();
+
+               $meta_id = add_metadata( 'term', $term_id, 'foo', 'bar' );
+
+               // Set database version to last version before term meta support.
+               update_option( 'db_version', 34369 );
+
+               $this->assertFalse( get_metadata( 'term', $term_id, 'foo', true ) );
+               $this->assertFalse( add_metadata( 'term', $term_id, 'foo', 'bar' ) );
+               $this->assertFalse( update_metadata( 'term', $term_id, 'foo', 'bar' ) );
+               $this->assertFalse( delete_metadata( 'term', $term_id, 'foo' ) );
+               $this->assertFalse( get_metadata_by_mid( 'term', $meta_id ) );
+               $this->assertFalse( update_metadata_by_mid( 'term', $meta_id, 'baz' ) );
+               $this->assertFalse( delete_metadata_by_mid( 'term', $meta_id ) );
+               $this->assertFalse( update_meta_cache( 'term', array( $term_id ) ) );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre>
</div>
</div>

</body>
</html>