How to move a WordPress site in 10 minutes or less

WordPress Hosting

I’ve had a VPS server at Rimuhosting.com for years to host UseStrict Consulting and other websites. I really enjoyed having root access and all the liberties that come with it. It was going really smoothly until I decided to try out Bitnami instead of the native PHP + Apache installs on my Ubuntu server – “if it ain’t broke…”, right?

But I did touch it and it did break. It turns out Bitnami has some php-fpm memory leaks that I couldn’t get around, and I figured I’d had enough of having to do sysadmin work for the time being. I decided I’d move to a managed hosting company where they’d take care of those issues for me. After some digging, I heard great things about SiteGround (yes, it’s an affiliate link – I like it so much that I endorse it) and decided to try it out.

After moving a few of my sites, I thought I’d share my experience on how to move a wordpress site. Yes, the title says it’s done in 10 minutes or less – I have it down to less than 5, honestly. It depends on how much practice you have, so your mileage may vary. ūüôā

The rest of this article will assume that your new host give you access to cPanel and simple one-click WordPress installs. Let me know in the comments if you want the non-cPanel version and I’ll write it up.

Ingredients

Here are the ingredients you’ll need for a quick and easy move:

  1. SSH or SFTP Access to both old and new servers;
  2. cPanel access on the new server;
  3. Access to your domain’s DNS settings;
  4. Remember to replace all occurrences of foobar.com below with the domain you’re moving;

If you’re not familiar with SSH, you’ll be able to do everything using SFTP and other tools like phpMyAdmin, but I find SSH faster. If you’re stuck with a Windows computer, look into getting PuTTY installed. In my days of having to use Windows, I’d also always use Cygwin.

Move a WordPress Site

The first thing you need to do is make sure your new host is ready to receive your domain. Go to your cPanel Home and set up the domain you want to move. If it’s your account’s primary domain, that’s already done. If it’s a secondary domain, create it as an Addon Domain. Let’s assume it’s an addon domain.

Creating an Addon Domain

Click on the Addon Domain icon in the domains section of cPanel. You’ll be taken to a page with a form to set up the new domain.

cPanel Addon Domains Icon

cPanel Addon Domains Icon

Fill in the form with your new domain. The rest (except for the password fields) will automatically be filled in for you. Feel free to change the default values, but for the purpose of this tutorial, we won’t change anything.

Create an AddOn Domain

Create an AddOn Domain

Click ‘Add Domain’ and this part is done. Next, we set up WordPress on the new domain.

Setting up WordPress

Back in your cPanel home, look for and click on the WordPress autoinstaller. Yes, you can choose to install WP yourself, but then you probably wouldn’t need these steps at all. But I digress…

cPanel Autoinstallers

cPanel Autoinstallers

SiteGround uses Softaculous to install applications. Granted, I don’t have much experience with cPanel (I’ve always done stuff manually) so I don’t know if it’s something every host uses or not. When you click on the WordPress autoinstaller, you’re taken to the Overview screen in the installer page. I’ve done this a few times now, and for some reason I’m wired to look for an install button at the bottom of the page. It’s not there. Look for the blue install button right next to the Overview tab.

WordPress Install Button

WordPress Install Button

Once you click on the ‘Install’ button, you’re presented with some basic fields to fill in. As you’re moving your site from your old host here, you really care about the following only:

  • Protocol (whether it’s HTTP or HTTPS)
  • Domain (select the AddOn domain that you just created)
  • Directory (leave empty to install WordPress under /home/youraccount/www/foobar.com)
  • Table Prefix (THIS MUST BE THE SAME AS YOUR EXISTING WP INSTALL)
  • Language (select the language of your existing WP install)

Now, you’ll have to live with the fact that the database name and credentials will be different, so if you have any third-party connections to your existing WordPress install, make sure to change them later.

Click ‘Install’ and wait until the progress bar finishes. You’re now ready to receive your old WordPress.

Export Your Old WordPress

The main thing here is that you want to export a dump of your old WordPress database. I use the terminal via SSH whenever I can. If you don’t like to use a terminal and SSH, export it via phpMyAdmin.

This is what I’d typically do via the terminal (on the old server):

$ mysqldump -u <username> -p  <database> | gzip -c > old-wp-dump.sql.gz

