So, this seems like a rather simple task but I've been stuck on it for a while.

I need either in hook_node_presave or in hook_node_submit (but NOT in hook_node_validate) to check for a field value in a node and according to that value choose whether or not to cancel the node saving procedure.

How do I do that? (The canceling part, not the checking part ;) )

  • hook_node_validate() is the correct hook, why can't you use it?
    – Clive
    Aug 31 '12 at 12:45
  • cause for some reason which is not relevant to the issue, the 'problematic' value has not been set yet. Dont ask me how and why, but it's the trurh =)
    – magtak
    Aug 31 '12 at 13:00
  • if it makes any difference, it's a 'hack' I want to prevent where if someone gives you a link to post content in a public og_group you are not a member of, the link looks like this: node/add/article?gids_node[]=1 and seems to set the value from NULL to 1 after the form validation. It's weird but it happens.
    – magtak
    Aug 31 '12 at 13:03
  • Took me multiple print_r's to figure it out. I am positive it happens, I am clueless to why exactly.
    – magtak
    Aug 31 '12 at 13:11

Implement drupal_goto()

I believe this function obliterates any followup processing other than saving session data and forwards the user immediately on to a new page.

Excerpt from Drupal.org: drupal_goto();

This function ends the request; use it instead of a return in your menu callback.

To define where the users will be sent to, simply pass the same data you would to the url() function.

For example:

drupal_goto('node/44');  // Sends users to yoursite.com/node/44

An update regarding the drupal_goto() function from a submit handler (See https://drupal.stackexchange.com/a/33281):

//Note from https://drupal.stackexchange.com/a/33281
//When using drupal_goto() from a submit function you may need to be more aggressive. 
$url = url("node/$nid");
drupal_set_message(t('Message to be displayed in the next page'));
  • Was about to answer my own question. A drupal_goto() call seems to work just fine. My only "issue" now is that the redirect doesn't seem to work in case I wanted it to go to a specific page (say the front page). It breaks the node_save but leads me back to the page I started from which is not that bad, but I'd like to have a nice redirect option.
    – magtak
    Aug 31 '12 at 12:58
  • Updated my answer to include a functional example. :)
    – Citricguy
    Aug 31 '12 at 13:02
  • Did that, didn't work that's why I am puzzled.
    – magtak
    Aug 31 '12 at 13:03
  • 1
    Very interesting. Just experienced the same thing. It looks like this has been noted before. See: drupal.stackexchange.com/a/33281/1747
    – Citricguy
    Aug 31 '12 at 13:06
  • This is probably not a great approach. It will break things like views bulk operations. Jul 31 '15 at 18:48

I've found that the best way is to just thrown an error during presave. Here's a simple example:

function mymodule_node_presave($node){
    throw new Exception('Error saving node: Title cannot be empty');

The node_save() function has a try...catch block wrapping the presave step that will catch the exception.

The advantage of this over drupal_goto() is that, if you're importing multiple nodes, it will skip the current node and proceeed to the next one. This is great if you're using something like the Feeds module. In contrast drupal_goto() will exit immediately and may interfere with other steps in the request or cron, which will break importing multiple nodes.

  • Great solution!
    – davewilly
    Sep 17 '14 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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