Index: www/wp-includes/class-wp-object-type.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- www/wp-includes/class-wp-object-type.php	(revision )
+++ www/wp-includes/class-wp-object-type.php	(revision )
@@ -0,0 +1,443 @@
+<?php
+
+/**
+ * Class WP_Object_Type
+ *
+ * Object Type is an infrastructure class used to classify fields and forms with
+ * other potential classification use cases in the future.
+ *
+ * Registered fields are often intended to be for specific post types and as such
+ * post types need to be specified. However, Fields should not be specific to
+ * post types as fields would be beneficial for users, comments, options, and more.
+ *
+ * So the Object Type was designed to capture and allow developers to specify both
+ * the $type_group of object (i.e. 'post', 'user', 'comment', etc.) as well as the
+ * $subtype specific to the type, (i.e. 'post', 'page', 'attachment', etc. for
+ * Object Types of $class 'post.')
+ *
+ * Object Types literals are specified in string form with a colon separating $class
+ * from $subtype, which looks like this:
+ *
+ *    'post:post'
+ *    'post:page'
+ *    'post:attachment'
+ *    'post:my_post_type'
+ *
+ * Object can be comparied with $object_type where is_object($object_type) is
+ * true (because of the Object Type's __toString() method.):
+ *
+ *    $object_type = new WP_Object_Type( 'post:my_post_type' );
+ *
+ *    if ( 'post:my_post_type' == $object_type ) {
+ *       echo 'They *are* equal!'
+ *    }
+ *
+ * The 'any' subtype will match any item of the specified type group, and if subtype
+ * is ommitted then it implies 'any'. All of these are equivalent:
+ *
+ *    'post:any'
+ *    'post:'
+ *    'post'
+ *
+ * All of these groups of three are equivalent:
+ *
+ *    'term'
+ *    'term:'
+ *    'term:any'
+ *
+ *    'user'
+ *    'user:'
+ *    'user:any'
+ *
+ *    'comment'
+ *    'comment:'
+ *    'comment:any'
+ *
+ */
+final class WP_Object_Type {
+
+	/**
+	 * The $_type property is used to contain the type group of object 
+	 * such as 'post', 'user', 'comment', 'option', etc.
+	 *
+	 * @var null|string
+	 */
+	private $_type_group = null;
+
+	/**
+	 * The $_subtype property is to contain the 'type' relevant to the Object Type's
+	 * $_type, i.e. for 'post' there is 'post', 'page', 'attachment' and whatever
+	 * custom post types have been defined.
+	 *
+	 * For $_type values of 'user' we are currently assuming role will used for $_subtype.
+	 *
+	 * For all other $_type values the value of $_subtype is TBD.
+	 *
+	 * @var null|string[]
+	 */
+	private $_subtype = null;
+
+	/**
+	 * The $_as_string property will contain the string representation of the Object Type
+	 *
+	 * @var null|string[]
+	 */
+	private $_as_string = null;
+
+	/**
+	 * List of valid Object Type Names
+	 *
+	 * @var string[]
+	 */
+	private static $_object_type_names = array(
+		'post',
+		'term',
+		'user',
+		'ccomment',
+	);
+
+	/**
+	 * List of Object Types to be dispensed by get_instance()
+	 *
+	 * @var self[]
+	 */
+	private static $_object_types = array();
+
+	/**
+	 * Returns an immutable instance of WP_Object_Type, reusing when object types match
+	 *
+	 * @example:
+	 *
+	 *      $object_type = WP_Object_Type()::get_instance( 'post:my_post_type' );
+	 *      $object_type2 = WP_Object_Type()::get_instance( $object_type );
+	 *      $object_type3 = WP_Object_Type()::get_instance( 'post:my_post_type' );
+	 *
+	 *      echo $object_type === $object_type2  // true
+	 *      echo $object_type === $object_type3  // true
+	 *
+	 * @param WP_Object_Type|object|array|string $object_type
+	 * @return WP_Object_Type
+	 *
+	 */
+	static function get_instance( $object_type ) {
+
+		do {
+			if ( $object_type instanceof WP_Object_Type ) {
+				break;
+			}
+
+			if ( is_string( $object_type ) && isset( self::$_object_types[ $object_type ] ) ) {
+				$object_type = self::$_object_types[ $object_type ];
+				break;
+			}
+
+			list( $type, $subtype ) = self::parse_object_type( $object_type );
+
+			$as_string = self::_as_string( $type, $subtype );
+
+			if ( ! isset( self::$_object_types[ $as_string ] ) ) {
+
+				$object_type = new WP_Object_Type();
+
+				$object_type->_type      = $type;
+				$object_type->_subtype  = $subtypes;
+				$object_type->_as_string = $as_string;
+
+				self::$_object_types[ $as_string ] = $object_type;
+
+			}
+
+			$object_type = self::$_object_types[ $as_string ];
+
+		} while ( false );
+
+		return $object_type;
+
+	}
+
+	/**
+	 * Parses an $object_type include and returns a 2 element array
+	 *
+	 * @example:
+	 *
+	 *    $result = WP_Object_Type::parse( 'post:my_type1' )
+	 *    echo count( $result );   // 2
+	 *    echo $result[1];         // post
+	 *    echo $result[2];         // my_type3
+	 *
+	 * @param string|WP_Object_Type $object_type
+	 * @return string[]
+	 *
+	 */
+	static function parse_object_type( $object_type ) {
+
+		do {
+
+			if ( empty( $object_type ) ) {
+
+				_doing_it_wrong( __FUNCTION__, sprintf( __( 'Empty parameter \$object_type' ) ), '4.6.0' );
+
+				$result = array( null, null );
+
+				break;
+
+			}
+
+			if ( is_a( $object_type, __CLASS__ ) ) {
+
+				/**
+				 * If a WP_Object_Type object was passed in then copy it's values.
+				 *
+				 * @see The PHPDoc for __construct() to understand why accepting an
+				 *      object in addition to a string literal is useful.
+				 */
+				$result = array( $object_type->_type_group, $object_type->_subtype );
+				
+				break;
+
+			}
+
+			if ( is_string( $object_type ) ) {
+
+
+				/**
+				 * Otherwise split the Object Type literal on a colon and assign
+				 * to $class and $subtypes, respectively.
+				 */
+				list( $type, $subtypes ) = array_map( 'trim', explode( ':', "{$object_type}:" ) );
+
+				$result = array( $type, $subtypes );
+
+				break;
+
+			}
+
+			if ( is_array( $object_type ) && 2 === count( $object_type ) && isset( $object_type[0] ) && isset( $object_type[1] ) ) {
+
+				/**
+				 * A 2 element numerically indexed array where the first element is
+				 * $class and the 2nd is $subtype. So assign it.
+				 */
+
+				$result = $object_type;
+
+				break;
+
+			}
+
+			if ( ! in_array( $result[ 0 ], self::$_object_types ) ) {
+
+				_doing_it_wrong( __FUNCTION__, sprintf( __( 'Invalid "type" %s for \$object_type.' ), $result[ 0 ] ), '4.6.0' );
+				
+				break;
+
+			}
+
+			if ( 'post' === $result[ 0 ] ) {
+
+				global $wp_post_types;
+				if ( ! in_array( $result[ 1 ], $wp_post_types ) ) {
+
+					_doing_it_wrong( __FUNCTION__, sprintf( __( 'Invalid post type: %s.' ), $result[ 1 ] ), '4.6.0' );
+					$result[ 1 ] = false;
+			
+				}
+				break;
+			} 
+
+			if ( 'term' === $result[ 0 ] ) {
+
+				global $wp_taxonomies;
+				if ( ! in_array( $result[ 1 ], $wp_taxonomies ) ) {
+
+					_doing_it_wrong( __FUNCTION__, sprintf( __( 'Invalid taxonomy: %s.' ), $result[ 1 ] ), '4.6.0' );
+					$result[ 1 ] = false;
+
+				}
+				break;
+			}
+
+			if ( ! $result[ 1 ] ) {
+
+				/**
+				 * Default to 'any'.
+				 */
+				$result[ 1 ] = array( 'any' );
+
+			}
+
+		} while ( false );
+
+
+		return $result;
+
+	}
+
+	/**
+	 * Method to access type property
+	 *
+	 * @return string
+	 */
+	function type_group() {
+
+		return $this->_type_group;
+
+	}
+
+
+	/**
+	 * Method to access $this->_subtype property
+	 *
+	 * @return array
+	 */
+	function subtype() {
+
+		return $this->_subtype;
+
+	}
+
+	/**
+	 * Return the post_type for a post
+	 *
+	 * @return array
+	 */
+	function post_type() {
+
+		return 'post' === $this->_type_group ? $this->_subtype : null;
+
+	}
+
+	/**
+	 * Return the taxonomy for a term
+	 *
+	 * @return array
+	 */
+	function taxonomy() {
+
+		return 'term' === $this->_type_group ? $this->_subtype : null;
+
+	}
+
+
+	/**
+	 * Method to extract ab Object Type to an array.
+	 *
+	 * @return array
+	 */
+	function to_array() {
+
+		return array( $this->_type_group, $this->_subtype );
+
+	}
+
+	/**
+	 * @return string[]
+	 */
+	static function object_type_names() {
+
+		return self::$_object_type_names;
+
+	}
+
+	/**
+	 * @return bool
+	 */
+	function is_post_type_group() {
+
+		return 'post' === $this->_type_group;
+
+	}
+
+	/**
+	 * @return bool
+	 */
+	function is_term_type_group() {
+
+		return 'term' === $this->_type_group;
+
+	}
+
+	/**
+	 * @return bool
+	 */
+	function is_user_type_group() {
+
+		return 'user' === $this->_type_group;
+
+	}
+
+	/**
+	 * @return bool
+	 */
+	function is_comment_type_group() {
+
+		return 'comment' === $this->_type_group;
+
+	}
+
+	/**
+	 * Check if the current Object Type is valid.
+	 *
+	 * Validity is determined by having a non-empty $type_group value.
+	 *
+	 * @return bool Is the Object Type valid?
+	 */
+	function is_valid() {
+
+		return ! empty( $this->_type_group );
+
+	}
+
+	/**
+	 * Check if the current Object Type is equivalent to the one passed in.
+	 *
+	 * Equivalency is true if both objects have the same values for their $_type and $_subtype properties.
+	 *
+	 * If not parameter is passed then this method assume an object type based on the global $post object.
+	 *
+	 * @param WP_Object_Type|string| $object_type The Object Type to compare with $this.
+	 *
+	 * @return bool If $object_type is equivalent to $this.
+	 */
+	function is_equivalent( $object_type ) {
+
+		if ( ! is_a( $object_type, __CLASS__ ) ) {
+			/*
+			 * First check to see if the passed in parameter is a WP_Object_Type object.
+			 * If not, instantiate a new object with the passed $arg.
+			 */
+			$object_type = self::get_instance( $object_type );
+
+		}
+
+		/**
+		 * Check for object equivalency
+		 * Yes this is correct (if you thought it was not, like I did at first.)
+		 */
+		return $this->_as_string === (string) $object_type;
+
+	}
+
+	/**
+	 * Magic method to convert the Object Type into it's string literal form.
+	 *
+	 * @return string  An Object Type literal representing $this, the current Object Type.
+	 */
+	function __toString() {
+
+		return $this->_as_string;
+
+	}
+
+	/**
+	 * @param string $type
+	 * @param string $subtype
+	 *
+	 * @return string
+	 */
+	private static function _as_string( $type, $subtype ) {
+		return "{$type}:{$subtype}";
+
+	}
+
+}
Index: www/wp-includes/meta.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- www/wp-includes/meta.php	(revision 37822)
+++ www/wp-includes/meta.php	(revision )
@@ -17,7 +17,7 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
+ * @param WP_Object_Type|string $object_type  Type of object metadata is for (e.g., comment, post, or user)
  * @param int    $object_id  ID of the object metadata is for
  * @param string $meta_key   Metadata key
  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