Adding the password to the command line isn’t safe, so we leave it out and get prompted for it after we hit enter. Note that we’re also compressing on-the-fly.

Once you’re done with the database, make sure to create a tarball of your old wp-content directory as well.

$ cd /path/to/wordpress/install
$ tar -czvf old-wp-content.tar.gz wp-content/

Download both files to your computer (or leave them temporarily in a place where you can access them via a browser on your old server).

Import Into the New Server

Now we need to get those two files into the new server. I’m still using SSH, but you can use SFTP if you want to.

First thing to do is to back up your new server’s automatically-created wp-content directory (or rename it using SFTP):

$ mv /path/to/www/foobar.com/wp-content /path/to/www/foobar.com/wp-content.orig

Back up the automatically-created database. You can find the credentials in your new wp-config.php file.

$ mysqldump -u <new-username> -p <new-database> | gzip -c > new-wp-backup.dump.sql.gz

Now move the old server’s files to your new server. If you chose to leave them in a place accessible via a browser, you can use wget (if it’s available in your new host – it is on SiteGround) to download them directly to your server. Otherwise use SCP or SFTP to upload them from your computer.

We’ll need to uncompress the files soon. Unfortunately, SiteGround doesn’t have gunzip, but you can get around that with gzip -d (and even create an alias for it in your ~/.bashrc file – alias gunzip="gzip -d ")

It’s time to do the actual move. The following commands will read the compressed information and handle them accordingly. To import the database, use mysql:

$ gunzip -c old-wp-dump.sql.gz | mysql -u <new-username> -p <new-database>

Again you’ll be prompted for the password after hitting enter. All of the old tables will be created, replacing the new ones as long as you used the correct table prefix when you ran the autoinstaller.

Now uncompress your old wp-content:

$ mv old-wp-content.tar.gz /path/to/www/foobar.com/
$ gunzip -c old-wp-content.tar.gz | tar -xf -

Replace the Auth Keys and Salts

WordPress uses several Authentication Keys and Salts. In order to avoid issues logging into your new server’s install, you’ll have to replace the salts in the new wp-config.php with the ones from your old one.

The entry in wp-config.php typically looks like this:

/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define('AUTH_KEY',         ';LM|C1Op{p`aE>6 FTO64{n#J2c,5KDK6:UxO.OGjHp[`<d%Wj<Fxid-Y_3}#rIn');
define('SECURE_AUTH_KEY',  '6b*K_`ie.A7b2):A-0&|arFv]+b04hT2g93TTRUJHBfp>DL=vJ-a}A9Rh:[email protected]');
define('LOGGED_IN_KEY',    'Q8853bl6ZP-F>r(>wpJhbQu>M|Jt{b6zCcUwR3oyA/6+y<~l#-~,JA-WE.L{[email protected]');
define('NONCE_KEY',        'GzVYsIDpbKi%4,xVODWZRE3w?}[email protected]>I=cM VF[u6AuQF20Cta)Hr9s<hh');
define('AUTH_SALT',        'FmSUv`pq2|%K}yb~r*e)+(,G1}:7I7;/TBxg>h_Ejm0HDD:Y^G&x,yf9t9IRD$3p');
define('SECURE_AUTH_SALT', 'C,QO;+Iu0xw&U}x7}+O_2PS#wn:&z?zh5:75Ys}b[[email protected]|;dgR+R<u8%[B');
define('LOGGED_IN_SALT',   'T_[R}qRiDS2Ye2z|V:A8?ogn,nU[}[+!wcD#W!X.2)ZC8n5*)sC*Y%Ks*&vo++eT');
define('NONCE_SALT',       '[lP_CFP70&i6l- )z(6Cw <o<0ZDG?sxJ&o&.t|m!xkX!z3$QLB.[dG9XRHE^ yd');

Test It

Your migration is now ready for testing. Pull up your new server’s IP address from your cPanel home and add it to your /etc/hosts file (C:\Windows\System32\Drivers\etc\hosts in Windows)

123.123.123.123 foobar.com

Save the file and test your website. You should not see any difference at all when viewing it or logging in.

Once you’re satisfied, change the DNS A entry to point from the old IP to the new IP and that’s it! You’ve moved your website successfully. Allow for a couple of days of DNS propagation before taking your old one down.

