Replace term_exists() native function. Fixes #159
This commit is contained in:
parent
3aefcf9e42
commit
76a52dd8a4
|
@ -439,26 +439,32 @@ class Bulk_Edit {
|
|||
private function _add_value(Entities\Metadatum $metadatum, $value) {
|
||||
global $wpdb;
|
||||
$type = $metadatum->get_metadata_type_object();
|
||||
$taxRepo = Repositories\Taxonomies::get_instance();
|
||||
|
||||
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);
|
||||
$tax = $taxRepo->fetch($taxonomy_id);
|
||||
|
||||
if ($tax instanceof Entities\Taxonomy) {
|
||||
|
||||
$term = term_exists($value, $tax->get_db_identifier());
|
||||
$term = $taxRepo->term_exists($tax, $value, 0, true);
|
||||
$term_id = false;
|
||||
|
||||
if (!is_array($term)) {
|
||||
if (false === $term) {
|
||||
$term = wp_insert_term($value, $tax->get_db_identifier());
|
||||
if (is_WP_Error($term) || !isset($term['term_taxonomy_id'])) {
|
||||
return new \WP_Error( 'error', __( 'Error adding term', 'tainacan' ) );
|
||||
}
|
||||
$term_id = $term['term_taxonomy_id'];
|
||||
} else {
|
||||
$term_id = $term->term_taxonomy_id;
|
||||
}
|
||||
|
||||
if (is_WP_Error($term) || !isset($term['term_taxonomy_id'])) {
|
||||
return new \WP_Error( 'error', __( 'Error adding term', 'tainacan' ) );
|
||||
}
|
||||
|
||||
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %d", $term['term_taxonomy_id']) );
|
||||
|
||||
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %d", $term_id) );
|
||||
|
||||
$query = "INSERT IGNORE INTO $wpdb->term_relationships (object_id, term_taxonomy_id) $insert_q";
|
||||
|
||||
|
@ -506,28 +512,29 @@ class Bulk_Edit {
|
|||
private function _remove_value(Entities\Metadatum $metadatum, $value) {
|
||||
global $wpdb;
|
||||
$type = $metadatum->get_metadata_type_object();
|
||||
$taxRepo = Repositories\Taxonomies::get_instance();
|
||||
|
||||
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);
|
||||
$tax = $taxRepo->fetch($taxonomy_id);
|
||||
|
||||
if ($tax instanceof Entities\Taxonomy) {
|
||||
|
||||
$term = term_exists($value, $tax->get_db_identifier());
|
||||
$term = $taxRepo->term_exists($tax, $value, null, true);
|
||||
|
||||
if (!$term) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_WP_Error($term) || !isset($term['term_taxonomy_id'])) {
|
||||
if ( !isset($term->term_taxonomy_id) ) {
|
||||
return new \WP_Error( 'error', __( 'Term not found', 'tainacan' ) );
|
||||
}
|
||||
|
||||
$delete_q = $this->_build_select( "post_id" );
|
||||
|
||||
$query = $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d AND object_id IN ($delete_q)", $term['term_taxonomy_id'] );
|
||||
$query = $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d AND object_id IN ($delete_q)", $term->term_taxonomy_id );
|
||||
|
||||
return $wpdb->query($query);
|
||||
|
||||
|
@ -566,42 +573,48 @@ class Bulk_Edit {
|
|||
return new \WP_Error( 'error', __( 'New value and old value can not be the same', 'tainacan' ) );
|
||||
}
|
||||
|
||||
$taxRepo = Repositories\Taxonomies::get_instance();
|
||||
$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);
|
||||
$tax = $taxRepo->fetch($taxonomy_id);
|
||||
|
||||
if ($tax instanceof Entities\Taxonomy) {
|
||||
|
||||
// check old term
|
||||
$term = term_exists($value, $tax->get_db_identifier());
|
||||
$term = $taxRepo->term_exists($tax, $value, null, true);
|
||||
|
||||
if (!$term) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_WP_Error($term) || !isset($term['term_taxonomy_id'])) {
|
||||
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());
|
||||
$newterm = $taxRepo->term_exists($tax, $newvalue, 0, true);
|
||||
|
||||
if (!is_array($newterm)) {
|
||||
|
||||
if (false === $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' ) );
|
||||
}
|
||||
$newtermid = $newterm['term_taxonomy_id'];
|
||||
} else {
|
||||
$newtermid = $newterm->term_taxonomy_id;
|
||||
}
|
||||
|
||||
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']) );
|
||||
|
||||
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %d", $newtermid) );
|
||||
|
||||
// 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'] );
|
||||
$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 ";
|
||||
|
||||
|
|
|
@ -197,4 +197,18 @@ class Taxonomy extends Entity {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a term already exists
|
||||
*
|
||||
* @param string $term_name The term name
|
||||
* @param int|null $parent The ID of the parent term to look for children or null to look for terms in any hierarchical position. Default is null
|
||||
* @param bool $return_term wether to return the term object if it exists. default is to false
|
||||
*
|
||||
* @return bool|WP_Term return boolean indicating if term exists. If $return_term is true and term exists, return WP_Term object
|
||||
*/
|
||||
function term_exists($term_name, $parent = null, $return_term = false) {
|
||||
$repo = $this->get_repository();
|
||||
return $repo->term_exists($this, $term_name, $parent, $return_term);
|
||||
}
|
||||
|
||||
}
|
|
@ -218,40 +218,17 @@ class Term extends Entity {
|
|||
$name = $this->get_name();
|
||||
$taxonomy = $this->get_taxonomy();
|
||||
|
||||
/**
|
||||
* Code from WordPress Core, taxonomy.php#2070
|
||||
*/
|
||||
$repo = $this->get_repository();
|
||||
|
||||
/*
|
||||
* Prevent the creation of terms with duplicate names at the same level of a taxonomy hierarchy,
|
||||
* unless a unique slug has been explicitly provided.
|
||||
*/
|
||||
$name_matches = get_terms( $taxonomy, array(
|
||||
'name' => $name,
|
||||
'hide_empty' => false,
|
||||
'parent' => $parent,
|
||||
'exclude' => $this->get_id()
|
||||
) );
|
||||
$term_exists = $repo->term_exists($name, $taxonomy, $parent, true);
|
||||
|
||||
/*
|
||||
* The `name` match in `get_terms()` doesn't differentiate accented characters,
|
||||
* so we do a stricter comparison here.
|
||||
*/
|
||||
$name_match = null;
|
||||
if ( $name_matches ) {
|
||||
foreach ( $name_matches as $_match ) {
|
||||
if ( is_object($_match) && isset($_match) && strtolower( $name ) === strtolower( $_match->name ) ) {
|
||||
$name_match = $_match;
|
||||
break;
|
||||
}
|
||||
if (false !== $term_exists) {
|
||||
if ($this->get_id() != $term_exists->term_taxonomy_id) {
|
||||
$this->add_error( 'repeated', __('You can not have two terms with the same name at the same level', 'tainacan') );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($name_match) {
|
||||
$this->add_error( 'repeated', __('You can not have two terms with the same name at the same level', 'tainacan') );
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->set_as_valid();
|
||||
return true;
|
||||
|
||||
|
|
|
@ -126,6 +126,7 @@ class Taxonomy extends Metadata_Type {
|
|||
$term = $term->get_id();
|
||||
}
|
||||
|
||||
// TODO term_exists is not fully reliable. Use $terms_repository->term_exists. see issue #159
|
||||
if (!term_exists($term)) {
|
||||
$valid = false;
|
||||
break;
|
||||
|
|
|
@ -344,5 +344,20 @@ class Taxonomies extends Repository {
|
|||
return $prefix . $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a term already exists
|
||||
*
|
||||
* @param Entities\Taxonomy $taxonomy The taxonomy object where to look for terms
|
||||
* @param string $term_name The term name
|
||||
* @param int|null $parent The ID of the parent term to look for children or null to look for terms in any hierarchical position. Default is null
|
||||
* @param bool $return_term wether to return the term object if it exists. default is to false
|
||||
*
|
||||
* @return bool|WP_Term return boolean indicating if term exists. If $return_term is true and term exists, return WP_Term object
|
||||
*/
|
||||
public function term_exists(Entities\Taxonomy $taxonomy, $term_name, $parent = null, $return_term = false) {
|
||||
$TermsRepo = Terms::get_instance();
|
||||
return $TermsRepo->term_exists($term_name, $taxonomy, $parent, $return_term);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -266,6 +266,54 @@ class Terms extends Repository {
|
|||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a term already exists
|
||||
*
|
||||
* @param string $term_name The term name
|
||||
* @param mixed $taxonomy The taxonomy ID, slug or Entity.
|
||||
* @param int $parent The ID of the parent term to look for children or null to look for terms in any hierarchical position. Default is null
|
||||
* @param bool $return_term wether to return the term object if it exists. default is to false
|
||||
*
|
||||
* @return bool|WP_Term return boolean indicating if term exists. If $return_term is true and term exists, return WP_Term object
|
||||
*/
|
||||
public function term_exists($name, $taxonomy, $parent = null, $return_term = false) {
|
||||
|
||||
$Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::get_instance();
|
||||
|
||||
if ( is_numeric( $taxonomy ) ) {
|
||||
$taxonomy_slug = $Tainacan_Taxonomies->get_db_identifier_by_id( $taxonomy );
|
||||
} elseif (is_string($taxonomy)) {
|
||||
$taxonomy_slug = $taxonomy;
|
||||
} elseif ( $taxonomy instanceof Entities\Taxonomy ) {
|
||||
$taxonomy_slug = $taxonomy->get_db_identifier();
|
||||
}
|
||||
|
||||
$args = [
|
||||
'name' => $name,
|
||||
'taxonomy' => $taxonomy_slug,
|
||||
'parent' => $parent,
|
||||
'hide_empty' => 0,
|
||||
'suppress_filter' => true
|
||||
];
|
||||
|
||||
if (is_null($parent)) {
|
||||
unset($args['parent']);
|
||||
}
|
||||
|
||||
$terms = get_terms($args);
|
||||
|
||||
if (empty($terms)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($return_term) {
|
||||
return $terms[0];
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $term_id
|
||||
*
|
||||
|
|
|
@ -663,9 +663,9 @@ class CSV extends Importer {
|
|||
$this->add_error_log('Malformed term hierarchy for Item ' . $this->get_current_collection_item() . '. Term skipped. Value: ' . $values);
|
||||
return false;
|
||||
}
|
||||
$exists = term_exists( $value ,$taxonomy->get_db_identifier(), $parent );
|
||||
if (0 !== $exists && null !== $exists && isset($exists['term_id'])) {
|
||||
$parent = $exists['term_id'];
|
||||
$exists = $Tainacan_Terms->term_exists( $value ,$taxonomy->get_db_identifier(), $parent, true );
|
||||
if (false !== $exists && isset($exists->term_taxonomy_id)) {
|
||||
$parent = $exists->term_taxonomy_id;
|
||||
} else {
|
||||
$this->add_log('New term created: ' . $value . ' in tax_id: ' . $taxonomy->get_db_identifier() . '; parent: ' . $parent);
|
||||
$term = new Entities\Term();
|
||||
|
|
|
@ -105,5 +105,151 @@ class Taxonomies extends TAINACAN_UnitTestCase {
|
|||
|
||||
$this->assertEquals(1, sizeof($terms), 'you should be able to create a term even if the taxonomy is still auto-draft');
|
||||
|
||||
}
|
||||
|
||||
function test_term_exists() {
|
||||
|
||||
$taxonomy = $this->tainacan_entity_factory->create_entity(
|
||||
'taxonomy',
|
||||
array(
|
||||
'name' => 'genero',
|
||||
'description' => 'tipos de musica',
|
||||
'allow_insert' => 'yes',
|
||||
'status' => 'publish'
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::get_instance();
|
||||
$Tainacan_Terms = \Tainacan\Repositories\Terms::get_instance();
|
||||
|
||||
$term = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy->get_db_identifier(),
|
||||
'name' => 'Rock',
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$parent = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy->get_db_identifier(),
|
||||
'name' => 'Parent',
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$child = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy->get_db_identifier(),
|
||||
'name' => 'Child',
|
||||
'parent' => $parent->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$this->assertFalse( $Tainacan_Terms->term_exists('Reggae', $taxonomy->get_db_identifier()) );
|
||||
$this->assertTrue( $Tainacan_Terms->term_exists('Rock', $taxonomy->get_db_identifier()) );
|
||||
|
||||
//var_dump( $Tainacan_Terms->term_exists('Rock', $taxonomy->get_db_identifier(), 0, true) );
|
||||
|
||||
// test extreme case
|
||||
|
||||
$term_2 = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy->get_db_identifier(),
|
||||
'name' => 'test 123',
|
||||
'parent' => $term->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$this->assertFalse( $Tainacan_Terms->term_exists('test 123', $taxonomy->get_db_identifier(), 0) ); // parent 0
|
||||
$this->assertTrue( $Tainacan_Terms->term_exists('test 123', $taxonomy->get_db_identifier(), $term->get_id()) ); // spaces in between
|
||||
|
||||
// testing passing taxonomy object
|
||||
$this->assertTrue( $Tainacan_Terms->term_exists('Rock', $taxonomy) );
|
||||
|
||||
// testing passing ID
|
||||
$this->assertTrue( $Tainacan_Terms->term_exists('Rock', $taxonomy->get_id()) );
|
||||
|
||||
// testing via Taxonomy object
|
||||
$this->assertTrue( $taxonomy->term_exists('Rock') );
|
||||
|
||||
// testing retrieving the term
|
||||
$this->assertTrue( $taxonomy->term_exists('Rock', 0, true) instanceof \WP_Term );
|
||||
$this->assertEquals( $term->get_id(), $taxonomy->term_exists('Rock', 0, true)->term_taxonomy_id );
|
||||
|
||||
// test parent
|
||||
$this->assertTrue( $Tainacan_Terms->term_exists('Child', $taxonomy->get_db_identifier()) ); // parent null
|
||||
$this->assertFalse( $Tainacan_Terms->term_exists('Child', $taxonomy->get_db_identifier(), 0) ); // parent 0
|
||||
$this->assertTrue( $Tainacan_Terms->term_exists('Child', $taxonomy->get_db_identifier(), $parent->get_id()) ); // parent
|
||||
|
||||
}
|
||||
|
||||
function test_term_validation() {
|
||||
|
||||
$taxonomy = $this->tainacan_entity_factory->create_entity(
|
||||
'taxonomy',
|
||||
array(
|
||||
'name' => 'genero',
|
||||
'description' => 'tipos de musica',
|
||||
'allow_insert' => 'yes',
|
||||
'status' => 'publish'
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::get_instance();
|
||||
$Tainacan_Terms = \Tainacan\Repositories\Terms::get_instance();
|
||||
|
||||
$term = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy->get_db_identifier(),
|
||||
'name' => 'Rock',
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$parent = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy->get_db_identifier(),
|
||||
'name' => 'Parent',
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$child = $this->tainacan_entity_factory->create_entity(
|
||||
'term',
|
||||
array(
|
||||
'taxonomy' => $taxonomy->get_db_identifier(),
|
||||
'name' => 'Child',
|
||||
'parent' => $parent->get_id()
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
$newTerm = new \Tainacan\Entities\Term();
|
||||
$newTerm->set_name('Child');
|
||||
$newTerm->set_taxonomy($taxonomy->get_db_identifier());
|
||||
|
||||
$this->assertTrue( $newTerm->validate() );
|
||||
|
||||
$newTerm->set_parent($parent->get_id());
|
||||
|
||||
$this->assertFalse( $newTerm->validate(), 'term should not validate because it has a duplicate in the same level' );
|
||||
|
||||
$child->set_description('changed');
|
||||
|
||||
$this->assertTrue( $child->validate(), 'child should validate');
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue