[Drupal] How to create a php script to add a new set of categories by using existing taxonomy term as reference id in Drupal 6

| | 5 min read

In this article, I would explain how we can add a new set of categories to an already existing node by using existing taxonomy terms as reference id in Drupal 6. In order to achieve this, the following functions can be used: taxonomy_get_parents_all(), taxonomy_get_term(), node_save().

First of all, we must identify mapping of the terms in old vocabulary to the new vocabulary. In this case, mapping will be as follows - terms in the "Genre" Vocabulary to the new "Affiliate Category" Vocabulary. For example, "Books and Literature and all it subcategories" comes under "Genre" Vocabulary. In the case of these terms, we add "Books" which comes under "Affiliate Category" Vocabulary to the node. Once mapping is clear, we can continue. Let's see an example of mapping "Genre" Vocabulary to "Affiliate Category" Vocabulary.

  • Books & Lit (and all subcategories) - Books
  • Dance (and all subcategories) - Stage
  • Rock & Pop Stage (and all subcategories) - Music
  • Jazz & Folk (and all subcategories) - Music

In my previous article, "How to display Affiliate Links on page load for the contents using Category as reference id?", I have explained how we can add a new vocabulary and its terms and generate affiliate links using taxonomy terms as reference ID. Please refer this article, if you have any doubt regarding how to add a new vocabulary term for a specific content type.

Next is a configuration change. Add a new cck field for the content type you are updating. This field can be removed once the update is complete. We are adding this field to identify which nodes have been updated while running the script. CCK field we have added here is "Test Category : test_category".

Now comes our script. The first step is to take a copy of index.php file and rename it accordingly say custom_file.php. Now, remove all the lines except the following.


/**
 * @file
 * The PHP page that serves all page requests on a Drupal installation.
 *
 * The routines here dispatch control to the appropriate handler, which then
 * prints the appropriate page.
 *
 * All Drupal code is released under the GNU General Public License.
 * See COPYRIGHT.txt and LICENSE.txt.
 */

chdir(__DIR__);
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

Here we have added a new line "chdir(__DIR__);" this helps to execute the script from any where. All we have to do is tell the right path.

Next step is to write a db query to get all nids of the node particular content type (say event). Also, check the condition that the cck field we added "field_test_category_value" is NULL, because when we update each node, we also set the value for the field "field_test_category_value" as 1 to make sure the nodes won't repeat.


$nodeevent = db_query("SELECT node.vid AS node_vid, node.nid AS node_nid, content_type_event.nid AS content_type_event_nid, content_type_event.vid AS content_type_event_vid, content_type_event.field_test_category_value AS field_test_category_value, node.type AS type FROM {node} node LEFT JOIN {content_type_event} content_type_event ON  content_type_event.nid = node.nid WHERE type IN ('event') AND content_type_event.vid = node.vid AND field_test_category_value IS NULL LIMIT 10");
  while ($nodeeventset = db_fetch_object($nodeevent)) {
  }

Once we get the corresponding node id. Using node_load(), we can get all the values of the corresponding node.

$nodefulload=node_load($nodeeventset->node_nid);

Next step is to get the corresponding taxonomy terms for each node. For a node, we could have multiple taxonomy terms for different vocabulary. Here, we need only the taxonomy term under the "Genre" Vocabulary, so we filter by using its corresponding vid.


  foreach ($nodefulload->taxonomy as $value) {
    $categorynid = $value->tid;
    $categoryvid = $value->vid;
    if ($categoryvid == 1) {
      print $categoryname= $value->name;
    }
  }

If you see the mapping table, it becomes clear to you that to add the new taxonomy term, we need to know only the parent term for each taxonomy term. For this first, we used the function taxonomy_get_parents(), by passing termid as reference. Here, the problem is that if the taxonomy term is a child, we get the corresponding parent element. However, if the term is a parent, no result is displayed. So, we used the function taxonomy_get_parents_all(), by passing termid as reference. Here, if the term is child, it will return details of both the parent and child element. If the term we passed is parent, it will return details of that element alone. So, for each term, we get the corresponding parent element details.

$taxtermload = taxonomy_get_parents_all($categorynid);

Using foreach() we could list all the terms and its details. Now, we set a flag value as 0. Flag is set so that if a node has multiple terms of same vocabulary there is a chance for repetition. Here, we check only the first term under "Genre" vocabulary and add the corresponding "Affiliate Category" term which maps with this.


  foreach ($taxtermload as $list) {
    $flag = 0;
  }

Now, we can check whether each term comes under parent element. We check this using corresponding parent element term id or term name and flag is 0.


  if (($list->tid == 1) && ($flag == 0)) {
    print "Books";
  }
  if (($list->name == "Books and Literature") && ($flag == 0)) {
    print "Books";
  }

For each term, by checking its parent term, we enter the loop to add the new term. We use the function taxonomy_get_term() by passing termid as reference. Here, we could save the term in two ways

1. In this method, we will replace the existing taxonomy term with the new one. Here, the problem is that once we replace it, there is no way of getting it back or referring it.


  // Term 'Books and Literature' and all its subcategories - Books
  // Here the existing category gets replaced
  if (($list->tid == 1) && ($flag == 0)) {
    print "\n";
    $newvalueload = taxonomy_get_term(70039);
    print "\n";
    print $value->tid = $newvalueload->tid;
    print $value->vid = $newvalueload->vid;
    print $value->name = $newvalueload->name;
    print $value->description = $newvalueload->description;
    print $value->weight = $newvalueload->weight;
    print $nodefulload->field_test_category[0]['value'] = 1;
    $flag = 1;
    //node_save($nodefulload);
    print "\n";
  }

2. In this method, we will add the new term to the node so that we can use the old category for reference.


  // Term 'Visual Arts' and all its subcategories - Live Music
  else if (($list->tid == 7) && ($flag == 0)) {
    print "\n";
    $newvalueload = taxonomy_get_term(70041);
    print "\n";
    print $nodefulload->taxonomy[$newvalueload->tid]=$newvalueload;
    print $nodefulload->field_test_category[0]['value'] = 1;
    $flag = 1;
    //node_save($nodefulload);
    print "\n";
  }

Hope its "so far so good" stuff for you all. If you have any doubts, please feel free to share your thoughts.