Create bullet-proof integration tested WordPress plugins with CakePHP
First copy WordPress in a new directory that is being served by your webserver. Next create your WordPress database to use, along with the test bed that will be used by CakePHP.
Edit your WordPress configuration with the above details (you don’t have to use wordpress_tests at the moment). You’re just doing a regular WordPress install.
The next step will largely depend on your URL scheme. For now, we’ll create a folder simply called “cake”. After installing CakePHP, change the database configuration file with the details of the two databases that you created earlier. At this point what you should have is a WordPress install with a CakePHP installation under the /cake directory. For our simple application, we’ll create a page that adds a WordPress user, if they give the page a specific password. This will then be unit-tested using CakePHP. To do this, we’ll create a Memberships controller. Often it is easier to type in the URL first, to make sure that CakePHP is working: http://testing.local/cake/memberships/add gives, “Error: Create the class MembershipsController below in file: app/Controller/MembershipsController.php”. So we create this class:
Now we get with “http://testing.local/cake/memberships/add”, “Error: The view for MembershipsController::add() was not found.” So lets add the view:
Then we want to create a simple Model for our data validation, so that the view can work.
Now for the interesting part. By providing CakePHP with details of the underlying database tables, it can dynamically (re-)create the entire database for use in unit tests. I’ve already created the ORM models, building on an earlier project, that you can use in your project. You can also populate the tables with seed data using CakePHP’s fixtures. The only caveat is that you can’t use expect WordPress’s own database functions to connect to the dynamic database that CakePHP creates. They will connect to the database configuration as specified in your wp-config.php file. However in most situations, you can work around this.
So how do you mesh WordPress and CakePHP without namespace conflicts? The answer is to add WordPress at the following points:
You can check it works with a simple test. Firstly, login to WordPress, secondly add this line to your add.ctp page:
You should see details of your current user display on screen. If this works, then you can use all the WordPress functions from within your CakePHP application. To connect to the WordPress database, however, you need to create models that tell CakePHP how to interact with the WordPress database. This is a time-consuming process, so helpfully I’ve already done this work for you.
And make sure that the plugin is loaded with the following line to your bootstrap.php file:
Now let’s get to the interesting bit and create our application that registers a new WordPress user if they know the secret password. Let’s return to our MembershipsController and add the following:
The code should be fairly self-explanatory if you have used CakePHP before. We just use some extra WordPress functions, so that the user is automatically added to be a “Contributor”, and of course use the WordPress password hashing function. Note that we are not using WordPress’s wpdb object to save to the database, so it will work with CakePHP’s dynamic fixtures. So let’s have a go at unit testing this. (If you don’t have phpunit installed, follow my earlier guide).
Here we have two unit tests: one that tests a successful membership account creation, the other checks that our validation is working. Its quite neat as through our fixtures, CakePHP can create an entirely new WordPress installation with each test function. There is nothing here that is really new if you are familiar to CakePHP unit testing, apart from the following:
This is used as WordPress loses track of its own database connection between the tests. You shouldn’t need it unless it is too awkward to create a CakePHP abstraction for everything that WordPress does. I was using a third party library that created codes, and checked the database to make sure that its code was unique, which created an error, as it was losing the connection.
This meant that my code was not completely isolated, but I was OK with this trade-off. You can actually remove these two lines if you want, but I thought I would keep them in just in case you found yourself scratching your head, trying to work out why your first test ran perfectly, when all the other tests fall over.
So there you go. Now you can create bullet-proof WordPress plugins using all the functionality you know in CakePHP. I can imagine this might come in handy when you need to do some heavy-lifting using CakePHP, then just displaying the results with a traditional WordPress plugin.