Solved SQL Query and tree algorithm! #230
This commit is contained in:
parent
49bee40ced
commit
befb9044bb
|
@ -1014,19 +1014,78 @@ class Metadata extends Repository {
|
|||
if ( $metadatum_type === 'Tainacan\Metadata_Types\Taxonomy' ) {
|
||||
|
||||
if ($items_query) {
|
||||
$base_query = $wpdb->prepare("FROM $wpdb->term_relationships tr
|
||||
INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
|
||||
INNER JOIN $wpdb->terms t ON tt.term_id = t.term_id
|
||||
WHERE
|
||||
tt.parent = %d AND
|
||||
tr.object_id IN ($items_query) AND
|
||||
tt.taxonomy = %s
|
||||
$search_q
|
||||
|
||||
// $base_query = $wpdb->prepare("FROM $wpdb->term_relationships tr
|
||||
// INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
|
||||
// INNER JOIN $wpdb->terms t ON tt.term_id = t.term_id
|
||||
// WHERE
|
||||
// tt.parent = %d AND
|
||||
// tr.object_id IN ($items_query) AND
|
||||
// tt.taxonomy = %s
|
||||
// $search_q
|
||||
// ORDER BY t.name ASC
|
||||
// ",
|
||||
// $args['parent_id'],
|
||||
// $taxonomy_slug
|
||||
// );
|
||||
|
||||
//$search_query = "AND (tt.parent <> %d OR t.name LIKE '%master%')";
|
||||
|
||||
|
||||
$base_query = $wpdb->prepare("
|
||||
SELECT DISTINCT t.term_id, t.name, tt.parent, coalesce(tr.term_taxonomy_id, 0) as have_items
|
||||
FROM
|
||||
$wpdb->terms t INNER JOIN $wpdb->term_taxonomy tt ON t.term_id = tt.term_id
|
||||
LEFT JOIN $wpdb->term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id AND tr.object_id IN ($items_query)
|
||||
WHERE tt.taxonomy = %s
|
||||
ORDER BY t.name ASC
|
||||
",
|
||||
$args['parent_id'],
|
||||
$taxonomy_slug
|
||||
",
|
||||
$taxonomy_slug
|
||||
);
|
||||
|
||||
$all_hierarchy = $wpdb->get_results($base_query);
|
||||
|
||||
$results = $this->_process_terms_tree($all_hierarchy, $args['parent_id']);
|
||||
$total = count($results);
|
||||
|
||||
// $results = [];
|
||||
//
|
||||
// function children_has_items($term_id, $hierarchy) {
|
||||
//
|
||||
// $has_items = false;
|
||||
//
|
||||
// foreach ( $hierarchy as $h ) {
|
||||
//
|
||||
// if ( $term_in_hierarchy->parent != $term_id ) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if ( $h->have_items > 0 ) {
|
||||
// return true;
|
||||
// } else {
|
||||
// return children_has_items($h->term_id, $hierarchy);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//
|
||||
// }
|
||||
// var_dump($all_hierarchy);
|
||||
// foreach ($all_hierarchy as $term_in_hierarchy) {
|
||||
// if ( $term_in_hierarchy->parent != $args['parent_id'] ) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if ( $term_in_hierarchy->have_items > 0 || children_has_items($term_in_hierarchy->term_id, $all_hierarchy) ) {
|
||||
// $results[] = $term_in_hierarchy;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
$base_query = $wpdb->prepare("FROM $wpdb->term_taxonomy tt
|
||||
INNER JOIN $wpdb->terms t ON tt.term_id = t.term_id
|
||||
|
@ -1039,14 +1098,18 @@ class Metadata extends Repository {
|
|||
$args['parent_id'],
|
||||
$taxonomy_slug
|
||||
);
|
||||
|
||||
$query = "SELECT DISTINCT t.name, t.term_id, tt.term_taxonomy_id, tt.parent $base_query $pagination";
|
||||
|
||||
$total_query = "SELECT COUNT(DISTINCT tt.term_taxonomy_id) $base_query";
|
||||
$total = $wpdb->get_var($total_query);
|
||||
|
||||
$results = $wpdb->get_results($query);
|
||||
|
||||
}
|
||||
|
||||
|
||||
$query = "SELECT DISTINCT t.name, t.term_id, tt.term_taxonomy_id, tt.parent $base_query $pagination";
|
||||
|
||||
$total_query = "SELECT COUNT(DISTINCT tt.term_taxonomy_id) $base_query";
|
||||
|
||||
$results = $wpdb->get_results($query);
|
||||
|
||||
// add selected to the result
|
||||
if ( !empty($args['include']) ) {
|
||||
|
@ -1071,7 +1134,7 @@ class Metadata extends Repository {
|
|||
}
|
||||
}
|
||||
|
||||
$total = $wpdb->get_var($total_query);
|
||||
|
||||
$number = is_integer($args['number']) && $args['number'] >=1 ? $args['number'] : $total;
|
||||
if( $number < 1){
|
||||
$pages = 1;
|
||||
|
@ -1197,6 +1260,75 @@ class Metadata extends Repository {
|
|||
];
|
||||
|
||||
}
|
||||
|
||||
public function _process_terms_tree($tree, $search_parent) {
|
||||
|
||||
$h_map = [];
|
||||
$results = [];
|
||||
foreach ( $tree as $h ) {
|
||||
|
||||
//echo "Processing $h->term_id\n";
|
||||
//var_dump($h);
|
||||
//echo "Já ta mapeado?\n";
|
||||
//var_dump(( isset($h_map[$h->term_id]) && $h_map[$h->term_id]->have_items > 0 ));
|
||||
|
||||
if ( $h->have_items > 0 || ( isset($h_map[$h->term_id]) && $h_map[$h->term_id]->have_items > 0 ) ) {
|
||||
|
||||
//echo "have_items\n";
|
||||
|
||||
$h->have_items = 1;
|
||||
$h_map[$h->term_id] = $h;
|
||||
|
||||
|
||||
|
||||
if ($h->parent == $search_parent) {
|
||||
//echo "Add to results\n";
|
||||
$results[] = $h;
|
||||
}
|
||||
|
||||
$_parent = $h->parent;
|
||||
|
||||
if ( $h->parent > 0 && !isset($h_map[$_parent]) ) {
|
||||
//echo "Setting parent with have items 1\n";
|
||||
//echo "Parent ID = $_parent\n";
|
||||
$h_map[$_parent] = (object)['have_items' => 1];
|
||||
}
|
||||
|
||||
while( isset($h_map[$_parent]) && $h_map[$_parent]->have_items != 1 ) {
|
||||
|
||||
//echo "Looping\n";
|
||||
|
||||
$h_map[$_parent]->have_items = 1;
|
||||
|
||||
if ( isset($h_map[$_parent]->parent) ) {
|
||||
//echo "Parent exists: $_parent\n";
|
||||
if ($h_map[$_parent]->parent == $search_parent) {
|
||||
//echo "Add to results: {$h_map[$_parent]->term_id}\n";
|
||||
$results[] = $h_map[$_parent];
|
||||
}
|
||||
$_parent = $h_map[$_parent]->parent;
|
||||
} else {
|
||||
//echo "Parent not exists\n";
|
||||
$_parent = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
//echo "Not have items\n";
|
||||
$h_map[$h->term_id] = $h;
|
||||
if ( $h->parent > 0 && !isset($h_map[$h->parent]) ) {
|
||||
//echo "Parent added: $h->parent\n";
|
||||
$h_map[$h->parent] = (object)['have_items' => $h->have_items];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $results;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the value of the taxonomy_id option to use on update_taxonomy_metadatum method.
|
||||
|
|
|
@ -52,6 +52,19 @@ class Facets extends TAINACAN_UnitApiTestCase {
|
|||
|
||||
$this->taxonomy = $taxonomy;
|
||||
|
||||
$taxonomy2 = $this->tainacan_entity_factory->create_entity(
|
||||
'taxonomy',
|
||||
array(
|
||||
'name' => 'genero2',
|
||||
'description' => 'tipos de musica2',
|
||||
'allow_insert' => 'yes',
|
||||
'status' => 'publish'
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$this->taxonomy = $taxonomy;
|
||||
|
||||
$term_1 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
|
@ -113,6 +126,104 @@ class Facets extends TAINACAN_UnitApiTestCase {
|
|||
true
|
||||
);
|
||||
|
||||
$term2_root = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'Root'
|
||||
),
|
||||
true
|
||||
);
|
||||
$term2_root2 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'Root2'
|
||||
),
|
||||
true
|
||||
);
|
||||
$term2_root_c1 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'Children',
|
||||
'parent' => $term2_root->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
$term2_root_c2 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'Children2',
|
||||
'parent' => $term2_root->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
$term2_root_gc1 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'GChildren',
|
||||
'parent' => $term2_root_c2->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
$term2_root_gc2 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'GChildren2',
|
||||
'parent' => $term2_root_c2->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
$term2_root2_c1 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'Children',
|
||||
'parent' => $term2_root2->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
$term2_root2_c2 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'Children2',
|
||||
'parent' => $term2_root2->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
$term2_root2_gc1 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'GChildren',
|
||||
'parent' => $term2_root2_c2->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
$term2_root2_gc2 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'GChildren2',
|
||||
'parent' => $term2_root2_c2->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
$term2_root2_ggc1 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy2->get_db_identifier(),
|
||||
'name' => 'GGChildren1',
|
||||
'parent' => $term2_root2_gc2->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$meta_1_tax = $this->tainacan_entity_factory->create_entity(
|
||||
'metadatum',
|
||||
array(
|
||||
|
@ -150,6 +261,24 @@ class Facets extends TAINACAN_UnitApiTestCase {
|
|||
|
||||
$this->meta_2_tax = $meta_2_tax;
|
||||
|
||||
$meta_3_tax = $this->tainacan_entity_factory->create_entity(
|
||||
'metadatum',
|
||||
array(
|
||||
'name' => 'test taxonomy',
|
||||
'status' => 'publish',
|
||||
'collection' => $collection2,
|
||||
'metadata_type' => 'Tainacan\Metadata_Types\Taxonomy',
|
||||
'metadata_type_options' => [
|
||||
'allow_new_terms' => true,
|
||||
'taxonomy_id' => $taxonomy2->get_id()
|
||||
],
|
||||
'multiple' => 'yes'
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$this->meta_3_tax = $meta_3_tax;
|
||||
|
||||
$metadatum_text = $this->tainacan_entity_factory->create_entity(
|
||||
'metadatum',
|
||||
array(
|
||||
|
@ -239,8 +368,16 @@ class Facets extends TAINACAN_UnitApiTestCase {
|
|||
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_2_tax, [$term_2_c->get_id()]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// hierarchical taxonomy
|
||||
if ($i <= 10) {
|
||||
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_3_tax, [$term2_root_c1->get_id()]);
|
||||
} elseif($i <= 20) {
|
||||
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_3_tax, [$term2_root2_c1->get_id()]);
|
||||
} elseif($i <= 30) {
|
||||
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_3_tax, [$term2_root2_gc2->get_id()]);
|
||||
} elseif($i <= 40) {
|
||||
$this->tainacan_item_metadata_factory->create_item_metadata($item, $meta_3_tax, [$term2_root2_ggc1->get_id()]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->repository = \Tainacan\Repositories\Metadata::get_instance();
|
||||
|
@ -647,7 +784,16 @@ class Facets extends TAINACAN_UnitApiTestCase {
|
|||
// test count items normal
|
||||
|
||||
// test default taxonomy
|
||||
$values = $this->repository->fetch_all_metadatum_values( $this->meta_3_tax->get_id());
|
||||
$values = $this->get_values($values);
|
||||
$this->assertEquals(2, sizeof($values));
|
||||
|
||||
// test default taxonomy without filter
|
||||
$values = $this->repository->fetch_all_metadatum_values( $this->meta_3_tax->get_id(), [
|
||||
'items_filter' => false
|
||||
]);
|
||||
$values = $this->get_values($values);
|
||||
$this->assertEquals(2, sizeof($values));
|
||||
// test search taxonomy
|
||||
// test search taxonomy with filter
|
||||
// test search taxonomy without filter
|
||||
|
@ -660,6 +806,168 @@ class Facets extends TAINACAN_UnitApiTestCase {
|
|||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @group term_tree
|
||||
*/
|
||||
public function test_process_term_tree() {
|
||||
|
||||
$data = [
|
||||
(object) [
|
||||
'term_id' => 1,
|
||||
'name' => 'Root',
|
||||
'parent' => 0,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 2,
|
||||
'name' => 'Child 1',
|
||||
'parent' => 1,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 3,
|
||||
'name' => 'G Child 1',
|
||||
'parent' => 2,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 4,
|
||||
'name' => 'G G Child',
|
||||
'parent' => 3,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 5,
|
||||
'name' => 'G G Child 2',
|
||||
'parent' => 3,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 6,
|
||||
'name' => 'G G G Child',
|
||||
'parent' => 4,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 7,
|
||||
'name' => 'G G G Child 2',
|
||||
'parent' => 5,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 8,
|
||||
'name' => '2 Root',
|
||||
'parent' => 0,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 9,
|
||||
'name' => '2 Child',
|
||||
'parent' => 8,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 10,
|
||||
'name' => '2 Child 2',
|
||||
'parent' => 8,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 11,
|
||||
'name' => '2 G Child',
|
||||
'parent' => 10,
|
||||
'have_items' => 0
|
||||
],
|
||||
(object) [
|
||||
'term_id' => 12,
|
||||
'name' => '2 G Child 2',
|
||||
'parent' => 10,
|
||||
'have_items' => 0
|
||||
]
|
||||
];
|
||||
|
||||
$data_b = $data;
|
||||
|
||||
|
||||
$MetaRepo = \Tainacan\Repositories\Metadata::get_instance();
|
||||
|
||||
|
||||
// items on 5 and 12
|
||||
$data[4]->have_items = 1;
|
||||
$data[11]->have_items = 1;
|
||||
$i = 0;
|
||||
while ($i<100) {
|
||||
$i++;
|
||||
|
||||
shuffle($data);
|
||||
|
||||
$results = $MetaRepo->_process_terms_tree($data, 0);
|
||||
|
||||
$this->assertEquals(2, count($results));
|
||||
$ids = array_map(function($el) {return $el->term_id; }, $results);
|
||||
$this->assertContains(1, $ids);
|
||||
$this->assertContains(8, $ids);
|
||||
|
||||
|
||||
$results = $MetaRepo->_process_terms_tree($data, 3);
|
||||
|
||||
$this->assertEquals(1, count($results));
|
||||
$ids = array_map(function($el) {return $el->term_id; }, $results);
|
||||
$this->assertContains(5, $ids);
|
||||
|
||||
$results = $MetaRepo->_process_terms_tree($data, 5);
|
||||
$this->assertEquals(0, count($results));
|
||||
|
||||
$results = $MetaRepo->_process_terms_tree($data, 10);
|
||||
$this->assertEquals(1, count($results));
|
||||
$this->assertEquals(12, $results[0]->term_id);
|
||||
|
||||
}
|
||||
|
||||
// items on 6, 7 and 8
|
||||
$data = $data_b;
|
||||
$data[4]->have_items = 0;
|
||||
$data[11]->have_items = 0;
|
||||
$data[7]->have_items = 1;
|
||||
$data[6]->have_items = 1;
|
||||
$data[5]->have_items = 1;
|
||||
|
||||
$i = 0;
|
||||
while ($i<100) {
|
||||
$i++;
|
||||
|
||||
shuffle($data);
|
||||
|
||||
$results = $MetaRepo->_process_terms_tree($data, 0);
|
||||
|
||||
$this->assertEquals(2, count($results));
|
||||
$ids = array_map(function($el) {return $el->term_id; }, $results);
|
||||
$this->assertContains(1, $ids);
|
||||
$this->assertContains(8, $ids);
|
||||
|
||||
|
||||
$results = $MetaRepo->_process_terms_tree($data, 3);
|
||||
$this->assertEquals(2, count($results));
|
||||
$ids = array_map(function($el) {return $el->term_id; }, $results);
|
||||
$this->assertContains(5, $ids);
|
||||
$this->assertContains(4, $ids);
|
||||
|
||||
$results = $MetaRepo->_process_terms_tree($data, 5);
|
||||
$this->assertEquals(1, count($results));
|
||||
$ids = array_map(function($el) {return $el->term_id; }, $results);
|
||||
$this->assertContains(7, $ids);
|
||||
|
||||
$results = $MetaRepo->_process_terms_tree($data, 10);
|
||||
$this->assertEquals(0, count($results));
|
||||
|
||||
$results = $MetaRepo->_process_terms_tree($data, 6);
|
||||
$this->assertEquals(0, count($results));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue