-
-
Save carlalexander/66bfb197dd55be218083a351e6e4f080 to your computer and use it in GitHub Desktop.
WordPress query builder class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Builds a WP_Query object using a fluent interface. | |
* | |
* @author Carl Alexander <contact@carlalexander.ca> | |
*/ | |
class WP_Query_Builder | |
{ | |
/** | |
* The query arguments collected by the query builder. | |
* | |
* @var array | |
*/ | |
private $query_arguments; | |
/** | |
* Constructor. | |
* | |
* @param array $query_arguments | |
*/ | |
public function __construct(array $query_arguments = array()) | |
{ | |
$this->query_arguments = array_merge(array( | |
'no_found_rows' => true, | |
'update_post_meta_cache' => false, | |
'update_post_term_cache' => false, | |
), $query_arguments); | |
} | |
/** | |
* Generates a group of query arrays using the given query arrays. The query | |
* result must match all the given query arrays. | |
* | |
* @param array ...$query_arrays | |
* | |
* @return array | |
*/ | |
public function and_where() | |
{ | |
$query_arrays = func_get_args(); | |
$query_arrays['relation'] = 'AND'; | |
return $query_arrays; | |
} | |
/** | |
* Generates a taxonomy array for a category. | |
* | |
* @param array|string $categories | |
* @param string $field | |
* @param string $operator | |
* @param bool $include_children | |
* | |
* @return array | |
*/ | |
public function category($categories, $field = 'term_id', $operator = 'IN', $include_children = true) | |
{ | |
return $this->taxonomy('category', $categories, $field, $operator, $include_children); | |
} | |
/** | |
* Specify the post types that the query will retrieve. | |
* | |
* Can be a comma separated string or an array. Overwrites previous | |
* specification criteria if called multiple times. | |
* | |
* @param string|array $from | |
* | |
* @return self | |
*/ | |
public function from($from) | |
{ | |
if (is_string($from)) { | |
$from = array_map('trim', explode(',', $from)); | |
} elseif (!is_array($from)) { | |
return $this; | |
} | |
$this->query_arguments['post_type'] = $from; | |
return $this; | |
} | |
/** | |
* Query WordPress using the current specifications of the builder. | |
* | |
* @return WP_Post[] | |
*/ | |
public function get_results() | |
{ | |
var_dump($this->query_arguments); | |
$query = new WP_Query($this->query_arguments); | |
return $query->posts; | |
} | |
/** | |
* Generates a taxonomy array where posts have one of the given categories. | |
* | |
* @param array|string $categories | |
* @param string $field | |
* @param bool $include_children | |
* | |
* @return array | |
*/ | |
public function in_category($categories, $field = 'term_id', $include_children = true) | |
{ | |
return $this->in_taxonomy('category', $categories, $field, $include_children); | |
} | |
/** | |
* Generates a taxonomy array where posts have one of the given | |
* taxonomy terms. | |
* | |
* @param string $taxonomy | |
* @param array|string $terms | |
* @param string $field | |
* @param bool $include_children | |
* | |
* @return array | |
*/ | |
public function in_taxonomy($taxonomy, $terms, $field = 'term_id', $include_children = true) | |
{ | |
return $this->taxonomy($taxonomy, $terms, $field, 'IN', $include_children); | |
} | |
/** | |
* Specify the maximum number of results that the query will retrieve. | |
* | |
* Overwrites previous specification criteria if called multiple times. | |
* | |
* @param int $limit | |
* | |
* @return self | |
*/ | |
public function limit($limit) | |
{ | |
if (!is_numeric($limit)) { | |
return $this; | |
} | |
$this->query_arguments['posts_per_page'] = (int) $limit; | |
return $this; | |
} | |
/** | |
* Generates a taxonomy array where posts don't have one of the given categories. | |
* | |
* @param array|string $categories | |
* @param string $field | |
* @param bool $include_children | |
* | |
* @return array | |
*/ | |
public function not_in_category($categories, $field = 'term_id', $include_children = true) | |
{ | |
return $this->not_in_taxonomy('category', $categories, $field, $include_children); | |
} | |
/** | |
* Generates a taxonomy array where posts don't have one of the given | |
* taxonomy terms. | |
* | |
* @param string $taxonomy | |
* @param array|string $terms | |
* @param string $field | |
* @param bool $include_children | |
* | |
* @return array | |
*/ | |
public function not_in_taxonomy($taxonomy, $terms, $field = 'term_id', $include_children = true) | |
{ | |
return $this->taxonomy($taxonomy, $terms, $field, 'NOT IN', $include_children); | |
} | |
/** | |
* Generates a group of query arrays using the given query arrays. The query | |
* result must match one of the given query arrays. | |
* | |
* @param array ...$query_arrays | |
* | |
* @return array | |
*/ | |
public function or_where() | |
{ | |
$taxonomy = func_get_args(); | |
$taxonomy['relation'] = 'OR'; | |
return $taxonomy; | |
} | |
/** | |
* Specify the order of the query results. | |
* | |
* Overwrites previous specification criteria if called multiple times. | |
* | |
* @param string|array $sort | |
* @param string $order | |
* | |
* @return self | |
*/ | |
public function order_by($sort, $order = 'DESC') | |
{ | |
if (empty($sort) || (!is_array($sort) && !is_string($sort))) { | |
return $this; | |
} elseif (!is_string($order) || !in_array(strtoupper($order), array('ASC', 'DESC'))) { | |
$order = 'DESC'; | |
} | |
$this->query_arguments['orderby'] = $sort; | |
$this->query_arguments['order'] = $order; | |
return $this; | |
} | |
/** | |
* Specify the columns that the query will retrieve. | |
* | |
* Overwrites previous specification criteria if called multiple times. | |
* | |
* @param string $select | |
* | |
* @return self | |
*/ | |
public function select($select) | |
{ | |
if (empty($select) || !is_string($select)) { | |
return $this; | |
} | |
$this->query_arguments['fields'] = $select; | |
return $this; | |
} | |
/** | |
* Generates a taxonomy array for a tag. | |
* | |
* @param array|string $tags | |
* @param string $field | |
* @param string $operator | |
* @param bool $include_children | |
* | |
* @return array | |
*/ | |
public function tag($tags, $field = 'term_id', $operator = 'IN', $include_children = true) | |
{ | |
return $this->taxonomy('tag', $tags, $field, $operator, $include_children); | |
} | |
/** | |
* Generates a taxonomy array. | |
* | |
* @param string $taxonomy | |
* @param array|string $terms | |
* @param string $field | |
* @param string $operator | |
* @param bool $include_children | |
* | |
* @return array | |
*/ | |
public function taxonomy($taxonomy, $terms, $field = 'term_id', $operator = 'IN', $include_children = true) | |
{ | |
if (!is_array($terms)) { | |
$terms = array($terms); | |
} | |
return array( | |
'taxonomy' => $taxonomy, | |
'field' => $field, | |
'terms' => $terms, | |
'operator' => $operator, | |
'include_children' => $include_children, | |
); | |
} | |
/** | |
* Specify the taxonomy of the posts that the query will retrieve. | |
* | |
* @param array ...$taxonomies | |
* | |
* @return self | |
*/ | |
public function where_taxonomy() | |
{ | |
$this->query_arguments['tax_query'] = array_reduce(func_get_args(), array($this, 'merge_query_argument')); | |
return $this; | |
} | |
/** | |
* Merges the given query array argument into the given query. | |
* | |
* @param mixed $query | |
* @param array $query_argument | |
* | |
* @return array | |
*/ | |
private function merge_query_argument($query, array $query_argument) | |
{ | |
if (!is_array($query)) { | |
$query = array(); | |
} | |
if (!isset($query_argument['relation'])) { | |
$query_argument = array($query_argument); | |
$query_argument['relation'] = 'AND'; | |
} | |
$query['relation'] = $query_argument['relation']; | |
unset($query_argument['relation']); | |
foreach ($query_argument as $query_array) { | |
$query[] = $query_array; | |
} | |
return $query; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment