3

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 ;) )

4
  • hook_node_validate() is the correct hook, why can't you use it?
    – Clive
    Commented Aug 31, 2012 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 =)
    – user5005
    Commented Aug 31, 2012 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.
    – user5005
    Commented Aug 31, 2012 at 13:03
  • Took me multiple print_r's to figure it out. I am positive it happens, I am clueless to why exactly.
    – user5005
    Commented Aug 31, 2012 at 13:11

2 Answers 2

2

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");
header("Location:$url");
drupal_set_message(t('Message to be displayed in the next page'));
drupal_exit(); 
5
  • 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.
    – user5005
    Commented Aug 31, 2012 at 12:58
  • Updated my answer to include a functional example. :)
    – Citricguy
    Commented Aug 31, 2012 at 13:02
  • Did that, didn't work that's why I am puzzled.
    – user5005
    Commented Aug 31, 2012 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
    Commented Aug 31, 2012 at 13:06
  • This is probably not a great approach. It will break things like views bulk operations. Commented Jul 31, 2015 at 18:48
9

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){
  if(empty($node->title)){
    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.

1
  • Great solution!
    – davewilly
    Commented Sep 17, 2014 at 15:25

Your Answer

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