Category Archives: Drupal

Drupal 6: Redirecting the User Destination After Registration

Scenario: An unregistered user visits a page that only logged in users can visit. Say it’s this page:

http://www.your-site.com/protected/page

Drupal throws up the login form, but the URL above remains the same – good as we’re going to use that. If they login, they are brought right back to this page, no problem. But what if they have to register? Assuming you have your User Settings set so that new users are logged in right away (no email confirmation, etc.), you’d of course like to redirect them back to the page they wanted originally. Instead, they just go to their new user account page, and that kinda sucks.

Figuring out a solution to this kinda sucked. After exploring numerous attempts at redirecting the form and using hook_user() – I finally just set a cookie, and blamo, it works. This needs to go into a custom module of yours:

// Implementaion of hook_user
function yourModule_user($op, &$edit, &$account, $category = NULL) {
    $refer = rtrim($_SERVER['HTTP_REFERER'], '/'); // removes any trailing slash
    $refer_array = explode('/', $refer); 
    $len = count($refer_array);
    if ($refer_array[$len - 1] == 'protected' && $refer_array[$len - 2] == 'page') {
        setcookie("YourDrupalDest", 'protected/page/', time()+200);  /* expire in 7.5 minutes */
    }
    switch ($op) {
        case 'insert':
            if ($_COOKIE["YourDrupalDest"]) {
                $_REQUEST['destination'] = 'protected/page/';
            }
            break;

        default:
            # code...
            break;
    }
}

Anyways, hope that helps point someone in the right, erm, destination.

Tweaking Drupal Date-Popup Format in an Exposed View

* Note this entry only pertains to the Date-Popup boxes when used in a Views filter, not a regular node-based form.

views-filter-calToday I needed to change the format of the date-popup box on an exposed views filter. It normally defaults to YYYY-MM-DD as shown to the left there. Most us ‘merican folks don’t like that much. Unfortunately, it only seems to be changeable via creating your own module.

Once you know how to create a Drupal module, just add this to it. With the below code, I reformat the date to the more familiar MM/DD/YYYY format for both the “from date” (min) and “to date” (max) values:

/**
* This will change the date format on all views-exposed forms
*/
function YOUR_MOD_NAME_form_views_exposed_form_alter(&$form, $form_state) {
  $form['date_filter']['min']['#date_format'] = 'm/d/Y';
  $form['date_filter']['max']['#date_format'] = 'm/d/Y';
}

As the comment says, this will change the date formatting for any view that uses these date boxes across the site, which I’m fine with. Whereas with hook_form_alter() we can target a form by incorporating the form id value into a specialized function name, all view IDs are views_exposed_form and that’s just that. If you need to get more specific, you can var_dump($form) the form from within the function and glean some unique info that would allow you to target that particular form using some conditionals, again within the function.

Hope that helps someone else out! Took me a bit to figure that out – cheers.

Trouble Installing PECL’s uploadprogress On OS X – MAMP?

Note – this assumes you are running MAMP on a Mac. For this I’m using Leopard 10.5.8.

All you want to do is get this installed so you can have fancy upload bars in your Drupal 7 installation. So you follow the instructions and only get a bunch of errors. Maybe you see stuff like this:

make: *** [uploadprogress.lo] Error 1

And toward the top of your “make” you see stuff like this:

error: php.h: No such file or directory

I was seriously stumped. I knew this was probably related to having both the default version of PHP that comes with OS X enabled, as well as the MAMP version – but it’s the same stuff, right? Nope – MAMP does not come with everything needed to compile a PECL installation, at least not with my setup (MAMP version 1.7.2 running PHP 5.2.x).

So what you have to whip out the command line and specifically setup your installation environment by explicitly declaring which PHP environment to use. So fire up your Terminal!

OK – MAMP does come with the phpize command, but it’ll setup the wrong environment for our needs. So head into the uploadprogress directory that your downloaded and untarred, and run:

/usr/bin/phpize
./configure --with-php-config=/usr/bin/php-config

Next up:

make
sudo make install

If all went well, you should have no errors, and you’ll have some output telling you the extension directory it placed uploadprogress.so in.

You’ll need to open up MAMP’s php.ini file and make some changes now. For me, this is in MAMP/conf/php5

Around line 428 – you’ll need to put something like this in:

extension_dir = "(insert the outputted extension directory from after you ran the make install command)"

(If you’re like me and already had this setup from installing xdebug, then you’ll need to just move the uploadprogress.so file into the defined directory.)

Now we need to tell php to load this extension. Around line 540 or so, add this:

extension=uploadprogress.so

Now restart MAMP, and you should be all loaded up! If you head over to your Drupal status report, you should see PECL is now installed (image below, my frickin’ badge of honor). Boy, hopefully this is easier on the production server!