As an added bonus, if you’re dealing with a high-traffic site that gets lots of database changes, you can set up Remote MySQL connections in cPanel, whitelisting your old server’s IP for incomming connections, and then change your old server’s wp-config.php to connect to your new server’s MySQL database. That way changes coming from people who still have a cached DNS entry pointing to the old server will be made on the new database automatically.

MVC Starter Plugin for WordPress: Parent Class Overview

Inheritance with MVC Starter Plugin for WordPress

Except for Models, all classes in MVC Starter Plugin for WordPress are extensions of the Parent Class, defined in plugin-name.php. This makes it possible to call methods like load_lib() from anywhere in the child classes. This is important also because MVCSP works with singletons whenever possible.

Yes, I’m aware of the war regarding singletons, but when you look at debug logs and see that WordPress reloads your plugin at least twice in some cases, you really want to make sure that you’re not doing things more often than you should. If you still want to avoid singletons in load_lib(), you can. Refer to the section on that method to know more.

Support for PHP < 5.3

MVC Starter Plugin for WordPress comes with a bootstrap() method that instantiates/serves singletons. It relies on the native function get_called_class(), which was made available in PHP version 5.3. For those few who still run on PHP 5.2 and under, I strongly recommend that you have your hosting company upgrade or switch hosting companies to a more serious one. If that’s not a possibility, you can still use this Starter Plugin because it implements its own get_called_class() if the native one doesn’t exist. Like all methods, it is slower than native calls, so it really is better if you upgrade to a modern PHP version.

Best practices

In order to keep my code easily maintainable, I tend to follow these guidelines:

  • Place add_action and add_filter calls in the __construct() of Controllers
  • Make sure to check that admin-related logic is indeed running under the admin with checks to parent::is_admin().
  • Do the same for front-end logic, checking that parent::is_admin() is false.
  • Avoid having calls to non-controller methods inside the Parent Class constructor, with the odd exception of an abstract class that needs to be loaded beforehand.
  • NEVER have a closing PHP tag at the end of any file. Nobody likes to deal with “headers already sent” errors caused by extra space or newlines that shouldn’t be there. Instead, use a comment to indicate that the file has finished.
/* End of file file-name.php */
/* Location: plugin-dir/file-name.php */

Let me know if there are any other best practices you’d like me to add here.

MVC Starter Plugin for WordPress: Set Up

Template Variables

After you download the MVC Starter Plugin for WordPress, you’ll need to replace a few template variables across all existing files with values of your choosing. They are:

PLUGIN_NAME, PLUGIN_DESC, PluginClass, and <plugin-dir>

  • PLUGIN_NAME: The actual name of your plugin. This will appear in the Installed Plugins screen and in the Admin -> Settings submenu.
  • PLUGIN_DESC: The description of the plugin. This will appear in the Installed Plugins screen.
  • PluginClass: The overall class of your plugin. MVCSP is Object Oriented and all Controllers, DAOs, and Views should extend the parent class.
  • <plugin-dir>: MVCSP borrowed the end-of-file style from CodeIgniter, in the sense that it does not close PHP tags but instead has a comment to indicate that the file is not truncated. The <plugin-dir> tag is only used as part of that comment.

The Set-Up Helper Script

There are several methods to replace the template variables with your desired values. I personally like to use grep or find piped into a Perl one-liner. To make things easier, I included a setup.pl script which takes a few parameters and runs some shell commands in the background. This only works for people using Mac or Linux machines, or probably Windows with Cygwin (not having used Windows in years, I haven’t had a chance to test it). Run it without any parameters and this is what you get:

Usage: perl ./setup.pl --long-name="The Plugin Name" --desc="Full Plugin Description" --class-name="DesiredPHPClassName"

All 3 parameters are required. Use a valid class name or your plugin will throw an error during activation.

The parameters are self-explanatory.

Note: Once you’ve run the setup.pl script, the file plugin-name.php will be renamed to whatever name of the domain is. So suppose you extract the Starter Plugin zip file contents in to a directory called my-plugin, the file plugin-name.php will be renamed to my-plugin.php. WordPress will then have my-plugin/my-plugin.php as the plugin signature.