@@ -27,10 +27,10 @@
  *                           no change will be made.
  * @return int|false The meta ID on success, false on failure.
  */
-function add_metadata($meta_type, $object_id, $meta_key, $meta_value, $unique = false) {
+function add_metadata( $object_type, $object_id, $meta_key, $meta_value, $unique = false ) {
 	global $wpdb;
 
-	if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
+	if ( ! $object_type || ! $meta_key || ! is_numeric( $object_id ) ) {
 		return false;
 	}
 
@@ -39,6 +39,10 @@
 		return false;
 	}
 
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$meta_type = $object_type->type_group();
+
 	$table = _get_meta_table( $meta_type );
 	if ( ! $table ) {
 		return false;
@@ -49,7 +53,7 @@
 	// expected_slashed ($meta_key)
 	$meta_key = wp_unslash($meta_key);
 	$meta_value = wp_unslash($meta_value);
-	$meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type );
+	$meta_value = sanitize_meta( $meta_key, $meta_value, $object_type );
 
 	/**
 	 * Filters whether to add metadata of a specific type.
@@ -66,8 +70,9 @@
 	 * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
 	 * @param bool      $unique     Whether the specified meta key should be unique
 	 *                              for the object. Optional. Default false.
+	 * @param WP_Object_Type    $object_type  Type and subtype of object
 	 */
-	$check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique );
+	$check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique, $object_type );
 	if ( null !== $check )
 		return $check;
 
