module development

Passing urls as path arguments in urls

Sometimes you want to pass a url as a path argument. Drupal explodes urls by slash (/) to get the separate "arguments". Since the passed url probably also contains slashes, this will give erroneous results.

Using the following functions (compress_string and decompress_string) you can safely pass urls now and read them well at the other end.

Example:

print url('bookmark/add/'. compress_string('some/path/on/my/site?query=test'));

function compress_string($string) {
  return urlsafe_base64_encode(gzcompress($string, 9));
}

function decompress_string($string) {
  return gzuncompress(urlsafe_base64_decode($string));
}

function urlsafe_base64_encode($string) {
    $data = base64_encode($string);
    $data = str_replace(array('+','/','='),array('-','_',''),$data);
    return $data;
}

function urlsafe_base64_decode($string) {
    $data = str_replace(array('-','_'),array('+','/'),$string);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    return base64_decode($data);
}

Disable Drupal's page cache for some pages

We all know our Drupal sites can gain a huge performance boost by enabling page caching. But sometimes, you want to exclude certain pages from being cached.

One option to do such a thing is using a small module called CacheExclude.

You might also opt to program this yourself in your own modules by setting the cache variable to FALSE. Variables can be set temporarily for the current request by setting the global array conf.

A small example might clarify things. We're disabling caching on the front page here (not a thing you'd like to do every day, but it's an example ;)).

if (drupal_is_front_page()) {
  $GLOBALS['conf']['cache'] = FALSE;
}

Deleting Drupal variable directly in the database

This is just a quick caveat (or reminder). If you delete a variable from the variables table, always clear the cached entry of the variables too. Drupal caches the whole variables table in the cache table in an entry called 'variables'.

Here are two cases (of the many) you'll need this.

When you're writing your own module and you're setting some variables, always clean them up. Fastest way is by issuing a direct query to the database.

/**
 * Implementation of hook_uninstall().
 */

function my_module_uninstall() {
  db_query("DELETE FROM {variable} WHERE name LIKE 'my_module_%'");
  cache_clear_all('variables', 'cache');
}

A second typical case I can come up with is when releasing the cron semaphore after it got 'stuck'.

DELETE FROM variable WHERE name = 'cron_semaphore';
DELETE FROM cache WHERE cid = 'variables';

Never use t function in a global context!

We were struggling with performance issues on a client's site for some time now. We pinned down the real cause today. It was hidden very well as a bug in the Advanced User module.

I'm writing this down here since I'll probably make the same mistake myself sooner or later:

"Usage of t() in a global context, such as define(‘CONST’, t(‘...’)). The locale system is not yet initialized at that time, so this usage is incorrect and also leads to nasty performance problems. Never do it."

I got this quote from Gábor Hojtsy's Drupal 6 Translation Cheat Sheet.

How to measure the execution time of your Drupal scripts

While doing Drupal development, you sometimes might want to find out how fast or slow a certain part in your code is. Did you know that Drupal has 3 easy functions to do this built right in to core, timer_start($name), timer_read($name) and timer_stop($name).

You can have multiple timers in one run and each one of them is identified by the $name parameter you have to pass to each of these three functions.
I think the functions are pretty self explanatory:

  • timer_start starts a timer
  • timer_read tells you how long the timer has been running
  • and timer_stop stops the timer and returns an array that contains the number of times the timer has been started and stopped (count) and the accumulated timer value in ms (time).
Syndicate content