Changing a wordpress domain name

Holy permanent domain names Batman!

Once in a while, I discover something about wordpress that makes me wonder how it ever got so popular. The most recent discovery is that wordpress stores your site’s domain name into the mysql database. Worst of all, it doesn’t just store it in one place but litters it throughout several tables and records. And of course wordpress does not come with any way to migrate the site to a different domain name.

This is a problem because I want to be able to setup a pre-production site on a pre-production domain and then move it to a production domain once it’s ready.  For example, I recently wanted move this blog to wordpress 3.2 but I wanted to see it in action on my test url first.

After doing some research, there were no official list of where the domain name may be stored and there were just too many tables and records to look through manually.  In addition, I knew I had to change the domain a few times so I put in some time and wrote a php script to look through all the tables, records, fields, etc for the existing domain name.  When it finds one in a particular field, it updates the value to the new domain.

<?php

$longopts = array(
  "db_name:",
  "db_user:",
  "db_pw:",
  "find_string:",
  "replace_string:",
  "replace_guid_field"
);

$options = getopt("", $longopts);
print "Found arguments:\n";
print_r($options);

$database = $options["db_name"];
$database_user = $options["db_user"];
$database_pw = $options["db_pw"];
$find_string = $options["find_string"];
$replace_string = $options["replace_string"];
$replace_guid = array_key_exists("replace_guid_field", $options);

$link = mysql_connect("localhost", $database_user, $database_pw);
mysql_select_db($database);

$query = "SHOW TABLES FROM $database";
$result = mysql_query($query);

while ($arr = mysql_fetch_array($result, MYSQL_NUM)) {
  foreach ($arr as $table) {
    process_table($table, $find_string, $replace_string, $replace_guid);
  }
}
mysql_close($link);

print "done";

function process_table($table, $find_string, $replace_string, $replace_guid) {
  print "\nprocessing $table....";

  $field_arr = array();
  $query = "SELECT * FROM $table";
  $result = mysql_query($query);
  while ($row_arr = mysql_fetch_array($result, MYSQL_ASSOC)) {
    foreach ($row_arr as $key => $value) {
      if (strpos($value, $find_string) !== false) {
        // Create a list of fields which contain the found string.
        $field_arr[$key] = true;
        //print_r($row_arr);
      }
    }
  }

  if (count($field_arr) == 0) {
    print " string not found.";
  } else {
    print " string found in field(s): " . implode(', ', array_keys($field_arr)) . "\n";
    foreach (array_keys($field_arr) as $field) {
      if ($field != "guid") {
        $query = "UPDATE $table SET $field = replace($field, '$find_string', '$replace_string') WHERE $field LIKE '%$find_string%'";
        update_table($query);
      } else {
        if ($replace_guid) {
          $query = "UPDATE $table SET $field = replace($field, '$find_string', '$replace_string') WHERE $field LIKE '%$find_string%'";
          update_table($query);
        } else {
          print "\nString found in guid field but not replacing. Override this by using the --replace_guid_field flag.\n";
        }
      }
    }
  }
}

function update_table($query) {
  print "\n$query\n";
  $result = mysql_query($query);
  $num_updated = mysql_affected_rows();
  print "... updated $num_updated records\n";
}
?>

The script is designed to be run from the command line.  Run the script by passing in the following options:

php change-domain.php --db_name=<your_db_name> --db_user=<db_login> --db_pw=<db_password> --find_string=<original_domain> --replace_string=<new_domain> --replace_guid_field

You can download the script but use at your own risk. If you do use it, I suggest you backup your database first.

Your php may not have the command line interpreter installed.  You’ll need the php5-cli package in order to run php from the shell.

apt-get install php5-cli
>> dpkg --list |grep php
ii  libapache2-mod-php5              5.3.2-1ubuntu4.9                  server-side, HTML-embedded scripting languag
ii  php5-cli                         5.3.2-1ubuntu4.9                  command-line interpreter for the php5 script
ii  php5-common                      5.3.2-1ubuntu4.9                  Common files for packages built from the php
ii  php5-gd                          5.3.2-1ubuntu4.9                  GD module for php5
ii  php5-mysql                       5.3.2-1ubuntu4.9                  MySQL module for php5

 

Rosewill Metas external hard drive enclosure

 

My wife and I started using a shared network drive recently to store our collective media. To make this media portable, I decided to get the Rosewill Metas 3.5″ external hard drive enclosure.  The Metas has both esata and usb 3 support.  The e-sata will be used most of time as it’s connected to my NAS while the usb connector will mostly be used when it goes portable.

Quick Overview

Plus

  • Both esata and usb 3
  • Fan speed control
  • Vertical stand

