Daniel Guerrero Thoughts

Tuesday, December 06, 2005

Cheap Tip #2 - Drupal modules and taxonomies

I'm working on a job, developing a module for drupal, as I didin't know anything about this CMS, I started developing a small module, all seems to go smoothly, but yesterday I had a trouble, I'm using taxonomies, and first I added "manually" (direct sql insert), but this wasn't working.
I tried to "emulate" the way other modules works (only have blogapi), but no one was working; I start debbugging the sql inserts (this is really great =) ):
Change
function _db_query($query, $debug = 0) {
for:
function _db_query($query, $debug = 1) {
In database.mysql.inc (of course I'm using mysql, you should change in your properly file).

After debug, I see there was a DELETE statement after my insert; I was searching with no luck which function was called. After a while, I get this:

function node_invoke_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
$return = array();
foreach (module_list() as $name) {
$function = $name .'_nodeapi';
if (function_exists($function)) {
$result = $function($node, $op, $a3, $a4);
if (is_array($result)) {
$return = array_merge($return, $result);
}
else if (isset($result)) {
$return[] = $result;
}
}
}
return $return;
}


In the node.module; what this is doing is simple call all the modules: page, MyModule, comments, taxonomy among others.

So I check the taxonomy.module to see which is making on its nodeapi:

function taxonomy_nodeapi($node, $op, $arg = 0) {
switch ($op) {
case 'insert':
taxonomy_node_save($node->nid, $node->taxonomy);
break;
case 'update':
taxonomy_node_save($node->nid, $node->taxonomy);
break;
case 'delete':
taxonomy_node_delete($node->nid);
break;
case 'rss item':
return taxonomy_rss_item($node);
break;
}


Fine, insert and update call to taxonomy_node_save what does this function?:

function taxonomy_node_save($nid, $terms) {
taxonomy_node_delete($nid);

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 ($term) {
db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term);
}
}
}
}


The first statement speak by itself, it delete all the nodes, and next makes again the nodes with info of the $terms, first using a rough: taxonomy_node_save($node->nid, array(0 => $taxonomy_category)); worked inserting the node, but not backuping the data when it calls taxonomy_node_save, so I was almost at the beggining; but of course, checking again taxonomy_nodeapi I saw that the "backup" is on: $node->taxonomy so I need to alter the $node on my mymodule_nodeapi =), here is a snippet:

function mymodule_nodeapi(&$node, $op, $teaser = NULL, $page = NULL)
{
if ($op == "insert" || $op == "update")
{
$node->taxonomy = array(0 => $taxonomy_category);
}
}


And all works smoothly!! =).

Hope this help you,