That’s all there is to setting up the Starter Plugin. You can now activate it in your Admin -> Installed Plugins.

If you want to set up your plugin to run tests, refer the Running Tests section.

MVC Starter Plugin for WordPress

A Little Background

This is the seventh anniversary of UseStrict Consulting. It was born out of my passion for Perl, long before I ever thought of writing plugins for WordPress.

A lot has changed since then – I fell in love with building WordPress plugins in 2011. Like with Perl back in 1998, it started as an itch that needed scratching. My first plugin wasn’t a simple task. I wanted to get live shipping rates from Canada Post to use on my wife’s online pharmacy running eShop. The end result was messy, but it worked… and still does!

Fast forward 4 years. Enter the MVC Starter Plugin for WordPress.

MVC Starter Plugin for WordPress

The MVC Starter Plugin for WordPress is the result of best practices adopted from CodeIgniter, Catalyst, and of course, the WordPress Codex. It is a robust Object Oriented Model/View/Controller framework for WordPress plugins. I haven’t released it to Github yet, as it’d be nice to get some peer feedback before I do that.

The framework comes with a few handy methods and classes, as well as test files which can serve as templates for your own tests. They are designed to work with the WordPress Unit Test Suite and phpunit. I’ll be adding the documentation below as time permits, but feel free to download¬†MVC Starter Plugin and play around with it!

Documentation

  1. Download
  2. Set Up
  3. The Parent Class
    1. Overview
    2. Method: bootstrap()
    3. Method: __construct()
    4. Method: is_admin()
    5. Method: load_lib()
    6. Method: load_all()
    7. Method: render_template()
    8. Method: set_env()
    9. Method: get_env()
    10. Method: log_msg()
  4. Admin Notices Controller
    1. The Notice Pool
    2. Method: set_notice()
  5. The Settings API
    1. Setting Controller Class
    2. Settings DAO and Model Classes
    3. The Settings View
  6. Ajax
    1. The Ajax Controller
    2. The Ajax Request Model

bbPress Notify (No Spam) – Opt Out Add-on

bbPress Notify (No spam) was originally built to let admins know when there is a new message in the forums. Over time, it was modified to notify other roles chosen by the Admin. This add-on allows users to opt-out of notifications.

Version 1.0 has arrived!

Version 1.0 is now available at a special price – only $14.99. This is what you get for that price:

  1. 2 available email template tags for unsubscribe URLs:
    1. [opt-out-url-wp] – gets converted into the wp-admin/profile.php URL
    2. [opt-out-url-bbpress] – gets converted into the bbPress profile URL for that user
  2. Your subscribers can opt-out in either profile screen (WP or bbPress). You choose the one that fits you best (for those who have plugins that disable /wp-admin/profile.php for certain users)
  3. bbPress Subscriptions screen will tell your subscriber whether he has opted out.
  4. From your subscriber’s point of view, nothing happens if he is not part of one of the roles selected to receive notifications.
  5. This price is for version 1.0 only. Once I add more functionality, the price goes up for new buyers.

Please sign up below to receive updates regarding the development process.

Cheers,
Vinny

eShop PayPal Pro Merchant Gateway

eShop PayPal Pro Merchant Gateway allows you to collect Credit Card payments without the need for your client to leave your site.

Installation

  1. Download eshop-paypal-pro.zip¬†and upload it to to your blog’s wp-content/plugins directory;
  2. Activate the plugin in your Plugin Admin interface;
  3. Go to the Settings -> eShop -> Merchant Gateways and enter your sandbox and live PayPal credentials.

Overview

eShop for WordPress comes with basic PayPal support out of the box. This means that your client gets sent to PayPal to make their payments and has the option of not returning. With eShop PayPal Pro Merchant Gateway plugin, you can collect the payment directly from the checkout page, no redirections to outside servers whatsoever.

For PCI compliance, no Credit Card data gets stored. It is up to you, however, to set up SSL on the checkout page.

Settings

Once you activate this plugin, a new section is shown under Settings -> eShop -> Merchant Gateways.

eShop PayPal Pro Settings

Tick the ‘Accept payment by PayPal Pro’ box and enter your Sandbox and Live PayPal credentials (API Username, API Password, and Signature). If you don’t use PayPal Payments Pro yet, click here to learn more about it.