Minus

  • Installing drive requires screw
  • Flimsy plastic clips hold both case and tray
  • noisy when laid flat due to lack of rubber feet on body

Back panel

  • usb 3 type B connector
  • esata connector
  • power connector
  • power switch
  • variable fan speed control dial.

The fan turned down all the way is pretty quiet but turned up all the way, it becomes very loud.  Fortunately you can adjust it to your liking.

Included

  • 1 36 inch esata cable
  • 1 36 usb 3 cable (type a on one end, type b on the other)
  • 1 power cable
  • 1 vertical stand

Inside the case

There is one plastic clip which holds the lid in place.  While this clip feels very fragile, there is not a lot of force pushing against the lid.

Opening the lid reveals the internal fan which sits right below the lid and directly on the top of the hard drive.  While the fan is 80mm, it’s much thinner which means you won’t be able to replace it with a normal 80mm computer fan.

The hard drive and tray slides out towards the front of the case once the lid is open.  There are two flimsy plastic tabs next to the fan which are suppose to lock the tray and drive in place but unfortunately does not do a good job of it.  Putting a little pressure on the tray, I can feel it wiggle side to side.  My guess is that they wanted to allow you to easily remove the hard drive without tools.  The only problem is that the hard drive must be screwed onto the tray as shown below.  Since a screw driver is going to be needed anyways, it makes the ability to pull out the tray quickly to be quite useless.

 Hard drive activity indicator

Physical features

The top, front and back are black plastic with the exception of the top fan intake grate which is a thin piece of metal.  The bottom and sides is silver and metal.

Vertical Stand recommended

Another problem with the enclosure is the lack of rubber feet on the metal underside. Because of this, the enclosure vibrates against my desk as my 7200 rpm drive spins up. To keep it quiet, I had to use the vertical stand which does have rubber feet. If you wanted to put it flat, I would have to recommend a different enclosure or to go out and buy some rubber feet.

Summary

If you want both usb 3 and esata, then this enclosure is a good choice.  Quite frankly, there are not a lot of other choices out there.  But this enclosure is nice and I feel confident that if there were more choices, this enclosure would still be in the top.  There are definitely small areas for improvement but nothing major.

Since I got the metas, Rosewill upgraded their RX models from usb 2 to usb 3.  At this point, I would also consider getting the RX-358 U3C SLV which has a lower price point.

 

 

Remove url / website from wordpress comments

Holy spam bots Batman!

I finally got fed up with comment spam on my wordpress blog.  To help solve my problem, I decided to remove all the the url / website values for comments in my blog.  It seems like the most popular use of the author url value in a comment is for spam.  In fact, I would say over 90% of all my comments containing an author url is some form of ad spam. For these cases, the author url usually links to some random site with no relevant content. On the other hand, almost all my readers who post legitimate comments do not bother putting in a comment author url.

So I decided the author url is useless and decided take aggresive action against it:

  1. remove the url field from the comment form
  2. prevent comment posts with author url in it
  3. remove urls for existing comments
  4. remove comments which contained random author urls which has a slight hint of being spam.

Customize the comment form

To remove the url or website field from the comment form, you can customize the wordpress comment form by adding a filter and using the “comment_form_default_fields” hook. Go into your theme and find all usages of the function comment_form().  Before each usage, add the following filter:

    <?php
      function remove_url_field($fields) {
        unset($fields['url']);
        return $fields;
      }
      add_filter('comment_form_default_fields', 'remove_url_field')
    ?>

    <?php comment_form(); ?>

I’m using the default twenty-eleven theme and the above appears in comments.php.

Validate server comment post

Customizing the comment form is great for your users but it will not make a bit of difference for spam bots.  Spam bots can post comments directly to your wordpress and bypass the form directly.  Because of this, you need to add validation to the php file that accepts comments.  Inside wp-comments-post.php, find the following lines of code (should be somewhere near the middle of the file):

$comment_author       = ( isset($_POST['author']) )  ? trim(strip_tags($_POST['author'])) : null;
$comment_author_email = ( isset($_POST['email']) )   ? trim($_POST['email']) : null;
$comment_author_url   = ( isset($_POST['url']) )     ? trim($_POST['url']) : null;
$comment_content      = ( isset($_POST['comment']) ) ? trim($_POST['comment']) : null;

Put the following if statement right after:

if ($comment_author_url) {
   wp_redirect('/');
   exit;
}

This will redirect anyone who submits a comment author url back to the main page.  This should only affect bots which bypassed your form since it will not realize you do not have a url input anymore.

Remove existing author url

Finally, remove the existing urls from the mysql database.  The urls are stored in wp_comments in the comment_author_url field.

mysql> update wp_comments set comment_author_url = '';

Notes

The above changes were performed on wordpress 3.2.1.