tips

Tip: Avoid bugs with translation strings

Tags: 

I came across a small problem recently with translation strings and wanted to share how I resolved it. Due to how PHP handles strings that are quoted with single quotes (') and double quotes ("), you should always copy the exact string and the quotes signs from the original file when you're overriding a string rather than transposing it into your own coding format, that way you'll avoid subtle bugs and those late-night #facepalm moments.

Fixing Apache on CentOS/RHEL 5 for Drupal

Tags: 

While not strictly a requirement, in the interests of not having crazy URLs on your Drupal site it's recommended to set up your web server to support .htaccess files. This will let you have URLs like "/products/cool/stuff" instead of "?q=products/cool/stuff" - obviously much nicer, and better for both usability and search engine optimization. Well unfortunately on Redhat Enterprise Linux 5 (RHEL) and CentOS 5 (which is basically the same as RHEL) the standard web server, Apache, is set to ignore these files. So here's how to fix it.

Whether you're configuring the virtual host in a separate file or in the main httpd.conf, the change you'll want to make is the same:

Step 1: enabling .htaccess files:

  • In the main httpd.conf file (should be at /etc/httpd/conf/httpd.conf) search for the string "AccessFileName",
  • If the line is commented out (it starts with "#") uncomment the line by removing the "#" symbol,
  • Update the line to say:
    • AccessFileName .htaccess
  • Restart Apache, reload the site and.. enjoy the error message :-)
  • On to the second part..

Step 2: allowing .htaccess files to override settings:

  • Find the VirtualHost configuration for the Drupal site,
  • There should be a <Directory> section within that block,
  • If there isn't a line that starts with AllowOverride, add a new one within the <Directory> block,
  • Set the AllowOverride line to the following:
    • AllowOverride Options Indexes Limit FileInfo
  • Restart Apache again.
  • Et voila.

This will allow the Drupal .htaccess file to run and make your URLs all nice & shiny!

Removing the acquia_subscription_status menu

Tags: 

For a Drupal site I was developing I originally tried out the Acquia distribution but ultimately dropped it in favor of the vanilla core release. In doing so I also removed the custom Acquia modules that provided integration with their network as I wasn't going to be using it either. All was good, except that the admin menus retained an unneeded menu item named "acquia_subscription_status" that just linked to acquia.com - I had to vanquish it!

Having removed all of the custom Acquia modules I was confused as to why there was this random menu item hanging around. It wasn't part of any of the contrib modules I was using, so I grep'ed my entire site to see if something remained - it was clean. Given the admin_menu module works off the normal menus I then tried the configured menus, again to no avail. So that just left the database.

In the database it seemed fairly obvious that it should be in the menu tables, and sure enough it was. The menu_links table included a menu item that went something like this:

menu_name: admin_menu
link_path: http://www.acquia.com/
link_title: acquia_subscription_status
external: 1

Sure enough, this was it. So then I just removed the menu item and..

It was still there. :-|

A quick look identified the simple fact that the menu was cached! Duh.

So, a quick "TRUNCATE cache_menu;" (or Flush All Caches -> Menu) later and life was good, the menu item was gone.

Disabling the Views_Bulk_Operations default view

Tags: 

The Views_Bulk_Operations module for Drupal is really pretty awesome, out of the box it solves one of the top 5 problems newcomers have with Drupal - the standard content admin page, /admin/content/node, does not include a field to search for content by the title, instead you have to do a search in the main search engine and then click the edit link, presuming you haven't hidden it or something. Further, you can customize it by adding additional fields to the display or adding more filters, e.g. the taxonomy tree, and, more commonly, change the page path to be "admin/content/node" so it replaces the built-in admin page rather than compliment it.

That said, on every site I've used it I've customized it, but when I have that view loading through a custom module the default view still shows. As a result the Views list page (/admin/build/views) ends up with two different entries - the custom one and the default VBO one. Being a bit of a neat-freak when it comes to my Drupal installs, this doesn't work for me so I fix it. Here's how:

  // Disable the built-in Views_Bulk_Operations node admin view.
  $views_status = variable_get('views_defaults', array());
  $views_status['admin_content'] = TRUE; // True is disabled
  variable_set('views_defaults', $views_status);
  views_invalidate_cache();
  
  // Update the menu router information.
  menu_rebuild();

Stick that in your module's install script and you're good to go.

Fixing update_sql() to accept parameters

Tags: 

A pretty simple yet cool feature of Drupal's db_query() function is that you can pass in parameters that will make it automatically adjust the query to correctly escape the arguments. This is one of the simple security features in Drupal as it will properly escape the string to avoid SQL injection attacks, and just simply safe you hassle. Good stuff!

When it comes to module development you'll occasionally have to update the database schema for one reason or another, so you'd figure the corresponding update_sql() function, which has some extra purpose for update scripts, would also handle parameters. Not so, unfortunately. In Drupal 5 and 6 the only argument that update_sql() accepts is the query itself, so there's no direct way of doing the parameter auto-magic gravy. Thankfully, all is not lost.

If you look at the code in update_sql(), it's actually very simple - it just runs the standard db_query() string and compiles a nice array to let the update script give a reasonable return message. So, simply put, to do the parameter processing in Drupal 5 and 6 all you have to do is replicate the update_sql() function inline, e.g.:

<?php
/**
 * Change the primary color from blue to green.
 */
function funkychicken_update_6001() {
  $ret = array();
  
  $sql = "UPDATE {funkychicken} SET color='%s' WHERE color='blue'";
  $result = db_query($sql, 'green');
  $ret[] = array('success' => $result !== FALSE, 'query' => check_plain($sql));

  return $ret;
}

So that's all there is to it!

Going a step further, here's an alternative to update_sql() to make it even easier. This can be added to your module's update file, e.g.:

<?php
/**
 * Change the primary color from blue to green.
 */
function funkychicken_update_6001() {
  $ret = array();
  
  $ret[] = update_sql2("UPDATE {funkychicken} SET color='%s' WHERE color='blue'", 'green');

  return $ret;
}

/**
 * An alternative to update_sql() that accepts parameters.
 * Params:
 *   $sql - The query to execute, as a string.
 *   $args - The parameters to pass to the query.
 * Return:
 *   An array containing the success status (boolean) and the query.
 */
if (!function_exists('update_sql2')) {
  function update_sql2($sql, $args = NULL) {
    $result = db_query($sql, $args);
    return array('success' => $result !== FALSE, 'query' => check_plain($sql));
  }
}

FYI there's a patch available for Drupal 6 that might eventually make it into a release, it just needs to be worked on a bit more. Either way, hopefully a fix for this will work its way into Drupal 7.

Pages

Subscribe to tips