Tick the credit cards that you want to use – note that PayPal does not allow American Express and Discover in certain regions. Make sure to test those cards before going live. Test credit card numbers can be found here.

Click ‘Save Changes’ and you’re good to go.

Checkout

When your clients reach the checkout page, they will see the Credit Card option as one of the payment methods. If it is the only active option, the CC fields will be visible. The type of credit card is identified automatically when the clients type in the number. If there are more Payment options, the fields will only be displayed if the clients click on the CC radio button.

Credit Card Option with Hidden Fields

Credit Card Option with Hidden Fields

Credit Card Fields Displayed

Credit Card Fields Displayed

Fields Shown Automatically

Fields shown automatically when it is the only option available

Confirmation Page

The confirmation page will show only the last four digits of the credit card number and card type.

Confirmation Page Data

Confirmation Page Data

eShop Multi-Currencies Plugin for WordPress

eShop Multi-Currencies plugin allows you to offer your products using over 165 currencies, with automatic exchange rate updates.

Installation

  1. Download eshop-multi-currency.zip¬†and upload it to to your blog’s wp-content/plugins directory;
  2. Activate the plugin in your Plugin Admin interface;
  3. Go to Settings -> eShop -> Currencies tab to customize your settings.

Overview

eShop Multi-Currencies plugin for WordPress gives you the ability to offer multiple currencies to your visitors. Select from over 165 currencies and display your chosen ones via a widget or shortcode. eShop’s default currency settings (base currency and base currency symbol) are moved to the new Currencies tab under eShop -> Settings, where you can also select whether to fetch exchange rates via OpenExchangeRates.org. Display allowed currencies using either a shortcode or a widget.

Settings

Once you activate this plugin, a new Tab is shown under Settings -> eShop -> Currencies.

The new currencies tab on the far right.

The new currencies tab on the far right.

Base Currency

You will also find that the currency symbol and currency options that were originally under ‘General’ and ‘Merchant Gateways’ tabs, respectively, have been moved to the new tab under the ‘eShop Base Currency’ box.

eShop Base Currency Settings

eShop Base Currency Settings

In addition to those two items, you can also select to have the plugin always send the base currency to the merchant gateway, or whatever currency the client has selected. CAVEAT: This is a potentially dangerous option, depending on the merchant gateway. Potential issues include failed transaction due to currency not accepted by the gateway, failed transaction due to given currency different from base currency without explicit acceptance in the gateway settings (outside of eShop), or even additional currency conversion fees. Make sure you know what you’re doing and test it out in a sandbox before using this option.

Open Exchange Rates

When dealing with multiple currencies, the system needs to know the exchange rates for each selected option. The plugin comes with integration with http://openexchangerates.org and instructions on how to get a free account. Due to performance reasons, exchange rates are not fetched in real time, but scheduled from hourly to monthly. You can also force the system to update on demand.

Open Exchange Rates

Allowed Currencies

The next section is for the actual allowed currencies. Choose as many currencies as you want (remember to play by your Merchant Gateway’s rules), and set the name, symbol, conversion rate (if you’re not using OXR as that sets it for you). You can also adjust fixed rates and percentages if you feel you need to. If you want to deactivate a currency without actually removing it, just toggle the ‘Active’ checkbox.

Allowed Currencies

Allowed Currencies

 eShop Orders Screen

To help you keep track of the currencies the sales have been made in (for those passing the non-base currency to the Merchant Gateways), All orders screens have been updated to display the 3-letter currency code instead of the base currency’s symbol.

User Preferences

Currency preference is kept via a cookie in your customer’s browser. When he completes the payment and opts to create an account, the preferred currency is stored and is viewable/modifiable under your customer’s profile screen.

Shortcode and Widget

You can place the currency selector drop-down anywhere you want by using the [emc-currency-selector] shortcode, or the special widget provided by the plugin. To add it directly to your theme, call

<?php echo do_shortcode('[emc-currency-selector]'); ?>

Requirements

This plugin uses shortcode_exists(), which was added in WP 3.6. It has been tested with WP v4.1 and newer.

Bugs