pecl-success1

Later that day…

So looks like now that this is up and running, I’ve discovered that Drupal 7.0 has a bug that prevents the progress bar from showing. Hopefully we’ll get this fixed in 7.1.

Later later that day…

This was actually much easier on my Red Hat production server, the commands were pretty much the same. Here it is working with Drupal 6.20:
Uploading... graphic

Fix: Drupal Site Redirects to p3p0.com

I recently helped a client fix a particularly sneaky site hack. While this pertains to Drupal – similar attacks have been reported in Joomla, or any other PHP based site. The fix here may help still – you’ll just need to look harder. Here’s the rundown:

The symptom:
When you type your full website domain name into a browser, all seems well. However, when you click a search engine (or any other link) to your site, it goes to some variation of a p3p0.com site – a dirty, affiliate-based site that hawks anything from mortgages to meeting singles.

The Cause:
The following core Drupal files have been hacked:

  1. xmlrpc.php
  2. update.php
  3. install.php
  4. cron.php
  5. 500.php
  6. index.php

Any other files in your root directory may have been hacked too – check the timestamps.

The Fix:
Look for something that resembles this code – and either comment it out (if you are unsure) or delete it:

eval(base64_decode("ZXJyb3...etc..."));

The actual line of code will be quite long – I’ve shortened it here. It’s generally at the very top of the page.

And lastly – change your FTP login! That’s how they got in and did this – it isn’t a Drupal security issue, it’s that somebody hacked your FTP server – it’s the only way they could’ve done this. Or, if your web host has some sort of file editing feature within the control panel, then change your login for your webhost too.

Why did they do this?
They did it to make money by redirecting actual traffic to your site to their crappy, scum-bag affiliate site. Basically, they identify websites that seem to get a fair amount of traffic or have a heavy user base with lots of content for search engines to crawl. The code they use is sneaky in that it only kicks in when it detects someone is clicking through from another site, like a search engine. So if you don’t Google (or Yahoo, Bing, whatever) your site much, then it’ll take you awhile to even realize what’s happening.

What a pain -  hope this helps someone out.

Drupal – Select List “default_value”

After beating my head against the desk the past hour, I finally figured out that to set a default value on a plain select list, you need to use “#value” and not “#default_value”. So, for example, say I have an array of banks consisting of the bank id and the bank name, like so:

$banks = array(14=>"bank one", 22=>"bank two);

I then want to construct a simple select form element, this WILL NOT work:

$form['drop'] = array(
 #id' => "bank_drop",
 '#type' => 'select',
 '#title' => 'test',
 '#options' =>; $banks,
 '#default_value' => 22  // will NOT work!
);

But this works:

$form['drop'] = array(
  #id' => "bank_drop",
  '#type' => 'select',
  '#title' => 'test',
  '#options' => $banks,
  '#value' => 22  // works!
);

This was on Drupal 6.15

Hope that saves someone some headache :)

Drupal: Redirecting a User After Login

This has me beating my head on the desk a bit. I’m coding up a Drupal 6 module, and wanted to redirect the user after logging in, depending on what role they belong to.

In this example, let’s say I have a role called “treasurer” – and anyone that’s logged in and not a treasurer is an administrator. In my module (called mymod here), I knew that hook_user would do the trick somehow. Note that in hook_user, the $op variable contains what operation is being performed, and “login” is an option we can use here. So, this will fire right after the login form is processed and the user is loaded. The $account variable contains the entire $user object being worked on (so we can use it instead of a “global $user” declaration). Here’s what I originally wanted to do but it does not work:

function mymod_user($op, &$edit, &$account, $category = NULL) {
  switch ($op) {
    case 'login':
      if (in_array('treasurer', $account->roles)) {
        drupal_goto('user/' . $account->uid);
      } else {
        drupal_goto('admin/users');
      }
      break;
    default:
      // nothing
      break;
  }
}

We can’t  use drupal_goto here, surprisingly. But after a little Googling, here is the way to do it – this works:

function mymod_user($op, &$edit, &$account, $category = NULL) {
  switch ($op) {
    case 'login':
      if (in_array('treasurer', $account->roles)) {
        $_REQUEST['destination'] = 'user/' . $account->uid;
      } else {
        $_REQUEST['destination'] = 'admin/user/user';
      }
      break;
    default:
      // nothing
      break;
  }
}

In short, we just need to set $_REQUEST['destination'] to whatever we want. In the above example, if the user is a treasurer, we sent them to their user account page. Otherwise, we know that it’s an administrator (since that’s the only other role I set up), and we show the admin all the users. Tailor to your needs. Note that if your destination has a url alias setup, this will automatically fetch the alias too. Cheers.