Drupal

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

New Drupal modules: Administration theme and Instant Search

I have just contributed two small modules.

The first one is Instant Search and allows you to make your Drupal content appear directly in search results after creation.
By default, Drupal indexes node content only when running the cron. This means that your new or updated content may only appear in search results after a few minutes, when cron has run. Using Instant search, you can make Drupal index your new nodes when submitting them (inserting or updating), after which they will instantly appear in search results.

The second one is called Administration theme use Drupal's built in administration theme feature on more pages then possible with Drupal's out of the box settings. You can have the administration theme then on batch processing pages, devel pages, ... or any page from a list you define.

Administration themeAdministration theme

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

Drupal 6 time field element

Drupal core offers a standard date field type, but it has no knowledge of a field type to represent (a certain moment in) time. The following snippet of code generates a Drupal 6 time element for you which you can use in all your forms. It consists of 3 select fields representing hour, minute and meridiem (like 12:01 PM).

An example of usage is the following:

$form['test_reset']['test_reset_time'] = array(
    '#type' => 'test_time',
    '#title' => t('Reset time'),
    '#default_value' => variable_get('test_reset_time', array('hour' => 12, 'minute' => 0, 'meridiem' => 'pm')),
);

The code for the element is:

<?php
function time_field_elements() {
  $type['time_field_time'] = array(
    '#input' => TRUE,
    '#process' => array('time_field_expand_time'),
  );
  return $type;
}

function time_field_expand_time($element) {
  if (empty($element['#value'])) {
    $element['#value'] = array(
      'hour' => intval(format_date(time(), 'custom', 'h')),
      'minute' => intval(format_date(time(), 'custom', 'i')),
      'meridiem' => format_date(time(), 'custom', 'a'),
    );
  }
 
  $element['#tree'] = TRUE;

  foreach ($element['#value'] as $type => $value) {
    switch ($type) {
      case 'hour':
        $options = drupal_map_assoc(range(1, 12));
        break;
      case 'minute':
        $options = drupal_map_assoc(range(0, 59));
        break;
      case 'meridiem':
        $options = drupal_map_assoc(array('am', 'pm'));
        break;
    }
   
    if ($type == 'hour' || $type == 'minute') {
      foreach ($options as $option) {
        $options[$option] = str_pad($options[$option], 2, '0', STR_PAD_LEFT);
      }
    }
    $parents = $element['#parents'];
    $parents[] = $type;
    $element[$type] = array(
      '#type' => 'select',
      '#default_value' => $element['#value'][$type],
      '#attributes' => $element['#attributes'],
      '#options' => $options,
    );
  }

  return $element;
}

/**
 * Implementation of hook_theme().
 */

function time_field_theme($existing, $type, $theme, $path) {
  return array(
    'time_field_time' => array(
      'arguments' => array('element' => NULL),
    ),
  );
}

function theme_time_field_time($element) {
  return theme('form_element', $element, '<div class="container-inline">'. $element['#children'] .'</div>');
}

Syndicate content