@@ -90,8 +95,9 @@
 	 * @param int    $object_id  Object ID.
 	 * @param string $meta_key   Meta key.
 	 * @param mixed  $meta_value Meta value.
+	 * @param WP_Object_Type    $object_type  Type and subtype of object
 	 */
-	do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value );
+	do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value, $object_type );
 
 	$result = $wpdb->insert( $table, array(
 		$column => $object_id,
@@ -118,8 +124,9 @@
 	 * @param int    $object_id  Object ID.
 	 * @param string $meta_key   Meta key.
 	 * @param mixed  $meta_value Meta value.
+	 * @param WP_Object_Type    $object_type  Type and subtype of object
 	 */
-	do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value );
+	do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value, $object_type );
 
 	return $mid;
 }
@@ -132,7 +139,7 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
+ * @param WP_Object_Type|string $object_type  Type of object metadata is for (e.g., comment, post, or user)
  * @param int    $object_id  ID of the object metadata is for
  * @param string $meta_key   Metadata key
  * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
@@ -140,10 +147,10 @@
  * 		                     the specified value. Otherwise, update all entries.
  * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
  */
-function update_metadata($meta_type, $object_id, $meta_key, $meta_value, $prev_value = '') {
+function update_metadata( $object_type, $object_id, $meta_key, $meta_value, $prev_value = '' ) {
 	global $wpdb;
 
-	if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
+	if ( ! $object_type || ! $meta_key || ! is_numeric( $object_id ) ) {
 		return false;
 	}
 
@@ -152,6 +159,10 @@
 		return false;
 	}
 
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$meta_type = $object_type->type_group();
+
 	$table = _get_meta_table( $meta_type );
 	if ( ! $table ) {
 		return false;
@@ -165,7 +176,7 @@
 	$meta_key = wp_unslash($meta_key);
 	$passed_value = $meta_value;
 	$meta_value = wp_unslash($meta_value);
-	$meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type );
+	$meta_value = sanitize_meta( $meta_key, $meta_value, $object_type );
 
 	/**
 	 * Filters whether to update metadata of a specific type.
@@ -183,8 +194,9 @@
 	 * @param mixed     $prev_value Optional. If specified, only update existing
 	 *                              metadata entries with the specified value.
 	 *                              Otherwise, update all entries.
+	 * @param WP_Object_Type    $object_type  Type and subtype of object
 	 */
-	$check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value );
+	$check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value, $object_type );
 	if ( null !== $check )
 		return (bool) $check;
 
@@ -226,8 +238,9 @@
 		 * @param int    $object_id  Object ID.
 		 * @param string $meta_key   Meta key.
 		 * @param mixed  $meta_value Meta value.
+		 * @param WP_Object_Type    $object_type  Type and subtype of object
 		 */
-		do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
+		do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value, $object_type );
 
 		if ( 'post' == $meta_type ) {
 			/**
@@ -239,8 +252,9 @@
 			 * @param int    $object_id  Object ID.
 			 * @param string $meta_key   Meta key.
 			 * @param mixed  $meta_value Meta value.
+			 * @param WP_Object_Type    $object_type  Type and subtype of object
 			 */
-			do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
+			do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value, $object_type );
 		}
 	}
 
@@ -263,8 +277,9 @@
 		 * @param int    $object_id  Object ID.
 		 * @param string $meta_key   Meta key.
 		 * @param mixed  $meta_value Meta value.
+		 * @param WP_Object_Type    $object_type  Type and subtype of object
 		 */
