I'm tearing my hair out over this one. For some reason Drupal is not triggering all the hooks in my custom module.

I'm creating a "review" content type. I have hooks for review_form, review_load, review_insert, review_validate, review_load and others. Only review_form, review_prepare and review_view appear to be recognized by Drupal, and even review_form only partially works because it's not calling review_load before the review_form, so the $node param is only populated with the basic node values, not the additional values I need to add via review_load().

What am I missing? I've created other custom node types in the past without any problem. Here's what I have for hook_node_info():

function review_node_info() {
  return array('review' => array('name' => t('review'), 'base' => 'review'));
}

Is there something else I need to do to tell Drupal to trigger the other hooks?

I tried moving some of my functions in hook_nodeapi, but that didn't work because I'm also having a simlar problem with nodeapi. It's only triggering a couple of the operations - prepare and view. It doesn't invoke validate or load at all.

I did some hacking and found that node_validate() and some of the other node_* functions are not being called at all.

Comments

nevets’s picture

This is the sequence of hook calls as I understand it when creating new content or editing existing content. The sequences are for the hooks used by a module that implements it's own content type

  • Create new content
    • hook_form()
    • hook_validate()
    • hook_submit()
    • hook_insert()
    • hook_load() - to prepare for viewing the node
    • hook_view()
  • Edit content
    • hook_load () - To prepare the node for editing
    • hook_form()
    • hook_validate()
    • hook_submit()
    • hook_iupdate()
    • hook_load() - to prepare for viewing the node
    • hook_view()

You of course need to define the hooks as needed, at a minimum you need hook_load(), hook_form(), hook_insert() and hook_update(). Each hook needs to use your content type in place of hook, so hook_load() would be review_load().
If you use the module builder module it can quickly provide the framework for a new module.

If this does help, exactly what do you mean when you say it does not work?

drumdance’s picture

Here's what gets called by node_invoke on create new content:

  • hook_prepare()
  • hook_form()

If I add some content to the form and click "preview", these get called:

  • hook_prepare()
  • hook_form()
  • hook_view()

If I save the content, these get called:

  • hook_prepare()
  • hook_form()
  • hook_submit()
  • hook_insert()

If I edit an existing node, I get:

  • hook_load()
  • hook_prepare()
  • hook_form()

If I preview an existing node:

  • hook_load()
  • hook_prepare()
  • hook_form()
  • hook_view()

If I save an existing node:

  • hook_load()
  • hook_prepare()
  • hook_form()
  • hook_submit()
  • hook_update()
  • hook_load()

You might notice that hook_validate() is never called. That's what's driving me crazy. I can't validate the user's submission for some custom fields.

nevets’s picture

Best guess from my own experience is you have mis-named the validated function, if your module is called review it should be called review_validate(). If it visually looks correct try delete the whole line the reads "function review_validate($form_id, $form_values) {" (I have more than once managed to type a control character as part of the function name).

If you like you could also post the code for the validate function.

drumdance’s picture

Thanks for the tip, but no luck. I double checked and validate is not even being called in node_invoke(), so whatever master controller that tells node_invoke what do to, it's missing validate altogether.

I did find a workaround. In all cases outlined above, hook_prepare is always called. So I added some validation code there that is only triggered if the $_POST array exists (indicating content has been submitted for saving or previewing). Calling form_set_error() in that context tells Drupal to reload the form, not save the content. Hacky, but it works.

Another question: I believe Drupal is automatically supposed to populate the $node object with any variables submitted in the form's edit[] array. For some reason it's not doing that with one of the values. Makes no sense at all to me.

drumdance’s picture

(This comment is also posted here.)

After a lot of sleuthing, I think I've figured out why hook_validate() does not get called, or at least when.

In developing modules, I've used example.module as my baseline template. In node_example_form(), the function ends with

return array_merge($form, filter_form($node->format));

...which I kept in my code even though I didn't really know what it meant. Big mistake.

For some mysterious reason, merging the $form variable with the results of filter_form($node->format) causes Drupal to NOT call node_validate() (and thus all the attached hooks).

I removed the aray_merge line and changed the code to just:

return $form;

Hook validate is now called as expected, though I have no idea why.

drumdance’s picture

I also tested node_invoke_nodapi(). The "validate" $op is never called in any of the circumstances above.