The function taxonomy_save_term currently allows freeform tagging to create duplicate term names in the database. To prevent duplicate terms in the same vocabulary from being inserted from freetagging, do the following:
First, add a $vid paramter to function taxonomy_get_term_by_name for easier calling.
replace:
function taxonomy_get_term_by_name($name) {
$db_result = db_query(db_rewrite_sql("SELECT t.tid, t.* FROM {term_data} t WHERE LOWER('%s') LIKE LOWER(t.name)", 't', 'tid'), trim($name));
with:
function taxonomy_get_term_by_name($name, $vid = 0) {
if ($vid) {
$db_result = db_query(db_rewrite_sql("SELECT t.tid, t.* FROM {term_data} t WHERE LOWER('%s') LIKE LOWER(t.name) AND t.vid = %d", 't', 'tid'), trim($name), $vid);
}
else {
$db_result = db_query(db_rewrite_sql("SELECT t.tid, t.* FROM {term_data} t WHERE LOWER('%s') LIKE LOWER(t.name)", 't', 'tid'), trim($name));
}
Then edit taxonomy.module and replace:
function taxonomy_save_term(&$form_values) {
if ($form_values['tid'] && $form_values['name']) {
db_query("UPDATE {term_data} SET name = '%s', description = '%s', weight = %d WHERE tid = %d", $form_values['name'], $form_values['description'], $form_values['weight'], $form_values['tid']);
$hook = 'update';
$status = SAVED_UPDATED;
}
else if ($form_values['tid']) {
return taxonomy_del_term($form_values['tid']);
}
else {
$form_values['tid'] = db_next_id('{term_data}_tid');
db_query("INSERT INTO {term_data} (tid, name, description, vid, weight) VALUES (%d, '%s', '%s', %d, %d)", $form_values['tid'], $form_values['name'], $form_values['description'], $form_values['vid'], $form_values['weight']);
$hook = 'insert';
$status = SAVED_NEW;
}
with:
function taxonomy_save_term(&$form_values) {
if ($form_values['tid'] && $form_values['name']) {
db_query("UPDATE {term_data} SET name = '%s', description = '%s', weight = %d WHERE tid = %d", $form_values['name'], $form_values['description'], $form_values['weight'], $form_values['tid']);
$hook = 'update';
$status = SAVED_UPDATED;
}
else if ($form_values['tid']) {
return taxonomy_del_term($form_values['tid']);
}
else {
// Make sure it doesn't exist first
$termexists = taxonomy_get_term_by_name($form_values['name'], $form_values['vid']);
if (!empty($termexists)) {
$form_values['tid'] = $termexists->tid;
db_query("UPDATE {term_data} SET name = '%s', description = '%s', weight = %d WHERE tid = %d", $form_values['name'], $form_values['description'], $form_values['weight'], $form_values['tid']);
$hook = 'update';
$status = SAVED_UPDATED;
}
else {
$form_values['tid'] = db_next_id('{term_data}_tid');
db_query("INSERT INTO {term_data} (tid, name, description, vid, weight) VALUES (%d, '%s', '%s', %d, %d)", $form_values['tid'], $form_values['name'], $form_values['description'], $form_values['vid'], $form_values['weight']);
$hook = 'insert';
$status = SAVED_NEW;
}
}
I'll figure out how to create patches sometime soon.
Comments
Comment #1
drummPlease make a proper patch file. See http://drupal.org/patch
Comment #2
csc4 commentedThis seems like a really big bug with large consequences for free tagging taxonomies. If the OP doesn't produce a patch will it still get fixed in taxonomy??
Or should we be using the code posted to fix the module manually? and if we do that what happens when we upgrade?
Comment #3
neofpo commentedHello,
I can confirm this issue with Drupal 5.7 and the above patch does NOT fix the problem. After applying it, I still get duplicate terms at the following situation:
- TAC http://drupal.org/project/taxonomy_access module.
- Permission denied (with TAC) for a certain user role to create nodes using a certain (existing) term.
Regarding the denied permission, users can still create new nodes using that forbidden term. However, it creates a new term with the exact same name, instead of rejecting it.
The patch however fix the creating of new duplicate terms with Home » Administer » Content management » Categories interface. But still, it outputs no warning so ever and behaves as if there was no pre-existing term at that particular vocabulary. I believe it should message that there already exists a term with that name.
Hope this get fixed, because it is very annoying.
Comment #4
prfctns6@gmail.com commentedWe're still running 5.1, but FWIW I modified the above code slightly and created a patch file relative to 5.1.
I can't recreate this bug, either with or without the patch. Can someone give me some details about the circumstances that cause this bug to manifest, other than the 'permission denied' case that neofpo describes?
Comment #5
totaldrupal commentedsame problem, is a 5.7 fix in the works?
Comment #6
bcn commentedpatch from #4 no longer applies cleanly to a 5.7 install, though it does fix the problem.
To recreate the bug, you need to create a vocabulary and allow free-tagging. Enable this vocab for a particular node type, then go create a new node of this type. When adding terms, add the same term a number of times (eg, add 'duplicate', 'duplicate', duplicate', etc) and you the term 'duplicate' will be added 3 times (or however many you added it) to the term table, generating duplicate id's for the same term.
Comment #7
dpearcefl commentedConsidering the time elapsed between now and the last comment plus the fact that D5 is no longer supported, I am closing this ticket.