Posted on

WordPress 4.5 Breaking JavaScript (aka Where Is My Map?)

Ever since WordPress 4.5 rolled off the press there have been numerous complaints about websites breaking.   Numerous reports are coming into our Store Locator Plus forums and support email telling us “our map broke when they updated our website”.  The problem?  jQuery. To be more specific the problem is not jQuery but  how some plugins and themes implement jQuery in WordPress.

WordPress 4.5 started shipping jQuery version 1.12.3 as the “official” version of jQuery being used  with WordPress core. jQuery 1.12 has more stringent controls than previous versions.   The most obvious, jQuery 1.12 no longer “hides” some of the syntax errors that lay dormant in plugin code.   If there is malformed  or incorrect syntax, jQuery 1.12 will complain.  Your browser will most likely stop executing ALL scripts from that point forward.  As you can imagine, this causes things, like themes and plugins  to break.
Continue reading WordPress 4.5 Breaking JavaScript (aka Where Is My Map?)

Posted on

Fixing VVV svn cleanup Invalid cross-device link messages

Ran into a unique situation while updating my VVV box after  a weekend of WordPress Core and plugin development at WordCamp US this past weekend.   Today, after the formal release of WordPress 4.4 I needed to update the code in my WordPress trunk directory on the VVV box.  Since I have other things in progress I didn’t want to take the time to reprovision the entire box.  Though, as it turn out, that would have been faster.

The issue was when I tried to do the svn up command to update the /srv/www/wordpress-trunk directory and make sure I was on the latest code.   The command failed, insisting that a previous operation was incomplete.  Not surprising since the connectivity at the conference was less-than-consistent.    svn kindly suggest I run svn cleanup.  Which I did.  And was promptly met with an “invalid device cross-link” error when it tried to restore hello.php to the plugin directory.

The problem is that I develop plugins for a living.   As such I have followed the typical VVV setup and have linked my local plugin source code directory to the vvv plugin directory for each of the different source directories on that box.    I created the suggested Customfile on my host system and mapped the different directory paths.     On the guest box, however, the system sees this mapping as a separate drive.  Which it is.  And, quite honestly I’m glad they have some security in place to protect this.  Otherwise a rogue app brought in via the Vagrant guest could start writing stuff to your host drive.   I can think of more than one way to do really bad things if that was left wide-open as a two-way read-write channel.

VVV Customfile Cross Device Maker
VVV Customfile Cross Device Maker

The solution?

Comment out the mapping in Customfile on the host server.  Go to your vvv directory and find that Customfile.  Throw a hashtag (or pound sign for us old guys) in front of the directory paths you are trying to update with svn.  In my case wordpress-trunk.

Run the vagrant reload command so you don’t pull down and provision a whole new box, but DO break the linkage to the host directory and guest directory.

Go run your svn cleanup and update on the host to fetch the latest WP code.

Go back to the host, kill the hashtag, and reload.


Hope that saves you an extra 20 minutes surfing Google, or your favorite search service, for the answer.


Posted on

VVV For WordPress Development

Banner Vagrant Cloud WP Dev Kit Box

Now that 4.3 has been released I am taking a few days to reconfigure my production environment for WordPress plugin development. After a number of issues running the self-contained GUI development environment that included WordPress core, full plugin development, and all of my supporting infrastructure including phpStorm, SmartGit, and a series of Grunt scripts in an all-in-one Vagrant-based Virtualbox, I decided to try something new. Losing 20 minutes every few days because the self-contained GUI in Virtualbox could not sync between guest and host was too much. Something in the Virtualbox or CentOS 7 upgrades over the past year broke something fundamental in GUI I/O and I’ve been unable to track it down. Time for a change.

My change? Learning Varying Vagrant Vagrants. For those that are not familiar with VVV for WordPress development you may want to check it out here:

What is VVV?

VVV is a virtual development environment for WordPress.    It spins up a headless (no GUI interface) Virtualbox that contains three separate versions of WordPress (stable, dev, and trunk) as well as a myriad of tools like phpMyAdmin.   All of the settings are in place to allow your local system, my OS/X desktop for my setup, to interact with the local WordPress install from your preferred web browser.

The upside is there is a lot of community support , articles, and various tools-and-trick available to you for doing almost anything you want.    A lot of the “cool dev tricks” I never had fully working, like interactive XDebug support in phpStorm, are readily available.     It is also super-easy to switch between WordPress releases which is cool if you are sending core patches or need to test on the upcoming major release.

The downside is that you need to setup all of your development tools locally on your desktop.   Guess what happens if your computer dies?   Yup, another few hours of setting it up again.   With my prior custom self-contained virtual environment I only need to save my Virtualbox, usually by creating a Vagrant image, any time I made notable changes to my tool kit; by doing so I could restore it easily to ANY desktop ANYWHERE in the world and have EXACTLY the same environment in no more time than it takes to spin up a VVV based box.

In short, VVV is a virtual machine store on your local desktop with several WordPress installs ready-and-waiting behind your browser screen.

My Startup Tricks

I develop a number of WordPress plugins, so having full development tools and my source code are key to productivity.  Here are some things I needed to tweak on the default VVV setup to get going.

Linking Plugin Source

I am primarily developing plugins and I want them on all of the WordPress installs provided by VVV.  I can “take over” a VVV server-based directory with a local directory my mapping the local directory to the destination with a Vagrant Customfile.    Go to the base location where you placed your VVV install, you will know you are in the right place as it has the Vagrantfile for the VVV box, and create a new file named “Customfile”.

Here is my mapping entries to take over the plugin directory on all 3 WordPress installs that come with VVV:

config.vm.synced_folder "/Users/lancecleveland/Store Locator Plus/plugin_code", "/srv/www/wordpress-default/wp-content/plugins", :owner => "www-data", :mount_options => [ "dmode=775", "fmode=774" ]

config.vm.synced_folder "/Users/lancecleveland/Store Locator Plus/plugin_code", "/srv/www/wordpress-develop/wp-content/plugins", :owner => "www-data", :mount_options => [ "dmode=775", "fmode=774" ]

config.vm.synced_folder "/Users/lancecleveland/Store Locator Plus/plugin_code", "/srv/www/wordpress-trunk/wp-content/plugins", :owner => "www-data", :mount_options => [ "dmode=775", "fmode=774" ]

Configuring XDebug

phpStorm comes with an XDebug listener.  This allows you to set breaks in your PHP code files, inspect variables in real-time, and do a lot of other things that are much more efficient than var_dump or print_r or die littered throughout the code.     The are a number of articles and videos on using XDebug with phpStorm.  Check it out, it is a great debugging tool.   For now, how to enable it with VVV:

Turning on XDebug is easy with VVV.

Go to the VVV install directory.

Enter Vagrant via SSH: vagrant ssh

Turn on Xdebug from the SSH command line on the virtual machine: xdebug_on

That’s it, I can now use my  local phpStorm tool to debug my VVV files.

Here is THE XDebug + VVV + phpStorm video to watch to do this.

Useful Meta

With VVV installed these URLs should work in your browser.

Users and passwords:

  • For the WP installs:  wp / wp
  • For WP Admin Users: admin / password
  • MySQL Root: root / root
    • Default DB Name: wordpress_default
    • Trunk DB Name: wordpress_trunk
    • Develop DB Name: wordpress_develop


  • Local directories (relative to Vagrant install): ./www
  • Server-Side directories: /srv/www
Posted on

WordPress dbDelta Better In 4.2, Not Yet Perfect

WP dbDelta Bug Report Banner

There have been a LOT of changes in WordPress Core including updates to the dbDelta() method in the upgrade function set.   What is dbDelta()?  dbDelta is the primary function used by WordPress to determine if the structure of data tables needs to be augmented between releases.   It works great for upgrading core WordPress data tables.    Where it has problems is with developer-specific SQL statements used to create secondary tables in plugins and themes.    Store Locator Plus, for example, uses a secondary table to storing basic location data.

