2

Can someone explain clearly the difference between hook_load and hook_node_load? hook_load says it is a "node-type-specific hook". What does that mean? hook_node_load actually has a types parameter.

1
  • One big note is that it is called last. As for definition I'm not sure I can do better than the linked page does under the $types parameter.
    – sareed
    Apr 21, 2016 at 22:05

2 Answers 2

3

This paragraph in hook_node_load() docs page explains it in details:

This hook is invoked during node loading, which is handled by entity_load(), via classes NodeController and DrupalDefaultEntityController. After the node information is read from the database or the entity cache, hook_load() is invoked on the node's content type module, then field_attach_load_revision() or field_attach_load() is called, then hook_entity_load() is invoked on all implementing modules, and finally hook_node_load() is invoked on all implementing modules.

Here's the breakdown, from first to last call:

  1. entity_load()
  2. hook_load()
  3. field_attach_load_revision() or field_attach_load()
  4. hook_entity_load()
  5. hook_node_load()

What this means to you is that using a different hook you will be able to modify values earlier or later. This matters if you're overriding value from another module for example. Otherwise, I think it's safe to use either.

3
  • 2
    In all of my Drupal work, I don't think I have ever used hook_load(); always the entity version (when I have one that works on multiple entity types) or the entity specific version (which is probably about 95% of the time).
    – mpdonadio
    Apr 21, 2016 at 22:34
  • Thanks @MPD, same here. I've always used hook_node_load() instead. Apr 22, 2016 at 8:03
  • 2
    @MPD We only implement hook_node_load() because hook_load() is invoked only for modules implementing a content type.
    – apaderno
    Apr 22, 2016 at 8:51
2

Looking at the code of NodeController::attachLoad(), and a note in the documentation for hook_node_load(), I would say that hook_load() is only invoked for the modules implementing a content type. In fact, the note in hook_node_load() documentation says the following. (Emphasis is mine.)

hook_load() is invoked on the node's content type module, then field_attach_load_revision() or field_attach_load() is called, then hook_entity_load() is invoked on all implementing modules, and finally hook_node_load() is invoked on all implementing modules.

Plus, the only code dealing with hook_load() implementations is the following one.

  // Call object type specific callbacks on each typed array of nodes.
  foreach ($typed_nodes as $node_type => $nodes_of_type) {
    if (node_hook($node_type, 'load')) {
      $function = node_type_get_base($node_type) . '_load';
      $function($nodes_of_type);
    }
  }

node_type_get_base() returns the node type base, which the function documentation describes as follows:

The base indicates which module implements this node type and is used to execute node-type-specific hooks.

It seems that in the Drupal 7 documentation, the term node-type-specific replaced what in the Drupal 6 documentation was described as used by node modules. See Drupal 6 hook_load(), Drupal 7 hook_validate(), and Drupal 6 hook_validate().

To be sure that is the only code invoking hook_load(), see DrupalDefaultEntityController::attachLoad(), called from NodeController::attachLoad(), since DrupalDefaultEntityController is the parent class of NodeController; apart from field-related hooks, its code only invokes hook_entity_load() and hook_TYPE_load() which, for node entities, is hook_node_load().

  // Attach fields.
  if ($this->entityInfo['fieldable']) {
    if ($revision_id) {
      field_attach_load_revision($this->entityType, $queried_entities);
    }
    else {
      field_attach_load($this->entityType, $queried_entities);
    }
  }

  // Call hook_entity_load().
  foreach (module_implements('entity_load') as $module) {
    $function = $module . '_entity_load';
    $function($queried_entities, $this->entityType);
  }
  // Call hook_TYPE_load(). The first argument for hook_TYPE_load() are
  // always the queried entities, followed by additional arguments set in
  // $this->hookLoadArguments.
  $args = array_merge(array($queried_entities), $this->hookLoadArguments);
  foreach (module_implements($this->entityInfo['load hook']) as $module) {
    call_user_func_array($module . '_' . $this->entityInfo['load hook'], $args);
  }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.