improving fetch!

This commit is contained in:
Leo Germani 2017-11-30 14:42:11 -02:00
parent 8bbc602774
commit 6676d03aa0
9 changed files with 118 additions and 79 deletions

View File

@ -157,15 +157,14 @@ class Item_Metadata_Entity extends Entity {
if ($this->is_collection_key()) {
$Tainacan_Items = new \Tainacan\Repositories\Items();
$test = $Tainacan_Items->query([
'collections' => $item->get_collection(),
'metadata' => [
$test = $Tainacan_Items->fetch([
'meta_query' => [
[
'key' => $this->metadata->get_id(),
'value' => $value
],
]
]);
], $item->get_collection());
if ($test->have_posts()) {
$this->add_error('key_exists', $metadata->get_name() . ' is a collection key and there is another item with the same value');

View File

@ -160,7 +160,9 @@ class Collections extends Repository {
* fetch collection based on ID or WP_Query args
*
* Collections are stored as posts. Check WP_Query docs
* to learn all args accepted in the $args parameter
* to learn all args accepted in the $args parameter (@see https://developer.wordpress.org/reference/classes/wp_query/)
* You can also use a mapped property, such as name and description, as an argument and it will be mapped to the
* appropriate WP_Query argument
*
* @param array $args WP_Query args || int $args the collection id
* @param string $output The desired output format (@see \Tainacan\Repositories\Repository::fetch_output() for possible values)
@ -174,7 +176,9 @@ class Collections extends Repository {
'posts_per_page' => -1,
'post_status' => 'publish',
], $args);
$args = $this->parse_fetch_args($args);
$args['post_type'] = Entities\Collection::get_post_type();
// TODO: Pegar coleções registradas via código

View File

@ -138,7 +138,9 @@ class Filters extends Repository {
* fetch filter based on ID or WP_Query args
*
* Filters are stored as posts. Check WP_Query docs
* to learn all args accepted in the $args parameter
* to learn all args accepted in the $args parameter (@see https://developer.wordpress.org/reference/classes/wp_query/)
* You can also use a mapped property, such as name and description, as an argument and it will be mapped to the
* appropriate WP_Query argument
*
* @param array $args WP_Query args || int $args the filter id
* @param string $output The desired output format (@see \Tainacan\Repositories\Repository::fetch_output() for possible values)
@ -153,7 +155,9 @@ class Filters extends Repository {
'posts_per_page' => -1,
'post_status' => 'publish'
], $args);
$args = $this->parse_fetch_args($args);
$args['post_type'] = Entities\Filter::get_post_type();
$wp_query = new \WP_Query($args);

View File

@ -117,7 +117,9 @@ class Items extends Repository {
* fetch items based on ID or WP_Query args
*
* Items are stored as posts. Check WP_Query docs
* to learn all args accepted in the $args parameter
* to learn all args accepted in the $args parameter (@see https://developer.wordpress.org/reference/classes/wp_query/)
* You can also use a mapped property, such as name and description, as an argument and it will be mapped to the
* appropriate WP_Query argument
*
* The second paramater specifies from which collections item should be fetched.
* You can pass the Collection ID or object, or an Array of IDs or collection objects
@ -172,7 +174,9 @@ class Items extends Repository {
}
//TODO: get collection order and order by options
$args = $this->parse_fetch_args($args);
$args = array_merge([
'post_status' => 'publish',
], $args);
@ -191,52 +195,4 @@ class Items extends Repository {
}
// same as WP_Query with few paramaters more:
// collections ID or array of IDs, object or array of objects
// metadata - array of metadata in meta_query format
// other item properties, present in the "map"
public function query($args) {
$map = $this->get_map();
$wp_query_exceptions = [
'ID' => 'p',
'post_title' => 'title'
];
$meta_query = [];
foreach ($map as $prop => $mapped) {
if (array_key_exists($prop, $args)) {
$prop_value = $args[$prop];
unset($args[$prop]);
if ( $mapped['map'] == 'meta' || $mapped['map'] == 'meta_multi' ) {
$meta_query[] = [
'key' => $prop,
'value' => $prop_value
];
} else {
$prop_search_name = array_key_exists($mapped['map'], $wp_query_exceptions) ? $wp_query_exceptions[$mapped['map']] : $mapped['map'];
$args[$prop_search_name] = $prop_value;
}
}
}
if ( isset($args['metadata']) && is_array($args['metadata']) && !empty($args['metadata'])) {
$meta_query = array_merge($args['metadata'],$meta_query);
}
$args['meta_query'] = $meta_query;
unset($args['metadata']);
$collections = !empty($args['collections']) ? $args['collections'] : [];
unset($args['collections']);
return $this->fetch($args, $collections);
### TODO I think its better if we return a WP_Query object. easier for loop and debugging
}
}

View File

@ -113,7 +113,9 @@ class Logs extends Repository {
* fetch logs based on ID or WP_Query args
*
* Logs are stored as posts. Check WP_Query docs
* to learn all args accepted in the $args parameter
* to learn all args accepted in the $args parameter (@see https://developer.wordpress.org/reference/classes/wp_query/)
* You can also use a mapped property, such as name and description, as an argument and it will be mapped to the
* appropriate WP_Query argument
*
* @param array $args WP_Query args || int $args the log id
* @param string $output The desired output format (@see \Tainacan\Repositories\Repository::fetch_output() for possible values)
@ -127,6 +129,8 @@ class Logs extends Repository {
'post_status' => 'publish',
], $args);
$args = $this->parse_fetch_args($args);
$args['post_type'] = Entities\Log::get_post_type();
$wp_query = new \WP_Query($args);

View File

@ -132,7 +132,9 @@ class Metadatas extends Repository {
* fetch metadata based on ID or WP_Query args
*
* metadata are stored as posts. Check WP_Query docs
* to learn all args accepted in the $args parameter
* to learn all args accepted in the $args parameter (@see https://developer.wordpress.org/reference/classes/wp_query/)
* You can also use a mapped property, such as name and description, as an argument and it will be mapped to the
* appropriate WP_Query argument
*
* @param array $args WP_Query args || int $args the metadata id
* @param string $output The desired output format (@see \Tainacan\Repositories\Repository::fetch_output() for possible values)

View File

@ -101,6 +101,71 @@ abstract class Repository {
return $result;
}
}
/**
* Maps repository mapped properties to WP_Query arguments.
*
* This allows to build fetch arguments using both WP_Query arguments
* and the mapped properties for the repository.
*
* For example, you can use any of the following methods to browse collections by name:
* $TaincanCollections->fetch(['title' => 'test']);
* $TaincanCollections->fetch(['name' => 'test']);
*
* The property `name` is transformed into the native WordPress property `post_title`. (actually only title for query purpouses)
*
* Example 2, this also works with properties mapped to postmeta. The following methods are the same:
* $TaincanMetadatas->fetch(['required' => 'yes']);
* $TaincanMetadatas->fetch(['meta_query' => [
* [
* 'key' => 'required',
* 'value' => 'yes'
* ]
* ]]);
*
*
* @param array $args [description]
* @return Array $args new $args array with mapped properties
*/
public function parse_fetch_args($args = []) {
$map = $this->get_map();
$wp_query_exceptions = [
'ID' => 'p',
'post_title' => 'title'
];
$meta_query = [];
foreach ($map as $prop => $mapped) {
if (array_key_exists($prop, $args)) {
$prop_value = $args[$prop];
unset($args[$prop]);
if ( $mapped['map'] == 'meta' || $mapped['map'] == 'meta_multi' ) {
$meta_query[] = [
'key' => $prop,
'value' => $prop_value
];
} else {
$prop_search_name = array_key_exists($mapped['map'], $wp_query_exceptions) ? $wp_query_exceptions[$mapped['map']] : $mapped['map'];
$args[$prop_search_name] = $prop_value;
}
}
}
if ( isset($args['meta_query']) && is_array($args['meta_query']) && !empty($args['meta_query'])) {
$meta_query = array_merge($args['meta_query'],$meta_query);
}
$args['meta_query'] = $meta_query;
return $args;
}
/**
* @param $object

View File

@ -123,7 +123,9 @@ class Taxonomies extends Repository {
* fetch taxonomies based on ID or WP_Query args
*
* Taxonomies are stored as posts. Check WP_Query docs
* to learn all args accepted in the $args parameter
* to learn all args accepted in the $args parameter (@see https://developer.wordpress.org/reference/classes/wp_query/)
* You can also use a mapped property, such as name and description, as an argument and it will be mapped to the
* appropriate WP_Query argument
*
* @param array $args WP_Query args | int $args the taxonomy id
* @param string $output The desired output format (@see \Tainacan\Repositories\Repository::fetch_output() for possible values)
@ -142,6 +144,8 @@ class Taxonomies extends Repository {
'post_status' => 'publish'
], $args);
$args = $this->parse_fetch_args($args);
$args['post_type'] = Entities\Taxonomy::get_post_type();
$wp_query = new \WP_Query($args);

View File

@ -78,22 +78,26 @@ class Items extends \WP_UnitTestCase {
$item = $Tainacan_Items->insert($i);
// should return all 4 items
$test_query = $Tainacan_Items->query([]);
$test_query = $Tainacan_Items->fetch([]);
$this->assertEquals(4, $test_query->post_count );
// should also return all 4 items
$test_query = $Tainacan_Items->query(['collections' => [$collection, $collection2]]);
$test_query = $Tainacan_Items->fetch([], [$collection, $collection2]);
$this->assertEquals(4, $test_query->post_count);
// should return 2 items
$test_query = $Tainacan_Items->fetch(['posts_per_page' => 2], [$collection, $collection2]);
$this->assertEquals(2, $test_query->post_count);
// should return only the first item
$test_query = $Tainacan_Items->query(['collections' => $collection]);
$test_query = $Tainacan_Items->fetch([], $collection);
$this->assertEquals(1,$test_query->post_count);
$test_query->the_post();
$item = new \Tainacan\Entities\Item( get_the_ID() );
$this->assertEquals('orange', $item->get_title() );
$test_query = $Tainacan_Items->query(['title' => 'orange']);
$test_query = $Tainacan_Items->fetch(['title' => 'orange']);
$test_query->the_post();
$item = new \Tainacan\Entities\Item( get_the_ID() );
@ -101,10 +105,10 @@ class Items extends \WP_UnitTestCase {
$this->assertEquals('orange', $item->get_title());
// should return the other 3 items
$test_query = $Tainacan_Items->query(['collections' => $collection2]);
$test_query = $Tainacan_Items->fetch([], $collection2);
$this->assertEquals(3,$test_query->post_count);
$test_query = $Tainacan_Items->query(['title' => 'apple']);
$test_query = $Tainacan_Items->fetch(['title' => 'apple']);
$test_query->the_post();
$item = new \Tainacan\Entities\Item( get_the_ID() );
@ -118,40 +122,37 @@ class Items extends \WP_UnitTestCase {
}
// should return 1 item
$test_query = $Tainacan_Items->query([
'collections' => $collection2,
'metadata' => [
$test_query = $Tainacan_Items->fetch([
'meta_query' => [
[
'key' => $metadata2->get_id(),
'value' => 'value_2'
]
]
]);
], $collection2);
$this->assertEquals(1, $test_query->post_count);
// should return 2 items
$test_query = $Tainacan_Items->query([
'collections' => $collection2,
'metadata' => [
$test_query = $Tainacan_Items->fetch([
'meta_query' => [
[
'key' => $metadata2->get_id(),
'value' => 'value_3'
]
]
]);
], $collection2);
$this->assertEquals(2, $test_query->post_count);
// should return 2 item
$test_query = $Tainacan_Items->query([
'collections' => $collection2,
'metadata' => [
$test_query = $Tainacan_Items->fetch([
'meta_query' => [
[
'key' => $metadata3->get_id(),
'value' => 'value_2',
'compare' => '>'
]
]
]);
], $collection2);
$this->assertEquals(2, $test_query->post_count);
}