views:

866

answers:

4

I'm writing a module that interfaces with Google Base. It needs to insert a link to the page that the item is on, however, this item has no path until pathauto runs. How can I either make sure pathauto runs its hooks before my module does, or get the path that will result from pathauto?.

The solution needs to be generic enough to work with any kind of node having different pathauto settings as outlined by the admin.

The problem is that the [path] value for the $node variable looks like the following when I call the function: [path] => [pathauto_perform_alias] => 1

The value for the node path comes out empty, and the value given to Google Base is simply the base-url for the website.

Is there a way to change the weight at which hook_nodeapi functions run, so that they'll run later instead of sooner?

i ran into a similar problem with taxonomy not having attached the terms to the node that I was trying to access. I got around that by using taxonomy_node_get_terms()

Thanks in advance.

+1  A: 

Is there a way to change the weight at which hook_nodeapi functions run, so that they'll run later instead of sooner?

Yes. Does that solve your problem?

Jeremy French
no it doesn't solve the problem. Even after having set the weight higher than all of the other weights in the system table, the path setting of the $node object still shows [path] => [pathauto_perform_alias] => 1 ... which semantically doesn't make much sense to me anyway.
msumme
+1  A: 

Is there a way to change the weight at which hook_nodeapi functions run, so that they'll run later instead of sooner?

Modules themselves have a weight that determines the order in which they get called for invocations of their hook implementations. Modules with the same weight get called in alphabetical order, AFAIK.

If you do not explicitly set the weight of your module on installation (via hook_install), it gets the default weight of 0.

If you need your modules hook implementations to run after that of a specific other module, like e.g. pathauto you should do something like this in your modules hook_install implementation:

// Get the weight of the module you need to run after/before
$pathauto_weight = db_result(db_query("SELECT weight FROM {system} WHERE name = 'pathauto'"));
// Define your modules weight relative to that
$yourModule_weight = $pathauto_weight + 1;
// Set your modules weight
db_query("UPDATE {system} SET weight = %d WHERE name = 'yourModule'", $yourModule_weight);

Beware: The modules weight influences the order in which all of the modules hook implementations get called in relation to all other modules!

I do not know of a way to influence a single hook implementations call order, so for cases where I needed a single hook implementation to run in a special order, while others needed to run in a different order, I ended up creating one or more sub modules to allow for different weight settings on different hook implementations.

Henrik Opel
To clarify on Jeremy French's answer in http://stackoverflow.com/questions/1286107/get-drupal-paths-during-node-insert-operation-with-pathauto-enabled/1299189#1299189 :It looks like pathauto is not directly updating the $node object with the path it sets on hook_nodeapi() insert/update operations, so to get the created path, you need to explicitely ask for it via drupal_get_path_alias(). Note that you still need to ensure to make this call after pathauto did its work, though!(Would have added this comment to Jeremy's answer, but I do not have enough points yet to do so)
Henrik Opel
+1  A: 

Looking at the code in the pathauto module I see the following lines which may be of use to you

 if (!isset($node->pathauto_perform_alias) || $node->pathauto_perform_alias) {
        $placeholders = pathauto_get_placeholders('node', $node);
        $src = "node/$node->nid";
        $alias = pathauto_create_alias('node', $op, $placeholders, $src, $node->nid, $node->type, $node->language);
      }

If you just want to know the url, you could crib these into your module. It is also worth noting that this code is run only for op=='insert' and op=='update'.

Another thing to note on this is that it calls path_set_alias() which puts a value into the url_alias table. I think calling drupal_get_path_alias will do what you want.

$path = 'node/'. $node->nid;
$alias = drupal_get_path_alias($path);
Jeremy French
A: 

The implementations of a hook are executed basing on the weight of the modules. In the specific case, changing the weight could not work because the form fields are probably changed in hook_form_alter() or hook_form_FORM_ID_alter().

kiamlaluno