-		do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
+		do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value, $object_type );
 
 		if ( 'post' == $meta_type ) {
 			/**
@@ -276,8 +291,9 @@
 			 * @param int    $object_id  Object ID.
 			 * @param string $meta_key   Meta key.
 			 * @param mixed  $meta_value Meta value.
+			 * @param WP_Object_Type    $object_type  Type and subtype of object
 			 */
-			do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
+			do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value, $object_type );
 		}
 	}
 
@@ -291,7 +307,7 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
+ * @param WP_Object_Type|string $object_type Type of object metadata is for (e.g., comment, post, or user)
  * @param int    $object_id  ID of the object metadata is for
  * @param string $meta_key   Metadata key
  * @param mixed  $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete
@@ -304,10 +320,10 @@
  *                           the specified object_id.
  * @return bool True on successful delete, false on failure.
  */
-function delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false) {
+function delete_metadata( $object_type, $object_id, $meta_key, $meta_value = '', $delete_all = false ) {
 	global $wpdb;
 
-	if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) && ! $delete_all ) {
+	if ( ! $object_type || ! $meta_key || ! is_numeric( $object_id ) && ! $delete_all ) {
 		return false;
 	}
 
@@ -316,6 +332,10 @@
 		return false;
 	}
 
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$meta_type = $object_type->type_group();
+
 	$table = _get_meta_table( $meta_type );
 	if ( ! $table ) {
 		return false;
@@ -343,8 +363,9 @@
 	 * @param bool      $delete_all Whether to delete the matching metadata entries
 	 *                              for all objects, ignoring the specified $object_id.
 	 *                              Default false.
+	 * @param WP_Object_Type    $object_type  Type and subtype of object
 	 */
-	$check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all );
+	$check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all, $object_type );
 	if ( null !== $check )
 		return (bool) $check;
 
@@ -384,8 +405,9 @@
 	 * @param int    $object_id  Object ID.
 	 * @param string $meta_key   Meta key.
 	 * @param mixed  $meta_value Meta value.
+	 * @param WP_Object_Type    $object_type  Type and subtype of object
 	 */