This plugin has been tested extensively. We do our best to provide as bug-free code as possible, but we cannot possibly test with all the different scenarios in the wild. If you find a bug, please let us know via our contact form.

Thanks

We’d like to thank Triple Ace Games for helping fund this project. Feel free to pay them a visit as they have some pretty cool products :).

WooCommerce Canada Post Shipping Rates Plugin

Canada Post Shipping Rates for WooCommerce  allows you to get Canada Post rates with more control over the countries you ship to.

Installation

  1. Download usc-wc-shipping-canada-post.zip¬†and upload it to to your blog’s wp-content/plugins directory;
  2. Activate the plugin in your Plugin Admin interface;
  3. Go to WooCommerce -> Settings -> Canada Post and follow the instructions to connect to Canada Post and customize your settings.

Overview

The WooCommerce Canada Post Shipping Rates Plugin¬†is a fork of Woothemes’ Canada Post plugin with some improvements:

  1. It does NOT require that you give your credit card number to Canada Post;
  2. It allows you to set country-specific service options;
  3. It allows you to opt to use default service options for every country not in the country list.

No Credit Card required for Canada Post

I was once caught by surprise when using Woothemes’ Canada Post plugin. I installed an update and suddenly I was asked to go to Canada Post to enter my Credit Card information. All the while my customers were unable to place orders. This plugin does NOT involve entering Credit Cards in any way.

Set Country-Specific Service Options

I sell a lot to Brazil, and because of that I wanted to translate the shipping options for Brazilians only. I also wanted to control which International services were available when shipping to that country. With this plugin, the specific countries selected will have each its own services section which you can control however you like.

WooCommerce Canada Post Brazil Selected

WooCommerce Canada Post Brazil Selected

Brazil Services Headline

Brazil Services Headline

WooCommerce Canada Post Custom Brazil Options

Custom Brazil Options

Use Default Services for Everyone Else

In case you decided to have country-specific settings for one or two countries and would like to have blanket settings for everyone else, just tick ‘Use Default’ to get the Default Services list displayed.

WooCommerce Canada Post Use Default Option

WooCommerce Canada Post Use Default Services

WooCommerce Canada Post Default Services Headline

Default Services Headline

Cronblocks for WordPress

A couple of years ago I had an idea of a project targeting people who want to offer dynamic content on their sites but do not have the programming knowledge to do so. I called it Cronblocks (http://cronblocks.com) – a system where the user can create snippets of content and choose when to display them. Not satisfied, I decided to add Geo-Location as a possible condition for displaying the snippets. It worked (and still works) fine for sites built in plain html or any programming language as the code is sourced via Javascript.

I recently decided to write a port of Cronblocks as a WordPress plugin as a proof of concept, with the following features:

  1. Snippets are a WordPress Custom Post Type
  2. They can (and should) be grouped into category-like taxonomies called Snippet Groups
  3. Set the snippet controls to use either Geo-Location (visitor’s country) or a Scheduled display time range and date (choose days of the week or days of months)
  4. Assign the Snippets to a Snippet Group (just like categories)
  5. Control overlapping Snippets in a Group with Priorities

To use it, place the Snippet Group shortcode to control where on your page/post you want the appropriate Snippet to be displayed, and that’s it!

The plugin will check for all snippets associated with the shortcode’s Snippet Group and will decide which one should be displayed according to the control settings for each Snippet. If more than one Snippet match the display conditions, a random one of the matching set will be selected.

As mentioned above, this is a proof of concept. I plan on writing a fully featured companion plugin that will offer the following:

  • Enable multiple control conditions of each type, and mix/match
  • Keep and show statistics of snippets being displayed
  • Optionally display snippets based on the visitor’s local time
  • Optionally reload the snippet group after a given amount of time (say a visitor is watching a video, reload the snippet group after 3 minutes)
  • Enable Region and City scope
  • Use Maxmind GeoIP2 database, which is more accurate than the GeoIP databased used in the Cronblocks plugin
  • Allow overriding of snippet options via the shortcode attributes
  • Set up roles that can access the snippet administration
  • Add an icon to the TinyMCE interface as a shortcut to inserting the shortcode
  • Add a Snippet Group Widget

While the fully featured one doesn’t come out, feel free to download the proof of concept from WordPress.org’s plugin repository: Download