WordPressを読む 34-3 /blog/wp-includes/meta.php 3
2014/12/17
目次
/blog/wp-includes/meta.php 3
関数 get_meta_sql()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /** * Given a meta query, generates SQL clauses to be appended to a main query * * @since 3.2.0 * * @see WP_Meta_Query * * @param array $meta_query A meta query * @param string $type Type of meta * @param string $primary_table * @param string $primary_id_column * @param object $context (optional) The main query object * @return array( 'join' => $join_sql, 'where' => $where_sql ) */ function get_meta_sql( $meta_query, $type, $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 ); } |
WP_Meta_Query::クラス変数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /** * Container class for a multiple metadata query * * @since 3.2.0 */ class WP_Meta_Query { /** * List of metadata queries. A single query is an associative array: * - 'key' string The meta key * - 'value' string|array The meta value * - 'compare' (optional) string How to compare the key to the value. * Possible values: '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', * 'BETWEEN', 'NOT BETWEEN', 'REGEXP', 'NOT REGEXP', 'RLIKE'. * Default: '=' * - 'type' string (optional) The type of the value. * Possible values: 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'. * Default: 'CHAR' * * @since 3.2.0 * @access public * @var array */ public $queries = array(); /** * The relation between the queries. Can be one of 'AND' or 'OR'. * * @since 3.2.0 * @access public * @var string */ public $relation; |
WP_Meta_Query::__construct() コンストラクタ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /** * Constructor * * @param array $meta_query (optional) A meta query */ public function __construct( $meta_query = false ) { if ( !$meta_query ) return; if ( isset( $meta_query['relation'] ) && strtoupper( $meta_query['relation'] ) == 'OR' ) { $this->relation = 'OR'; } else { $this->relation = 'AND'; } $this->queries = array(); foreach ( $meta_query as $key => $query ) { if ( ! is_array( $query ) ) continue; $this->queries[] = $query; } } |
WP_Meta_Query::parse_query_vars()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /** * Constructs a meta query based on 'meta_*' query vars * * @since 3.2.0 * @access public * * @param array $qv The query variables */ public function parse_query_vars( $qv ) { $meta_query = array(); // Simple query needs to be first for orderby=meta_value to work correctly foreach ( array( 'key', 'compare', 'type' ) as $key ) { if ( !empty( $qv[ "meta_$key" ] ) ) $meta_query[0][ $key ] = $qv[ "meta_$key" ]; } // WP_Query sets 'meta_value' = '' by default if ( isset( $qv[ 'meta_value' ] ) && '' !== $qv[ 'meta_value' ] && ( ! is_array( $qv[ 'meta_value' ] ) || $qv[ 'meta_value' ] ) ) $meta_query[0]['value'] = $qv[ 'meta_value' ]; if ( !empty( $qv['meta_query'] ) && is_array( $qv['meta_query'] ) ) { $meta_query = array_merge( $meta_query, $qv['meta_query'] ); } $this->__construct( $meta_query ); } |
WP_Meta_Query::get_cast_for_type()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /** * Given a meta type, return the appropriate alias if applicable * * @since 3.7.0 * * @param string $type MySQL type to cast meta_value * @return string MySQL type */ public function get_cast_for_type( $type = '' ) { if ( empty( $type ) ) return 'CHAR'; $meta_type = strtoupper( $type ); if ( ! preg_match( '/^(?:BINARY|CHAR|DATE|DATETIME|SIGNED|UNSIGNED|TIME|NUMERIC(?:\(\d+(?:,\s?\d+)?\))?|DECIMAL(?:\(\d+(?:,\s?\d+)?\))?)$/', $meta_type ) ) return 'CHAR'; if ( 'NUMERIC' == $meta_type ) $meta_type = 'SIGNED'; return $meta_type; } |
WP_Meta_Query::get_sql()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | /** * Generates SQL clauses to be appended to a main query. * * @since 3.2.0 * @access public * * @param string $type Type of meta * @param string $primary_table * @param string $primary_id_column * @param object $context (optional) The main query object * @return array( 'join' => $join_sql, 'where' => $where_sql ) */ public function get_sql( $type, $primary_table, $primary_id_column, $context = null ) { global $wpdb; if ( ! $meta_table = _get_meta_table( $type ) ) return false; $meta_id_column = sanitize_key( $type . '_id' ); $join = array(); $where = array(); $key_only_queries = array(); $queries = array(); // Split out the queries with empty arrays as value foreach ( $this->queries as $k => $q ) { if ( isset( $q['value'] ) && is_array( $q['value'] ) && empty( $q['value'] ) ) { $key_only_queries[$k] = $q; unset( $this->queries[$k] ); } } // Split out the meta_key only queries (we can only do this for OR) if ( 'OR' == $this->relation ) { foreach ( $this->queries as $k => $q ) { if ( ( empty( $q['compare'] ) || 'NOT EXISTS' != $q['compare'] ) && ! array_key_exists( 'value', $q ) && ! empty( $q['key'] ) ) $key_only_queries[$k] = $q; else $queries[$k] = $q; } } else { $queries = $this->queries; } // Specify all the meta_key only queries in one go if ( $key_only_queries ) { $join[] = "INNER JOIN $meta_table ON $primary_table.$primary_id_column = $meta_table.$meta_id_column"; foreach ( $key_only_queries as $key => $q ) $where["key-only-$key"] = $wpdb->prepare( "$meta_table.meta_key = %s", trim( $q['key'] ) ); } foreach ( $queries as $k => $q ) { $meta_key = isset( $q['key'] ) ? trim( $q['key'] ) : ''; $meta_type = $this->get_cast_for_type( isset( $q['type'] ) ? $q['type'] : '' ); if ( array_key_exists( 'value', $q ) && is_null( $q['value'] ) ) $q['value'] = ''; $meta_value = isset( $q['value'] ) ? $q['value'] : null; if ( isset( $q['compare'] ) ) $meta_compare = strtoupper( $q['compare'] ); else $meta_compare = is_array( $meta_value ) ? 'IN' : '='; if ( ! in_array( $meta_compare, array( '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP', 'RLIKE' ) ) ) $meta_compare = '='; $i = count( $join ); $alias = $i ? 'mt' . $i : $meta_table; if ( 'NOT EXISTS' == $meta_compare ) { $join[$i] = "LEFT JOIN $meta_table"; $join[$i] .= $i ? " AS $alias" : ''; $join[$i] .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column AND $alias.meta_key = '$meta_key')"; $where[$k] = ' ' . $alias . '.' . $meta_id_column . ' IS NULL'; continue; } $join[$i] = "INNER JOIN $meta_table"; $join[$i] .= $i ? " AS $alias" : ''; $join[$i] .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column)"; $where[$k] = ''; if ( !empty( $meta_key ) ) $where[$k] = $wpdb->prepare( "$alias.meta_key = %s", $meta_key ); if ( is_null( $meta_value ) ) { if ( empty( $where[$k] ) ) unset( $join[$i] ); continue; } if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) { if ( ! is_array( $meta_value ) ) $meta_value = preg_split( '/[,\s]+/', $meta_value ); if ( empty( $meta_value ) ) { unset( $join[$i] ); continue; } } else { $meta_value = trim( $meta_value ); } if ( 'IN' == substr( $meta_compare, -2) ) { $meta_compare_string = '(' . substr( str_repeat( ',%s', count( $meta_value ) ), 1 ) . ')'; } elseif ( 'BETWEEN' == substr( $meta_compare, -7) ) { $meta_value = array_slice( $meta_value, 0, 2 ); $meta_compare_string = '%s AND %s'; } elseif ( 'LIKE' == $meta_compare || 'NOT LIKE' == $meta_compare ) { $meta_value = '%' . $wpdb->esc_like( $meta_value ) . '%'; $meta_compare_string = '%s'; } else { $meta_compare_string = '%s'; } if ( ! empty( $where[$k] ) ) $where[$k] .= ' AND '; $where[$k] = ' (' . $where[$k] . $wpdb->prepare( "CAST($alias.meta_value AS {$meta_type}) {$meta_compare} {$meta_compare_string})", $meta_value ); } $where = array_filter( $where ); if ( empty( $where ) ) $where = ''; else $where = ' AND (' . implode( "\n{$this->relation} ", $where ) . ' )'; $join = implode( "\n", $join ); if ( ! empty( $join ) ) $join = ' ' . $join; /** * Filter the meta query's generated SQL. * * @since 3.1.0 * * @param array $args { * An array of arguments. * * @type array $clauses Array containing the query's JOIN and WHERE clauses. * @type array $queries Array of meta queries. * @type string $type Type of meta. * @type string $primary_table Primary table. * @type string $primary_id_column Primary column ID. * @type object $context The main query object. * } */ return apply_filters_ref_array( 'get_meta_sql', array( compact( 'join', 'where' ), $this->queries, $type, $primary_table, $primary_id_column, $context ) ); } } |
WP_Meta_Query::クラス定義終了
関数 _get_meta_table()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** * Retrieve the name of the metadata table for the specified object type. * * @since 2.9.0 * @uses $wpdb WordPress database object for queries. * * @param string $type Type of object to get metadata table for (e.g., comment, post, or user) * @return mixed Metadata table name, or false if no metadata table exists */ function _get_meta_table($type) { global $wpdb; $table_name = $type . 'meta'; if ( empty($wpdb->$table_name) ) return false; return $wpdb->$table_name; } |
関数 is_protected_meta()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /** * Determine whether a meta key is protected. * * @since 3.1.3 * * @param string $meta_key Meta key * @return bool True if the key is protected, false otherwise. */ function is_protected_meta( $meta_key, $meta_type = null ) { $protected = ( '_' == $meta_key[0] ); /** * Filter whether a meta key is protected. * * @since 3.2.0 * * @param bool $protected Whether the key is protected. Default false. * @param string $meta_key Meta key. * @param string $meta_type Meta type. */ return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type ); } |
関数 sanitize_meta()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /** * Sanitize meta value. * * @since 3.1.3 * * @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 */ function sanitize_meta( $meta_key, $meta_value, $meta_type ) { /** * Filter the sanitization of a specific meta key of a specific meta type. * * The dynamic portions of the hook name, $meta_type and $meta_key, refer to the * metadata object type (comment, post, or user) and the meta key value, * respectively. * * @since 3.3.0 * * @param mixed $meta_value Meta value to sanitize. * @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 ); } |
関数 register_meta()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /** * Register meta key * * @since 3.3.0 * * @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 array $args Arguments */ 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 ); if ( empty( $auth_callback ) ) { if ( is_protected_meta( $meta_key, $meta_type ) ) $auth_callback = '__return_false'; else $auth_callback = '__return_true'; } if ( is_callable( $auth_callback ) ) add_filter( "auth_{$meta_type}_meta_{$meta_key}", $auth_callback, 10, 6 ); } |