Automating WordPress Installation For Development

|

I’ve been doing WordPress plugin development for a little while now. I finally got around to setting up a development environment for this purpose. I wanted to have all of the version 2 releases available for testing so I went to the WordPress site to see how many there were. Seventeen. Hmmm, this could take a while. Setup the database, unzip the WordPress install, create the configuration file, use a browser to run the installation… you see my delima. Well, being a software engineer I decided there had to be a better (translates quicker and lazier) way of doing this.

Database

All WordPress installations need a MySQL database setup to function, right? Initially I figured I’d have to setup seventeen databases for this batch. I’d also have to create new databases for future releases. Wait a minute! WordPress supports multiple installations within the same database. Problem solved. I create my development database and tucked the connection settings aside for later.

Obtaining The Software

Now I needed to get a copy of all of the WordPress version 2 releases to setup. I created a folder on my web server to serve as a repository for these installation archives: >mkdir -p ~/software/WordPress/Releases. Next I browsed over to the WordPress Release Archive and copied the links to the version 2 releases into a text file, one link per line. I grabbed the zip files, but you could just as easily implement this using the tar-balls. For easy downloading I saved the text file to ~/software/WordPress/Releases/WordPress-Builds.txt. Then from the command prompt I navigated to the Releases directory and used the wget program to retrieve them all for me: >wget -i WordPress-Builds.txt.

Automating Installation

Ok, so far the process has been a manual process and nothing that you wouldn’t do for a normal WordPress installation with the exception of downloading all of the releases. This however is where the normal process would have been tedious for seventeen separate installations. Thus… automation.

First I wanted to automate the unzipping process, which isn’t all that tedious but it will be a start. In the root of my development web ~/dev.franzone.com I created my Bash script file to perform the automation. There will be a loop that drives the installation process. This loop basically finds all of the releases in my releases directory.

# Find all releases
for F in `find ${RELEASES} -name "*.zip"`
do
  # ...
done

Listing 1

Next I would like to base the blog subdirectory of my web on the name of the release. Luckily the name of the zip files will do nicely with a bit of massaging.

  # Calculate blog directory name
  DNAME=`basename "${F}"`
  DNAME=${DNAME%.zip}
  DNAME=${DNAME#wordpress}
  DNAME="wp${DNAME}"

Listing 2
Calling basename on the filename will strip off any directory references and leave me with just the name of the file itself. The next line removes the “.zip” file extension from the name (notice the variable syntax which you can read up on at The Linux Documentation Project – Advanced Bash Scripting Guide). I then remove the “wordpress” prefix on the name and replace it with “wp” instead. I did this with two lines, but could have done it with one. I’ll leave it as extra credit to lookup the syntax for combining the two lines into one call.

Now that I know where the file is that I will be extracting and I know what name I want the directory to be… I just have to make the calls to get it done.

  # Create blog directory and extract software
  unzip "${F}" > /dev/null
  mv -f wordpress "${DNAME}"

Listing 3

The next step is to create the configuration file. WordPress actually comes with a sample configuration named wp-config-sample.php. All I really need to do is copy this file to a file with the real config name, wp-config.php. I’ll also provide the file with my database connection information while I am at it. Oh, remember that mention earlier of installing multiple WordPress blogs into the same MySQL database? Well, here is how to do it. The first part of this code snippet calculates a table prefix which I set in the configuration file. That way all of my WordPress installations have their own set of tables with a specific table name prefix, which incidentally is based on the release number.

  # Calculate DB table prefix
  TNAME=${DNAME//./_}
  TNAME="${TNAME//-/_}_"

  # ...

  # Create our config file and set DB Connection Info AND Table Prefix
  sed -e 's/define('"${TIC}"'DB_NAME'"${TIC}"', '"${TIC}"'[[:alnum:]]*'"${TIC}"')/define('"${TIC}"'DB_NAME'"${TIC}"', '"${TIC}${DB_NAME}${TIC}"')/g
s/define('"${TIC}"'DB_USER'"${TIC}"', '"${TIC}"'[[:alnum:]]*'"${TIC}"')/define('"${TIC}"'DB_USER'"${TIC}"', '"${TIC}${DB_USER}${TIC}"')/g
s/define('"${TIC}"'DB_PASSWORD'"${TIC}"', '"${TIC}"'[[:alnum:]]*'"${TIC}"')/define('"${TIC}"'DB_PASSWORD'"${TIC}"', '"${TIC}${DB_PASSWORD}${TIC}"')/g
s/define('"${TIC}"'DB_HOST'"${TIC}"', '"${TIC}"'[[:alnum:]]*'"${TIC}"')/define('"${TIC}"'DB_HOST'"${TIC}"', '"${TIC}${DB_HOST}${TIC}"')/g
s/$table_prefix  = '"${TIC}"'wp_'"${TIC}"'/$table_prefix  = '"${TIC}${TNAME}${TIC}"'/g' "${DNAME}/wp-config-sample.php" > "${DNAME}/wp-config.php"

Listing 4

You’ll notice that I have used Sed, a stream editor to accomplish this task. It works nicely as a regular expression pattern matcher for substituting the sample configuration lines with my real configuration data. I then direct the output into the configuration file.

Next I need to activate all of these WordPress installations so that it can create the proper tables in the database. This is typically done in a web browser, but I do not want to open up the URL for each and every installation. Instead I’ll script the web calls using curl.

  # Activate the blog
  curl -u ${WEB_USER}:${WEB_PASS} -d \
    "weblog_title=${BLOG_NAME}&admin_email=${BLOG_EMAIL}" \
    http://${DOMAIN}/${DNAME}/wp-admin/install.php?step=2 > results_${DNAME}.html

Listing 5

Did you notice the WEB_USER and WEB_PASS variables in the command line parameters passed to curl? This is because I have HTTP authentication on my development domain. These parameters tell curl to login with my username and password. It then performs a POST to the installation script with my blog’s name and my email address.

Now, that should do it! All seventeen releases of WordPress are installed and activated. Finished, right? Wrong. After running this I have seventeen nice little emails telling me login information… different login information for all seventeen blogs. That just won’t do. So the final step I perform is to set the admin password on all of the blogs to the same value.

  # Now set the admin password in the DB
  echo -n "UPDATE ${TNAME}users SET user_pass = '" > set_password.sql
  md5sum check_password | awk '{printf("%s", $1)}' >> set_password.sql
  echo "' WHERE ID=1;" >> set_password.sql
  mysql -h ${DB_HOST} -D ${DB_NAME} -u ${DB_USER} -p${DB_PASSWORD} < set_password.sql

Listing 6

This basically creates a SQL file with a single update statement, containing an MD5 hash of the password I want to use. It then uses the mysql command-line program to connect to my database and run the script.

Conclusion / Download

Ok, now I am done. I have seventeen releases of WordPress in subdirectories of my development domain all with the same login information. Plus the great part about scripting this out is that I can duplicate the process anytime I want. Why would I want to do that? Well, after testing plugins, themes and whatever else I want to test it would be nice to be able to get back to a clean install. This way I know that I am testing just one change on a known working platform. All I have to do is run a quick SQL query to drop all of the tables from my database and then re-run my script. Quick and simple.

Here is the BASH script I used (minus my personal information) and the URL file containing links to all seventeen of the WordPress releases that I used. I hope this has been helpful and thanks for stopping by!