get_id(); } $terms = get_the_terms( $object_id, $taxonomy ); if ( false === $terms || is_wp_error( $terms ) ) { return array(); } return wp_list_pluck( $terms, 'term_id' ); } /** * Returns an array of meta for an object. * * @since 3.0.0 * @param WC_Data * @return array */ public function read_meta( &$object ) { global $wpdb; $db_info = $this->get_db_info(); $raw_meta_data = $wpdb->get_results( $wpdb->prepare( " SELECT {$db_info['meta_id_field']} as meta_id, meta_key, meta_value FROM {$db_info['table']} WHERE {$db_info['object_id_field']} = %d ORDER BY {$db_info['meta_id_field']} ", $object->get_id() ) ); $this->internal_meta_keys = array_merge( array_map( array( $this, 'prefix_key' ), $object->get_data_keys() ), $this->internal_meta_keys ); return array_filter( $raw_meta_data, array( $this, 'exclude_internal_meta_keys' ) ); } /** * Deletes meta based on meta ID. * * @since 3.0.0 * @param WC_Data * @param stdClass (containing at least ->id) * @return array */ public function delete_meta( &$object, $meta ) { delete_metadata_by_mid( $this->meta_type, $meta->id ); } /** * Add new piece of meta. * * @since 3.0.0 * @param WC_Data * @param stdClass (containing ->key and ->value) * @return int meta ID */ public function add_meta( &$object, $meta ) { return add_metadata( $this->meta_type, $object->get_id(), $meta->key, $meta->value, false ); } /** * Update meta. * * @since 3.0.0 * @param WC_Data * @param stdClass (containing ->id, ->key and ->value) */ public function update_meta( &$object, $meta ) { update_metadata_by_mid( $this->meta_type, $meta->id, $meta->value, $meta->key ); } /** * Table structure is slightly different between meta types, this function will return what we need to know. * * @since 3.0.0 * @return array Array elements: table, object_id_field, meta_id_field */ protected function get_db_info() { global $wpdb; $meta_id_field = 'meta_id'; // for some reason users calls this umeta_id so we need to track this as well. $table = $wpdb->prefix; // If we are dealing with a type of metadata that is not a core type, the table should be prefixed. if ( ! in_array( $this->meta_type, array( 'post', 'user', 'comment', 'term' ) ) ) { $table .= 'woocommerce_'; } $table .= $this->meta_type . 'meta'; $object_id_field = $this->meta_type . '_id'; // Figure out our field names. if ( 'user' === $this->meta_type ) { $meta_id_field = 'umeta_id'; $table = $wpdb->usermeta; } if ( ! empty( $this->object_id_field_for_meta ) ) { $object_id_field = $this->object_id_field_for_meta; } return array( 'table' => $table, 'object_id_field' => $object_id_field, 'meta_id_field' => $meta_id_field, ); } /** * Internal meta keys we don't want exposed as part of meta_data. This is in * addition to all data props with _ prefix. * @since 2.6.0 * @return array */ protected function prefix_key( $key ) { return '_' === substr( $key, 0, 1 ) ? $key : '_' . $key; } /** * Callback to remove unwanted meta data. * * @param object $meta * @return bool */ protected function exclude_internal_meta_keys( $meta ) { return ! in_array( $meta->meta_key, $this->internal_meta_keys ) && 0 !== stripos( $meta->meta_key, 'wp_' ); } /** * Gets a list of props and meta keys that need updated based on change state * or if they are present in the database or not. * * @param WC_Data $object The WP_Data object (WC_Coupon for coupons, etc). * @param array $meta_key_to_props A mapping of meta keys => prop names. * @param string $meta_type The internal WP meta type (post, user, etc). * @return array A mapping of meta keys => prop names, filtered by ones that should be updated. */ protected function get_props_to_update( $object, $meta_key_to_props, $meta_type = 'post' ) { $props_to_update = array(); $changed_props = $object->get_changes(); // Props should be updated if they are a part of the $changed array or don't exist yet. foreach ( $meta_key_to_props as $meta_key => $prop ) { if ( array_key_exists( $prop, $changed_props ) || ! metadata_exists( $meta_type, $object->get_id(), $meta_key ) ) { $props_to_update[ $meta_key ] = $prop; } } return $props_to_update; } /** * Get valid WP_Query args from a WC_Object_Query's query variables. * * @since 3.1.0 * @param array $query_vars query vars from a WC_Object_Query * @return array */ protected function get_wp_query_args( $query_vars ) { $skipped_values = array( '', array(), null ); $wp_query_args = array( 'meta_query' => array(), 'date_query' => array(), ); foreach( $query_vars as $key => $value ) { if ( in_array( $value, $skipped_values, true ) || 'meta_query' === $key ) { continue; } // Build meta queries out of vars that are stored in internal meta keys. if ( in_array( '_' . $key, $this->internal_meta_keys ) ) { $wp_query_args['meta_query'][] = array( 'key' => '_' . $key, 'value' => $value, 'compare' => '=', ); // Other vars get mapped to a 'post_*' or just left alone. } else { $key_mapping = array ( 'parent' => 'post_parent', 'parent__in' => 'post_parent__in', 'parent__not_in' => 'post_parent__not_in', 'in' => 'post__in', 'not_in' => 'post__not_in', 'status' => 'post_status', 'per_page' => 'posts_per_page', 'type' => 'post_type', 'return' => 'fields', ); if ( isset( $key_mapping[ $key ] ) ) { $wp_query_args[ $key_mapping[ $key ] ] = $value; } elseif ( ! empty( $query_vars['date_before'] ) ) { $wp_query_args['date_query']['before'] = $query_vars['date_before']; } elseif ( ! empty( $query_vars['date_after'] ) ) { $wp_query_args['date_query']['after'] = $query_vars['date_after']; } else { $wp_query_args[ $key ] = $value; } } } return apply_filters( 'woocommerce_get_wp_query_args', $wp_query_args, $query_vars ); } }