There should be a way, so that optionally, a module could select a term in a taxonomy to be the parent of new terms added in free tagging,
In this way a user selects the class of the node being created, but specifies it further, creating new subclasses as the node is submitted.

This was a little hard to get at, and so the code shows one way of making it happen, but not necessarily the best way.

Requires a change to taxonomy_node_save in taxonomy.module.


global $target_parents;

function taxonomy_parent_specify($vid,$parent) {
  global $target_parents;

  if ( !isset($target_parents) ) {
    $target_parents = array();
  }

  $target_parents[$vid] = $parent;
}


function taxonomy_parent_specified($vid) {
  global $target_parents;

  $parent = null;
  if (isset($target_parents[$vid])) {
    $parent = $target_parents[$vid];
  }

  return($parent);
}


function taxonomy_parent_unspecify($vid) {
  unset($target_parents[$vid]);
}

/**
 * Save term associations for a given node.
 */
function taxonomy_node_save($nid, $terms) {
  taxonomy_node_delete($nid);

  // Free tagging vocabularies do not send their tids in the form,
  // so we'll detect them here and process them independently.
  if (isset($terms['tags'])) {
    $typed_input = $terms['tags'];
    unset($terms['tags']);

    foreach ($typed_input as $vid => $vid_value) {
      // This regexp allows the following types of user input:
      // this, "somecmpany, llc", "and ""this"" w,o.rks", foo bar
      $regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x';
      preg_match_all($regexp, $vid_value, $matches);
      $typed_terms = array_unique($matches[1]);

      $inserted = array();
      foreach ($typed_terms as $typed_term) {
        // If a user has escaped a term (to demonstrate that it is a group,
        // or includes a comma or quote character), we remove the escape
        // formatting so to save the term into the database as the user intends.
        $typed_term = str_replace('""', '"', preg_replace('/^"(.*)"$/', '\1', $typed_term));
        $typed_term = trim($typed_term);
        if ($typed_term == "") { continue; }

        // See if the term exists in the chosen vocabulary
        // and return the tid; otherwise, add a new record.
        $possibilities = taxonomy_get_term_by_name($typed_term);
        $typed_term_tid = NULL; // tid match, if any.
        foreach ($possibilities as $possibility) {
          if ($possibility->vid == $vid) {
            $typed_term_tid = $possibility->tid;
          }
        }

        if (!$typed_term_tid) {
      $parent = taxonomy_parent_specified($vid);
      if ( isset($parent) ) {
        $edit = array('vid' => $vid, 'name' => $typed_term, "parent" => $parent);
      } else {
         $edit = array('vid' => $vid, 'name' => $typed_term);
      }
      $status = taxonomy_save_term($edit);
      $typed_term_tid = $edit['tid'];
        }

        // Defend against duplicate, differently cased tags
        if (!isset($inserted[$typed_term_tid])) {
          db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $typed_term_tid);
          $inserted[$typed_term_tid] = TRUE;
        }
      }
    }
  }


  taxonomy_parent_unspecify($vid);

  if (is_array($terms)) {
    foreach ($terms as $term) {
      if (is_array($term)) {
        foreach ($term as $tid) {
          if ($tid) {
            db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $tid);
          }
        }
      }
      else if (is_object($term)) {
        db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term->tid);
      }
      else if ($term) {
        db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term);
      }
    }
  }
}

Comments

dmitrig01’s picture

Status: Needs work » Active

please attach a patch http://drupal.org/diffandpatch

dpearcefl’s picture

If there is any interest in this issue, it should be moved to and applied against D8.

Status: Active » Closed (outdated)

Automatically closed because Drupal 6 is no longer supported. If the issue verifiably applies to later versions, please reopen with details and update the version.