-	do_action( "delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
+	do_action( "delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value, $object_type );
 
 	// Old-style action.
 	if ( 'post' == $meta_type ) {
@@ -395,8 +417,9 @@
 		 * @since 2.9.0
 		 *
 		 * @param array $meta_ids An array of post metadata entry IDs to delete.
+		 * @param WP_Object_Type    $object_type  Type and subtype of object
 		 */
-		do_action( 'delete_postmeta', $meta_ids );
+		do_action( 'delete_postmeta', $meta_ids, $object_type );
 	}
 
 	$query = "DELETE FROM $table WHERE $id_column IN( " . implode( ',', $meta_ids ) . " )";
@@ -426,8 +449,9 @@
 	 * @param int    $object_id  Object ID.
 	 * @param string $meta_key   Meta key.
 	 * @param mixed  $meta_value Meta value.
+	 * @param WP_Object_Type    $object_type  Type and subtype of object
 	 */
-	do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
+	do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value, $object_type );
 
 	// Old-style action.
 	if ( 'post' == $meta_type ) {
@@ -437,8 +461,9 @@
 		 * @since 2.9.0
 		 *
 		 * @param array $meta_ids An array of deleted post metadata entry IDs.
+		 * @param WP_Object_Type    $object_type  Type and subtype of object
 		 */
-		do_action( 'deleted_postmeta', $meta_ids );
+		do_action( 'deleted_postmeta', $meta_ids, $object_type );
 	}
 
 	return true;
@@ -449,7 +474,7 @@
  *
  * @since 2.9.0
  *
- * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
+ * @param WP_Object_Type|string $object_type Type of object metadata is for (e.g., comment, post, or user)
  * @param int    $object_id ID of the object metadata is for
  * @param string $meta_key  Optional. Metadata key. If not specified, retrieve all metadata for
  * 		                    the specified object.
@@ -458,8 +483,9 @@
  *                          This parameter has no effect if meta_key is not specified.
  * @return mixed Single metadata value, or array of values
  */
-function get_metadata($meta_type, $object_id, $meta_key = '', $single = false) {
-	if ( ! $meta_type || ! is_numeric( $object_id ) ) {
+function get_metadata( $object_type, $object_id, $meta_key = '', $single = false ) {
+
+	if ( ! $object_type || ! is_numeric( $object_id ) ) {
 		return false;
 	}
 
@@ -468,6 +494,10 @@
 		return false;
 	}
 
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$meta_type = $object_type->type_group();
+
 	/**
 	 * Filters whether to retrieve metadata of a specific type.
 	 *
@@ -482,8 +512,9 @@
 	 * @param int               $object_id Object ID.
 	 * @param string            $meta_key  Meta key.
 	 * @param bool              $single    Whether to return only the first value of the specified $meta_key.
+	 * @param WP_Object_Type    $object_type  Type and subtype of object
 	 */
-	$check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single );
+	$check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single, $object_type );
 	if ( null !== $check ) {
 		if ( $single && is_array( $check ) )
 			return $check[0];
@@ -520,13 +551,13 @@
  *
  * @since 3.3.0
  *
- * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
+ * @param WP_Object_Type|string $object_type Type of object metadata is for (e.g., comment, post, or user)
  * @param int    $object_id ID of the object metadata is for
  * @param string $meta_key  Metadata key.
  * @return bool True of the key is set, false if not.
  */
-function metadata_exists( $meta_type, $object_id, $meta_key ) {
-	if ( ! $meta_type || ! is_numeric( $object_id ) ) {
+function metadata_exists( $object_type, $object_id, $meta_key ) {
+	if ( ! $object_type || ! is_numeric( $object_id ) ) {
 		return false;
 	}
 
@@ -535,8 +566,12 @@
 		return false;
 	}
 
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$meta_type = $object_type->type_group();
+
 	/** This filter is documented in wp-includes/meta.php */
-	$check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, true );
+	$check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, true , $object_type);
 	if ( null !== $check )
 		return (bool) $check;
 
@@ -560,14 +595,14 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param string $meta_type Type of object metadata is for (e.g., comment, post, term, or user).
+ * @param WP_Object_Type|string $object_type Type of object metadata is for (e.g., comment, post, or user)
  * @param int    $meta_id   ID for a specific meta row
  * @return object|false Meta object or false.
  */
-function get_metadata_by_mid( $meta_type, $meta_id ) {
+function get_metadata_by_mid( $object_type, $meta_id ) {
 	global $wpdb;
 
-	if ( ! $meta_type || ! is_numeric( $meta_id ) ) {
+	if ( ! $object_type || ! is_numeric( $meta_id ) ) {
 		return false;
 	}
 
@@ -576,6 +611,10 @@
 		return false;
 	}
 
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$meta_type = $object_type->type_group();
+
 	$table = _get_meta_table( $meta_type );
 	if ( ! $table ) {
 		return false;
@@ -601,17 +640,17 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
+ * @param WP_Object_Type|string $object_type Type of object metadata is for (e.g., comment, post, or user)
  * @param int    $meta_id    ID for a specific meta row
  * @param string $meta_value Metadata value
- * @param string $meta_key   Optional, you can provide a meta key to update it
+ * @param string|bool $meta_key   Optional, you can provide a meta key to update it
  * @return bool True on successful update, false on failure.
  */
-function update_metadata_by_mid( $meta_type, $meta_id, $meta_value, $meta_key = false ) {
+function update_metadata_by_mid( $object_type, $meta_id, $meta_value, $meta_key = false ) {
 	global $wpdb;
 
 	// Make sure everything is valid.
-	if ( ! $meta_type || ! is_numeric( $meta_id ) ) {
+	if ( ! $object_type || ! is_numeric( $meta_id ) ) {
 		return false;
 	}
 
@@ -620,6 +659,10 @@
 		return false;
 	}
 
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$meta_type = $object_type->type_group();
+
 	$table = _get_meta_table( $meta_type );
 	if ( ! $table ) {
 		return false;
@@ -643,7 +686,7 @@
 
 		// Sanitize the meta
 		$_meta_value = $meta_value;
-		$meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type );
+		$meta_value = sanitize_meta( $meta_key, $meta_value, $object_type );
 		$meta_value = maybe_serialize( $meta_value );
 
 		// Format the data query arguments.
@@ -657,11 +700,11 @@
 		$where[$id_column] = $meta_id;
 
 		/** This action is documented in wp-includes/meta.php */
-		do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
+		do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value, $object_type );
 
 		if ( 'post' == $meta_type ) {
 			/** This action is documented in wp-includes/meta.php */
-			do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
+			do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value, $object_type );
 		}
 
 		// Run the update query, all fields in $data are %s, $where is a %d.
@@ -673,11 +716,11 @@
 		wp_cache_delete($object_id, $meta_type . '_meta');
 
 		/** This action is documented in wp-includes/meta.php */
-		do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
+		do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value, $object_type );
 
 		if ( 'post' == $meta_type ) {
 			/** This action is documented in wp-includes/meta.php */
-			do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
+			do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value, $object_type );
 		}
 
 		return true;
@@ -694,15 +737,15 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param string $meta_type Type of object metadata is for (e.g., comment, post, term, or user).
+ * @param WP_Object_Type|string $object_type Type of object metadata is for (e.g., comment, post, or user)
  * @param int    $meta_id   ID for a specific meta row
  * @return bool True on successful delete, false on failure.
  */
-function delete_metadata_by_mid( $meta_type, $meta_id ) {
+function delete_metadata_by_mid( $object_type, $meta_id ) {
 	global $wpdb;
 
 	// Make sure everything is valid.
-	if ( ! $meta_type || ! is_numeric( $meta_id ) ) {
+	if ( ! $object_type || ! is_numeric( $meta_id ) ) {
 		return false;
 	}
 
@@ -711,6 +754,10 @@
 		return false;
 	}
 
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$meta_type = $object_type->type_group();
+
 	$table = _get_meta_table( $meta_type );
 	if ( ! $table ) {
 		return false;
@@ -725,7 +772,7 @@
 		$object_id = $meta->{$column};
 
 		/** This action is documented in wp-includes/meta.php */
-		do_action( "delete_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
+		do_action( "delete_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value, $object_type );
 
 		// Old-style action.
 		if ( 'post' == $meta_type || 'comment' == $meta_type ) {
@@ -738,8 +785,9 @@
 			 * @since 3.4.0
 			 *
 			 * @param int $meta_id ID of the metadata entry to delete.
+			 * @param WP_Object_Type    $object_type  Type and subtype of object
 			 */
-			do_action( "delete_{$meta_type}meta", $meta_id );
+			do_action( "delete_{$meta_type}meta", $meta_id, $object_type );
 		}
 
 		// Run the query, will return true if deleted, false otherwise
@@ -749,7 +797,7 @@
 		wp_cache_delete($object_id, $meta_type . '_meta');
 
 		/** This action is documented in wp-includes/meta.php */
-		do_action( "deleted_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
+		do_action( "deleted_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value, $object_type );
 
 		// Old-style action.
 		if ( 'post' == $meta_type || 'comment' == $meta_type ) {
@@ -762,8 +810,9 @@
 			 * @since 3.4.0
 			 *
 			 * @param int $meta_ids Deleted metadata entry ID.
+			 * @param WP_Object_Type    $object_type  Type and subtype of object
 			 */
-			do_action( "deleted_{$meta_type}meta", $meta_id );
+			do_action( "deleted_{$meta_type}meta", $meta_id, $object_type );
 		}
 
 		return $result;
@@ -781,17 +830,21 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param string    $meta_type  Type of object metadata is for (e.g., comment, post, or user)
+ * @param WP_Object_Type|string $object_type Type of object metadata is for (e.g., comment, post, or user)
  * @param int|array $object_ids Array or comma delimited list of object IDs to update cache for
  * @return array|false Metadata cache for the specified objects, or false on failure.
  */
-function update_meta_cache($meta_type, $object_ids) {
+function update_meta_cache( $object_type, $object_ids) {
 	global $wpdb;
 
-	if ( ! $meta_type || ! $object_ids ) {
+	if ( ! $object_type || ! $object_ids ) {
 		return false;
 	}
 
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$meta_type = $object_type->type_group();
+
 	$table = _get_meta_table( $meta_type );
 	if ( ! $table ) {
 		return false;
@@ -876,15 +929,15 @@
  * @see WP_Meta_Query
  *
  * @param array $meta_query         A meta query.
- * @param string $type              Type of meta.
+ * @param string $type_group        Type of meta: 'post', 'term', 'user', 'comment'
  * @param string $primary_table     Primary database table name.
  * @param string $primary_id_column Primary ID column name.
  * @param object $context           Optional. The main query object
  * @return array Associative array of `JOIN` and `WHERE` SQL.
  */
-function get_meta_sql( $meta_query, $type, $primary_table, $primary_id_column, $context = null ) {
+function get_meta_sql( $meta_query, $type_group, $primary_table, $primary_id_column, $context = null ) {
 	$meta_query_obj = new WP_Meta_Query( $meta_query );
-	return $meta_query_obj->get_sql( $type, $primary_table, $primary_id_column, $context );
+	return $meta_query_obj->get_sql( $type_group, $primary_table, $primary_id_column, $context );
 }
 
 /**
@@ -894,14 +947,16 @@
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
- * @param string $type Type of object to get metadata table for (e.g., comment, post, or user)
+ * @param WP_Object_Type|string $object_type Type of object metadata is for (e.g., comment, post, or user)
  * @return string|false Metadata table name, or false if no metadata table exists
  */
-function _get_meta_table($type) {
+function _get_meta_table( $object_type ) {
 	global $wpdb;
 
-	$table_name = $type . 'meta';
+	$object_type = WP_Object_Type::get_instance( $object_type );
 
+	$table_name = $object_type->type_group() . 'meta';
+
 	if ( empty($wpdb->$table_name) )
 		return false;
 
@@ -914,10 +969,10 @@
  * @since 3.1.3
  *
  * @param string      $meta_key Meta key
- * @param string|null $meta_type
+ * @param WP_Object_Type|string|null $object_type Type of object metadata is for (e.g., comment, post, or user)
  * @return bool True if the key is protected, false otherwise.
  */
-function is_protected_meta( $meta_key, $meta_type = null ) {
+function is_protected_meta( $meta_key, $object_type = null ) {
 	$protected = ( '_' == $meta_key[0] );
 
 	/**
@@ -929,21 +984,27 @@
 	 * @param string $meta_key  Meta key.
 	 * @param string $meta_type Meta type.
 	 */
-	return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type );
+	return apply_filters( 'is_protected_meta', $protected, $meta_key, $object_type->type_group(), $object_type );
 }
 
 /**
  * Sanitize meta value.
  *
  * @since 3.1.3
+ * @since 4.6.0 Added the `$object_subtype` parameter.
  *
- * @param string $meta_key   Meta key
- * @param mixed  $meta_value Meta value to sanitize
- * @param string $meta_type  Type of meta
- * @return mixed Sanitized $meta_value
+ * @param string $meta_key       Meta key.
+ * @param mixed  $meta_value     Meta value to sanitize.
+ * @param WP_Object_Type|string $object_type  Type of object the meta is registered to.
+ *
+ * @return mixed Sanitized $meta_value.
  */
-function sanitize_meta( $meta_key, $meta_value, $meta_type ) {
+function sanitize_meta( $meta_key, $meta_value, $object_type ) {
 
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$type_group = $object_type->type_group();
+
 	/**
 	 * Filters the sanitization of a specific meta key of a specific meta type.
 	 *
@@ -958,30 +1019,235 @@
 	 * @param string $meta_key   Meta key.
 	 * @param string $meta_type  Meta type.
 	 */
-	return apply_filters( "sanitize_{$meta_type}_meta_{$meta_key}", $meta_value, $meta_key, $meta_type );
+	return apply_filters( "sanitize_{$type_group}_meta_{$meta_key}", $meta_value, $meta_key, $object_type );
 }
 
 /**
- * Register meta key
+ * Registers a meta key.
  *
  * @since 3.3.0
+ * @since 4.6.0 Modified to support an array of data to attach to registered meta keys. Previous arguments for
+ *              `$sanitize_callback` and `$auth_callback` have been folded into this array.
  *
- * @param string       $meta_type         Type of meta
- * @param string       $meta_key          Meta key
- * @param string|array $sanitize_callback A function or method to call when sanitizing the value of $meta_key.
- * @param string|array $auth_callback     Optional. A function or method to call when performing edit_post_meta, add_post_meta, and delete_post_meta capability checks.
+ * @param WP_Object_Type|string $object_type  Type of object the meta is registered to.
+ * @param string $meta_key                    Meta key to register.
+ * @param array  $args {
+ *     Data used to describe the meta key when registered.
+ *
+ *     @type string   $sanitize_callback A function or method to call when sanitizing `$meta_key` data.
+ *     @type string   $auth_callback     Optional. A function or method to call when performing edit_post_meta, add_post_meta, and delete_post_meta capability checks.
+ *     @type string   $type_group        The type of data associated with this meta key.
+ *     @type string   $description       A description of the data attached to this meta key.
+ *     @type bool     $show_in_rest      Whether data associated with this meta key can be considered public.
+ * }
  */
-function register_meta( $meta_type, $meta_key, $sanitize_callback, $auth_callback = null ) {
-	if ( is_callable( $sanitize_callback ) )
-		add_filter( "sanitize_{$meta_type}_meta_{$meta_key}", $sanitize_callback, 10, 3 );
+function register_meta( $object_type, $meta_key, $args ) {
+	global $wp_meta_keys;
 
-	if ( empty( $auth_callback ) ) {
-		if ( is_protected_meta( $meta_key, $meta_type ) )
-			$auth_callback = '__return_false';
-		else
-			$auth_callback = '__return_true';
+	if ( ! is_array( $wp_meta_keys ) ) {
+		$wp_meta_keys = array();
 	}
 
-	if ( is_callable( $auth_callback ) )
-		add_filter( "auth_{$meta_type}_meta_{$meta_key}", $auth_callback, 10, 6 );
+	$meta_args = (object) array(
+		'sanitize_callback' => null,
+		'old_sanitize_callback' => null,
+		'auth_callback' => null,
+		'old_auth_callback' => null,
+		'type' => 'string',
+		'description' => '',
+		'show_in_rest' => false,
+	);
+
+	$passed_args = array_slice( func_get_args(), 2 );
+
+	if ( is_callable( $passed_args[0] ) ) {
+		$meta_args->old_sanitize_callback = $passed_args[0];
+	} elseif ( isset( $passed_args[0]['sanitize_callback'] ) ) {
+		$meta_args->sanitize_callback = $passed_args[0]['sanitize_callback'];
+	}
+
+	if ( isset( $passed_args[1] ) && is_callable( $passed_args[1] ) ) {
+		$meta_args->old_auth_callback = $passed_args[1];
+	} elseif ( isset( $passed_args[0]['auth_callback'] ) ) {
+		$meta_args->auth_callback = $passed_args[0]['auth_callback'];
+	}
+
+	if ( isset( $passed_args[0]['show_in_rest'] ) && $passed_args[0]['show_in_rest'] ) {
+		$meta_args->show_in_rest = true;
+	}
+
+	if ( isset( $passed_args[0]['type'] ) ) {
+		$meta_args->type = $passed_args[0]['type'];
+	}
+
+	if ( isset( $passed_args[0]['description'] ) ) {
+		$meta_args->description = $passed_args[0]['description'];
+	}
+
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	$wp_meta_keys[ $type_group = $object_type->type_group() ][ $object_type->post_type() ][ $meta_key ] = $args;
+
+	if ( is_callable( $meta_args->old_sanitize_callback ) ) {
+		add_filter( "sanitize_{$type_group}_meta_{$meta_key}", $meta_args->old_sanitize_callback, 10, 3 );
+	}
+
+	if ( is_callable( $meta_args->sanitize_callback ) ) {
+		add_filter( "sanitize_{$type_group}_meta_{$meta_key}", $meta_args->sanitize_callback, 10, 3 );
+	}
+
+	// If neither new or legacy `auth_callback` is provided, fallback to `is_protected_meta()`.
+	if ( empty( $meta_args->auth_callback ) && empty( $meta_args->old_auth_callback ) ) {
+		if ( is_protected_meta( $meta_key, $object_type ) ) {
+			$meta_args->auth_callback = '__return_false';
+		} else {
+			$meta_args->auth_callback = '__return_true';
+		}
+	}
+
+	// The auth here is currently used to edit or add meta, not to view, and only for posts.
+	if ( 'post' === $type_group && is_callable( $meta_args->old_auth_callback ) ) {
+		add_filter( "auth_{$type_group}_meta_{$meta_key}", $meta_args->old_auth_callback, 10, 6 );
+	}
+
+	if ( 'post' === $type_group && is_callable( $meta_args->auth_callback ) ) {
+		add_filter( "auth_{$type_group}_meta_{$meta_key}", $meta_args->auth_callback, 10, 6 );
+	}
+}
+
+/**
+ * Checks if a meta key is registered.
+ *
+ * @since 4.6.0
+ *
+ * @param WP_Object_Type|string $object_type  Type of object the meta is registered to.
+ * @param string $meta_key
+ *
+ * @return bool True if the meta key is registered to the object type and subtype. False if not.
+ */
+function registered_meta_key_exists( $object_type, $meta_key ) {
+	global $wp_meta_keys;
+
+	if ( ! is_array( $wp_meta_keys ) ) {
+		return false;
+	}
+
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	if ( ! isset( $wp_meta_keys[ $type_group = $object_type->type_group() ] ) ) {
+		return false;
+	}
+
+	if ( ! isset( $wp_meta_keys[ $type_group ][ $post_type = $object_type->post_type() ] ) ) {
+		return false;
+	}
+
+	if ( isset( $wp_meta_keys[ $type_group ][ $post_type ][ $meta_key ] ) ) {
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * Unregisters a meta key from the list of registered keys.
+ *
+ * @since 4.6.0
+ *
+ * @param WP_Object_Type|string $object_type  Type of object the meta is registered to.
+ * @param string $meta_key       The meta key.
+ *
+ * @return bool|WP_Error True if successful. WP_Error if the meta key is invalid.
+ */
+function unregister_meta_key( $object_type, $meta_key ) {
+	global $wp_meta_keys;
+
+	if ( ! registered_meta_key_exists( $object_type, $meta_key ) ) {
+		return new WP_Error( 'invalid_meta_key', __( 'Invalid meta key' ) );
+	}
+
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	unset( $wp_meta_keys[ $object_type->type_group() ][ $object_type->post_type() ][ $meta_key ] );
+
+	return true;
+}
+
+/**
+ * Retrieves a list of registered meta keys for an object type and subtype.
+ *
+ * @since 4.6.0
+ *
+ * @param WP_Object_Type|string $object_type  Type of object the meta is registered to.
+ *
+ * @return array List of registered meta keys.
+ */
+function get_registered_meta_keys( $object_type ) {
+	global $wp_meta_keys;
+
+	$object_type = WP_Object_Type::get_instance( $object_type );
+
+	if ( ! isset( $wp_meta_keys[ $type_group = $object_type->type_group() ] ) ) {
+		return array();
+	}
+
+	if ( ! isset( $wp_meta_keys[ $type_group ][ $post_type = $object_type->post_type() ] ) ) {
+		return array();
+	}
+
+	return $wp_meta_keys[ $type_group ][ $post_type ];
+}
+
+/**
+ * Retrieves registered metadata for a specified object.
+ *
+ * @since 4.6.0
+ *
+ * @param WP_Object_Type|string $object_type  Type of object to request metadata for. (e.g. comment, post, term, user)
+ * @param int    $object_id      ID of the object the metadata is for.
+ * @param string $meta_key       Optional. Registered metadata key. If not specified, retrieve all registered
+ *                               metadata for the specified object.
+ *
+ * @return mixed|WP_Error
+ */
+function get_registered_metadata( $object_type, $object_id, $meta_key = '' ) {
+	global $wp_meta_keys;
+	
+	if ( ! is_array( $wp_meta_keys ) ) {
+		return new WP_Error( 'invalid_meta_key', __( 'Invalid meta key. Not registered.' ) );
+	}
+
+	$type_subtype = WP_Object_Type::parse_object_type( $object_type );
+	
+	if ( 'post' === $type_subtype[ 0 ] ) {
+		$type_subtype[ 1 ] = array( get_post_type( $object_id ) );
+	}
+	
+	$object_type = WP_Object_Type::get_instance( $type_subtype );
+
+	if( ! empty( $meta_key ) ) {
+		if ( ! registered_meta_key_exists( $object_type, $meta_key ) ) {
+			return new WP_Error( 'invalid_meta_key', __( 'Invalid meta key. Not registered.' ) );
+		}
+		$meta_keys = get_registered_meta_keys( $object_type );
+		$meta_key_data = $meta_keys[ $object_type->type_group() ][ $object_type->post_type() ][ $meta_key ];
+
+		$data = get_metadata( $object_type, $object_id, $meta_key, $meta_key_data->single );
+
+		return $data;
+	}
+
+	$data = get_metadata( $object_type->type_group(), $object_id, $meta_key );
+
+	$meta_keys = get_registered_meta_keys( $object_type );
+
+    $registered_data = array();
+
+	foreach( $meta_keys as $k => $v ) {
+		if ( isset( $data[ $k ] ) ) {
+			$registered_data[ $k ] = $data[ $k ];
+		}
+	}
+
+	return $registered_data;
 }
Index: www/wp-includes/class-wp-meta-query.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- www/wp-includes/class-wp-meta-query.php	(revision 37822)
+++ www/wp-includes/class-wp-meta-query.php	(revision )
@@ -311,7 +311,7 @@
 	 * @since 3.2.0
 	 * @access public
 	 *
-	 * @param string $type              Type of meta, eg 'user', 'post'.
+	 * @param string $type_group        Type of meta, eg 'user', 'post'.
 	 * @param string $primary_table     Database table where the object being filtered is stored (eg wp_users).
 	 * @param string $primary_id_column ID column for the filtered object in $primary_table.
 	 * @param object $context           Optional. The main query object.
@@ -322,15 +322,15 @@
 	 *     @type string $where SQL fragment to append to the main WHERE clause.
 	 * }
 	 */
-	public function get_sql( $type, $primary_table, $primary_id_column, $context = null ) {
-		if ( ! $meta_table = _get_meta_table( $type ) ) {
+	public function get_sql( $type_group, $primary_table, $primary_id_column, $context = null ) {
+		if ( ! $meta_table = _get_meta_table( $type_group ) ) {
 			return false;
 		}
 
 		$this->table_aliases = array();
 
 		$this->meta_table     = $meta_table;
-		$this->meta_id_column = sanitize_key( $type . '_id' );
+		$this->meta_id_column = sanitize_key( $type_group . '_id' );
 
 		$this->primary_table     = $primary_table;
 		$this->primary_id_column = $primary_id_column;
@@ -352,12 +352,12 @@
 		 *
 		 * @param array  $clauses           Array containing the query's JOIN and WHERE clauses.
 		 * @param array  $queries           Array of meta queries.
-		 * @param string $type              Type of meta.
+		 * @param string $type_group              Type of meta.
 		 * @param string $primary_table     Primary table.
 		 * @param string $primary_id_column Primary column ID.
 		 * @param object $context           The main query object.
 		 */
-		return apply_filters_ref_array( 'get_meta_sql', array( $sql, $this->queries, $type, $primary_table, $primary_id_column, $context ) );
+		return apply_filters_ref_array( 'get_meta_sql', array( $sql, $this->queries, $type_group, $primary_table, $primary_id_column, $context ) );
 	}
 
 	/**
