How to move WPMU domains

Posted May 31st, 2012 in Database, PHP

Here’s a very quick set of SQL snippets for updating a WPMU domain. This might be useful when building a site on a development domain before moving to a production one later on.

Firstly update the wp_blogs table:

1
UPDATE wp_blogs SET domain='newdomain.com';

There will be a bunch of wp_options and wp_posts tables – one per site. Find all the tables:

1
2
SHOW TABLES LIKE "%_options";
SHOW TABLES LIKE "%_posts";

and for each table, perform the following query:

1
2
3
4
#_options tables
UPDATE <tablename> SET option_value=REPLACE(option_value, 'http://olddomain.com', 'http://newdomain.com');
#_posts tables
UPDATE <tablename> SET post_content=REPLACE(post_content, 'http://olddomain.com', 'http://newdomain.com');

This was enough to get the sites working for me. Additional tweaks are probably required afterwards – if you find anything let me know in the comments below.

Read More »

Moving WordPress Multi-Site Between Servers

Posted January 11th, 2012 in Database, Linux, PHP

Tonight I had to move my WPMU install from my local development machine to the live server – this meant a change in installation path which is always a hassle with WordPress. Below I’ll detail my issues and the corresponding fixes in the hopes it will make life easier for others experiencing the same problems.

Redirection to wp-signup.php

First thing I noticed was that when loading the site on a live domain, I’d get instantly redirected to mydomain.com/wp-signup.php?new=mydomain.com. With a bit of Googling I came across this forum thread which recommended adding the following to my wp-config.php:

1
2
define( 'NOBLOGREDIRECT', '' );
define( 'SUBDOMAIN_INSTALL', false );

Don’t do this! It will get the site closer to working order but it’s not going to help you in the long run – especially when you need the other domains working too. Instead here’s what you should be doing:

1
2
3
4
5
6
7
#Dump your DB
mysqldump - u<username> -p<password> -h<host> <dbname> > test.sql
 
#Update folder path to that of the new servers
sed -i "s/path/to/install/new/path/to/install/g" test.sql 
#If you installed into localhost/foo/bar/mysite, change that to your live servers domain
sed -i "s/url/path/to/site/www.domain.com/g" test.sql

This is pretty standard behavior for moving WordPress sites, however if you load the above dump up on your live domain you’ll probably be greeted with the dreaded Error establishing a database connection.

Error establishing a database connection

Heading to www.domain.com/wp-admin will shed a little more light on the situation – you need to update your wp_blogs table for the main site. WPMU is currently using your development servers URL from this table and ignoring what’s in wp-config.php. To play things safe we’ll update any occurrances of our test servers domain in test.sql:

1
2
#Update your live servers subdomain in wp_blogs to your live servers domain
sed -i  "s/yoursite.localhost.com/www.yourdomain.com/g" test.sql

This should do the trick. Load that bad boy into your live server and you should be good to go!

Read More »

MySQL FROM_UNIXTIME() With Negative Numbers

Posted December 21st, 2011 in Database

MySQL’s built in FROM_UNIXTIME() function only handles positive numbers however we can still convert negative integers to dates using its handy DATE_ADD() function like so:

1
SELECT DATE_ADD(FROM_UNIXTIME(0), INTERVAL -13391999 SECOND)

which gives:

1
1969-07-30 10:00:01

Note that this also works with positive numbers, so if your database contains a mixture of both it’s still safe to use.

Credit to user fat_kid for his tutorial here.

Read More »

UCFirst Function for MySQL

Posted December 19th, 2011 in Database

Without any adieu what-so-ever, below is a MySQL implementation of PHP’s ucfirst function which capitalizes the first letter of each word in a string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
DELIMITER $$
CREATE FUNCTION CAP_FIRST (INPUT VARCHAR(255))
 
RETURNS VARCHAR(255)
 
DETERMINISTIC
 
BEGIN
    DECLARE len INT;
    DECLARE i INT;
 
    SET len   = CHAR_LENGTH(INPUT);
    SET INPUT = LOWER(INPUT);
    SET i = 0;
 
    WHILE (i < len) DO
        IF (MID(INPUT,i,1) = ' ' OR i = 0) THEN
            IF (i < len) THEN
                SET INPUT = CONCAT(
                    LEFT(INPUT,i),
                    UPPER(MID(INPUT,i + 1,1)),
                    RIGHT(INPUT,len - i - 1)
                );
            END IF;
        END IF;
        SET i = i + 1;
    END WHILE;
 
    RETURN INPUT;
