post_type = $this->post_type ? $this->post_type : $post_type; $this->category_tax = $this->category_tax ? $this->category_tax : $category_tax; $this->tag_tax = $this->tag_tax ? $this->tag_tax : $tag_tax; $this->_wp_query_args = array( 'post_type' => $this->post_type, 'posts_per_page' => -1, ); if ( ! self::$_ ) { self::$_ = ET_Core_Data_Utils::instance(); } } /** * Adds a meta query to the WP Query args for this instance. * * @since 3.0.99 * * @param string $key The meta key. * @param string $value The meta value. * @param bool $negate Whether or not to negate this meta query. */ protected function _add_meta_query( $key, $value, $negate ) { if ( ! isset( $this->_wp_query_args['meta_query'] ) ) { $this->_wp_query_args['meta_query'] = array(); } if ( is_null( $value ) ) { $compare = $negate ? 'NOT EXISTS' : 'EXISTS'; } else if ( is_array( $value ) ) { $compare = $negate ? 'NOT IN' : 'IN'; } else { $compare = $negate ? '!=' : '='; } $query = array( 'key' => $key, 'compare' => $compare, ); if ( ! is_null( $value ) ) { $query['value'] = $value; } if ( '!=' === $compare ) { $query = array( 'relation' => 'OR', array( 'key' => $key, 'compare' => 'NOT EXISTS', ), $query, ); } $this->_wp_query_args['meta_query'][] = $query; } /** * Adds a tax query to the WP Query args for this instance. * * @since 3.0.99 * * @param string $taxonomy The taxonomy name. * @param array $terms Taxonomy terms. * @param bool $negate Whether or not to negate this tax query. */ protected function _add_tax_query( $taxonomy, $terms, $negate ) { if ( ! isset( $this->_wp_query_args['tax_query'] ) ) { $this->_wp_query_args['tax_query'] = array(); } $operator = $negate ? 'NOT IN' : 'IN'; $field = is_int( $terms[0] ) ? 'term_id' : 'name'; $query = array( 'taxonomy' => $taxonomy, 'field' => $field, 'terms' => $terms, 'operator' => $operator, ); if ( $negate ) { $query = array( 'relation' => 'OR', array( 'taxonomy' => $taxonomy, 'operator' => 'NOT EXISTS', ), $query, ); } $this->_wp_query_args['tax_query'][] = $query; } /** * Resets {@see self::$_negate} to default then returns the previous value. * * @return bool */ protected function _reset_negate() { $negate = $this->_negate; $this->_negate = false; return $negate; } /** * Adds a tax query to this instance's WP Query args for it's category taxonomy. * * @since 3.0.99 * * @param mixed ...$categories Variable number of category arguments where each arg can be * a single category name or ID or an array of names or IDs. * * @return $this */ public function in_category() { $negate = $this->_reset_negate(); if ( ! $this->category_tax ) { et_error( 'A category taxonomy has not been set for this query!' ); return $this; } $args = func_get_args(); $args = self::$_->array_flatten( $args ); if ( ! $args ) { return $this; } $this->_add_tax_query( $this->category_tax, $args, $negate ); return $this; } /** * Negates the next query arg that is set. * * @since 3.0.99 * * @return $this */ public function not() { $this->_negate = true; return $this; } /** * Performs a new WP Query using the instance's current query params and then returns the * results. Typically, this method is the last method call in a set of chained calls to other * methods on this class during which various query params are set. * * Examples: * * $cpt_query * ->in_category( 'some_cat' ) * ->with_tag( 'some_tag' ) * ->run(); * * $cpt_query * ->with_tag( 'some_tag' ) * ->not()->in_category( 'some_cat' ) * ->run(); * * @since 3.0.99 * * @param array $args Optional. Additional arguments for {@see WP_Query}. * * @return WP_Post|WP_Post[] $posts */ public function run( $args = array() ) { if ( ! is_null( $this->_query_result ) ) { return $this->_query_result; } $name = $this->post_type; if ( $args ) { $this->_wp_query_args = array_merge_recursive( $this->_wp_query_args, $args ); } /** * Filters the WP Query args for a custom post type query. The dynamic portion of * the filter name, $name, refers to the name of the custom post type. * * @since 3.0.99 * * @param array $args {@see WP_Query::__construct()} */ $this->_wp_query_args = apply_filters( "et_core_cpt_{$name}_query_args", $this->_wp_query_args ); $query = new WP_Query( $this->_wp_query_args ); $this->_query_result = $query->posts; if ( 1 === count( $this->_query_result ) ) { $this->_query_result = array_pop( $this->_query_result ); } return $this->_query_result; } /** * Adds a meta query to this instance's WP Query args. * * @since 3.0.99 * * @param string $key The meta key. * @param mixed $value Optional. The meta value to compare. When `$value` is not provided, * the comparison will be 'EXISTS' or 'NOT EXISTS' (when negated). * When `$value` is an array, comparison will be 'IN' or 'NOT IN'. * When `$value` is not an array, comparison will be '=' or '!='. * * @return $this */ public function with_meta( $key, $value = null ) { $this->_add_meta_query( $key, $value, $this->_reset_negate() ); return $this; } /** * Adds a tax query to this instance's WP Query args for it's primary tag-like taxonomy. * * @since 3.0.99 * * @param mixed ...$tags Variable number of tag arguments where each arg can be * a single tag name or ID, or an array of tag names or IDs. * * @return $this */ public function with_tag() { $negate = $this->_reset_negate(); if ( ! $this->tag_tax ) { et_error( 'A tag taxonomy has not been set for this query!' ); return $this; } $args = func_get_args(); $args = self::$_->array_flatten( $args ); if ( ! $args ) { return $this; } $this->_add_tax_query( $this->tag_tax, $args, $negate ); return $this; } }