Fernando, It is, as you suggested about halfway down, about guaranteeing the calling order. If I write a module that defines a new node type, I want to guarantee that my loading code is called before any other module attempts to modify the node through hook_nodeapi(). This is where hook_load()/hook_save() et. al. are necessary. For the purpose of being a module author, hook_nodeapi() is called on every active module in an arbitrary order. While it is the system weights order internally, as a module author you cannot guarantee that your module will be run at a given weight relative to other modules that are using hook_nodeapi() to modify it, even with a fresh new install system. The more modules that are active on a site, the more load-order challenges you may have. I only rely on system weight for modules on sites where I've written a module that will only run on that site and nowhere else. hook_load() is a very simple (and clean) solution to this ordering challenge. For a simple deployment where a node-defining module is not augmented by any other module I can see where one could argue that hook_load() and hook_nodeapi(op=load) are identical. When you get into a site with more than a handful of custom/contributed node types they become different in a crucial and subtle way. Scott www.folkjam.org Fernando Silva wrote:
I do not quite understand that. Let's assume the "example.module" that creates a new node type.
I'll must use the "example_load()" hook to load some data from an extra table: function example_load($node) { $additions = db_fetch_object(db_query('SELECT * FROM {mytable} WHERE nid = %s', $node->nid)); return $additions; }
But then, if I use "example_nodeapi()" instead the code should be something like this: function example_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { switch ($op) {
case 'load':
$additions = db_fetch_object(db_query('SELECT * FROM {mytable} WHERE nid = %s', $node->nid)); return $additions; } }
It's the exact same code, but we also need to have sure that both API functions run at exactly the places. If we go to the node.module, in the node_load() function we have at the lines 525 and 531 we have *exactly* the same code to invoke both APIs.
This means, that when the nodeapi() is invoked with other $op it is already loaded. Or else, you can be saying that if another module (eg. "intercept.module") wants to intercept the 'load', the node will not be 'loaded': * example.module implements a new node type * node_load() will load example.module new node type by doing hook_load() * intercept.module will do something to the example.module node by using nodeapi()
Is this a correct conclusion, or I am missing something?
This seems to me a bit strange, because in this case the only reason we have hook_load() and hook_nodeapi('load') is because we can't get a way to enforce the correct 'loading' order with hook_nodeapi.
Or can we?! If with the new "install system" we have module dependencies, why can't we have a way to give priorities to those dependencies...
As a side note, this behaviour is implemented since Drupal 4.6
Thanks, Fernando Silva
On 1/3/07, Gerhard Killesreiter <gerhard@killesreiter.de> wrote:
Fernando Silva wrote:
node_load() if ($extra = node_invoke($node, 'load')) { foreach ($extra as $key => $value) {$node->$key = $value;}} if ($extra = node_invoke_nodeapi($node, 'load')) { foreach ($extra as $key => $value) {$node->$key = $value;}}
node_save() node_invoke($node, 'insert'); node_invoke_nodeapi($node, 'insert'); node_invoke($node, 'update'); node_invoke_nodeapi($node, 'update');
node_delete() node_invoke($node, 'delete'); node_invoke_nodeapi($node, 'delete');
The conclusion is that the "nodeapi" is the way to do things, and that the other way was just keeped as unnecessary compatibility, and should be quickly deprecated.
I don't think that this is a valid conclusion. /If/ you create your own node type and it has an extra table you should use the basic hooks. Because then your node will already be fully populated once it gets into nodeapi and other modules can act on the full node.
Cheers, Gerhard