Unfortunately dbDelta has always had issues (see running commentary on Trac ticket 10404), especially when it comes to indices on a MySQL table.   Most well-designed data tables will have primary and secondary indexes on the table to improve query performance.    dbDelta has a hard time figuring out when an index already exists and has not been modified.   If you did not craft your CREATE TABLE command EXACTLY the way dbDelta wants to see it, the dbDelta method will create new indexes.    This can cause performance degradation and unnecessary overhead in the MySQL tables when a data column ends up with 10, 20 , 30+ copies of the index; one created every time the plugin or theme is updated.

Many plugins and themes suffer from this malady.   Over two years ago I dug into dbDelta and learned the syntax secrets to get WordPress to stop creating duplicate indexes.   Today I found a site that was back to its old tricks running the latest version of Store Locator Plus and WordPress 4.2.2.   As it turns out the rules for dbDelta have changed and thus the syntax for creating a “dbDelta friendly” SQL statement has changed as well.    With dbDelta a behind-the-scenes feature it is never broadcast to the general public that it has changed and thus goes undetected for a while when something goes awry.

Turns out the changes are not new.  They go back to at least WordPress 4.1.    The last time I dug into this issue was WordPress 3.8.   Guess it is time for some phpUnit testing on dbDelta within my own plugin suite testing.   If things are running properly the dbDelta command for an existing installation of Store Locator Plus 4.2 should yield NO QUERY UPDATES when activating/installing a newer version of the plugin.

WP 4.1 dbDelta Results

Source SQL:

dbDelta SQL: CREATE TABLE wp_store_locator ( sl_id mediumint(8) unsigned NOT NULL auto_increment, sl_store varchar(255) NULL, sl_address varchar(255) NULL, sl_address2 varchar(255) NULL, sl_city varchar(255) NULL, sl_state varchar(255) NULL, sl_zip varchar(255) NULL, sl_country varchar(255) NULL, sl_latitude varchar(255) NULL, sl_longitude varchar(255) NULL, sl_tags mediumtext NULL, sl_description text NULL, sl_email varchar(255) NULL, sl_url varchar(255) NULL, sl_hours varchar(255) NULL, sl_phone varchar(255) NULL, sl_fax varchar(255) NULL, sl_image varchar(255) NULL, sl_private varchar(1) NULL, sl_neat_title varchar(255) NULL, sl_linked_postid int NULL, sl_pages_url varchar(255) NULL, sl_pages_on varchar(1) NULL, sl_option_value longtext NULL, sl_lastupdated timestamp NOT NULL default current_timestamp, PRIMARY KEY (sl_id), KEY sl_store (sl_store), KEY sl_longitude (sl_longitude), KEY sl_latitude (sl_latitude) ) DEFAULT CHARACTER SET utf8

dbDelta Updates List:

QUERY: ALTER TABLE wp_store_locator CHANGE COLUMN sl_linked_postid sl_linked_postid int NULL
QUERY: ALTER TABLE wp_store_locator CHANGE COLUMN sl_lastupdated sl_lastupdated timestamp NOT NULL default current_timestamp
QUERY: ALTER TABLE wp_store_locator ADD PRIMARY KEY (sl_id)
QUERY: ALTER TABLE wp_store_locator ADD KEY sl_store (sl_store)
QUERY: ALTER TABLE wp_store_locator ADD KEY sl_longitude (sl_longitude)
QUERY: ALTER TABLE wp_store_locator ADD KEY sl_latitude (sl_latitude)
for update

Update Results:

[wp_store_locator.sl_linked_postid] => Changed type of wp_store_locator.sl_linked_postid from int(11) to int
[wp_store_locator.sl_lastupdated] => Changed type of wp_store_locator.sl_lastupdated from timestamp to
[0] => Added index wp_store_locator PRIMARY KEY (sl_id)
[1] => Added index wp_store_locator KEY sl_store (sl_store)
[2] => Added index wp_store_locator KEY sl_longitude (sl_longitude)
[3] => Added index wp_store_locator KEY sl_latitude (sl_latitude)

My WP 4.2 dbDelta Results

Better, but still not quite right.

Source SQL:

