Fixes metadata duplication on son collection (issue #79)

This commit is contained in:
weryques 2018-07-17 12:51:59 -03:00
parent 814fcdd167
commit daa9bbee65
6 changed files with 305 additions and 53 deletions

View File

@ -265,7 +265,7 @@ class Collections extends Repository {
$this->pre_update_moderators( $collection );
$new_collection = parent::insert( $collection );
$Tainacan_Metadata->register_core_metadata( $new_collection );
//$Tainacan_Metadata->register_core_metadata( $new_collection );
$collection->register_collection_item_post_type();
flush_rewrite_rules(false); // needed to activate items post type archive url
$this->update_moderators( $new_collection );

View File

@ -52,8 +52,8 @@ class Item_Metadata extends Repository {
if ($metadata_type->get_core()) {
$this->save_core_metadatum_value($item_metadata);
// Core metadata are also stored as regular metadata (in the code following below)
// This is usefull to create queries via filters, advanced search or apis
// si you can search for title and content with meta_query as if they were regular metadata
// This is useful to create queries via filters, advanced search or APIs
// if you can search for title and content with meta_query as if they were regular metadata
}
if ($metadata_type->get_primitive_type() == 'term') {
@ -122,11 +122,14 @@ class Item_Metadata extends Repository {
public function save_core_metadatum_value(\Tainacan\Entities\Item_Metadata_Entity $item_metadata) {
$metadata_type = $item_metadata->get_metadatum()->get_metadata_type_object();
if ($metadata_type->get_core()) {
$item = $item_metadata->get_item();
$set_method = 'set_' . $metadata_type->get_related_mapped_prop();
$value = $item_metadata->get_value();
$item->$set_method( is_array( $value ) ? $value[0] : $value );
if ($item->validate_core_metadata()) {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$Tainacan_Items->insert($item);

View File

@ -37,6 +37,8 @@ class Metadata extends Repository {
parent::__construct();
add_filter('pre_trash_post', array( &$this, 'disable_delete_core_metadata' ), 10, 2 );
add_filter('pre_delete_post', array( &$this, 'force_delete_core_metadata' ), 10, 3 );
add_action('tainacan-collection-parent-updated', array(&$this, 'update_core_metadata_meta_keys'), 10, 2);
}
public function get_map() {
@ -496,6 +498,154 @@ class Metadata extends Repository {
return $this->metadata_types;
}
/**
* That function update the core metadatum meta key, in case of changing the collection parent
*
* @param Entities\Collection $collection
* @param $parent_collection_id
*
* @return void
* @throws \Exception
*/
public function update_core_metadata_meta_keys($collection_old, Entities\Collection $collection_new){
global $wpdb;
$wpdb->flush();
$item_post_type = "%%{$collection_new->get_id()}_item";
$parent_collection_id = $collection_new->get_parent();
if($parent_collection_id != 0){
$metadata = $this->get_core_metadata( $collection_new );
$data_core_metadata = $this->get_data_core_metadata($collection_new);
$parent_collection = new Entities\Collection($parent_collection_id);
$parent_cores = $this->get_core_metadata($parent_collection);
if(!empty($metadata)){
foreach ( $data_core_metadata as $index => $data_core_metadatum ) {
foreach ( $metadata as $metadatum ){
if ( $metadatum->get_metadata_type() === $data_core_metadatum['metadata_type'] ) {
foreach ($parent_cores as $parent_core){
if($metadatum->get_metadata_type() === $parent_core->get_metadata_type()){
$old_metadatum_id = $metadatum->get_id();
$new_metadatum_id = $parent_core->get_id();
$sql_statement = $wpdb->prepare(
"UPDATE $wpdb->postmeta
SET meta_key = %s
WHERE meta_key = %s AND post_id IN (
SELECT ID
FROM $wpdb->posts
WHERE post_type LIKE %s
)", $new_metadatum_id, $old_metadatum_id, $item_post_type
);
$res = $wpdb->query($sql_statement);
wp_cache_flush();
if($res !== false) {
update_post_meta( $metadatum->get_id(), 'metadata_type', 'to_delete', $data_core_metadatum['metadata_type'] );
wp_delete_post( $metadatum->get_id(), true);
}
}
}
}
}
}
}
} else {
$old_parent = 0;
if (!$collection_old) {
$this->register_core_metadata($collection_new);
} else {
$old_parent = $collection_old->get_parent();
$this->register_core_metadata($collection_new);
}
if($old_parent != 0) {
$metadata = $this->get_core_metadata( $collection_new );
$data_core_metadata = $this->get_data_core_metadata( $collection_new );
$parent_collection = new Entities\Collection( $old_parent );
$parent_cores = $this->get_core_metadata( $parent_collection );
foreach ( $data_core_metadata as $index => $data_core_metadatum ) {
foreach ( $metadata as $metadatum ) {
if ( $metadatum->get_metadata_type() === $data_core_metadatum['metadata_type'] ) {
foreach ( $parent_cores as $parent_core ) {
if ( $metadatum->get_metadata_type() === $parent_core->get_metadata_type() ) {
$old_metadatum_id = $parent_core->get_id();
$new_metadatum_id = $metadatum->get_id();
$sql_statement = $wpdb->prepare(
"UPDATE $wpdb->postmeta
SET meta_key = %s
WHERE meta_key = %s AND post_id IN (
SELECT ID
FROM $wpdb->posts
WHERE post_type LIKE %s
)", $new_metadatum_id, $old_metadatum_id, $item_post_type
);
$res = $wpdb->query($sql_statement);
wp_cache_flush();
}
}
}
}
}
}
}
}
/**
* @param Entities\Collection $collection
*
* @return array
*/
private function get_data_core_metadata(Entities\Collection $collection){
return $data_core_metadata = [
'core_description' => [
'name' => 'Description',
'description' => 'description',
'collection_id' => $collection->get_id(),
'metadata_type' => 'Tainacan\Metadata_Types\Core_Description',
'status' => 'publish',
'exposer_mapping' => [
'dublin-core' => 'description'
]
],
'core_title' => [
'name' => 'Title',
'description' => 'title',
'collection_id' => $collection->get_id(),
'metadata_type' => 'Tainacan\Metadata_Types\Core_Title',
'status' => 'publish',
'exposer_mapping' => [
'dublin-core' => 'title'
]
]
];
}
/**
* @param Entities\Collection $collection
*
@ -507,45 +657,7 @@ class Metadata extends Repository {
$metadata = $this->get_core_metadata( $collection );
// TODO: create a better way to retrieve this data
$data_core_metadata = [
'core_description' => [
'name' => 'Description',
'description' => 'description',
'collection_id' => $collection->get_id(),
'metadata_type' => 'Tainacan\Metadata_Types\Core_Description',
'status' => 'publish',
'exposer_mapping' => [
'dublin-core' => 'description'
]
],
'core_title' => [
'name' => 'Title',
'description' => 'title',
'collection_id' => $collection->get_id(),
'metadata_type' => 'Tainacan\Metadata_Types\Core_Title',
'status' => 'publish',
'exposer_mapping' => [
'dublin-core' => 'title'
]
]
];
if( $collection->get_parent() != 0 ){
if(!empty($metadata)){
foreach ( $data_core_metadata as $index => $data_core_metadatum ) {
foreach ( $metadata as $metadatum ){
if ( $metadatum->get_metadata_type() === $data_core_metadatum['metadata_type'] ) {
update_post_meta($metadatum->get_id(), 'metadata_type', 'to_delete', $data_core_metadatum['metadata_type']);
wp_delete_post($metadatum->get_id(), true);
}
}
}
}
return false;
}
$data_core_metadata = $this->get_data_core_metadata($collection);
foreach ( $data_core_metadata as $index => $data_core_metadatum ) {
if( empty( $metadata ) ){

View File

@ -77,8 +77,15 @@ abstract class Repository {
// TODO: Throw Warning saying you must validate object before insert()
}
$is_update = false;
$diffs = [];
$is_update = false;
$is_updated_parent = false;
$old = '';
if ( $obj instanceof Entities\Collection && $obj->get_status() != 'auto-draft' ) {
$is_updated_parent = true;
}
$diffs = [];
if ( $obj->get_id() ) {
$old = $obj->get_repository()->fetch( $obj->get_id() );
@ -109,15 +116,15 @@ abstract class Repository {
$obj->WP_Post->post_status = 'publish';
}
if( $obj instanceof Entities\Item ){
if ( $obj instanceof Entities\Item ) {
// get collection to determine post type
$collection = $obj->get_collection();
if ( !$collection ) {
if ( ! $collection ) {
return false;
}
$post_t = $collection->get_db_identifier();
$post_t = $collection->get_db_identifier();
$obj->WP_Post->post_type = $post_t;
}
@ -134,8 +141,11 @@ abstract class Repository {
}
}
// TODO: Logs for header image insert and update
if($is_updated_parent){
do_action('tainacan-collection-parent-updated', $old, $obj);
}
// TODO: Logs for header image insert and update
do_action( 'tainacan-insert', $obj, $diffs, $is_update );
do_action( 'tainacan-insert-' . $obj->get_post_type(), $obj );

View File

@ -7,16 +7,16 @@ class Item_Metadata_Factory {
public function create_item_metadata(\Tainacan\Entities\Item $item, \Tainacan\Entities\Metadatum $metadatum, $value = ''){
$Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance();
$item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($item, $metadatum);
$this->item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($item, $metadatum);
if (!empty($value))
$item_metadata->set_value($value);
$this->item_metadata->set_value($value);
if ($item_metadata->validate()) {
$item_metadata = $Tainacan_Item_Metadata->insert($item_metadata);
if ($this->item_metadata->validate()) {
$this->item_metadata = $Tainacan_Item_Metadata->insert($this->item_metadata);
}
return $item_metadata; // If not validated, get_error() method should return the errors. Its up to the tests to use it or not
return $this->item_metadata; // If not validated, get_error() method should return the errors. Its up to the tests to use it or not
}
}

View File

@ -209,4 +209,131 @@ class CoreMetadatumTypes extends TAINACAN_UnitTestCase {
}
function test_collection_parent_change_and_update_core_metadata(){
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
$collection_parent2 = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'Parent2',
'status' => 'publish'
),
true
);
$collection_parent = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'Parent',
'status' => 'publish'
),
true
);
$collection_parent_item = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'Par',
'description' => 'par',
'status' => 'publish',
'collection' => $collection_parent,
),
true
);
$core_metadata_parent = $collection_parent->get_core_metadata();
$item_metadatum_title0 = $this->tainacan_item_metadata_factory->create_item_metadata(
$collection_parent_item,
$core_metadata_parent[1], 'Son of son');
$item_metadatum_desc0 = $this->tainacan_item_metadata_factory->create_item_metadata(
$collection_parent_item, $core_metadata_parent[0],
'Desc of son of son');
$collection_son = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'Son',
'status' => 'publish'
),
true
);
$core_metadata_son = $collection_son->get_core_metadata();
# Creates a item
$collection_son_item = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'Son of son',
'description' => 'Desc of son of son',
'collection' => $collection_son,
'status' => 'publish'
),
true
);
$item_metadatum_title = $this->tainacan_item_metadata_factory->create_item_metadata($collection_son_item,
$core_metadata_son[1], 'Son of son');
$item_metadatum_desc = $this->tainacan_item_metadata_factory->create_item_metadata($collection_son_item, $core_metadata_son[0],
'Desc of son of son');
$this->assertEquals($core_metadata_son[0]->get_id(), $item_metadatum_desc->get_metadatum()->get_id());
$this->assertEquals($core_metadata_son[1]->get_id(), $item_metadatum_title->get_metadatum()->get_id());
$this->assertNotEquals($core_metadata_parent[0]->get_id(), $item_metadatum_desc->get_metadatum()->get_id());
$this->assertNotEquals($core_metadata_parent[1]->get_id(), $item_metadatum_title->get_metadatum()->get_id());
# When updated the parent, the item metadata key, have to be update too
$collection_son->set_parent($collection_parent->get_id());
$collection_son->validate();
$collection_son = $Tainacan_Collections->update($collection_son);
$core_metadata_son = $collection_son->get_core_metadata();
$this->assertNotEquals($core_metadata_son[0]->get_id(), $item_metadatum_desc->get_metadatum()->get_id());
$this->assertNotEquals($core_metadata_son[1]->get_id(), $item_metadatum_title->get_metadatum()->get_id());
$it = get_post_meta($collection_son_item->get_id());
$this->assertArrayHasKey($core_metadata_parent[0]->get_id(), $it);
$this->assertArrayHasKey($core_metadata_parent[1]->get_id(), $it);
# Changes parent again
$collection_son->set_parent(0);
$collection_son->validate();
$collection_son = $Tainacan_Collections->update($collection_son);
$core_metadata_son2 = $collection_son->get_core_metadata();
$it2 = get_post_meta($collection_son_item->get_id());
$this->assertArrayHasKey($core_metadata_son2[0]->get_id(), $it2);
$this->assertArrayHasKey($core_metadata_son2[1]->get_id(), $it2);
$this->assertArrayNotHasKey($core_metadata_parent[0]->get_id(), $it2);
$this->assertArrayNotHasKey($core_metadata_parent[1]->get_id(), $it2);
# Changes parent again
$collection_son->set_parent($collection_parent2->get_id());
$collection_son->validate();
$collection_son = $Tainacan_Collections->update($collection_son);
$core_metadata_son3 = $collection_son->get_core_metadata();
$it3 = get_post_meta($collection_son_item->get_id());
$this->assertArrayHasKey($core_metadata_son3[0]->get_id(), $it3);
$this->assertArrayHasKey($core_metadata_son3[1]->get_id(), $it3);
$this->assertArrayNotHasKey($core_metadata_parent[0]->get_id(), $it3);
$this->assertArrayNotHasKey($core_metadata_parent[1]->get_id(), $it3);
}
}