END$$
DELIMITER ;

Use it like so:

1
SELECT CAP_FIRST('my string of words');

and you should get:

My String Of Words

All credit and many thanks for this function to Joezack.

Read More »

Cloud Database Backup

Posted May 25th, 2011 (Updated 29 Oct 2011) in Database, Linux

Update 2011-10-12: More storage options! Google Storage, Local HDD, FTP, experimental unlimited Google Docs conversion

Have you ever wanted to ensure that even if your server dies in the most spectacular of ways, your DB is safe? Meet Cloud Database Backup. Cloud Database Backup is a little script I’ve written that allows you to quickly and easily back up your MySQL DBs to the cloud.

Currently you can back your database up to:

  • Amazon S3
  • FTP
  • Google Docs
  • Google Storage
  • Local HDD

Download the script here.

Requirements:

  • MySQL with access to INFORMATION_SCHEMA database
  • php, php5-cli (for S3 backups)
  • python2, python-gdata (for Google Docs backups)

This is an updated version of my old Automatic MySQL Database Backup script that adds support for Google Docs (which now allows uploads of any file type for non-enterprise users), the recently opened Google Storage, as well as local HDD and FTP servers. It does a MySQL dump of each DB separately, zips them all and uploads the zip to your cloud service of choice.

I’ve also added in an experimental ‘db chunker’ which uses this script to split SQL dumps into convertible sizes for Google Docs, allowing you to upload unlimited backups for free; owever due to a reproducible bug in Google Docs, I wouldn’t recommend its use (and it’s disabled by default).

To get started simply update your details in the appropriate places at the top of backup.sh and type ./backup.sh. Presto!

I’ve also included a crontab example to allow automation of backups.

Read More »

MySQL – Returning Rows in a Specific Order

Posted February 12th, 2010 (Updated 29 Oct 2011) in Database

The MySQL ORDER BY clause let’s you easily order in fields in ascending or descending order however occasionally you’ll want to have a specific order

Take for instance if you have a list of products on a sales site ordered by name. Your boss tells you he wants to show one (or several) products before all others on the page. At this point you have 2 options – add a ‘special’ column in the table and do an ORDER BY special, name – which would only work if he wanted these special products in alphabetical or reverse alphabetical order – or use a UNION with multiple SELECT queries. Neither are great options. This is where the FIELD() function comes in.

The rows ordered by FIELD() will appear at the end of your table, so to get them appearing at the top just add DESC and put enter your FIELD() arguments in reverse order. All rows not specifically ordered with FIELD() will remain unordered unless specified otherwise. Here’s an example.

If the ID of the products your boss wants to appear first are 36, 40, 12 respectively, we can order like so:

SELECT *
FROM products
ORDER BY FIELD(id, 12, 40, 36) DESC, name

There is no limit to the number of arguments you can add and they must be the same data type as your field.

Read More »

MySQL Limits and Total Row Counts

Posted February 11th, 2010 (Updated 29 Oct 2011) in Database

When paginating data on your website you’ll probably have a query something like the following:

SELECT *
FROM my_table
LIMIT 0,50

However in doing so, chances are you’ll want to have a ‘Showing x-y of z rows‘ clause at the top of your table. Retrieving that z value can be quite a hassle – it’d be very ugly to need to execute the same query again sans the LIMIT clause. Recently I’ve come across an easy way of accomplishing this in MySQL – the FOUND_ROWS() function.

To use it is simple. In your first query place SQL_CALC_FOUND_ROWS after the SELECT keyword like so:

SELECT SQL_CALC_FOUND_ROWS *
FROM my_table
LIMIT 0,50

Then immediately afterwards execute this query to return the total number of rows before the LIMIT clause was executed:

SELECT FOUND_ROWS()

That’s it. Make sure to use the second query straight after the first or the result count will be lost.

Read More »

Automatic MySQL Database Backups

Posted January 24th, 2010 (Updated 29 Oct 2011) in Database, Linux

UPDATE: This script has been superseded by my Cloud Database Backup script. It’s advised you use that instead.

If you’re a developer you should back up your data. Go ahead – do it, do it now. Okay, now that we’ve got that out of the way here’s a nice automated solution to backing up your MySQL databases and optionally uploading to Amazon S3 for added safety.

Read More »