bulk edit: replace method add new value only when old value is found (#18)

This commit is contained in:
Leo Germani 2018-09-05 15:56:48 -03:00
parent b9b9638860
commit 3e3063c448
2 changed files with 242 additions and 2 deletions

View File

@ -276,6 +276,10 @@ class Bulk_Edit {
if ($metadatum->is_collection_key()) {
return new \WP_Error( 'invalid_action', __( 'Unable to set a value to a metadata set to be a collection key', 'tainacan' ) );
}
if ($new_value == $old_value) {
return new \WP_Error( 'invalid_action', __( 'Old value and new value can not be the same', 'tainacan' ) );
}
$dummyItem = new Entities\Item();
$dummyItem->set_status('publish');
@ -283,8 +287,7 @@ class Bulk_Edit {
$checkItemMetadata->set_value( $metadatum->is_multiple() ? [$new_value] : $new_value );
if ($checkItemMetadata->validate()) {
$this->_remove_value($metadatum, $old_value);
return $this->_add_value($metadatum, $new_value);
return $this->_replace_value($metadatum, $new_value, $old_value);
} else {
return new \WP_Error( 'invalid_value', __( 'Invalid Value', 'tainacan' ) );
}
@ -477,6 +480,107 @@ class Bulk_Edit {
}
}
/**
* Replaces a value in the current group of items
*
* This method replaces a value from the database directly, and adds a new value to all itemsm that had the previous value
*
* TODO: Possible refactor: This method is almost identical to the _add_value method and calls the _remove_value at the end. So it is almost
* the same thing as calling _add_value() and _remove_value() one after another. The only difference is that it does both checks before doing anything to the DB
* and a small change to the insert queries (marked below)
*
*/
private function _replace_value(Entities\Metadatum $metadatum, $newvalue, $value) {
global $wpdb;
if ($value == $newvalue) {
return new \WP_Error( 'error', __( 'New value and old value can not be the same', 'tainacan' ) );
}
$type = $metadatum->get_metadata_type_object();
if ($type->get_primitive_type() == 'term') {
$options = $metadatum->get_metadata_type_options();
$taxonomy_id = $options['taxonomy_id'];
$tax = Repositories\Taxonomies::get_instance()->fetch($taxonomy_id);
if ($tax instanceof Entities\Taxonomy) {
// check old term
$term = term_exists($value, $tax->get_db_identifier());
if (!$term) {
return 0;
}
if (is_WP_Error($term) || !isset($term['term_taxonomy_id'])) {
return new \WP_Error( 'error', __( 'Term not found', 'tainacan' ) );
}
// check new term
$newterm = term_exists($newvalue, $tax->get_db_identifier());
if (!is_array($newterm)) {
$newterm = wp_insert_term($newvalue, $tax->get_db_identifier());
}
if (is_WP_Error($newterm) || !isset($newterm['term_taxonomy_id'])) {
return new \WP_Error( 'error', __( 'Error adding term', 'tainacan' ) );
}
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %d", $newterm['term_taxonomy_id']) );
// only where old_value is present (this is what this method have different from the _add_value())
$insert_q .= $wpdb->prepare( " AND post_id IN(SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d)", $term['term_taxonomy_id'] );
$query = "INSERT IGNORE INTO $wpdb->term_relationships (object_id, term_taxonomy_id) $insert_q ";
// Add
$wpdb->query($query);
// Remove
return $this->_remove_value($metadatum, $value);
//TODO update term count
}
} else {
global $wpdb;
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %s, %s", $metadatum->get_id(), $newvalue) );
// only where old_value is present (this is what this method have different from the _add_value())
$insert_q .= $wpdb->prepare( " AND post_id IN (SELECT post_ID FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s)", $metadatum->get_id(), $value );
$query = "INSERT IGNORE INTO $wpdb->postmeta (post_id, meta_key, meta_value) $insert_q";
$affected = $wpdb->query($query);
if ($type->get_core()) {
$field = $type->get_related_mapped_prop();
$map_field = [
'title' => 'post_title',
'description' => 'post_content'
];
$column = $map_field[$field];
$update_q = $this->_build_select( "post_id" );
// only where old_value is present (this is what this method have different from the _add_value())
$update_q .= $wpdb->prepare( " AND post_id IN (SELECT post_ID FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s)", $metadatum->get_id(), $value );
$core_query = $wpdb->prepare( "UPDATE $wpdb->posts SET $column = %s WHERE ID IN ($update_q)", $newvalue );
$wpdb->query($core_query);
}
return $this->_remove_value($metadatum, $value);
}
}
/**
* Removes all values of a metadatum from the current group of items

View File

@ -103,6 +103,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$this->tainacan_item_metadata_factory->create_item_metadata($item, $metadatum, $i % 2 == 0 ? 'even' : 'odd');
$this->tainacan_item_metadata_factory->create_item_metadata($item, $category, ['good', 'bad']);
$this->tainacan_item_metadata_factory->create_item_metadata($item, $collection->get_core_title_metadatum(), 'testeItem ' . $i);
}
@ -476,6 +477,141 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$this->assertEquals(15, $items->found_posts);
}
/**
* @group replace
*/
function test_replace_only_when_search_is_present_tax() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$query = [
'meta_query' => [
[
'key' => $this->metadatum->get_id(),
'value' => 'even'
]
],
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
]);
// add test to 20 items
$bulk->add_value($this->category, 'test');
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $this->items_ids,
]);
$bulk->replace_value($this->category, 'super', 'test');
// should add super only to the 20 items that had test
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => 'super'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(20, $items->found_posts);
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => 'test'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(0, $items->found_posts);
}
/**
* @group replace
*/
function test_replace_only_when_search_is_present() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
// all items
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $this->items_ids,
]);
$bulk->replace_value($this->metadatum, 'super', 'even');
// should add super only to the 20 items that had even
$items = $Tainacan_Items->fetch([
'meta_query' => [
[
'key' => $this->metadatum->get_id(),
'value' => 'super'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(20, $items->found_posts);
$items = $Tainacan_Items->fetch([
'meta_query' => [
[
'key' => $this->metadatum->get_id(),
'value' => 'even'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(0, $items->found_posts);
}
/**
* @group replace
*/
function test_replace_core_metadatum() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
// all items
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $this->items_ids,
]);
$core_title = $this->collection->get_core_title_metadatum();
// all items selected, search and replace the value of one
$bulk->replace_value($core_title, 'super_test', 'testeItem 22');
$items = $Tainacan_Items->fetch([
'meta_query' => [
[
'key' => $core_title->get_id(),
'value' => 'super_test'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(1, $items->found_posts);
$items = $Tainacan_Items->fetch(['title' => 'super_test']);
$this->assertEquals(1, $items->found_posts);
}
function test_set_tax_meta() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();