Project:Taxonomy Batch Operations
Version:5.x-1.0
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:needs review

Issue Summary

I've coded up a modification to this module. There are some minor validation issues, but I didn't want to rewrite the whole lot (see the big commented out section).
Anyone who's willing can think it out and do it but I'm too lazy.

First of all... not sure if it was intended this way but around line 322 change

<?php
  $form
['vid'] = array('#type' => 'value', '#value' => $vocabulary->vid);
?>

to
<?php
  $form
['vid'] = array('#type' => 'hidden', '#value' => $vocabulary->vid);
?>

And change the entire taxonomy_add_multiple_terms_form_submit function:

<?php
function taxonomy_add_multiple_terms_form_submit($form_id, $form_values) {
 
$terms = explode("\n", $form_values['name']);
 
$count = 0;

  foreach (
$terms as $key => $term) {
   
$term = trim($term); // keep ending up with a trailing space, haven't tracked it down

    // strip of prefix and suffix, if necessary
   
if (!empty($form_values['prefix']) && strpos($term, $form_values['prefix']) === 0)
     
$term = substr($term, strlen($form_values['prefix']));

    if (!empty(
$form_values['suffix']) && strpos($term, $form_values['suffix']) == strlen($term)-strlen($form_values['suffix']))
     
$term = substr($term, 0, strlen($term)-strlen($form_values['suffix']));

   
// create our term array to pass to taxonomy_save_term
   
if (trim($term) != "") {
           
$parentkey = array_keys($form_values['parent']);
     
$values[$key]['parent'] = $parentkey[0];
           
$values[$key]['generation'] = substr_count($term, "@"); // Count how many @ there are
     
$values[$key]['name'] = $term;
     
$values[$key]['vid'] = $form_values['vid'];
    }
  }
   
  foreach (
$values as $form_values) {
       
$message = array("","status");
       
$form_values['tid'] = db_next_id('{term_data}_tid');

        if(
$count > 0){ // First term must be a child of the term select in the form by the user.
           
if($form_values['generation'] > 0){ // Is the term a child?
               
$previousgen = $values[$count - 1]['generation']; // Get the previously entered term's generation.
               
if($previousgen == $form_values['generation']){ // Current and previous terms are siblings.
                   
$form_values['parent'] = $values[$count - 1]['parent']; // Both have same parent.
               
}
# There is one issue - generation gap. Example:
# Parent
# @@Child - This is not allowed, but I can't be bothered figuring all this out again.
#           It would require validation checking each line and previous line to it
#           The current setup has no such buffer - successful terms are added to database instantly.
#
#                else if($previousgen < ($form_values['generation'] - 1)){ // Generation gap in the descending direction, not allowed.
#                    $message[0] = (t('Aborted: Could not create term %name - child without a direct parent.', array('%name' => $form_values['name']))) . '<br>';
#                    $message[1] = "error";
#                    break;
#                }
               
else {
                   
$form_values['parent'] = $values[$count - 1]['tid']; // Parent is previous term.
               
}
               
$form_values['name'] = str_replace("@", "", $form_values['name']); // Remove the @
           
}
        }
       
        if((
$count == 0)&&($form_values['generation'] > 0)){
           
$message[0] = (t('Aborted: Term %name - first term cannot be a child (use form select) <a href="javascript:history.go(-1);">back</a>', array('%name' => $form_values['name']))) . '<br>';
           
$message[1] = 'error';
            break;
        }

        if(
$message[1] == "status"){ // No errors.
           
db_query("INSERT INTO {term_data} (tid, name, vid, description, weight) VALUES (%d, '%s', %d, '%s', %d)", $form_values['tid'], $form_values['name'], $form_values['vid'], "", 0);
           
db_query('INSERT INTO {term_hierarchy} (tid, parent) VALUES (%d, %d)', $form_values['tid'], $form_values['parent']);
           
cache_clear_all();
           
$message[0] .= (t('Created new term %name.', array('%name' => $form_values['name']))) . '<br>';
           
$values[$count]['tid'] = $form_values['tid']; // Set this term id for use in processing the next term
           
$count++;
        }
  }
   
   
 
drupal_set_message($message[0]);

    return
'admin/content/taxonomy/' . $form_values['vid'];
}
?>

Comments

#1

Oh i should probably mention how it can be used...

In the multiple terms entry, you can enter tree information, for example

Term 1
@Term 1.1
@Term 1.2
@@Term 1.2.1
Term 2
@Term 2.1
@@Term 2.1.1
@@@Term 2.1.1.1

And it'll make the parent/child tree. I chose @ because it's uncommon but still easy to enter.

Something I should have coded:
if(@ location = start of string), term is child

That would allow @ symbols elsewhere.

The principal use of this patch is to preserve hierarchy.

Another feature that would go well with this is a Terms Database Output to text for backup or reference purposes.

#2

I improved it alot (and it actually works now - last time i tested 2 things one after the other, tweaked as I went along, and didn't teast the first thing again). So here's the working version...

Replace function & add process_term function...

function taxonomy_add_multiple_terms_form_submit($form_id, $form_values) {
  $terms = explode("\n", $form_values['name']);
$message = array("","status");
  $count = 0;
$parents = array(0);
if(isset($form_values['parent'])){
$parents[0] = $form_values['parent'];
}

  foreach ($terms as $key => $term) {
    $term = trim($term);

$this_term = process_term($term);
$this_term_gen = $this_term[0];
$next_term = process_term($terms[$count + 1]);
$next_term_gen = $next_term[0];

$name = $this_term[1];
$parent = $parents[max(($this_term_gen - 1), 0)];
$vid = $form_values['vid'];
$tid = db_next_id('{term_data}_tid');

if(($count == 0)&&($this_term_gen > 0)){
$message[0] = (t('Aborted: Term %name - first term cannot be @ child (use form select) <a href="javascript:history.go(-1);">back</a>', array('%name' => $name))) . '<br>';
$message[1] = 'error';
break;
}

db_query("INSERT INTO {term_data} (tid, name, vid, description, weight) VALUES (%d, '%s', %d, '%s', %d)", $tid, $name, $vid, "", 0);
db_query('INSERT INTO {term_hierarchy} (tid, parent) VALUES (%d, %d)', $tid, $parent);
cache_clear_all();
$message[0] .= (t('Created new term %name.', array('%name' => $name))) . '<br>';

if($next_term_gen > $this_term_gen){ // Is a parent, update the parent array for the relevant generation.
$parents[$this_term_gen] = $tid;
}
$count++;
  }

  drupal_set_message($message[0]);
return 'admin/content/taxonomy/' . $form_values['vid'];
}

function process_term($term){
$node_indicator = "@";
$term_length = strlen($term);
$term = ltrim($term, $node_indicator);
$gen = $term_length - strlen($term);
  return array($gen, $term);
}

#3

Subscribing, greetings, Martijn

#4

Version:5.x-1.x-dev» 5.x-1.0

Tested your codes with 5.x-1.0 since I didn't find documentation, if any, to create the hierarchy this far. Unfortunately it didn't work as expected. Yes there are some hierarchy maintained, but most of the root terms became a child of some parent. The good thing, though, when I move the expected root to be the root term, all it's children is maintained. Hoping for a better handling. Thanks for your kind effort.

nobody click here