background image
HomeRecent PostsDrupalSearchTagsRSSContactAboutAccount
Eric.London's picture

Sometimes there's no escaping hard coded hostnames being stored in your Drupal database. If you have ever setup language translations (i18n) in production, and then deployed the site to a development environment (with a different hostname), you'll know exactly what I am talking about. The first thing you'll notice in your dev site is that all your urls are linking back to the production site, and you may even have a hard time logging in.

If you query the languages table, you'll see the following:

select language, domain
from {languages}

Results:

language	domain
de		http://de.ericlondon.com
en		http://www.ericlondon.com
es		http://es.ericlondon.com
fr		http://fr.ericlondon.com

At first I thought it would make sense to write a module or a hook_update_n() function to resolve this problem when deploying to another environment, but this method seemed rather clunky, repeatedly running the same revision of a module's update script. In the end, I decided to simply write a PHP script to run via Drush. The following code fetches your default language and all records in the language table, loops through them, and updates the hostname records to match your new hostname...

<?php
// ensure this script is being called from Drush ONLY
// ensure HTTP_HOST is being used
if (
  !
is_array($_SERVER['argv'])
  ||
substr($_SERVER['argv'][0], -9) != 'drush.php'
 
|| substr($_SERVER['SCRIPT_FILENAME'], -9) != 'drush.php'
 
|| !strlen($_SERVER['HTTP_HOST'])
) {
 
header('HTTP/1.1 403 Forbidden');
  die(
'Access Denied.');
}

$output = "";

// fetch hostname from globals
$http_host = $_SERVER['HTTP_HOST'];

// ensure http host exists
if (!$http_host || !is_string($http_host)) {
  die(
'Error occurred fetching http host.');
}

// set default http host
$default_http_host = 'www.' . $http_host;

// define default language
$default_language = 'en';

// define SQL to fetch default language
$sql = "
  select *
  from {languages}
  where language = '%s'
"
;

// execute SQL
$default_language_record = db_fetch_object(db_query($sql, $default_language));

// ensure record exists
if (!is_object($default_language_record)) {
  die(
'Error occurred fetching default language.');
}

// update default language record
$default_language_record->domain = 'http://' . $default_http_host;

// set new variable for "language_default"
variable_set('language_default', $default_language_record);
$output .= "Setting language_default variable to: " . $default_language_record->domain . "\n";

// fetch language records
$sql = "
  select *
  from {languages}
"
;
$resource = db_query($sql);
$language_records = array();
while (
$row = db_fetch_object($resource)) {
 
$language_records[] = $row;
}

// correct language records
foreach ($language_records as $key => $value) {

 
// determine language prefix 
 
switch ($value->language) {
    case
$default_language:
     
$prefix = 'www.';
      break;
    default:
     
$prefix = $value->language . '.';
      break;
  }

 
$new_domain = 'http://' . $prefix . $http_host;

 
$sql = "
    update {languages}
    set domain = '%s'
    where language = '%s'
  "
;
 
db_query($sql, $new_domain, $value->language);

 
$output .= "Setting language record for language: \"" . $value->language . "\" to: " . $new_domain . "\n";

}

drupal_flush_all_caches();

$output .= "Executed: drupal_flush_all_caches()\n";

$output .= "DONE.\n";

echo
$output;
?>

I dropped this script (named: fix_env.php) in the root of my Drupal site, and then executed it via Drush using the following shell command:

drush --uri=http://tdb.erl.dev scr fix_env.php

The "--uri" flag allows you to specific a hostname for multi-site environments, and the "scr" flag allows you to specify a php script to execute.

NOTE: I'm in the habit of never using sites/default, because it's a real PITA if you ever try to move your site into a multi-site configuration ^_^

After running the script via Drush, my hostname database records have been corrected to match my development environment...

select language, domain
from {languages}

Results:

language	domain
de		http://de.tdb.erl.dev
en		http://tdb.erl.dev
es		http://es.tdb.erl.dev
fr		http://fr.tdb.erl.dev
Eric.London's picture

This quick code snippet will show you how to update every external link on your site to open in a new window using jQuery. You can put this code in the script.js file in your theme.

$(document).ready(function(){

  // apply to all <a> tags that have an href that starts with "http"
  $("a[href^='http']").each(function(){

    // remove http:// and https://
    link = $(this).attr('href');
    if (link.substring(0,7)=='http://') {
      link = link.substring(7);
    } else if (link.substring(0,8)=='https://') {
      link = link.substring(8);
    } else {
      return;
    }

    // spilt on '/'
    split1 = link.split('/');

    // compare href hostname to site hostname
    if (split1[0]!=location.hostname) {
      // add target attribute to link
      $(this).attr('target','_blank');
    }

  });

});

If you're running a multi-site Drupal configuration, it's helpful to know which settings.php is being loaded. This information may be useful to your module or theme, or for troubleshooting purposes. For instance, you might be sharing the same theme across a few sites, but you'd like to modify the theme for one of your sites. Sharing themes (and modules) is capable in a multi-site configuration by placing your themes and modules in the [sites/all] folder, while defining a directory and settings.php file for each site installation in [sites]. To be able to tell which settings.php is being loaded, you could add the following code to each settings.php file you define:

<?php
$exploded
= explode("/", __FILE__);
$conf['multi_site_hostname'] = $exploded[count($exploded)-2];
?>

For example, you could pass this information to your page.tpl theme file:

<?php
// defining a preprocess_page function, placed in my template.php file:
function MYTHEME_preprocess_page(&$variables) {
 
// example: pass the configuration directly to the page.tpl.php:
 
$variables['multi_site_hostname'] = variable_get('multi_site_hostname',NULL);

 
// another example:
 
switch (variable_get('multi_site_hostname',NULL)) {
    case
'thedrupalblog.erl.dev':
    case
'ericlondon.com':
     
$variables['siteHostName'] = 'ericlondon.com';
      break;
    default:
     
$variables['siteHostName'] = 'default';
      break;
  }

}
?>

Syndicate content