views:

490

answers:

4

Hello, help please? I wish to develop a module to do something very simple with PHP. I am challenged by the Drupal API. I am using version 6.

Goal:

1) Determine if user is viewing a particular node (role is irrelevant) 2) If yes, check to see if cookie is set a) If cookie is set, do nothing b) If cookie is not set, then set cookie and then redirect user to another node

That's it!

I have created a module and installed it, there is no error yet it also does nothing. No cookie is set. I am not sure how the Drupal system likes to redirect requests so insight there would be helpful, please. THANK YOU SO MUCH!

<?php
//$Id: offer_survey.module,v 1.0 2009/09/21 11:31:55 blah Exp $
function offer_survey_init() {
  global $base_url;

  $offer_survey = true;
  $cookie_name = 'survey_offered';

  if ($node->nid == 651) {
    if ($_COOKIE[$cookie_name]) {
      // do nothing
    } else {
      setcookie($cookie_name,1,time() + (86400 * 365));
      //then do the redirect an internal webform URL
    }
  }
}

REVISED VERSION (THE LATEST)

<?php
//$Id: offer_survey.module,v 1.0 2009/09/21 11:31:55 durz Exp $
function offer_survey_init() {
  global $base_url;

  $offer_survey = true;
  $cookie_name = 'survey_offered';

  if (arg(0) === "testing") {   // the path of the page
   if (!$_COOKIE[$cookie_name]) {
   setcookie($cookie_name,1,time() + (86400 * 365));
   drupal_goto('new-destination'); // the path to be redirected to
 } 
  } 
}
+1  A: 

Is your module called offer_survey?

Is it turned on?

Your code looks like it can't work as it uses a $node variable which is not defined.

I think you may have better luck using hook_nodeapi op=load

Once you have sorted these things out you may find drupal_goto is useful to redirect, and you can use user_save for persistent data rather than using set cookie directly.

Jeremy French
thank you. i have used drupal_goto. yes the module is installed and turned on with no errors.
Stoob
+2  A: 

There are some different ways to go about this.

One option would be to used hook_nodeapi like jeremy suggests. Doing that you will have the node being loaded/viewed ect available as the $node variable. The other option would be to in your hook_init look at the $_GET and from that see if the user is requesting the node in question. Hook_nodeapi is probably the easiest way to go here.

You can as Jeremy said save data on the user object, however this is only possible if you user is logged in, as the user object otherwise will be the anonymous user which is the same for all not logged in users. In that case using a cookie could be an option. You have to take care though, as you have to create an per site unique cookie name. Else if this module was installed on several sites, users would not get surveys after visiting just one of them.

also in your code instead of doing:

if ($_COOKIE[$cookie_name]) {
  // do nothing
} else {
  setcookie($cookie_name,1,time() + (86400 * 365));
  //then do the redirect an internal webform URL
}

You should instead use the ! (not) operator:

if (!$_COOKIE[$cookie_name]) {
  setcookie($cookie_name,1,time() + (86400 * 365));
  //then do the redirect an internal webform URL
}
googletorp
+1 for flagging that user_save won't save for anon users, and for cookie per site.
Jeremy French
Thank you I have made edits to my code. I did not know $node was not a global. Note that I must use a cookie for anonymous users. HOWEVER this module won't work still. Ideas?<?php//$Id: offer_survey.module,v 1.0 2009/09/21 11:31:55 Stoob Exp $function offer_survey_init() { global $base_url; $offer_survey = true; $cookie_name = 'survey_offered'; if (arg(0) === "testing") { // the path of the page if (!$_COOKIE[$cookie_name]) { setcookie($cookie_name,1,time() + (86400 * 365)); drupal_goto('new-destination'); // the path to be redirected to } } }
Stoob
for more legible revised code, see above
Stoob
I gave it a test with the code above and it actually works. First time I go to testing I get redirected, 2nd+ time I don't. Your problem with testing this, is that you might have the cookie set in your browser and thus always skip the if statement.
googletorp
A: 

This is the working code. Note that it was necessary to use arg(1) for the if() statement as well as the node id (nid) rather than hook_nodeapi which didn't work.

Also it was necessary to set the cookie_domain, which is a drupal global.

<?php
//$Id: offer_survey.module,v 1.0 2009/09/21 11:31:55 Stoob Exp $
function offer_survey_init() {
  global $base_url;
  global $cookie_domain;

  $offer_survey = true;
  $cookie_name = 'survey_offered';

  if (arg(1) == 2) {   // the number of the node (nid) of the page
    if (!isset($_COOKIE[$cookie_name])) {
      setcookie($cookie_name,1,time() + (86400 * 365),null,$cookie_domain); //lasts a year
      drupal_goto('new/destination'); // the path to be redirected to
    } 
  } 
}
Stoob
A: 

Unless your cache is off, hook_init() only runs on uncached requests. As soon as the cache kicks in your anonymous users will not get this cookie.

You need to put this in hook_boot() but then you can't use drupal_goto since when _boot() runs,that hasn't loaded yet. But that's okay, you can just use header() to set the Location redirect header directly.

It's a good idea to stop execution after a redirect (although you might lose session info if you don't let drupal do some cleanup, take a peek inside what drupal_goto does if you really want to do this right).

<?php
//$Id: offer_survey.module,v 1.1 2010/10/21 11:31:55 tmcclure Exp $
function offer_survey_boot() {
  global $base_url;
  global $cookie_domain;

  $offer_survey = true;
  $cookie_name = 'survey_offered';

  if (arg(1) == 2) {   // the number of the node (nid) of the page
    if (!isset($_COOKIE[$cookie_name])) {
      setcookie($cookie_name,1,time() + (86400 * 365),null,$cookie_domain); //lasts a year
      header('Location: '.$base_url.'/new/destination',TRUE,302); // the path to be redirected to
      exit();
    } 
  } 
}
Tom McClure