CREATE TABLE wp_store_locator ( sl_id mediumint(8) unsigned NOT NULL auto_increment, sl_store varchar(255) NULL, sl_address varchar(255) NULL, sl_address2 varchar(255) NULL, sl_city varchar(255) NULL, sl_state varchar(255) NULL, sl_zip varchar(255) NULL, sl_country varchar(255) NULL, sl_latitude varchar(255) NULL, sl_longitude varchar(255) NULL, sl_tags mediumtext NULL, sl_description text NULL, sl_email varchar(255) NULL, sl_url varchar(255) NULL, sl_hours varchar(255) NULL, sl_phone varchar(255) NULL, sl_fax varchar(255) NULL, sl_image varchar(255) NULL, sl_private varchar(1) NULL, sl_neat_title varchar(255) NULL, sl_linked_postid int NULL, sl_pages_url varchar(255) NULL, sl_pages_on varchar(1) NULL, sl_option_value longtext NULL, sl_lastupdated timestamp NOT NULL default current_timestamp, PRIMARY KEY (sl_id), KEY sl_store (sl_store), KEY sl_longitude (sl_longitude), KEY sl_latitude (sl_latitude) ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci

dbDelta Updates List:

QUERY: ALTER TABLE wp_store_locator CHANGE COLUMN sl_linked_postid sl_linked_postid int NULL
QUERY: ALTER TABLE wp_store_locator CHANGE COLUMN sl_lastupdated sl_lastupdated timestamp NOT NULL default current_timestamp
QUERY: ALTER TABLE wp_store_locator ADD PRIMARY KEY (sl_id)

Update Results:

[wp_store_locator.sl_linked_postid] => Changed type of wp_store_locator.sl_linked_postid from int(11) to int
[wp_store_locator.sl_lastupdated] => Changed type of wp_store_locator.sl_lastupdated from timestamp to
[0] => Added index wp_store_locator PRIMARY KEY (sl_id)

WP 4.2 dbDelta SQL Best Practices

Some of these carry over from the prior dbDelta comments, some are new with later versions of dbDelta and MySQL.   The code is fairly robust, but if your MySQL installation comes back with a different format for the describe command this can wreak havoc on dbDelta().     I’ve presented things to look out for when crafting your dbDelta SQL statements as well as possible improvements in WP Core for dbDelta.    I may submit patches once again, but it has proven nearly impossible to get patches reviewed and approved for dbDelta.   Makes sense given the HUGE impact this function has on the WordPress Core engine, but there are thousands of plugins and themes wreaking havoc on WordPress performance due to some of these issues.    Maybe a detailed review like this will help get some updates into core.

Table Creation / Modification Commands

dbDelta() uses the MySQL DESCRIBE <table> command to fetch data about the table name passed in to dbDelta().  It is parsed with a regular expression out of the SQL statement looking for CREATE TABLE <…> , CREATE DATABASE <…> , INSERT INTO <..>, and UPDATE <…>  where the first “word” in the <…> part is assumed to be the table name.


  • The process appears to be case sensitive.  Use the commands as noted above in all caps.
  • Make sure you have no extra spaces, newlines, or other whitespace in between CREATE and TABLE or the other two-word directives noted here.
  • Make sure your table name has a leading space before and trailing space after.

Possible Improvements

  • Consider make thing preg_match() case insensitive.
  • Consider changing the single-space in commands like INSERT INTO into multi-whitespace regex i.e. INSERT\s+INTO

Defining Column Types

On some servers, such as my CentOS 7 development box, MySQL Ver 15.1 Distrib 5.5.41-MariaDB, has decided that post types of INT really mean INT(11).   Different variations may post different results back from the DESCRIBE command, but here is what I find working on MOST servers including my Linux dev box:

  • Always specify the LENGTH for each field type that accepts a length.  For most fields use the default length.
    • int(11)
    • mediumint(8)
    • varchar(1) to varchar(255), 255 is the default.
  • Fields without lengths:
    • longtext
    • mediumtext
    • text
  • Do not put spaces between the field type and the parens or the number in parens for the length.
  • User lowercase for field name and the field type.
  • Use uppercase for the NULL and NOT NULL specification.
  • Do NOT have extra spaces between the field name, the field type, and any of the additional definition parameters.


global $wpdb;
$sql =
'CREATE TABLE my_table (
my_id mediumint(8) unsigned NOT NULL auto_increment,
my_first_field varchar(1) NULL,
my_second_field varchar(255) NULL,
my_third_field int(11) NULL,
my_lastupdate timestamp NOT NULL default CURRENT_TIMESTAMP
DEFAULT CHARACTER SET ' . $wpdb->charset;

Things the cause problems in my setup:

  • Two spaces after the field name my_lastupdate and the word timestamp.
  • Using int instead of int(11) on my_third_field.
  • Using lowercase CURRENT_TIMESTAMP on my_lastupdate.

Possible Improvements

  • Consider make thing preg_match() case insensitive.
  • Make the comparison on the default case insensitive, or shift the inbound query uppercase.
  • Consider changing the single-space in commands into multi-whitespace regex tests.


Defining Keys (Indices)

The key comparison system is just as strict with whitespaces and case sensitivity as the column comparison routine in dbDelta.   You MUST have TWO spaces after the keywords “PRIMARY KEY” before defining your index field but only ONE SPACE after all other keys.

  •  ALWAYS declare the column names for every key type, including primary key.
  • ALWAYS put your column names inside parenthesis with no spaces.
  • PRIMARY KEY should NEVER have a key name.
  • PRIMARY KEY is always followed by two spaces then the parenthesis then the column name and closing parenthesis.
  • KEY is always followed by a single space, the column name, then a single space then parenthesis around the column name.
  • They keyword PRIMARY KEY must be uppercase.


global $wpdb;
$sql =
'CREATE TABLE my_table (
my_id mediumint(8) unsigned NOT NULL auto_increment,
my_first_field varchar(1) NULL,
my_second_field varchar(255) NULL,
my_third_field int(11) NULL,
my_lastupdate timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY  (my_id),
KEY third_key (my_third_field)
DEFAULT CHARACTER SET ' . $wpdb->charset;

Things the cause problems in my setup:

  • Missing the second space after the PRIMARY KEY definition.

Possible Improvements

  • Consider changing the single-space in commands into multi-whitespace regex tests.
  • Make the indices incoming text for the PRIMARY and KEY keywords force to uppercase.
Posted on

Analyzing WordPress PHP Memory Consumption

XDebug Banner

This weekend I have been processing a large 200,000 location data file for a Store Locator Plus customer.   This is one of the larger files I have processed on my test system and it is the first file over 60,000 locations I’ve processed since Store Locator Plus 4.2 and WordPress 4.x have been released.    This large file processing and the geocoding required is taxing several systems in the Store Locator Plus hierarchy.  WordPress, Google OEM API calls, and the locator are all showing their weak spots with this volume of data processing.   They can all handle it to some degree, but maximizing efficiency is the key.

The temporary solution to most of the issues is to increase memory and process limits.   These are some of the key findings, as posted on the CSV Import documentation pages for Store Locator Plus:

Check your php.ini post_max_size setting if doing a direct file import versus a cron URL based import. post_max_size is typically set to 8 (MiB) on most servers.   This is typically enough for around 25,000 locations but it depends on how long your descriptions are and how many data fields you have filled out.   SLP 4.2.41 will warn you if you try to upload a file larger than your post_max_size limit.

Check your php.ini memory_limit setting and make sure it is large enough to handle the WordPress overhead plus the size of your CSV file times two.   The WordPress database interface and the CSV file processing will consume lots of memory.  The more plugins, widgets, and advanced theme features you have more more memory WordPress will use and the more PHP memory will leak over time. A setting of 256M is enough for approximately 15,000 locations.

Check your wp-config WP_MEMORY_LIMIT.   You may need to add this define to wp-config.php.  define(‘WP_MEMORY_LIMIT’ , ‘256M’).  The number needs to be equal-to or less-than the php.ini memory-limit.    It is the WordPress-specific memory limit and works with php.ini memory_limit.

Check your wp-config WP_MAX_MEMORY_LIMIT.   You may need to add this define to wp-config.php.  define(‘WP_MAX_MEMORY_LIMIT’ , ‘256M’).   This is the WordPress admin interface memory limit and works like WP_MEMORY_LIMIT for admin pages.

Set Duplicates Handling to Add especially if you know you do not have duplicate locations in your data.  SLP 4.2.41 further improves the performance when using ‘add’ mode by eliminating extra data reads from the database.

Set Server-To-Server speed to Fast under the General Settings tab unless you are on a shared host or experience a large number of uncoded locations during import.

Set the PHP Time Limit to 0 (unlimited) under the General Settings tab.   For hosting providers that allow your web apps to change this, the unlimited value will let the import run to completion.

Keep in mind Google limits you to 2500 latitude/longitude (geocoding) lookups per 24 hours per server IP address.  If you are on a shared host you share that limit with all other sites on that host.

However, even with all of these settings tweaked to fairly high values for my VirtualBox development system running on a MacBook Pro Retina host, the 4GB of RAM allocated to WordPress still is not enough.   The system eventually runs out of memory when the file gets close to the 45,000 location mark.  Luckily the “skip duplicate addresses” option allows the process to continue.    The “out of memory” error still rears its ugly head in the wpdb  WordPress database engine and is a problem for handling larger files.

Enter Xdebug and memory profiling.   Somewhere buried in the Store Locator Plus code, WordPress code, PHP MySQL interface, or PHP core engine there is a memory leak.  With a complex application environment finding the leak is going to be a monumental task.  It may not be something I can fix, but if I can mitigate the memory usage when processing large files that will help enterprise-class sites use Store Locator Plus with confidence.

Getting Xdebug On CentOS 7

If you follow my blog posts on development you will know that I run a self-contained WordPress development environment.  The system uses Vagrant to fire up a VirtualBox guest that runs CentOS 7 with GUI tools along with a full WordPress install including my plugin code.   This gives me a 2GB “box file” that I can ship around and have my full self-contained development environment on any system capable of running VirutalBox.   Here is how I get Xdebug connected to my local Apache server running WordPress.

Install xdebug from the yum install script.

# sudo yum install php-pecl-xdebug.x86_64

Turn on xdebug in the php.ini file

# find / -name


#sudo vim /etc/php.ini


Check if xdebug is installed:

# php --version

... PHP 5.4.16
.... with xdebug v2.2.7

Enable some xdebug features by editing php.ini again.

Read about XDebug Profiling.

Read about XDebug Tracing.

# sudo vim /etc/php.ini

xdebug.default_enable=1  ; turns on xdebug any time a PHP page loads on this local server

xdebug.idekey="PHPSTORM" ; in case I turn on the automated listener for built-in PHP Storm debugging/tracing

xdebug.profiler_enable = 1 ; turn on the profiler which creates cachegrind files for stack trace/CPU execution analysis

xdebug.profiler_enable_trigger = 1;  turn on a cookie "hook" so third party browser plugins can turn the profiler on/off with a bookmark link

xdebug.profiler_output_dir = "/var/www/xdebug" ; make sure this directory is writable by apache and readable by your local user

xdebug.auto_trace = 1 ; when any page loads, enable the trace output for capturing memory data

xdebug.show_mem_delta = 1 ; this is what tells trace to trace memory consumption changes on each function call

xdebug.trace_output_dir = "/var/www/xdebug" ; same idea as the profiler output, this will be where trace txt files go

Restart the web server to get the php.ini settings in effect:

# sudo service httpd restart

At this point I can now open any WordPress page including the admin pages.   Shortly after the page has rendered the web server will finish the processing through xdebug and a trace* file will appear in /var/www/xdebug.   I can now see the stack trace of the functions that were called within WordPress with the memory consumption at each call.     This is the start of tracking down which processes are eating up RAM while loading a large CSV file without adding thousands of debugging output lines in the web app.

Be warned, if you are tracing large repetitive processes your trace file can be many GiB in size, make sure you have the disk space to run a full trace.

Posted on

CentOS 7 aapt ELF and Missing Lib

While building an Android Studio app the build failed with aapt errors.   The aapt part of the build started off with a missing error.    Turns out I had already installed the zlib library with yum install so already existed in /usr/lib64/.    The problem was with the library path.   That is easily fixed.

Put these commands in your ~/.bashprofile as well:


However the ELFs were not happy.    For those that don’t know what an ELF error means, it has something to do with byte offsets and library file formats.  Turns out it is a cryptic way of telling you the program is trying to load a 64-bit version of the library it needs instead of the 32-bit version.

Again an easy fix;

# sudo yum install zlib.i686

# LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/;/usr/lib64/;

The .i686 versions of the yum install kits are the 32-bit versions of the libraries.  They are placed in the /usr/lib directory.  Setting LD_LIBRARY_PATH helps the 32-bit dynamically linked executable find the proper link library.

Now on to building this Android app on my CentOS dev box.

Posted on

Unable to run mksdcard SDK tool CentOS

Android Studio Banner

Installing the Android Studio on my CentOS 7 development system went fairly well once I loaded the latest Java JDK from the standard yum repository.   During the install wizard I did run into an issue with a generic “Unable to run mksdcard” error message.    This is the studios watered-down message from the actual command execution.   You can get more details by going to ~/Android/Sdk/tools and running mksdcard from the command line.

# cd ~/Android/Sdk/tools

# ./mksdcard

Here is where I found the compiled executable was missing some 32-bit libraries that are required to run the exe.

bash: ./mksdcard: /lib/ bad ELF interpreter: No such file or directory

A bit of digging and I found I needed glibc, which after another attempt to execute mksdcard told me I also needed  By using yum whatprovides I learned both packages I needed to install.   These additional installs helped get Android Studio up-and-running on CentOS 7.

# sudo yum install glibc.i686

# ./mksdcard
./mksdcard: error while loading shared libraries: cannot open shared object file: No such file or directory

# whatprovides

libstdc++-4.8.2-16.el7.i686 : GNU Standard C++ Library

libstdc++-4.8.2-16.el7.i686 : GNU Standard C++ Library

# sudo yum install libstdc++-4.8.2-16.2.el7_0.i68


With those couple of new libraries installed the Android Studio app is now running on my CentOS 7 development box with the MATE desktop UI.


Posted on

Is phpUnit Good Enough For Testing WordPress?

I’ve been using Selenium IDE to test my Store Locator Plus plugin for the past year.   At nearly every WordCamp I attend I hear about using phpUnit to test “WordPress things”.   I heard about it at WordCamp Orlando during the contributor session; one of the first things Mark Jaquith asked me about a proposed patch to dbDelta was “is there a unit test for dbDelta?”.   If you Google “testing WordPress plugins” it is all about unit tests.

phpUnit is clearly the defacto standard for testing WordPress code.

My First Plugin phpUnit Test

Nine months after talking to Bryan Petty about phpUnit testing at WordCamp Atlanta, I finally got around to adding phpUnit tests to my plugin testing arsenal.   Since Mark provided a few hints on getting WordPress Core code pulled into my development environment I had the necessary tools to get started.    I created a new testing folder in my plugin assets directory, threw in the bootstrap, phpUnit XML directives config file, and added my first unit test class.


* phpUnit Test for SLPlus
* @package PHPUnit\StoreLocatorPlus
* @author Lance Cleveland <>
* @copyright 2014 Charleston Software Associates, LLC
class SLPlusTest extends PHPUnit_Framework_TestCase {

* @var \SLPlus
public $slplus;

* @var int
public $location_id;

* Setup the global pointer to the main SLPlus plugin object.
function setUp() {
$this->slplus = $GLOBALS[‘slplus_plugin’];

* Printout before this test suite runs.
public static function setUpBeforeClass() {
print "\n".get_class()."\n";

* To next line before next test suite runs.
public static function tearDownAfterClass() {
print "\n";

* Is the slplus variable an SLPlus object?
function test_slplus_is_set() {
$this->assertInstanceOf( ‘SLPlus’, $this->slplus );

Fairly simplistic test. It told me that I was on the right path to getting phpUnit tests working with my plugins.

Putting The Test Into Production

I added more tests with more complexity and eventually added phpUnit tests to my WordPress Development Kit production system, a Grunt-based series of scripts I use on my WordPress Development vagrant boxes.

Nice! I now have a low-level code-based system for testing functionality without having to run everything through an IDE. Selenium IDE is great for testing but it is a lot slower for a coder to write test scripts and the logic is far more restrictive.

This is going to be great!

phpUnit Imperfection

Within a few days I found the first chink in the phpUnit armor.

In my Selenium IDE tests I have a series of tests that check to see if PHP warnings like “Notice: Undefined…” , “Fatal error:…” , and other calamities pop up in the browser while running the tests.   Since I am always running with “DEBUG mode full on” on my development boxes, these errors pop up any time I fat-finger the code or have a brain-fart and forget to quote an array index.

While refining my Selenium IDE scripts, by adding rollups to increase consistency among the tests, I purposefully added a common coding error by typing asdf at the top of my base plugin class.    I re-run my Selenium IDE scripts.  They catch the error, exactly as they are supposed to.

Selenium Catches PHP Notices
With the right test command, Selenium makes PHP warnings and notices obvious.

I start wondering… “I wonder what phpUnit will do, I bet it is much faster at catching this sort of thing”.


phpUnit spit out a warning at the very top of the test, which quickly scrolled out of view.   At the end of a long test series I see all my tests passed.    If I didn’t scroll back to the start of the test series I’d never have seen the warnings and notices that were buried in the startup output from the phpUnit testing.

phpUnit Notices Not Errors
phpUnit does not make notices blatantly obvious.

For my personal workflow, where I am constantly multitasking, having those PHP warnings and notices force a proper phpUnit test ERROR would be a far better option.   In “go mode” I am only going to look at the final summary line.   OK (5 tests, 14 assertions)  DONE, WITHOUT ERRORS. If there is a notice or warning I want to see something like “DONE, WITHOUT ERRORS. LOTS OF NOTICES. LOTS AND LOTS OF NOTICES. FIX THEM!!!!”. Maybe not exactly like that, but you get the idea.

True, these were not errors, but a blatant PHP notice spitting out the the screen is not within my code standards.  Yes, it goes away if you do not run in debug mode, but in my world plugin code should not be generating errors, warnings, OR NOTICES.   Not only do they indicate a deeper issue with possible unforeseen ramifications but it often fills up log files, which means writing to disk, which directly affects performance of the WordPress system as a whole.

Doing It Wrong?

Since I am new to phpUnit I may be doing it wrong.

My phpunit.xml configuration:

            <directory prefix="" suffix="Test.php">./</directory>

I even tried this trick to force errors thanks to a hint from Bryan.

The default phpUnit setup and the plugin testing examples online indicate I have the correct setup in place.   My guess is other “phpUnit first timers” will end up with a similar configuration.  A configuration that does a less-than-stellar job of catching PHP warnings and notices.

Selenium IDE Required

Selenium IDE, on the other hand, makes PHP warnings, notices, and errors blatantly obvious if you test for them.   If you are running with debug logging enabled, which you ALWAYS ARE on your dev box because you are a coder that gives a damn, Selenium will flag the output when it is rendered on your WordPress pages.   Selenium highlights the errors in red and reports them in the test summary as failures.   This is something I see even in “go mode”.

Bottom line, I feel as though you must have both phpUnit and Selenium IDE (or Selenium Server) to properly test a WordPress code implementation of any kind.   Not too mention it is nearly impossible, as far as I know, to test advanced JavaScript and AJAX functionality with phpUnit.

Now I am curious:  Does WordPress Core have anything in place to perform similar user-interface testing?  Are they running anything like Selenium IDE to ensure the interface renders as expected?  The CSS is correct?  AJAX calls are running and producing front-end results?   Can phpUnit catch front-end output like errant “Notice: use  of undefined constant” messages when running in debug mode?

I’m sure some of you know a LOT more about this stuff than I do.   Share you knowledge in the comments!

If you want to know more about my Selenium IDE scripts, Grunt production helpers, and Vagrant boxes ping me here as well.   Everything I do is open source and freely available to the WordPress development community.

Posted on

Getting Started With SLPDev Cent 7 Vagrant Box

This article is for the Store Locator Plus development team that is helping maintain the Store Locator Plus plugin family.   It is a basic outline on how to get the SLPDev Cent 7 virtual machine, a private distribution given to qualified developers, personalized and ready for use to start working on the Store Locator Plus plugins.

Get The Box

The first step is to get the latest SLPDev Cent 7 Vagrant box image from Charleston Software Associates.   The image is approximately 2GB and requires a working Vagrant installation on your laptop or desktop computer along with a working install of VirtualBox.   You will use the provided image to create a new VirtualBox machine with the a self-contained GUI development environment for the Store Locator Plus WordPress plugin.

What Is On The Box

The box is configured according to the CentOS 7 WP Dev Kit specification with a few additions.    An ssh key has been configured to provide easy access to the repositories. The WordPress installation has been completed with a site title “SLPDev” and an admin user login of vagrant / vagrant.   You get to the WordPress site by opening Firefox via Applications/Favorites and surfing to http://localhost/.

All of the current Store Locator Plus plugins are installed via the BitBucket git repositories including:

  • Store Locator Plus
  • Contact Extender
  • Directory Builder
  • Enhanced Map
  • Enhanced Results
  • Enhanced Search
  • Event Location Manager (in development, debaat/CSA)
  • Janitor
  • Location Extender
  • Pro Pack
  • Real Estate Extender (in development, aknight/CSA)
  • Social Media Extender (debaat)
  • Store Pages
  • User Managed Locations (debaat)
  • Widgets

The Selenium IDE test suite is installed in the vagrant home directory as is the WordPress Dev Kit with the Store Locator Plus publication scripts.

Personalize The Box

Before starting development you will want to change several identifiers so your code updates can be attributed to you.    You will need to run SmartGit and enter your BitBucket username and password credentials to access the repositories.    You will also want to configure git to set your username and email as the default commit author.

Git / SmartGit Update

Run the following commands from the Linux command line terminal (Applications / Favorites):

git config --global ''

git config --global 'Your Name'

The next thing you should do for SLP development is open the SmartGit repository and pull (rebase, not merge as the default mode) and fetch the latest updates for any plugins you are going to work on.

Posted on

Good git Behavior for the CSA Code Team

Man Branches Banner

I am in the midst of training and evaluating people that are interested in working on the Store Locator Plus code projects.   Some people are veteran coders.  Others are learning coding in a team environment for the first time.    Here are some basic guidelines on using git when working on the CSA codebase that can be useful if you are using git version control for any team project.

Use Descriptive Commit Messages

Your commits messages should be descriptive at least 99% of the time.   These are not good commit messages:

Inline image 1
When the team or project lead goes to integrate your code with the work everyone else has contributed they should have some clue what each commit was doing.     A single word is NEVER a good commit message.   At the very least you should almost always be using a noun and a verb in a commit message.   Debug actions would be at least a little better than “debug”.   Better yet, us a short sentence.

Create Separate Debugging Branches

Since we are on the topic of debug commits, they should rarely be in  your “mainline” branch of code.  Yes debugging happens.    Yes, they often end up in a series of commits on a code branch especially when working on a complex piece of code.  However if you start out with a cycle of coding where you know “I’m going to do a lot of debugging to figure out what is going on here” then it is almost always a good idea to start by creating a new “debug_this_whacky_thing” branch and dumping all your “code barf” in there until you figure things out.
When you do, go back to the “real_work” branch and check that out and put the valuable pieces of code from your learned lessons in that branch.
If you manage to stumble across a useful piece of code on your “testing_stuff” branch you can always add it on to your “real_work” branch with something called “cherry picking”.    That is a git command and in SmartGit is simple to execute.  Checkout the real_work branch, then go select the one or two commits that did something useful from the debugging_code_barf branch and “cherry pick” them.

Commit Often

Small frequent commits are better with just about any version control system and ESPECIALLY when using git.   It tends to create fewer code conflicts during a merge.     This does not mean committing every single line of code on a per-commit basis.   However you should commit every time you write code that changed something and are at a “stopping point”.    Typically this is at the point of “ok I am going to test this now and see if it does what I expected”.    Often it is best to do a “dry run” and make sure there are no blatant errors such as syntax errors before committing.     Try to commit unbroken, if not functional, code.    In other words it should not crash whatever you are working on with an immediate and obvious “your forgot a curly bracket” error.

Use Branches

Like the debugging branch noted above, any time you start a new concept, path,  model, design, or feature start a new branch.   Try to work from a root point, such as the last major release of a product or the last tested-to-be-working version of the software.    Unless your new concept requires the code of a prior effort going back to the root “last working base copy we published” is a good starting point.    The project or team lead will merge code into a prerelease or production (master) branch or an integration branch to create a new product release version.
If you have done work on several feature branches that are not dependent on each other but work better together, create your own integration branch.   “my_super_pack” branch can be a merge-commit of your “feature_a”, “super_awesome_feature”, and “feature_b” branches.

CSA Branch Standards

At CSA I like to use a 3-branch methodology for managing projects.    The branches are master, prerelease, and integration. All 3 branches are only aligned when a new production version is released and there is no ongoing development on the project.
master – always points to the latest production release available to the general public.   This is where the current commit pointer ends up after integration and prerelease phases are complete and the production scripts are executed.  This branch is always tagged with the current production release number.  Developers only start new branches here if a prerelease branch does not exist.
git master branch
prerelease – always points to the latest release of the software that was published to the public in prerelease format.  Prerelease software is not fully tested, though usually has passed the rudimentary functional testing.  this is considered the “beta” version of the next master release.  All CSA Premier Members and beta test groups are given access to prerelease software.    This branch is always tagged with the current software version number, which is bumped if further changes are needed before “going to production”.   Developers almost always start new branches here.
git prerelease branch
integration – this branch points to the current integration branch used by the project manager to pull together developer commits in preparation for conflict resolution and rudimentary software testing prior to being given an official “prerelease” stamp.  This is the release used for internal testing and development and should be considered unstable.    Developers rarely start new code branches on this branch.
git integration branch


Posted on

Setting Up A WordPress Development Environment

Banner Vagrant Cloud WP Dev Kit Box

In preparation for several new projects, some of which are outside of the Store Locator Plus realm, I have been training some new developers in WordPress plugin wizardry.    This article is meant to help new developers get started with my specific Store Locator Plus development environment.    However, most of the steps here will apply to any WordPress related development environment.

Tools Required


VirtualBox is a free virtual machine software package provided by Oracle.   It will allows us to create a self-contained WordPress web server which, when using one of my virtual machine images, will contain a GUI desktop environment with all of the tools necessary to build and distribute WordPress plugins and themes.


Vagrant is a virtual machine management tool.   Vagrant is used to transport virtual machine images, import the machine images, configure the virtual machine hardware, and communicate with VirtualBox to help us get an initial machine running.

Command Line

Some knowledge of OS/X or Windows command line is useful as running Vagrant commands from the command prompt is required.  On Windows you will want to copy the Windows/System32/cmd.exe to a local “where I work on virtual machines” folder on your system and create a shortcut to it that runs in Administrator mode.


The process to get started is simple.    Install VirtualBox, install Vagrant, go to the command line for Vagrant and fetch one of my public VirtualBox environments from the VagrantCloud server, tweak the Vagrant file that manages the config for that box to turn on GUI mode, start the box.

For my developers I provide a custom VirtualBox environment that already has the Store Locator Plus family of plugins as well as access to the code repositories installed.    I will get into that specific setup in a later article.

Getting Started

Download and Install VirtualBox

Download VirtualBox from  When installing and activating VirtualBox for the first time it should ask you to install the Extension Pack.  If it does not, go tot he same link and download and install the appropriate Extension pack as well.

Download and Install Vagrant

Do the same for Vagrant here:    Vagrant will install a command line Ruby processor on your system and may guide you toward installing additional software.   Most of what you need will be contained in the install package.

Setup A Workspace

I recommend creating a folder on your system where you will work with your virtual boxes.   I create a folder under my user home directory named “VirtualBox VMs”.      On Windows you will want to  copy the Windows\System32\cmd.exe into this folder and create a shortcut that runs this in administrator mode.  This will make it easier to run your Vagrant commands without having to constantly change directories.

Fetch A Vagrant Box Image

Vagrant is a virtual machine manager.    It will take various server images and store them in a local repository of virtual machines it controls.    Part of the process here involves getting a copy of a vagrant machine image file onto your local system and adding it to that repository with vagrant commands.

Open your command line on your host system (Windows or OS/X).

Use vagrant to fetch a cloud box.    This is an older box but has a basic CentOS 6.5 configuration with WordPress up and running and some basic GUI dev tools available.    This is a good start for a “clean WordPress development environment”.  Someday I will be publishing another box that has updated software including WordPress 4.0, phpStorm eval in place of NetBeans, and other tools.    For my developers this is a good starting point, however I do have a custom box image that I can provide privately.

At the command line use the following command:

vagrant box add charlestonsw/centos6.5-wordpress-dev-kit-base-box

This will copy a 2GB virtual box image to your system and add it to the list of supported boxes with the label “charlestonsw/centos6.5-wordpress-dev-kit-base-box”. This particular Vagrant image will be linked to the VagrantCloud server and will fetch updates whenever they are available when using a vagrant init command.

Follow the link to see what is in the latest generic WordPress Dev Kit box on VagrantCloud.

Configure The New Box Hardware

I suggest starting by creating a new folder in your “Virtual Box Stuff Here” folder you created earlier for this specific system.  I do this for every new “box” I am going to run.  Create a folder called “WP Dev Kit Test Box” and change into that directory from the command prompt.

Now create a vanilla Vagrant startup file by using this command:

vagrant init charlestonsw/centos6.5-wordpress-dev-kit-base-box

This will create a generic vagrantfile to control the hardware configuration and startup commands for the new virtual machine. Edit that file to turn on GUI mode, set your memory usage, and monitor count. The memory usage and monitor count should be based on your host system hardware. I have 3 monitors and 16GB of RAM on my MacBook Pro so I set my memory to 8MB and monitor count to 2. You should set yours to use about half your RAM and typically leave it at one monitor.

Look for these lines in the vagrantfile and uncomment them:

# Provider-specific configuration so you can fine-tune various
 # backing providers for Vagrant. These expose provider-specific options.
 # Example for VirtualBox:
 config.vm.provider "virtualbox" do |vb|
 # Don't boot with headless mode
 vb.gui = true

 # # Use VBoxManage to customize the VM. For example to change memory:
 vb.customize ["modifyvm", :id, "--memory", "1024"]

Add in your monitorcount only if you are using more than one monitor for the virtual machine:

# Provider-specific configuration so you can fine-tune various
 # backing providers for Vagrant. These expose provider-specific options.
 # Example for VirtualBox:
 config.vm.provider "virtualbox" do |vb|
 # Don't boot with headless mode
 vb.gui = true

 # # Use VBoxManage to customize the VM. For example to change memory:
 vb.customize ["modifyvm", :id, "--memory", "1024"]
 vb.customize ["modifyvm", :id, "--monitorcount", "2"]

Start The Box

Still in command line, use this command to start up the new box. This will pull the box image out of the Vagrant repository and copy it into VirtualBox for use, then talk to VirtualBox and tell it to start running the new virtual machine.

vagrant up

This process may take some time. It takes 3-4 minutes on my SSD on a new MacBook Pro but took about 15 minutes on my older Windows laptop.

VirtualBox CentOS 6.5 GUI Base Box
VirtualBox CentOS 6.5 GUI Base Box

Using The Virtual Machine

System Login

Once the new box is up and running you can login with the generic user “vagrant” with a password of “vagrant”.

CentOS 6.5 Vagrant Login Banner

Surfing Local WordPress

On the new system GUI you will have Firefox installed along with basic development tools. You can bring up the local WordPress site by opening firefox and surfing to http://localhost/


Geek Details

The default user you work with is named “vagrant”.     It has access to most of the things you need on the server.   The vagrant user is part of the dev group, as is the Apache user that runs the local web server.   All of the web files are group-write enabled which means both Apache and your vagrant user can access them.

WordPress lives in the /var/www/html folder.
Plugins are in /var/www/wpslp/wp-content/plugins.

The super user is “root”.   It has the same password as the vagrant user.

You should go to System/Administration/Software update and check for system software updates.   Install the updates.

Since these are the generic Vagrant-style access credentials I strongly recommend you do not put your virtual machine on a public network.  By default it should only be accessible to your host system and should not be visible to the general network but you will want to check that.


If I have missed a step or something is not working as you expect please leave a comment on this article.   You will need to be a registered user so purchase the free “Forum Registration” on this site to get a user account.

Posted on

Vagrant : Testing WP Plugins On Multiple PHP Versions

SLP on PHP 5.5.13 with Vagrantfile Banner

If you’ve followed my prior blog posts you already know that I’ve been playing with Vagrant this year in an effort to improve my workflow.   To date the biggest impact of the improved workflow is being able to recreate my self-contained WordPress plugin development system which runs a full GUI dev environment on CentOS 6.5.     While that has been great for recovering from poorly designed laptop hardware, I am not really leveraging the power of Vagrant.

Today I have a new need and thus a new reason to extend my education in Vagrant.  The WordPress plugins I develop need to function in older versions of PHP.    If I write my plugins using PHP 5.5 then I run the risk of using functions that only work in newer versions of PHP.  Since the WordPress baseline is PHP 5.2 that will prevent some percentage of users from using my plugins.    By the same token, many users run newer versions of PHP that have deprecated functions.    In those cases using PHP 5.2 specific functions will not work for those customers, again limiting my overall market.  The ultimate goal is to write my plugins so they operate properly in PHP 5.2 up through the latest version of production which currently sits at version 5.5.

Vagrant is the right tool to get this job done.

Cloudy Vagrant Boxes

Up until today I have had a baseline WP Dev Kit Vagrant box, a “Vagrantized” version of my “uncluttered” Virtual Box system that has all of the tools I like to use when writing plugins.    The box is stored on my Google Drive and served via proxy from the VagrantCloud service.    Since that is the default location for the built-in Vagrant commands that is a good place to start.

The problem is that any time I need to create a new box it has to pull down a fairly large file from Google Drive to my local box.  Depending on how much throttling the ISPs are throwing in the mix between Google servers and my house it can take anywhere from 20 minutes to 20 hours to get the file in place and spin up my box.

I need something faster.    Local drive access will suffice for this latest project and Vagrant has methods to do just that.

Making It Local

To start things off I am going to make a copy of my latest fully-baked virtual box.    This is a box that started as a vanilla WP Dev Kit box I pulled down from Vagrant Cloud and over the past month have layered on all of my code and other “special tweaks” that only I am interested in.    To make it something Vagrant can “manhandle” I need to convert the full box into a Vagrant box format.

My VirtualBox Machine Names
My VirtualBox Machine Names
vagrant package --base &quot;SLP Dev Box 2.0&quot;

Now I have a full copy of my current running plugin development machine complete with updated code repositories, special data sets, and other “goodies” I am in the progress of building. Now I want to clone this “vagrant style” so I can set up a series ofprovisioning commands to alter the environment “on the fly”.

I create a new directory on my Windows box and initialize a new Vagrant box with the following commands:


[box type=”alert”]Make sure you are updated to the latest version of Vagrant when you run these commands.  If you are upgrading from Vagrant versions prior to 1.6 on Windows you will want to fully uninstall Vagrant 1.x, delete the C:\Hashicorp directory and install the latest version.  A reboot is required after  the update.[/box]

vagrant box add --name slp_2_0 &quot;C:\blah\blah\blah%20blah\one_dir_up\;

The above command adds the file that was created from the virtual box with my operating environment to the list of locally available Vagrant box images.   This will make it easier to spin up new boxes and provision updates via the Vagrant shell, or other Vagrant provisioner, commands.

The command puts the file into a usable format for Vagrant and assigns the label slp_2_0 for easier reference.

You can check your Vagrant box was added properly using the following command line command:

vagrant box list
Vagrant Box List
Vagrant Box List

Day 6 : Cloning

In case you missed it, that is meant to be a clever reference to The 6th Day… a movie about clones of former state politicians, or something like that.    No, we are not cloning politicians.  Who in the hell would want to do that?!?!    Instead we are going to clone something that is actually useful to us… the original “Vagrantized” development box.

I am going to create a new directory where I can setup my Vagrantfile and related scripts to configure the base OS and software utilities to my liking for a new test case.  In this case I want all the stuff on my main box plus some updates to PHP.

I’m sure that there is a shortcut to elminate the Vagrantfile editing by packaging the original box’s Vagrantfile in the base package but that will be a task for another blog post.

mkdir slp_2_0_with_php_5_5

vagrant init slp_2_0

This creates a Vagrantfile in the new folder that I need to edit to use the GUI.  I follow my prior post on the subject and modify the Vagrantfile.  I turn on the GUI interface and also force the display count to 1.

  config.vm.provider &quot;virtualbox&quot; do |vb|
    # Don't boot with headless mode
     vb.gui = true

    # Set to one monitor
    vb.customize [&quot;modifyvm&quot;, :id, &quot;--monitorcount&quot;, &quot;1&quot;]

Provisioning : The Magic Sauce

Provisioning was the last part that I needed to get in place and it took me a few tries to get it right. It is stupidly simple once you know what it is doing and how to get the commands in the right place.

The examples on the Vagrant site are a good start but are not very clear when viewing them within the context of a pre-existing Vagrantfile.    My first test is the “dump the date to a text file” test case are presented on the Vagrant site.   This will write the full date into a file named “provisioned_at”.

For this to work  you MUST have an authorized_keys file in your root user directory.   The shell provisioner logs in as ROOT.  That is important to note as I was looking inside of the “vagrant” user directory which is the one I use for my daily editing.

You will also want to place the provision commands inside of the main Vagrant.configure block to be consistent with the default Puppet, Chef, and other examples.     Below is my entire Vagrantfile with all of the comments boiled out so you can see how simple this can be.


Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| = &quot;slp_2_0&quot;

  config.vm.boot_timeout = 600

  config.vm.provider &quot;virtualbox&quot; do |vb|
    vb.gui = true
    vb.customize [&quot;modifyvm&quot;, :id, &quot;--monitorcount&quot;, &quot;1&quot;]

  config.vm.provision &quot;shell&quot;,  inline: &quot;date &gt; provisioned_at&quot;


When the system boots it will write the current date to the root home directory. If you login as vagrant you can run the sudo command to see the file:

# sudo cat /root/provisioned_at

Upgrading PHP With Provisioner

Now that the basics are working we can use some shell command sequences to force the vagrant up command to upgrade PHP when the box boots. The Vagrantfile will instruct Vagrant to take a copy of my slp_2_0 box and spin it up as a new cloned virtual machine in VirtualBox. When it finishes booting it will run the yum update command, fetch the yum repository for Webtatic that provides access to the PHP 5.5 repo for CentOS 6.5, remove the old version of PHP 5.3, install PHP 5.5 with the MySQL hooks, and restart Apache. When it is done I have a fully copy of the SLP development environment but running on a PHP 5.5 instead of PHP 5.3 install.

SLP on PHP 5.5.13 with Vagrantfile
SLP on PHP 5.5.13 with Vagrantfile

Here is my Vagrantfile to accomplish that:

# Run SLP 2.0 Box
# with PHP 5.5 instead of PHP 5.3


Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| = &quot;slp_2_0&quot;

  config.vm.boot_timeout = 600

  config.vm.provider &quot;virtualbox&quot; do |vb|
    vb.gui = true
    vb.customize [&quot;modifyvm&quot;, :id, &quot;--monitorcount&quot;, &quot;1&quot;]

  config.vm.provision &quot;shell&quot; do |s|
    s.inline = &quot;date &gt; provisioned_at&quot;
    s.inline = &quot;yum -y update&quot;
    s.inline = &quot;rpm -Uvh ;
    s.inline = &quot;yum -y remove php-common&quot;
    s.inline = &quot;yum -y install php55w&quot;
    s.inline = &quot;yum -y install php-mysql&quot;
    s.inline = &quot;service httpd restart&quot;

Posted on

Improved Grunt Tasks for the Vagrant WordPress Dev Box

Grunt WordPress Dev Kit

Last week I found myself having to rebuild my WordPress plugin development box after a “laptop fiasco”.   While it was a lot of work it feels as though I am in a better position to not only recover my environment quickly but also distribute it to other developers that are interested in assisting with plugin development.

If you are interested you can read more about it in the related WordPress Workflow and related WordPress Development Kit articles.

This morning I realized that having a new almost-fully-configured Vagrant box for my WordPress Development Kit allows me to make assumptions in my Grunt tasks.    While it would be more flexible to create options-based tasks where users can set their own configuration for things like MySQL usernames and passwords, the WP Dev Kit Vagrant box assumption allows me to bypass that for now and come back to it when time allows.  Fast turnaround and fewer interruptions in my already-busy work flow is paramount this week.

Today’s WordPress Dev Kit Updates

The official tag I’ve assigned to the newest WordPress Dev Kit is version 0.5.0.  Here is what has been added.

WordPress Database Reset

One of the tasks I do fairly often is to “clear the data cruft” from my development box WordPress tables.  I  accomplish this by dropping the WordPress database and recreating it.

The Vagrant box makes this far easier as I know that when I spin up the WP Dev Kit Vagrant box it already has the WordPress MySQL tables setup.  I also know the username and password.  As such I can execute a simple drop/create table as the privileges are already in place in the meta data for MySQL and will carry over.   Thus I only need to execute a single mysql-cli command to get the data reset.

To get this working in Grunt I added the grunt-ssh module and created a ‘resetdb’ target.

I can now reset my WordPress table with a simple grunt command:

$ grunt shell:resetdb

Online Documentation

The other change I made today will help me remember how the heck all this stuff works.  Now that the dev kit has grown to a couple of commands I know I will soon be forgetting the nuances to certain build and workflow processes.   I started creating my own Markdown files I realized that Bitbucket has a system for using .md files on the repository wiki.    The easy solution was to add the Bitbucket wiki as a submodule to the WP Dev Kit repository and edit the file there.    Doing so means that any doc update will also be published immediately when pushed back to the repo at the WP Dev Kit Bitbucket Wiki.

Now back to getting the Store Locator Plus and Enhanced Results first-pass testing run and prerelease copies published for my Premier Members.

Posted on

Installing Sass on CentOS 6.5

SLP Sass Banner

I just discovered that Sass is missing from my WordPress Development Kit Vagrant box.   My Vagrant box is on the latest CentOS 6.5 release and, luckily, setting up Sass is very simple for vanilla CentOS 6.5 users.  It is literally a two-step process:

$ sudo yum install rubygems
$ sudo gem install sass

Now I can add this to the NetBeans executables configuration by adding the path /usr/bin/sass.

Configuring Sass in NetBeans
Configuring Sass in NetBeans

Now I can edit my .scss files and have the corresponding .css files auto-generated right from NetBeans.  Nice!

Posted on

WordPress Development Fresh Start with Vagrant and Grunt

Banner Vagrant Cloud WP Dev Kit Box

HP finally did it.  They came out to replace a system board in my laptop and half of my files on my drive are corrupted.  Restoring the 70GB of corrupt files from the local USB3 backup will take some time and I am not 100% confident in the reliability of this system.   With 48 hours of downtime I decided it would be best to push forward with my Vagrant and Grunt setup for the WordPress Development Kit I’ve been working on.

Employing Vagrant

I am using VirutalBox and Vagrant to build a series of base boxes on which to layer my development environment.  Unlike most base boxes that are plain vanilla OS installs that then use provisioners to install all the software layers on top of the OS, my custom base boxes are going to be installed with all the base tools I need to develop WordPress plugins using my WordPress Development Kit tools.


Because it is far faster to download a compressed virtual machine image with most of my stuff installed  than to download a very similar image with no tools then have Vagrant go and download  a few dozen install kits.   Sure, the standard method is more flexible and ensures everything is up-to-date, but that is not what I am trying to accomplish here.    I am building a “fast start” box that has most of what you need pre-installed in a known environment.

I also want to have a method to deploy new virtual boxes with everything in place on my OS/X system, a different laptop, or even a cloud-based server the next time my HP laptop is smoked.  Which will probably be tomorrow.      As I’ve found, restoring a large image even from a local USB3 drive is not a quick process and it is not foolproof.   Especially when going from a Windows 8.1 based backup and restoring on an OS/X system that has not been patched or updated in 8 months.


Since I already have Vagrant installed and have a published base box I am able to get started quickly.   Once Vagrant is installed I only need to set my Vagrantfile, a script that tells Vagrant what to do, to pull down the base box from the URL I have published on Vagrant Cloud:

  • Create a folder on my host system named “C65 WP Devkit  Box Setup”.
  • Create the Vagrantfile, in that directory with the pointing to charlestonsw/centos6.5-wordpress-dev-kit-base-box.
  • Open the command line for Windows and go to that C65 WP Devkit Box Setup directory.
  • Run the vagrant up command.
My new Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don’t touch unless you know what you’re doing!
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| = "charlestonsw/centos6.5-wordpress-dev-kit-base-box"
config.vm.provider "virtualbox" do |vb|
vb.gui = true


When you boot the WordPress Dev Kit Base Box with Vagrant you will find that the full CentOS GUI is active. You can login to the GUI using the standard vagrant username with a password of vagrant.

WordPress 3.9

You will find a Firefox icon on the menu bar. Opening Firefox will open the http://localhost/ URL which brings up the local copy of WordPress 3.9 that has been installed.

MySQL for WordPress

The MySQL database has been configured for WordPress.

Database name: wordpress
MySQL User: vagrant
MySQL Password: vagrant

NetBeans 8.0

NetBeans 8.0 has been installed with the PHP and HTML 5 support packages.   NetBeans is a great no-cost IDE that I have found to be very useful for editing structured WordPress PHP code.   Write your code using an object oriented design and add a good amount of phpDoc commenting and NetBeans becomes a coding power tool for WordPress plugin coding.


Firefox is installed along with several add-on packs that I use for every day code management and development.  It includes Firebug to look at JavaScript, CSS, and HTML construction.   Selenium IDE is included which allows me to download and execute my web-interface based test scripts for Store Locator Plus.   LastPass is installed to provide unique long-string passwords to all of my web services.

WordPress Development Kit

My command line WordPress Development Kit is installed on the system under the vagrant user home directory in ~/wp-dev-kit. This comes with the basic Grunt build tasks I use to manage my plugins. While you can edit the ~/wp-dev-kit/grunt/plugins.json file and configure this for your site it is recommended that you create a fork of my WordPress Development Kit on the Bitbucket site and work from your forked repository. I would remove the wp-dev-kit directory with rm -rf and clone your forked copy into the same location.

The easiest method for cloning a public repository is to use git clone with the https repository path. If you have a private repository you may want to create a SSH key pair by going to ~/.ssh and running ssh-keygen. The key will need to be added as an authorized SSH key in your Bitbucket account access management list.  Since I will be pushing and pulling content from my various Bitbucket git repositories I will use this method when setting up my clone of the WP Dev Kit Basic Box.

Bitbucket HTTPS Path
Bitbucket HTTPS Path

Similar methods can be employed with Github repositories.

Preparing For Development

These are elements that will eventually go into a provisioner setup for the Vagrant box, assuming that at least one of the Vagrant provisioning services can hand user prompts and communication with third party services.

Create Your SSH Key

This will make it easier to push & pull content from your repositories.

cd ~/.ssh
xclip -sel clip &lt; ~/.ssh/
Setting A Vagrant SSH Key
Setting A Vagrant SSH Key

Login to your Bitbucket account, go to my account / access management, add the copied SSH key.

Bitbucket Add Vagrant Key
Bitbucket Add Vagrant Key

 Configure Your Git ID

git config –global “Lance Cleveland”
git config –global

Add SmartGit

I like the GUI interface that SmartGit provides over the git command line and gitk branch rendering.  I find SmartGit to be twice as efficient for my method of work flow over the built-in IDE and command line, so I always install this next and clone my base projects like the WP Dev Kit and my Selenium IDE scripts.   Today I am using the SmartGit 6 beta release as I find the project grouping and new interface design to be a big help in managing my projects.

SmartGit UI
SmartGit UI

I immediately setup SmartGit and clone my Selenium IDE repository so I can complete the next step with a script.

SmartGit Bitbucket Setup
SmartGit Bitbucket Setup

Complete The WordPress Install

Open Firefox and go to http://localhost/

Enter the WordPress local site information for your test site.  I use my Selenium IDE new site install script to handle this for me.

Selenium IDE setting up a  new WordPress install.
Selenium IDE setting up a new WordPress install.

Ready To Go

Now my system is ready to go.   I can start cloning my plugin code repositories into the ./wp-content/plugins directory, edit code with NetBeans, commit changes with SmartGit, and publish to my server or the WordPress plugin directory using my Grunt scripts.

With the current configuration it takes me 15 minutes to pull down a new clone and get the box booted then 5 minutes to install and configure SmartGit, clone my repository, run the WordPress install script, and fetch my first plugin repo.   20 minutes from “nothingness” to writing code.    With a local .box file on my system that time is cut down to about 8 minutes by avoiding the 1.5GB download of the box.

Not bad.

Now on to the code…