wp/wp-includes/meta.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    15  *
    15  *
    16  * @since 2.9.0
    16  * @since 2.9.0
    17  *
    17  *
    18  * @global wpdb $wpdb WordPress database abstraction object.
    18  * @global wpdb $wpdb WordPress database abstraction object.
    19  *
    19  *
    20  * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
    20  * @param string $meta_type  Type of object metadata is for (e.g., comment, post, term, or user).
    21  * @param int    $object_id  ID of the object metadata is for
    21  * @param int    $object_id  ID of the object metadata is for
    22  * @param string $meta_key   Metadata key
    22  * @param string $meta_key   Metadata key
    23  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
    23  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
    24  * @param bool   $unique     Optional, default is false.
    24  * @param bool   $unique     Optional, default is false.
    25  *                           Whether the specified metadata key should be unique for the object.
    25  *                           Whether the specified metadata key should be unique for the object.
    26  *                           If true, and the object already has a value for the specified metadata key,
    26  *                           If true, and the object already has a value for the specified metadata key,
    27  *                           no change will be made.
    27  *                           no change will be made.
    28  * @return int|false The meta ID on success, false on failure.
    28  * @return int|false The meta ID on success, false on failure.
    29  */
    29  */
    30 function add_metadata($meta_type, $object_id, $meta_key, $meta_value, $unique = false) {
    30 function add_metadata( $meta_type, $object_id, $meta_key, $meta_value, $unique = false ) {
    31 	global $wpdb;
    31 	global $wpdb;
    32 
    32 
    33 	if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
    33 	if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
    34 		return false;
    34 		return false;
    35 	}
    35 	}
    44 		return false;
    44 		return false;
    45 	}
    45 	}
    46 
    46 
    47 	$meta_subtype = get_object_subtype( $meta_type, $object_id );
    47 	$meta_subtype = get_object_subtype( $meta_type, $object_id );
    48 
    48 
    49 	$column = sanitize_key($meta_type . '_id');
    49 	$column = sanitize_key( $meta_type . '_id' );
    50 
    50 
    51 	// expected_slashed ($meta_key)
    51 	// expected_slashed ($meta_key)
    52 	$meta_key = wp_unslash($meta_key);
    52 	$meta_key   = wp_unslash( $meta_key );
    53 	$meta_value = wp_unslash($meta_value);
    53 	$meta_value = wp_unslash( $meta_value );
    54 	$meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
    54 	$meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
    55 
    55 
    56 	/**
    56 	/**
    57 	 * Filters whether to add metadata of a specific type.
    57 	 * Filters whether to add metadata of a specific type.
    58 	 *
    58 	 *
    59 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
    59 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
    60 	 * object type (comment, post, or user). Returning a non-null value
    60 	 * object type (comment, post, term, or user). Returning a non-null value
    61 	 * will effectively short-circuit the function.
    61 	 * will effectively short-circuit the function.
    62 	 *
    62 	 *
    63 	 * @since 3.1.0
    63 	 * @since 3.1.0
    64 	 *
    64 	 *
    65 	 * @param null|bool $check      Whether to allow adding metadata for the given type.
    65 	 * @param null|bool $check      Whether to allow adding metadata for the given type.
    68 	 * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
    68 	 * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
    69 	 * @param bool      $unique     Whether the specified meta key should be unique
    69 	 * @param bool      $unique     Whether the specified meta key should be unique
    70 	 *                              for the object. Optional. Default false.
    70 	 *                              for the object. Optional. Default false.
    71 	 */
    71 	 */
    72 	$check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique );
    72 	$check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique );
    73 	if ( null !== $check )
    73 	if ( null !== $check ) {
    74 		return $check;
    74 		return $check;
    75 
    75 	}
    76 	if ( $unique && $wpdb->get_var( $wpdb->prepare(
    76 
    77 		"SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d",
    77 	if ( $unique && $wpdb->get_var(
    78 		$meta_key, $object_id ) ) )
    78 		$wpdb->prepare(
    79 		return false;
    79 			"SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d",
       
    80 			$meta_key,
       
    81 			$object_id
       
    82 		)
       
    83 	) ) {
       
    84 		return false;
       
    85 	}
    80 
    86 
    81 	$_meta_value = $meta_value;
    87 	$_meta_value = $meta_value;
    82 	$meta_value = maybe_serialize( $meta_value );
    88 	$meta_value  = maybe_serialize( $meta_value );
    83 
    89 
    84 	/**
    90 	/**
    85 	 * Fires immediately before meta of a specific type is added.
    91 	 * Fires immediately before meta of a specific type is added.
    86 	 *
    92 	 *
    87 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
    93 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
    88 	 * object type (comment, post, or user).
    94 	 * object type (comment, post, term, or user).
    89 	 *
    95 	 *
    90 	 * @since 3.1.0
    96 	 * @since 3.1.0
    91 	 *
    97 	 *
    92 	 * @param int    $object_id  Object ID.
    98 	 * @param int    $object_id   Object ID.
    93 	 * @param string $meta_key   Meta key.
    99 	 * @param string $meta_key    Meta key.
    94 	 * @param mixed  $meta_value Meta value.
   100 	 * @param mixed  $_meta_value Meta value.
    95 	 */
   101 	 */
    96 	do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value );
   102 	do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value );
    97 
   103 
    98 	$result = $wpdb->insert( $table, array(
   104 	$result = $wpdb->insert(
    99 		$column => $object_id,
   105 		$table,
   100 		'meta_key' => $meta_key,
   106 		array(
   101 		'meta_value' => $meta_value
   107 			$column      => $object_id,
   102 	) );
   108 			'meta_key'   => $meta_key,
   103 
   109 			'meta_value' => $meta_value,
   104 	if ( ! $result )
   110 		)
   105 		return false;
   111 	);
       
   112 
       
   113 	if ( ! $result ) {
       
   114 		return false;
       
   115 	}
   106 
   116 
   107 	$mid = (int) $wpdb->insert_id;
   117 	$mid = (int) $wpdb->insert_id;
   108 
   118 
   109 	wp_cache_delete($object_id, $meta_type . '_meta');
   119 	wp_cache_delete( $object_id, $meta_type . '_meta' );
   110 
   120 
   111 	/**
   121 	/**
   112 	 * Fires immediately after meta of a specific type is added.
   122 	 * Fires immediately after meta of a specific type is added.
   113 	 *
   123 	 *
   114 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   124 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   115 	 * object type (comment, post, or user).
   125 	 * object type (comment, post, term, or user).
   116 	 *
   126 	 *
   117 	 * @since 2.9.0
   127 	 * @since 2.9.0
   118 	 *
   128 	 *
   119 	 * @param int    $mid        The meta ID after successful update.
   129 	 * @param int    $mid         The meta ID after successful update.
   120 	 * @param int    $object_id  Object ID.
   130 	 * @param int    $object_id   Object ID.
   121 	 * @param string $meta_key   Meta key.
   131 	 * @param string $meta_key    Meta key.
   122 	 * @param mixed  $meta_value Meta value.
   132 	 * @param mixed  $_meta_value Meta value.
   123 	 */
   133 	 */
   124 	do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value );
   134 	do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value );
   125 
   135 
   126 	return $mid;
   136 	return $mid;
   127 }
   137 }
   132  *
   142  *
   133  * @since 2.9.0
   143  * @since 2.9.0
   134  *
   144  *
   135  * @global wpdb $wpdb WordPress database abstraction object.
   145  * @global wpdb $wpdb WordPress database abstraction object.
   136  *
   146  *
   137  * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
   147  * @param string $meta_type  Type of object metadata is for (e.g., comment, post, term, or user).
   138  * @param int    $object_id  ID of the object metadata is for
   148  * @param int    $object_id  ID of the object metadata is for
   139  * @param string $meta_key   Metadata key
   149  * @param string $meta_key   Metadata key
   140  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
   150  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
   141  * @param mixed  $prev_value Optional. If specified, only update existing metadata entries with
   151  * @param mixed  $prev_value Optional. If specified, only update existing metadata entries with
   142  * 		                     the specified value. Otherwise, update all entries.
   152  *                           the specified value. Otherwise, update all entries.
   143  * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
   153  * @return int|bool The new meta field ID if a field with the given key didn't exist and was
   144  */
   154  *                  therefore added, true on successful update, false on failure.
   145 function update_metadata($meta_type, $object_id, $meta_key, $meta_value, $prev_value = '') {
   155  */
       
   156 function update_metadata( $meta_type, $object_id, $meta_key, $meta_value, $prev_value = '' ) {
   146 	global $wpdb;
   157 	global $wpdb;
   147 
   158 
   148 	if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
   159 	if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
   149 		return false;
   160 		return false;
   150 	}
   161 	}
   159 		return false;
   170 		return false;
   160 	}
   171 	}
   161 
   172 
   162 	$meta_subtype = get_object_subtype( $meta_type, $object_id );
   173 	$meta_subtype = get_object_subtype( $meta_type, $object_id );
   163 
   174 
   164 	$column = sanitize_key($meta_type . '_id');
   175 	$column    = sanitize_key( $meta_type . '_id' );
   165 	$id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
   176 	$id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
   166 
   177 
   167 	// expected_slashed ($meta_key)
   178 	// expected_slashed ($meta_key)
   168 	$raw_meta_key = $meta_key;
   179 	$raw_meta_key = $meta_key;
   169 	$meta_key = wp_unslash($meta_key);
   180 	$meta_key     = wp_unslash( $meta_key );
   170 	$passed_value = $meta_value;
   181 	$passed_value = $meta_value;
   171 	$meta_value = wp_unslash($meta_value);
   182 	$meta_value   = wp_unslash( $meta_value );
   172 	$meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
   183 	$meta_value   = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
   173 
   184 
   174 	/**
   185 	/**
   175 	 * Filters whether to update metadata of a specific type.
   186 	 * Filters whether to update metadata of a specific type.
   176 	 *
   187 	 *
   177 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   188 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   178 	 * object type (comment, post, or user). Returning a non-null value
   189 	 * object type (comment, post, term, or user). Returning a non-null value
   179 	 * will effectively short-circuit the function.
   190 	 * will effectively short-circuit the function.
   180 	 *
   191 	 *
   181 	 * @since 3.1.0
   192 	 * @since 3.1.0
   182 	 *
   193 	 *
   183 	 * @param null|bool $check      Whether to allow updating metadata for the given type.
   194 	 * @param null|bool $check      Whether to allow updating metadata for the given type.
   187 	 * @param mixed     $prev_value Optional. If specified, only update existing
   198 	 * @param mixed     $prev_value Optional. If specified, only update existing
   188 	 *                              metadata entries with the specified value.
   199 	 *                              metadata entries with the specified value.
   189 	 *                              Otherwise, update all entries.
   200 	 *                              Otherwise, update all entries.
   190 	 */
   201 	 */
   191 	$check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value );
   202 	$check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value );
   192 	if ( null !== $check )
   203 	if ( null !== $check ) {
   193 		return (bool) $check;
   204 		return (bool) $check;
       
   205 	}
   194 
   206 
   195 	// Compare existing value to new value if no prev value given and the key exists only once.
   207 	// Compare existing value to new value if no prev value given and the key exists only once.
   196 	if ( empty($prev_value) ) {
   208 	if ( empty( $prev_value ) ) {
   197 		$old_value = get_metadata($meta_type, $object_id, $meta_key);
   209 		$old_value = get_metadata( $meta_type, $object_id, $meta_key );
   198 		if ( count($old_value) == 1 ) {
   210 		if ( count( $old_value ) == 1 ) {
   199 			if ( $old_value[0] === $meta_value )
   211 			if ( $old_value[0] === $meta_value ) {
   200 				return false;
   212 				return false;
       
   213 			}
   201 		}
   214 		}
   202 	}
   215 	}
   203 
   216 
   204 	$meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) );
   217 	$meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) );
   205 	if ( empty( $meta_ids ) ) {
   218 	if ( empty( $meta_ids ) ) {
   206 		return add_metadata( $meta_type, $object_id, $raw_meta_key, $passed_value );
   219 		return add_metadata( $meta_type, $object_id, $raw_meta_key, $passed_value );
   207 	}
   220 	}
   208 
   221 
   209 	$_meta_value = $meta_value;
   222 	$_meta_value = $meta_value;
   210 	$meta_value = maybe_serialize( $meta_value );
   223 	$meta_value  = maybe_serialize( $meta_value );
   211 
   224 
   212 	$data  = compact( 'meta_value' );
   225 	$data  = compact( 'meta_value' );
   213 	$where = array( $column => $object_id, 'meta_key' => $meta_key );
   226 	$where = array(
   214 
   227 		$column    => $object_id,
   215 	if ( !empty( $prev_value ) ) {
   228 		'meta_key' => $meta_key,
   216 		$prev_value = maybe_serialize($prev_value);
   229 	);
       
   230 
       
   231 	if ( ! empty( $prev_value ) ) {
       
   232 		$prev_value          = maybe_serialize( $prev_value );
   217 		$where['meta_value'] = $prev_value;
   233 		$where['meta_value'] = $prev_value;
   218 	}
   234 	}
   219 
   235 
   220 	foreach ( $meta_ids as $meta_id ) {
   236 	foreach ( $meta_ids as $meta_id ) {
   221 		/**
   237 		/**
   222 		 * Fires immediately before updating metadata of a specific type.
   238 		 * Fires immediately before updating metadata of a specific type.
   223 		 *
   239 		 *
   224 		 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   240 		 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   225 		 * object type (comment, post, or user).
   241 		 * object type (comment, post, term, or user).
   226 		 *
   242 		 *
   227 		 * @since 2.9.0
   243 		 * @since 2.9.0
   228 		 *
   244 		 *
   229 		 * @param int    $meta_id    ID of the metadata entry to update.
   245 		 * @param int    $meta_id     ID of the metadata entry to update.
   230 		 * @param int    $object_id  Object ID.
   246 		 * @param int    $object_id   Object ID.
   231 		 * @param string $meta_key   Meta key.
   247 		 * @param string $meta_key    Meta key.
   232 		 * @param mixed  $meta_value Meta value.
   248 		 * @param mixed  $_meta_value Meta value.
   233 		 */
   249 		 */
   234 		do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
   250 		do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
   235 
   251 
   236 		if ( 'post' == $meta_type ) {
   252 		if ( 'post' == $meta_type ) {
   237 			/**
   253 			/**
   238 			 * Fires immediately before updating a post's metadata.
   254 			 * Fires immediately before updating a post's metadata.
   239 			 *
   255 			 *
   240 			 * @since 2.9.0
   256 			 * @since 2.9.0
   241 			 *
   257 			 *
   242 			 * @param int    $meta_id    ID of metadata entry to update.
   258 			 * @param int    $meta_id    ID of metadata entry to update.
   243 			 * @param int    $object_id  Object ID.
   259 			 * @param int    $object_id  Post ID.
   244 			 * @param string $meta_key   Meta key.
   260 			 * @param string $meta_key   Meta key.
   245 			 * @param mixed  $meta_value Meta value.
   261 			 * @param mixed  $meta_value Meta value. This will be a PHP-serialized string representation of the value if
       
   262 			 *                           the value is an array, an object, or itself a PHP-serialized string.
   246 			 */
   263 			 */
   247 			do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
   264 			do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
   248 		}
   265 		}
   249 	}
   266 	}
   250 
   267 
   251 	$result = $wpdb->update( $table, $data, $where );
   268 	$result = $wpdb->update( $table, $data, $where );
   252 	if ( ! $result )
   269 	if ( ! $result ) {
   253 		return false;
   270 		return false;
   254 
   271 	}
   255 	wp_cache_delete($object_id, $meta_type . '_meta');
   272 
       
   273 	wp_cache_delete( $object_id, $meta_type . '_meta' );
   256 
   274 
   257 	foreach ( $meta_ids as $meta_id ) {
   275 	foreach ( $meta_ids as $meta_id ) {
   258 		/**
   276 		/**
   259 		 * Fires immediately after updating metadata of a specific type.
   277 		 * Fires immediately after updating metadata of a specific type.
   260 		 *
   278 		 *
   261 		 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   279 		 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   262 		 * object type (comment, post, or user).
   280 		 * object type (comment, post, term, or user).
   263 		 *
   281 		 *
   264 		 * @since 2.9.0
   282 		 * @since 2.9.0
   265 		 *
   283 		 *
   266 		 * @param int    $meta_id    ID of updated metadata entry.
   284 		 * @param int    $meta_id     ID of updated metadata entry.
   267 		 * @param int    $object_id  Object ID.
   285 		 * @param int    $object_id   Object ID.
   268 		 * @param string $meta_key   Meta key.
   286 		 * @param string $meta_key    Meta key.
   269 		 * @param mixed  $meta_value Meta value.
   287 		 * @param mixed  $_meta_value Meta value.
   270 		 */
   288 		 */
   271 		do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
   289 		do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
   272 
   290 
   273 		if ( 'post' == $meta_type ) {
   291 		if ( 'post' == $meta_type ) {
   274 			/**
   292 			/**
   275 			 * Fires immediately after updating a post's metadata.
   293 			 * Fires immediately after updating a post's metadata.
   276 			 *
   294 			 *
   277 			 * @since 2.9.0
   295 			 * @since 2.9.0
   278 			 *
   296 			 *
   279 			 * @param int    $meta_id    ID of updated metadata entry.
   297 			 * @param int    $meta_id    ID of updated metadata entry.
   280 			 * @param int    $object_id  Object ID.
   298 			 * @param int    $object_id  Post ID.
   281 			 * @param string $meta_key   Meta key.
   299 			 * @param string $meta_key   Meta key.
   282 			 * @param mixed  $meta_value Meta value.
   300 			 * @param mixed  $meta_value Meta value. This will be a PHP-serialized string representation of the value if
       
   301 			 *                           the value is an array, an object, or itself a PHP-serialized string.
   283 			 */
   302 			 */
   284 			do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
   303 			do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
   285 		}
   304 		}
   286 	}
   305 	}
   287 
   306 
   293  *
   312  *
   294  * @since 2.9.0
   313  * @since 2.9.0
   295  *
   314  *
   296  * @global wpdb $wpdb WordPress database abstraction object.
   315  * @global wpdb $wpdb WordPress database abstraction object.
   297  *
   316  *
   298  * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
   317  * @param string $meta_type  Type of object metadata is for (e.g., comment, post, term, or user).
   299  * @param int    $object_id  ID of the object metadata is for
   318  * @param int    $object_id  ID of the object metadata is for
   300  * @param string $meta_key   Metadata key
   319  * @param string $meta_key   Metadata key
   301  * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
   320  * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
   302  *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
   321  *                           metadata entries with this value. Otherwise, delete all entries with the specified meta_key.
   303  *                           Pass `null, `false`, or an empty string to skip this check. (For backward compatibility,
   322  *                           Pass `null`, `false`, or an empty string to skip this check. (For backward compatibility,
   304  *                           it is not possible to pass an empty string to delete those entries with an empty string
   323  *                           it is not possible to pass an empty string to delete those entries with an empty string
   305  *                           for a value.)
   324  *                           for a value.)
   306  * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
   325  * @param bool   $delete_all Optional, default is false. If true, delete matching metadata entries for all objects,
   307  *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
   326  *                           ignoring the specified object_id. Otherwise, only delete matching metadata entries for
   308  *                           the specified object_id.
   327  *                           the specified object_id.
   309  * @return bool True on successful delete, false on failure.
   328  * @return bool True on successful delete, false on failure.
   310  */
   329  */
   311 function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false) {
   330 function delete_metadata( $meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false ) {
   312 	global $wpdb;
   331 	global $wpdb;
   313 
   332 
   314 	if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) && ! $delete_all ) {
   333 	if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) && ! $delete_all ) {
   315 		return false;
   334 		return false;
   316 	}
   335 	}
   323 	$table = _get_meta_table( $meta_type );
   342 	$table = _get_meta_table( $meta_type );
   324 	if ( ! $table ) {
   343 	if ( ! $table ) {
   325 		return false;
   344 		return false;
   326 	}
   345 	}
   327 
   346 
   328 	$type_column = sanitize_key($meta_type . '_id');
   347 	$type_column = sanitize_key( $meta_type . '_id' );
   329 	$id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
   348 	$id_column   = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
   330 	// expected_slashed ($meta_key)
   349 	// expected_slashed ($meta_key)
   331 	$meta_key = wp_unslash($meta_key);
   350 	$meta_key   = wp_unslash( $meta_key );
   332 	$meta_value = wp_unslash($meta_value);
   351 	$meta_value = wp_unslash( $meta_value );
   333 
   352 
   334 	/**
   353 	/**
   335 	 * Filters whether to delete metadata of a specific type.
   354 	 * Filters whether to delete metadata of a specific type.
   336 	 *
   355 	 *
   337 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   356 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   338 	 * object type (comment, post, or user). Returning a non-null value
   357 	 * object type (comment, post, term, or user). Returning a non-null value
   339 	 * will effectively short-circuit the function.
   358 	 * will effectively short-circuit the function.
   340 	 *
   359 	 *
   341 	 * @since 3.1.0
   360 	 * @since 3.1.0
   342 	 *
   361 	 *
   343 	 * @param null|bool $delete     Whether to allow metadata deletion of the given type.
   362 	 * @param null|bool $delete     Whether to allow metadata deletion of the given type.
   347 	 * @param bool      $delete_all Whether to delete the matching metadata entries
   366 	 * @param bool      $delete_all Whether to delete the matching metadata entries
   348 	 *                              for all objects, ignoring the specified $object_id.
   367 	 *                              for all objects, ignoring the specified $object_id.
   349 	 *                              Default false.
   368 	 *                              Default false.
   350 	 */
   369 	 */
   351 	$check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all );
   370 	$check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all );
   352 	if ( null !== $check )
   371 	if ( null !== $check ) {
   353 		return (bool) $check;
   372 		return (bool) $check;
       
   373 	}
   354 
   374 
   355 	$_meta_value = $meta_value;
   375 	$_meta_value = $meta_value;
   356 	$meta_value = maybe_serialize( $meta_value );
   376 	$meta_value  = maybe_serialize( $meta_value );
   357 
   377 
   358 	$query = $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s", $meta_key );
   378 	$query = $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s", $meta_key );
   359 
   379 
   360 	if ( !$delete_all )
   380 	if ( ! $delete_all ) {
   361 		$query .= $wpdb->prepare(" AND $type_column = %d", $object_id );
   381 		$query .= $wpdb->prepare( " AND $type_column = %d", $object_id );
   362 
   382 	}
   363 	if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value )
   383 
   364 		$query .= $wpdb->prepare(" AND meta_value = %s", $meta_value );
   384 	if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) {
       
   385 		$query .= $wpdb->prepare( ' AND meta_value = %s', $meta_value );
       
   386 	}
   365 
   387 
   366 	$meta_ids = $wpdb->get_col( $query );
   388 	$meta_ids = $wpdb->get_col( $query );
   367 	if ( !count( $meta_ids ) )
   389 	if ( ! count( $meta_ids ) ) {
   368 		return false;
   390 		return false;
       
   391 	}
   369 
   392 
   370 	if ( $delete_all ) {
   393 	if ( $delete_all ) {
   371 		if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) {
   394 		if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) {
   372 			$object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value ) );
   395 			$object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value ) );
   373 		} else {
   396 		} else {
   377 
   400 
   378 	/**
   401 	/**
   379 	 * Fires immediately before deleting metadata of a specific type.
   402 	 * Fires immediately before deleting metadata of a specific type.
   380 	 *
   403 	 *
   381 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   404 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   382 	 * object type (comment, post, or user).
   405 	 * object type (comment, post, term, or user).
   383 	 *
   406 	 *
   384 	 * @since 3.1.0
   407 	 * @since 3.1.0
   385 	 *
   408 	 *
   386 	 * @param array  $meta_ids   An array of metadata entry IDs to delete.
   409 	 * @param array  $meta_ids    An array of metadata entry IDs to delete.
   387 	 * @param int    $object_id  Object ID.
   410 	 * @param int    $object_id   Object ID.
   388 	 * @param string $meta_key   Meta key.
   411 	 * @param string $meta_key    Meta key.
   389 	 * @param mixed  $meta_value Meta value.
   412 	 * @param mixed  $_meta_value Meta value.
   390 	 */
   413 	 */
   391 	do_action( "delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
   414 	do_action( "delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
   392 
   415 
   393 	// Old-style action.
   416 	// Old-style action.
   394 	if ( 'post' == $meta_type ) {
   417 	if ( 'post' == $meta_type ) {
   400 		 * @param array $meta_ids An array of post metadata entry IDs to delete.
   423 		 * @param array $meta_ids An array of post metadata entry IDs to delete.
   401 		 */
   424 		 */
   402 		do_action( 'delete_postmeta', $meta_ids );
   425 		do_action( 'delete_postmeta', $meta_ids );
   403 	}
   426 	}
   404 
   427 
   405 	$query = "DELETE FROM $table WHERE $id_column IN( " . implode( ',', $meta_ids ) . " )";
   428 	$query = "DELETE FROM $table WHERE $id_column IN( " . implode( ',', $meta_ids ) . ' )';
   406 
   429 
   407 	$count = $wpdb->query($query);
   430 	$count = $wpdb->query( $query );
   408 
   431 
   409 	if ( !$count )
   432 	if ( ! $count ) {
   410 		return false;
   433 		return false;
       
   434 	}
   411 
   435 
   412 	if ( $delete_all ) {
   436 	if ( $delete_all ) {
   413 		foreach ( (array) $object_ids as $o_id ) {
   437 		foreach ( (array) $object_ids as $o_id ) {
   414 			wp_cache_delete($o_id, $meta_type . '_meta');
   438 			wp_cache_delete( $o_id, $meta_type . '_meta' );
   415 		}
   439 		}
   416 	} else {
   440 	} else {
   417 		wp_cache_delete($object_id, $meta_type . '_meta');
   441 		wp_cache_delete( $object_id, $meta_type . '_meta' );
   418 	}
   442 	}
   419 
   443 
   420 	/**
   444 	/**
   421 	 * Fires immediately after deleting metadata of a specific type.
   445 	 * Fires immediately after deleting metadata of a specific type.
   422 	 *
   446 	 *
   423 	 * The dynamic portion of the hook name, `$meta_type`, refers to the meta
   447 	 * The dynamic portion of the hook name, `$meta_type`, refers to the meta
   424 	 * object type (comment, post, or user).
   448 	 * object type (comment, post, term, or user).
   425 	 *
   449 	 *
   426 	 * @since 2.9.0
   450 	 * @since 2.9.0
   427 	 *
   451 	 *
   428 	 * @param array  $meta_ids   An array of deleted metadata entry IDs.
   452 	 * @param array  $meta_ids    An array of deleted metadata entry IDs.
   429 	 * @param int    $object_id  Object ID.
   453 	 * @param int    $object_id   Object ID.
   430 	 * @param string $meta_key   Meta key.
   454 	 * @param string $meta_key    Meta key.
   431 	 * @param mixed  $meta_value Meta value.
   455 	 * @param mixed  $_meta_value Meta value.
   432 	 */
   456 	 */
   433 	do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
   457 	do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
   434 
   458 
   435 	// Old-style action.
   459 	// Old-style action.
   436 	if ( 'post' == $meta_type ) {
   460 	if ( 'post' == $meta_type ) {
   450 /**
   474 /**
   451  * Retrieve metadata for the specified object.
   475  * Retrieve metadata for the specified object.
   452  *
   476  *
   453  * @since 2.9.0
   477  * @since 2.9.0
   454  *
   478  *
   455  * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
   479  * @param string $meta_type Type of object metadata is for (e.g., comment, post, term, or user).
   456  * @param int    $object_id ID of the object metadata is for
   480  * @param int    $object_id ID of the object metadata is for
   457  * @param string $meta_key  Optional. Metadata key. If not specified, retrieve all metadata for
   481  * @param string $meta_key  Optional. Metadata key. If not specified, retrieve all metadata for
   458  * 		                    the specified object.
   482  *                          the specified object.
   459  * @param bool   $single    Optional, default is false.
   483  * @param bool   $single    Optional, default is false.
   460  *                          If true, return only the first value of the specified meta_key.
   484  *                          If true, return only the first value of the specified meta_key.
   461  *                          This parameter has no effect if meta_key is not specified.
   485  *                          This parameter has no effect if meta_key is not specified.
   462  * @return mixed Single metadata value, or array of values
   486  * @return mixed Single metadata value, or array of values
   463  */
   487  */
   464 function get_metadata($meta_type, $object_id, $meta_key = '', $single = false) {
   488 function get_metadata( $meta_type, $object_id, $meta_key = '', $single = false ) {
   465 	if ( ! $meta_type || ! is_numeric( $object_id ) ) {
   489 	if ( ! $meta_type || ! is_numeric( $object_id ) ) {
   466 		return false;
   490 		return false;
   467 	}
   491 	}
   468 
   492 
   469 	$object_id = absint( $object_id );
   493 	$object_id = absint( $object_id );
   473 
   497 
   474 	/**
   498 	/**
   475 	 * Filters whether to retrieve metadata of a specific type.
   499 	 * Filters whether to retrieve metadata of a specific type.
   476 	 *
   500 	 *
   477 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   501 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
   478 	 * object type (comment, post, or user). Returning a non-null value
   502 	 * object type (comment, post, term, or user). Returning a non-null value
   479 	 * will effectively short-circuit the function.
   503 	 * will effectively short-circuit the function.
   480 	 *
   504 	 *
   481 	 * @since 3.1.0
   505 	 * @since 3.1.0
   482 	 *
   506 	 *
   483 	 * @param null|array|string $value     The value get_metadata() should return - a single metadata value,
   507 	 * @param null|array|string $value     The value get_metadata() should return - a single metadata value,
   486 	 * @param string            $meta_key  Meta key.
   510 	 * @param string            $meta_key  Meta key.
   487 	 * @param bool              $single    Whether to return only the first value of the specified $meta_key.
   511 	 * @param bool              $single    Whether to return only the first value of the specified $meta_key.
   488 	 */
   512 	 */
   489 	$check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single );
   513 	$check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single );
   490 	if ( null !== $check ) {
   514 	if ( null !== $check ) {
   491 		if ( $single && is_array( $check ) )
   515 		if ( $single && is_array( $check ) ) {
   492 			return $check[0];
   516 			return $check[0];
   493 		else
   517 		} else {
   494 			return $check;
   518 			return $check;
   495 	}
   519 		}
   496 
   520 	}
   497 	$meta_cache = wp_cache_get($object_id, $meta_type . '_meta');
   521 
   498 
   522 	$meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' );
   499 	if ( !$meta_cache ) {
   523 
       
   524 	if ( ! $meta_cache ) {
   500 		$meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
   525 		$meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
   501 		$meta_cache = $meta_cache[$object_id];
   526 		$meta_cache = $meta_cache[ $object_id ];
   502 	}
   527 	}
   503 
   528 
   504 	if ( ! $meta_key ) {
   529 	if ( ! $meta_key ) {
   505 		return $meta_cache;
   530 		return $meta_cache;
   506 	}
   531 	}
   507 
   532 
   508 	if ( isset($meta_cache[$meta_key]) ) {
   533 	if ( isset( $meta_cache[ $meta_key ] ) ) {
   509 		if ( $single )
   534 		if ( $single ) {
   510 			return maybe_unserialize( $meta_cache[$meta_key][0] );
   535 			return maybe_unserialize( $meta_cache[ $meta_key ][0] );
   511 		else
   536 		} else {
   512 			return array_map('maybe_unserialize', $meta_cache[$meta_key]);
   537 			return array_map( 'maybe_unserialize', $meta_cache[ $meta_key ] );
   513 	}
   538 		}
   514 
   539 	}
   515 	if ($single)
   540 
       
   541 	if ( $single ) {
   516 		return '';
   542 		return '';
   517 	else
   543 	} else {
   518 		return array();
   544 		return array();
       
   545 	}
   519 }
   546 }
   520 
   547 
   521 /**
   548 /**
   522  * Determine if a meta key is set for a given object
   549  * Determine if a meta key is set for a given object
   523  *
   550  *
   524  * @since 3.3.0
   551  * @since 3.3.0
   525  *
   552  *
   526  * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
   553  * @param string $meta_type Type of object metadata is for (e.g., comment, post, term, or user).
   527  * @param int    $object_id ID of the object metadata is for
   554  * @param int    $object_id ID of the object metadata is for
   528  * @param string $meta_key  Metadata key.
   555  * @param string $meta_key  Metadata key.
   529  * @return bool True of the key is set, false if not.
   556  * @return bool True of the key is set, false if not.
   530  */
   557  */
   531 function metadata_exists( $meta_type, $object_id, $meta_key ) {
   558 function metadata_exists( $meta_type, $object_id, $meta_key ) {
   538 		return false;
   565 		return false;
   539 	}
   566 	}
   540 
   567 
   541 	/** This filter is documented in wp-includes/meta.php */
   568 	/** This filter is documented in wp-includes/meta.php */
   542 	$check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, true );
   569 	$check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, true );
   543 	if ( null !== $check )
   570 	if ( null !== $check ) {
   544 		return (bool) $check;
   571 		return (bool) $check;
       
   572 	}
   545 
   573 
   546 	$meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' );
   574 	$meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' );
   547 
   575 
   548 	if ( !$meta_cache ) {
   576 	if ( ! $meta_cache ) {
   549 		$meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
   577 		$meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
   550 		$meta_cache = $meta_cache[$object_id];
   578 		$meta_cache = $meta_cache[ $object_id ];
   551 	}
   579 	}
   552 
   580 
   553 	if ( isset( $meta_cache[ $meta_key ] ) )
   581 	if ( isset( $meta_cache[ $meta_key ] ) ) {
   554 		return true;
   582 		return true;
       
   583 	}
   555 
   584 
   556 	return false;
   585 	return false;
   557 }
   586 }
   558 
   587 
   559 /**
   588 /**
   584 		return false;
   613 		return false;
   585 	}
   614 	}
   586 
   615 
   587 	$id_column = ( 'user' == $meta_type ) ? 'umeta_id' : 'meta_id';
   616 	$id_column = ( 'user' == $meta_type ) ? 'umeta_id' : 'meta_id';
   588 
   617 
       
   618 	/**
       
   619 	 * Filters whether to retrieve metadata of a specific type by meta ID.
       
   620 	 *
       
   621 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
       
   622 	 * object type (comment, post, term, or user). Returning a non-null value
       
   623 	 * will effectively short-circuit the function.
       
   624 	 *
       
   625 	 * @since 5.0.0
       
   626 	 *
       
   627 	 * @param mixed $value    The value get_metadata_by_mid() should return.
       
   628 	 * @param int   $meta_id  Meta ID.
       
   629 	 */
       
   630 	$check = apply_filters( "get_{$meta_type}_metadata_by_mid", null, $meta_id );
       
   631 	if ( null !== $check ) {
       
   632 		return $check;
       
   633 	}
       
   634 
   589 	$meta = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE $id_column = %d", $meta_id ) );
   635 	$meta = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE $id_column = %d", $meta_id ) );
   590 
   636 
   591 	if ( empty( $meta ) )
   637 	if ( empty( $meta ) ) {
   592 		return false;
   638 		return false;
   593 
   639 	}
   594 	if ( isset( $meta->meta_value ) )
   640 
       
   641 	if ( isset( $meta->meta_value ) ) {
   595 		$meta->meta_value = maybe_unserialize( $meta->meta_value );
   642 		$meta->meta_value = maybe_unserialize( $meta->meta_value );
       
   643 	}
   596 
   644 
   597 	return $meta;
   645 	return $meta;
   598 }
   646 }
   599 
   647 
   600 /**
   648 /**
   602  *
   650  *
   603  * @since 3.3.0
   651  * @since 3.3.0
   604  *
   652  *
   605  * @global wpdb $wpdb WordPress database abstraction object.
   653  * @global wpdb $wpdb WordPress database abstraction object.
   606  *
   654  *
   607  * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
   655  * @param string $meta_type  Type of object metadata is for (e.g., comment, post, term, or user).
   608  * @param int    $meta_id    ID for a specific meta row
   656  * @param int    $meta_id    ID for a specific meta row
   609  * @param string $meta_value Metadata value
   657  * @param string $meta_value Metadata value
   610  * @param string $meta_key   Optional, you can provide a meta key to update it
   658  * @param string $meta_key   Optional, you can provide a meta key to update it
   611  * @return bool True on successful update, false on failure.
   659  * @return bool True on successful update, false on failure.
   612  */
   660  */
   626 	$table = _get_meta_table( $meta_type );
   674 	$table = _get_meta_table( $meta_type );
   627 	if ( ! $table ) {
   675 	if ( ! $table ) {
   628 		return false;
   676 		return false;
   629 	}
   677 	}
   630 
   678 
   631 	$column = sanitize_key($meta_type . '_id');
   679 	$column    = sanitize_key( $meta_type . '_id' );
   632 	$id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
   680 	$id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
       
   681 
       
   682 	/**
       
   683 	 * Filters whether to update metadata of a specific type by meta ID.
       
   684 	 *
       
   685 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
       
   686 	 * object type (comment, post, term, or user). Returning a non-null value
       
   687 	 * will effectively short-circuit the function.
       
   688 	 *
       
   689 	 * @since 5.0.0
       
   690 	 *
       
   691 	 * @param null|bool   $check      Whether to allow updating metadata for the given type.
       
   692 	 * @param int         $meta_id    Meta ID.
       
   693 	 * @param mixed       $meta_value Meta value. Must be serializable if non-scalar.
       
   694 	 * @param string|bool $meta_key   Meta key, if provided.
       
   695 	 */
       
   696 	$check = apply_filters( "update_{$meta_type}_metadata_by_mid", null, $meta_id, $meta_value, $meta_key );
       
   697 	if ( null !== $check ) {
       
   698 		return (bool) $check;
       
   699 	}
   633 
   700 
   634 	// Fetch the meta and go on if it's found.
   701 	// Fetch the meta and go on if it's found.
   635 	if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) {
   702 	if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) {
   636 		$original_key = $meta->meta_key;
   703 		$original_key = $meta->meta_key;
   637 		$object_id = $meta->{$column};
   704 		$object_id    = $meta->{$column};
   638 
   705 
   639 		// If a new meta_key (last parameter) was specified, change the meta key,
   706 		// If a new meta_key (last parameter) was specified, change the meta key,
   640 		// otherwise use the original key in the update statement.
   707 		// otherwise use the original key in the update statement.
   641 		if ( false === $meta_key ) {
   708 		if ( false === $meta_key ) {
   642 			$meta_key = $original_key;
   709 			$meta_key = $original_key;
   651 		$meta_value  = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
   718 		$meta_value  = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
   652 		$meta_value  = maybe_serialize( $meta_value );
   719 		$meta_value  = maybe_serialize( $meta_value );
   653 
   720 
   654 		// Format the data query arguments.
   721 		// Format the data query arguments.
   655 		$data = array(
   722 		$data = array(
   656 			'meta_key' => $meta_key,
   723 			'meta_key'   => $meta_key,
   657 			'meta_value' => $meta_value
   724 			'meta_value' => $meta_value,
   658 		);
   725 		);
   659 
   726 
   660 		// Format the where query arguments.
   727 		// Format the where query arguments.
   661 		$where = array();
   728 		$where               = array();
   662 		$where[$id_column] = $meta_id;
   729 		$where[ $id_column ] = $meta_id;
   663 
   730 
   664 		/** This action is documented in wp-includes/meta.php */
   731 		/** This action is documented in wp-includes/meta.php */
   665 		do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
   732 		do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
   666 
   733 
   667 		if ( 'post' == $meta_type ) {
   734 		if ( 'post' == $meta_type ) {
   669 			do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
   736 			do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
   670 		}
   737 		}
   671 
   738 
   672 		// Run the update query, all fields in $data are %s, $where is a %d.
   739 		// Run the update query, all fields in $data are %s, $where is a %d.
   673 		$result = $wpdb->update( $table, $data, $where, '%s', '%d' );
   740 		$result = $wpdb->update( $table, $data, $where, '%s', '%d' );
   674 		if ( ! $result )
   741 		if ( ! $result ) {
   675 			return false;
   742 			return false;
       
   743 		}
   676 
   744 
   677 		// Clear the caches.
   745 		// Clear the caches.
   678 		wp_cache_delete($object_id, $meta_type . '_meta');
   746 		wp_cache_delete( $object_id, $meta_type . '_meta' );
   679 
   747 
   680 		/** This action is documented in wp-includes/meta.php */
   748 		/** This action is documented in wp-includes/meta.php */
   681 		do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
   749 		do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
   682 
   750 
   683 		if ( 'post' == $meta_type ) {
   751 		if ( 'post' == $meta_type ) {
   720 	if ( ! $table ) {
   788 	if ( ! $table ) {
   721 		return false;
   789 		return false;
   722 	}
   790 	}
   723 
   791 
   724 	// object and id columns
   792 	// object and id columns
   725 	$column = sanitize_key($meta_type . '_id');
   793 	$column    = sanitize_key( $meta_type . '_id' );
   726 	$id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
   794 	$id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
       
   795 
       
   796 	/**
       
   797 	 * Filters whether to delete metadata of a specific type by meta ID.
       
   798 	 *
       
   799 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
       
   800 	 * object type (comment, post, term, or user). Returning a non-null value
       
   801 	 * will effectively short-circuit the function.
       
   802 	 *
       
   803 	 * @since 5.0.0
       
   804 	 *
       
   805 	 * @param null|bool $delete  Whether to allow metadata deletion of the given type.
       
   806 	 * @param int       $meta_id Meta ID.
       
   807 	 */
       
   808 	$check = apply_filters( "delete_{$meta_type}_metadata_by_mid", null, $meta_id );
       
   809 	if ( null !== $check ) {
       
   810 		return (bool) $check;
       
   811 	}
   727 
   812 
   728 	// Fetch the meta and go on if it's found.
   813 	// Fetch the meta and go on if it's found.
   729 	if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) {
   814 	if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) {
   730 		$object_id = $meta->{$column};
   815 		$object_id = (int) $meta->{$column};
   731 
   816 
   732 		/** This action is documented in wp-includes/meta.php */
   817 		/** This action is documented in wp-includes/meta.php */
   733 		do_action( "delete_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
   818 		do_action( "delete_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
   734 
   819 
   735 		// Old-style action.
   820 		// Old-style action.
   749 
   834 
   750 		// Run the query, will return true if deleted, false otherwise
   835 		// Run the query, will return true if deleted, false otherwise
   751 		$result = (bool) $wpdb->delete( $table, array( $id_column => $meta_id ) );
   836 		$result = (bool) $wpdb->delete( $table, array( $id_column => $meta_id ) );
   752 
   837 
   753 		// Clear the caches.
   838 		// Clear the caches.
   754 		wp_cache_delete($object_id, $meta_type . '_meta');
   839 		wp_cache_delete( $object_id, $meta_type . '_meta' );
   755 
   840 
   756 		/** This action is documented in wp-includes/meta.php */
   841 		/** This action is documented in wp-includes/meta.php */
   757 		do_action( "deleted_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
   842 		do_action( "deleted_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
   758 
   843 
   759 		// Old-style action.
   844 		// Old-style action.
   784  *
   869  *
   785  * @since 2.9.0
   870  * @since 2.9.0
   786  *
   871  *
   787  * @global wpdb $wpdb WordPress database abstraction object.
   872  * @global wpdb $wpdb WordPress database abstraction object.
   788  *
   873  *
   789  * @param string    $meta_type  Type of object metadata is for (e.g., comment, post, or user)
   874  * @param string    $meta_type  Type of object metadata is for (e.g., comment, post, term, or user).
   790  * @param int|array $object_ids Array or comma delimited list of object IDs to update cache for
   875  * @param int|array $object_ids Array or comma delimited list of object IDs to update cache for
   791  * @return array|false Metadata cache for the specified objects, or false on failure.
   876  * @return array|false Metadata cache for the specified objects, or false on failure.
   792  */
   877  */
   793 function update_meta_cache($meta_type, $object_ids) {
   878 function update_meta_cache( $meta_type, $object_ids ) {
   794 	global $wpdb;
   879 	global $wpdb;
   795 
   880 
   796 	if ( ! $meta_type || ! $object_ids ) {
   881 	if ( ! $meta_type || ! $object_ids ) {
   797 		return false;
   882 		return false;
   798 	}
   883 	}
   800 	$table = _get_meta_table( $meta_type );
   885 	$table = _get_meta_table( $meta_type );
   801 	if ( ! $table ) {
   886 	if ( ! $table ) {
   802 		return false;
   887 		return false;
   803 	}
   888 	}
   804 
   889 
   805 	$column = sanitize_key($meta_type . '_id');
   890 	$column = sanitize_key( $meta_type . '_id' );
   806 
   891 
   807 	if ( !is_array($object_ids) ) {
   892 	if ( ! is_array( $object_ids ) ) {
   808 		$object_ids = preg_replace('|[^0-9,]|', '', $object_ids);
   893 		$object_ids = preg_replace( '|[^0-9,]|', '', $object_ids );
   809 		$object_ids = explode(',', $object_ids);
   894 		$object_ids = explode( ',', $object_ids );
   810 	}
   895 	}
   811 
   896 
   812 	$object_ids = array_map('intval', $object_ids);
   897 	$object_ids = array_map( 'intval', $object_ids );
       
   898 
       
   899 	/**
       
   900 	 * Filters whether to update the metadata cache of a specific type.
       
   901 	 *
       
   902 	 * The dynamic portion of the hook, `$meta_type`, refers to the meta
       
   903 	 * object type (comment, post, term, or user). Returning a non-null value
       
   904 	 * will effectively short-circuit the function.
       
   905 	 *
       
   906 	 * @since 5.0.0
       
   907 	 *
       
   908 	 * @param mixed $check      Whether to allow updating the meta cache of the given type.
       
   909 	 * @param array $object_ids Array of object IDs to update the meta cache for.
       
   910 	 */
       
   911 	$check = apply_filters( "update_{$meta_type}_metadata_cache", null, $object_ids );
       
   912 	if ( null !== $check ) {
       
   913 		return (bool) $check;
       
   914 	}
   813 
   915 
   814 	$cache_key = $meta_type . '_meta';
   916 	$cache_key = $meta_type . '_meta';
   815 	$ids = array();
   917 	$ids       = array();
   816 	$cache = array();
   918 	$cache     = array();
   817 	foreach ( $object_ids as $id ) {
   919 	foreach ( $object_ids as $id ) {
   818 		$cached_object = wp_cache_get( $id, $cache_key );
   920 		$cached_object = wp_cache_get( $id, $cache_key );
   819 		if ( false === $cached_object )
   921 		if ( false === $cached_object ) {
   820 			$ids[] = $id;
   922 			$ids[] = $id;
   821 		else
   923 		} else {
   822 			$cache[$id] = $cached_object;
   924 			$cache[ $id ] = $cached_object;
   823 	}
   925 		}
   824 
   926 	}
   825 	if ( empty( $ids ) )
   927 
       
   928 	if ( empty( $ids ) ) {
   826 		return $cache;
   929 		return $cache;
       
   930 	}
   827 
   931 
   828 	// Get meta info
   932 	// Get meta info
   829 	$id_list = join( ',', $ids );
   933 	$id_list   = join( ',', $ids );
   830 	$id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
   934 	$id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
   831 	$meta_list = $wpdb->get_results( "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC", ARRAY_A );
   935 	$meta_list = $wpdb->get_results( "SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list) ORDER BY $id_column ASC", ARRAY_A );
   832 
   936 
   833 	if ( !empty($meta_list) ) {
   937 	if ( ! empty( $meta_list ) ) {
   834 		foreach ( $meta_list as $metarow) {
   938 		foreach ( $meta_list as $metarow ) {
   835 			$mpid = intval($metarow[$column]);
   939 			$mpid = intval( $metarow[ $column ] );
   836 			$mkey = $metarow['meta_key'];
   940 			$mkey = $metarow['meta_key'];
   837 			$mval = $metarow['meta_value'];
   941 			$mval = $metarow['meta_value'];
   838 
   942 
   839 			// Force subkeys to be array type:
   943 			// Force subkeys to be array type:
   840 			if ( !isset($cache[$mpid]) || !is_array($cache[$mpid]) )
   944 			if ( ! isset( $cache[ $mpid ] ) || ! is_array( $cache[ $mpid ] ) ) {
   841 				$cache[$mpid] = array();
   945 				$cache[ $mpid ] = array();
   842 			if ( !isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey]) )
   946 			}
   843 				$cache[$mpid][$mkey] = array();
   947 			if ( ! isset( $cache[ $mpid ][ $mkey ] ) || ! is_array( $cache[ $mpid ][ $mkey ] ) ) {
       
   948 				$cache[ $mpid ][ $mkey ] = array();
       
   949 			}
   844 
   950 
   845 			// Add a value to the current pid/key:
   951 			// Add a value to the current pid/key:
   846 			$cache[$mpid][$mkey][] = $mval;
   952 			$cache[ $mpid ][ $mkey ][] = $mval;
   847 		}
   953 		}
   848 	}
   954 	}
   849 
   955 
   850 	foreach ( $ids as $id ) {
   956 	foreach ( $ids as $id ) {
   851 		if ( ! isset($cache[$id]) )
   957 		if ( ! isset( $cache[ $id ] ) ) {
   852 			$cache[$id] = array();
   958 			$cache[ $id ] = array();
   853 		wp_cache_add( $id, $cache[$id], $cache_key );
   959 		}
       
   960 		wp_cache_add( $id, $cache[ $id ], $cache_key );
   854 	}
   961 	}
   855 
   962 
   856 	return $cache;
   963 	return $cache;
   857 }
   964 }
   858 
   965 
   897  *
  1004  *
   898  * @since 2.9.0
  1005  * @since 2.9.0
   899  *
  1006  *
   900  * @global wpdb $wpdb WordPress database abstraction object.
  1007  * @global wpdb $wpdb WordPress database abstraction object.
   901  *
  1008  *
   902  * @param string $type Type of object to get metadata table for (e.g., comment, post, or user)
  1009  * @param string $type Type of object to get metadata table for (e.g., comment, post, term, or user).
   903  * @return string|false Metadata table name, or false if no metadata table exists
  1010  * @return string|false Metadata table name, or false if no metadata table exists
   904  */
  1011  */
   905 function _get_meta_table($type) {
  1012 function _get_meta_table( $type ) {
   906 	global $wpdb;
  1013 	global $wpdb;
   907 
  1014 
   908 	$table_name = $type . 'meta';
  1015 	$table_name = $type . 'meta';
   909 
  1016 
   910 	if ( empty($wpdb->$table_name) )
  1017 	if ( empty( $wpdb->$table_name ) ) {
   911 		return false;
  1018 		return false;
       
  1019 	}
   912 
  1020 
   913 	return $wpdb->$table_name;
  1021 	return $wpdb->$table_name;
   914 }
  1022 }
   915 
  1023 
   916 /**
  1024 /**
   917  * Determine whether a meta key is protected.
  1025  * Determines whether a meta key is considered protected.
   918  *
  1026  *
   919  * @since 3.1.3
  1027  * @since 3.1.3
   920  *
  1028  *
   921  * @param string      $meta_key Meta key
  1029  * @param string      $meta_key  Meta key.
   922  * @param string|null $meta_type
  1030  * @param string|null $meta_type Optional. Type of object metadata is for (e.g., comment, post, term, or user).
   923  * @return bool True if the key is protected, false otherwise.
  1031  * @return bool Whether the meta key is considered protected.
   924  */
  1032  */
   925 function is_protected_meta( $meta_key, $meta_type = null ) {
  1033 function is_protected_meta( $meta_key, $meta_type = null ) {
   926 	$protected = ( '_' == $meta_key[0] );
  1034 	$protected = ( '_' == $meta_key[0] );
   927 
  1035 
   928 	/**
  1036 	/**
   929 	 * Filters whether a meta key is protected.
  1037 	 * Filters whether a meta key is considered protected.
   930 	 *
  1038 	 *
   931 	 * @since 3.2.0
  1039 	 * @since 3.2.0
   932 	 *
  1040 	 *
   933 	 * @param bool   $protected Whether the key is protected. Default false.
  1041 	 * @param bool        $protected Whether the key is considered protected.
   934 	 * @param string $meta_key  Meta key.
  1042 	 * @param string      $meta_key  Meta key.
   935 	 * @param string $meta_type Meta type.
  1043 	 * @param string|null $meta_type Type of object metadata is for (e.g., comment, post, term, or user).
   936 	 */
  1044 	 */
   937 	return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type );
  1045 	return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type );
   938 }
  1046 }
   939 
  1047 
   940 /**
  1048 /**
   944  * @since 4.9.8 The `$object_subtype` parameter was added.
  1052  * @since 4.9.8 The `$object_subtype` parameter was added.
   945  *
  1053  *
   946  * @param string $meta_key       Meta key.
  1054  * @param string $meta_key       Meta key.
   947  * @param mixed  $meta_value     Meta value to sanitize.
  1055  * @param mixed  $meta_value     Meta value to sanitize.
   948  * @param string $object_type    Type of object the meta is registered to.
  1056  * @param string $object_type    Type of object the meta is registered to.
       
  1057  * @param string $object_subtype Optional. The subtype of the object type.
   949  *
  1058  *
   950  * @return mixed Sanitized $meta_value.
  1059  * @return mixed Sanitized $meta_value.
   951  */
  1060  */
   952 function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = '' ) {
  1061 function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = '' ) {
   953 	if ( ! empty( $object_subtype ) && has_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) {
  1062 	if ( ! empty( $object_subtype ) && has_filter( "sanitize_{$object_type}_meta_{$meta_key}_for_{$object_subtype}" ) ) {
   954 
  1063 
   955 		/**
  1064 		/**
   956 		 * Filters the sanitization of a specific meta key of a specific meta type and subtype.
  1065 		 * Filters the sanitization of a specific meta key of a specific meta type and subtype.
   957 		 *
  1066 		 *
   958 		 * The dynamic portions of the hook name, `$object_type`, `$meta_key`,
  1067 		 * The dynamic portions of the hook name, `$object_type`, `$meta_key`,
   959 		 * and `$object_subtype`, refer to the metadata object type (comment, post, term or user),
  1068 		 * and `$object_subtype`, refer to the metadata object type (comment, post, term, or user),
   960 		 * the meta key value, and the object subtype respectively.
  1069 		 * the meta key value, and the object subtype respectively.
   961 		 *
  1070 		 *
   962 		 * @since 4.9.8
  1071 		 * @since 4.9.8
   963 		 *
  1072 		 *
   964 		 * @param mixed  $meta_value     Meta value to sanitize.
  1073 		 * @param mixed  $meta_value     Meta value to sanitize.
   971 
  1080 
   972 	/**
  1081 	/**
   973 	 * Filters the sanitization of a specific meta key of a specific meta type.
  1082 	 * Filters the sanitization of a specific meta key of a specific meta type.
   974 	 *
  1083 	 *
   975 	 * The dynamic portions of the hook name, `$meta_type`, and `$meta_key`,
  1084 	 * The dynamic portions of the hook name, `$meta_type`, and `$meta_key`,
   976 	 * refer to the metadata object type (comment, post, or user) and the meta
  1085 	 * refer to the metadata object type (comment, post, term, or user) and the meta
   977 	 * key value, respectively.
  1086 	 * key value, respectively.
   978 	 *
  1087 	 *
   979 	 * @since 3.3.0
  1088 	 * @since 3.3.0
   980 	 *
  1089 	 *
   981 	 * @param mixed  $meta_value      Meta value to sanitize.
  1090 	 * @param mixed  $meta_value      Meta value to sanitize.
  1039 		'show_in_rest'      => false,
  1148 		'show_in_rest'      => false,
  1040 	);
  1149 	);
  1041 
  1150 
  1042 	// There used to be individual args for sanitize and auth callbacks
  1151 	// There used to be individual args for sanitize and auth callbacks
  1043 	$has_old_sanitize_cb = false;
  1152 	$has_old_sanitize_cb = false;
  1044 	$has_old_auth_cb = false;
  1153 	$has_old_auth_cb     = false;
  1045 
  1154 
  1046 	if ( is_callable( $args ) ) {
  1155 	if ( is_callable( $args ) ) {
  1047 		$args = array(
  1156 		$args = array(
  1048 			'sanitize_callback' => $args,
  1157 			'sanitize_callback' => $args,
  1049 		);
  1158 		);
  1053 		$args = (array) $args;
  1162 		$args = (array) $args;
  1054 	}
  1163 	}
  1055 
  1164 
  1056 	if ( is_callable( $deprecated ) ) {
  1165 	if ( is_callable( $deprecated ) ) {
  1057 		$args['auth_callback'] = $deprecated;
  1166 		$args['auth_callback'] = $deprecated;
  1058 		$has_old_auth_cb = true;
  1167 		$has_old_auth_cb       = true;
  1059 	}
  1168 	}
  1060 
  1169 
  1061 	/**
  1170 	/**
  1062 	 * Filters the registration arguments when registering meta.
  1171 	 * Filters the registration arguments when registering meta.
  1063 	 *
  1172 	 *