post

Grunt Automation for WordPress developers

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on Reddit

This is the third article in a series of developing for WordPress in a DevOps friendly way. The previous articles:

  1. Introduction to WordPress and DevOps
  2. Developing with WordPress and Vagrant
  3. Grunt Automation for WordPress developers
  4. WordPress configuration management

In the previous two posts we’ve had a look at the various tools we need to create an automated workflow for developing and a little bit about how Vagrant can be used to create a better development environment. We’ve also briefly touched on using Grunt and wp-cli to automate setting up WordPress inside the environment. In this post we’ll dive deeper into how to use Grunt to automate even more of the WordPress setup.

There’s a Git repository available with code for this post here: https://github.com/eriktorsner/gruntautomationforwp I suggest you clone or download the code to your development computer to make it easier to follow along.

What’s our goal?

In short. We want to run a single command at the command line to install WordPress, all our wanted plugins and other vital pieces of configuration. The end goal is to automate it to the extent that it can be part of a fully automated, non-interactive, deployment process.

Looking back at the first post in this series I talked a bit about DevOps and how it’s a bit of a challenge to make WordPress a good fit for it. Automation is one of the cornerstones within DevOps and historically WordPress has been more focused on getting up and running quick than on supporting an automated workflow.

Well, that changed entirely when wp-cli came onto the scene a few years back. Wp-cli stands for WordPress command line interface and is a project that aims to enable automation of WordPress management. Wp-cli makes it possible to automate installation, setup, theme and plugin installations and a lot of other common WordPress management tasks like modify settings or even add pages and posts.

The other part of the automation work will be carried out by Grunt. Grunt is a “modern JavaScript task runner” and allows us to create tasks that can be executed from the command line. So we can create a task “wp-install” that uses wp-cli to install WordPress and run that task from the command line using a simple “grunt wp-install”. The most common use case for Grunt is to run things like css and javascript minification or compile SASS file to css. But we’ll use Grunt mainly as a task runner for DevOps related tasks. That doesn’t stop you from using Grunt for those other things as well which may be a very good idea for your project.

Creating the environment

In the previous post, we covered how to get started with Vagrant. To follow along in this post I’m assuming that you’ve read that post and have installed the prerequisites for running Vagrant on your development computer. I’ve made a separate Github repository available for this post, so from now on when I’m talking about specific files, I’m referring to the ones you can find in the git repo at https://github.com/eriktorsner/gruntautomationforwp. If you have any problems following these steps, be sure to read up on the previous post and post any questions in the comments below if you’re still having issues.

A quick checklist to get you started with this Vagrant box

  1. Edit Vagrantfile (hostname, dns names and ip-numner) to fit in your environment
  2. copy localsettings.json.template to localsettings.json
  3. Run “vagrant up” to initialize the new machine”
  4. Go to folder /vagrant inside the virtual machine and run “npm install”

Wp-cli + Grunt

To show what Wp-cli can do in terms of automation, we’ll use it to perform the following tasks:

  1. Install WordPress
  2. Install and activate a few plugins from the official WordPress repo
  3. Change a few settings

As we’ll be doing this by automating wp-cli via Grunt. Let’s have a look at the important parts of the Grunt file that comes with this post (see the top of the post for information on how to get it). The first thing to notice is on 32 where we define the function getLocalSettings, a simple helper function.


function getLocalsettings(test) { 
    ls = grunt.file.readJSON('localsettings.json'); 
    if(ls.wppath === undefined) ls.wppath = shell.pwd() + '/www/wordpress-default'; 
    return ls; 
}

We’ll use this function in each of our Grunt tasks that deals with wp-cli so that we can get the parameters we define in localsettings.json into action. Let’s look at the settings file to get a hunch of what kind of parameters we’re including


{
    "environment": "development",
    "url": "www.gruntautomationforwp.local",
    "dbhost": "localhost",
    "dbname": "wordpress",
    "dbuser": "wordpress",
    "dbpass": "wordpress",
    "wpuser": "admin",
    "wppass": "admin",
    "wppath": "/vagrant/www/wordpress-default"
}

 

The idea is to have anything that is specific for this specific machine should be a parameter in this file. And the point of having settings in a json format is that json can be easily accessed both from javascript code like in the Gruntfile and in PHP code as well.

Let’s look at the first task defined, the default task:


grunt.registerTask('default', 'Log some stuff.', function() {
    ls = getLocalsettings();
    grunt.log.write('localsettings successfully read URL=' + ls.url).ok();
});

It will simply read the settings file and output the URL parameter from it, so it’s a simple test. Let’s try it within the Vagrant machine:

$ cd /vagrant
$ grunt
Running "default" task
localsettings successfully read URL=www.gruntautomationforwp.localOK

Done, without errors.

The next task to look at is the wp-install task, it’s a bit more interesting:

 /*
 * Installing WP
 */
 grunt.registerTask('wp-install', '', function() {
     ls = getLocalsettings();
     wpcmd = 'wp --path=' + ls.wppath + ' --allow-root ';

     shell.mkdir('-p', ls.wppath);

     if(!shell.test('-e', ls.wppath + '/wp-config.php')) {
         shell.exec(wpcmd + 'core download --force');
         shell.exec(wpcmd + 'core config --dbname=' + ls.dbname + ' --   dbuser=' + ls.dbuser + ' --dbpass=' + ls.dbpass + ' --quiet');
         shell.exec(wpcmd + 'core install --url=' + ls.url + ' --title="WordPress App" --admin_name=' + ls.wpuser + ' --admin_email="admin@local.dev" --admin_password="' + ls.wppass + '"');
     } else {
         grunt.log.write('Wordpress is already installed').ok();
     }
 });
  • Line 18 is just loading the localsettings as we saw above
  • Line 19 creates the base string for the wp-cli command. Note that we’re adding the switch –allow-root since this task is likely to be executed by root in a different environment like production. We’re also adding the –path switch which will instruct wp-cli to install WordPress in a sub folder.
  • In line 23 we’re checking if WordPress is already installed or not.
  • Lines 24 to 26 are executing the wp-cli commands “core download”, “core config” and “core install”.

There are a few interesting things to note. The first is obviously that after running this task we’re going to have a fully functioning WordPress installation in a sub folder. All parameters we needed are kept in a separate file which is fundamentally good for our efforts to make this a fully automated WordPress install. We’ve also managed to install WordPress in a sub folder that is explicitly kept out of source code control.

The reason for that is that WordPress in not our code, it’s a depencency to us. We want to avoid adding dependencies in our source code tree (look inside .gitignore, we’re explicitly ignoring the www sub folder) for several reasons. But the most important reason is not size or bloat, it’s the ability to handle upgrades well. WordPress and it’s extensions are upgraded frequently with major and minor upgrades. If you add all the source code for WordPress, themes and plugins into your own source code tree, you will be stuck with the task of upgrading them once new versions arrive, and they do quite often.

A clean separation between your own code and the dependencies means that you can easily test your code with the newest versions of each dependency. If your code breaks as a result of upgrading one of the third party plugins, the clean separation and automated setup makes it super easy to test and fix any such problems before you upgrade anything in production. That’s a big deal.

So, back to our example, let’s run the wp-install task:

$ grunt wp-install
Running "wp-install" task
Downloading WordPress 4.3.1 (en_US)...
Success: WordPress downloaded.
sh: 1: /usr/sbin/sendmail: not found
Success: WordPress installed successfully.

Adding more dependencies

Obviously, we’re going to need more dependencies. Let’s add a few plugins from the WordPress plugin repository. This is done with the wp-cli command “plugin install”. Let’s look at the next task in Gruntfile.js:

/*
* Setting up WP
* 
*/
grunt.registerTask('wp-setup', '', function() {
    ls = getLocalsettings();
    wpcmd = 'wp --path=' + ls.wppath + ' --allow-root ';
	
    // some standard plugins
    stdplugins = ['if-menu', 'baw-login-logout-menu','google-analyticator'];
    for(i=0;i<stdplugins.length;i++) {
        name = stdplugins[i];		
        shell.exec(wpcmd + 'plugin install --activate ' + name);
    }
})
  • Lines 37-38 are similar to the wp-install task
  • Line 41 sets up an array of plugins we want to install
  • Lines 42-45 iterates that array and creates a wp-cli command that installs and activates all the plugins in the array.

So no more manual plugin installations in the WordPress admin area! Let’s run the Grunt wp-setup task:

$ grunt wp-setup
Running "wp-setup" task
Installing If Menu (0.3)
Downloading install package from https://downloads.wordpress.org/plugin/if-menu.zip...
Unpacking the package...
Installing the plugin...
Plugin installed successfully.
Success: Translations updates are not needed for the 'English (US)' locale.
Activating 'if-menu'...
Success: Plugin 'if-menu' activated.
Installing Login Logout Menu (1.3.3)
Downloading install package from https://downloads.wordpress.org/plugin/baw-login-logout-menu.zip...
Unpacking the package...
Installing the plugin...
Plugin installed successfully.
Success: Translations updates are not needed for the 'English (US)' locale.
Activating 'baw-login-logout-menu'...
Success: Plugin 'baw-login-logout-menu' activated.
Installing Google Analyticator (6.4.9.6)
Downloading install package from https://downloads.wordpress.org/plugin/google-analyticator.6.4.9.6.zip...
Unpacking the package...
Installing the plugin...
Plugin installed successfully.
Success: Translations updates are not needed for the 'English (US)' locale.
Activating 'google-analyticator'...
Success: Plugin 'google-analyticator' activated.

Done, without errors.

Working with settings

The last part I’m going to cover in this post is a little bit on how to manipulate WordPress settings. Wp-cli is not the only option we have to get settings from a text file (code) into a live WordPress installation, but since wp-cli can do this, let’s have a look at how.

Most settings in WordPress are stored in a table named wp_options (assuming you’ve kept the standard “wp_” table name prefix). In order to change any of those settings via wp-cli, we first need to figure out what the various settings are called. Wp-cli have a sub command “option” that lets us list, add, delete or modify settings. For instance, if we want to change the settings “Site title” and “Tagline” we could use wp-cli to list all options and search for the options we want to find. In the wp-install task, we set the string “WordPress App” as the title, lets search for it:

$ cd /vagrant/www/wordpress-default/
$ wp option list | grep 'WordPress App'
blogname	WordPress App

Ok, there’s only one single row in the options table with that string, so we can safely assume that the option called “blogname” corresponds to Site title. Let’s look for the tagline, we haven’t changed it yet in our test installation, so it should still read “Just another WordPress site”:

$ wp option list | grep 'ust another WordPress site'
blogdescription	Just another WordPress site

Right. The parameter tagline that we can control in the WordPress admin is found in the option named “blogdescription”.

Knowing what the options are called makes it possible to set them via wp-cli. We can add a few lines to the wp-setup task:

    shell.exec(wpcmd + 'option update blogname "Another title"');
    shell.exec(wpcmd + 'option update blogdescription "experimental tagline");

Running the wp-setup task again, we should now see:

$ grunt wp-setup
Running "wp-setup" task
Warning: if-menu: Plugin already installed.
Activating 'if-menu'...
Warning: Plugin 'if-menu' is already active.
Warning: baw-login-logout-menu: Plugin already installed.
Activating 'baw-login-logout-menu'...
Warning: Plugin 'baw-login-logout-menu' is already active.
Warning: google-analyticator: Plugin already installed.
Activating 'google-analyticator'...
Warning: Plugin 'google-analyticator' is already active.
Success: Updated 'blogname' option.
Success: Updated 'blogdescription' option.

Done, without errors.

Note that wp-cli won’t attempt to reinstall the plugins that are already activated but instead just sends a warning saying that it’s already there. The last few lines tells us that the blogname and blogdescription settings are now updated to their new values. Mission accomplished.

 

Summary

In this post, we’ve taken another few steps towards gettings WordPress under our control. We’ve discussed the reasons why we want to treat WordPress itself as well as any third party extensions as dependencies rather than a part of our own application. Not in the sense that the code we develop would work well without WordPress and the plugins, but because we need to keep them out of our code base for upgrading and testing reasons.

In future installments in this series, we’ll dive into dealing with content and try to find ways to make WordPress separate content and content. If that sounds weird or if you’re just the curious anyway, stay tuned for the next episode. In the mean time, share insights, questions or other feedback in the comments below.

WordPress DevOps – The book

I’ve written an ebook on this subject. Released in September this year on Leanpub.com. Expect a 100+ tightly written pages where we walk through the creation of the skeleton of a WordPress based Saas application, connected to Stripe and Paypal with a working deployment process that takes content into account. Just add your billion dollar idea. Jump on over to Leanpub to get your copy.

WordPress DevOps - Strategies for developing and deploying with WordPress

WordPress DevOps – Strategies for developing and deploying with WordPress

 

 

 

 

 

 

 

[wysija_form id=”3″]

eBook on WordPress development and deployment

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on Reddit

Advanced WordPress development

Last weeks I’ve been busy finishing up an eBook with the kind of straight forward title: WordPress DevOps – Strategies for developing and deploying with WordPress It’s a 100 page guide covering how You can get WordPress to work a little bit better in a proper development process, covering automation, testing and deployment.

If you’re interested, click here or on the book cover above to head on over to Leanpub and sign up for it. You’ll get an email as soon as it’s available for download. And yes, it will be available in pdf, epub and mobi formats. When you do sign up, please share your email address with me, I’d love to be able to stay in touch with you.

post

WordPress profiler

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on Reddit

memory_added

This post is part two of a mini series where I (1) explain why keeping track of WordPress load timing is important and (2) discuss how WordPress load time profiling can be done using a newly created plugin. If you want to skip the chatter and go straight to the plugin, you can download it here.

I’ve updated my load time profiling plugin a little bit over the weekend. There are now two new features:

  1. The output will show you memory consumption at each log point
  2. The plugin will trace time spent in each function called via an ‘add_action’ callback.

Lets talk about both these two a bit and why they make sense

Memory consumption

There are a few reasons that you want your WordPress installation to have as low memory consumption as possible.

First of all, there is a limit. Sometimes on some hosts, you will get an error that tells you that your PHP script tried to allocate more memory than is available and it will halt execution. This is not a specific WordPress error, but since WordPress is built on PHP, you’ll get it sometimes. When troubleshooting this type of error, it’s not always obvious what code that is causing the problem. Even if Plugin A uses a lot of memory and pushes memory consumption right to the limit, it will sometimes load just fine anyway. But a little later, when Plugin B is initializing, your total memory consumption may hit the limit and processing will halt. When that happens, finding the problematic piece of code can be very time consuming, not to mention frustrating.

The other reason is that allocating memory pretty much always takes a lot of time, memory allocation is simply an expensive operation. Not that each call to emalloc in itself is all that expensive, but when a script gradually built up memory consumption there have usually been quite a few emalloc calls under the hood. So the mere act of consuming memory also costs a lot of CPU cycles.

The last reason is a matter of scalability. A script that uses 256Mb of memory will occupy the server RAM with… well, 256Mb. If your webserver only have 1024Mb available it can only make room for four 256Mb scripts running at the exact same time. If the script on average takes 2 seconds to finish it means that the maximum requests/sec that your server can handle will be heavily reduced. So you want your WordPress requests to consume as little RAM memory as possible simply because it means that the server can fit more requests into memory at any given point of time.

All the three above reasons makes it important to be able to track how your WordPress installation uses memory. I hope you find it useful.

Hooked functions

One of the features that makes WordPress such a wonderful product is the ability for a theme or plugin to hook into it. In practical terms it means that a plugin or theme can request to be notified via a callback whenever WordPress hits a certain point in it’s execution, in WordPress lingo, such a callback is referred to as an action. For instance, most plugins uses a hook for the Init event that fires early in the startup process and allows a plugin to perform certain initialization before the page starts to render. Plugins and themes can register that they want a callback for the Init event by simply calling the add_action function. More than one plugin can hook up to the same event and when this happens WordPress will just execute them one by one.

A potential problem with callbacks is that all plugins are not written with performance and memory efficiency in mind. On the contrary, some plugins will spend ages doing expensive initialization tasks and consuming a lot of memory for no particular reason at all. For the end user this means that the requested page is delayed until some plugin is done doing unneeded work. One example is the very popular NexGen Gallery plugin that on initialization will load a lot of PHP files into memory and perform some quite expensive initialization work on every single request, regardless if the resulting web page will actually display a gallery.

In the first version of my Load time profiler plugin you could track how long time WordPress took to complete a few of the actions, but it was not possible to see how long each individual callback would take. In this version, I’ve added code to track this so that for instance when the Init action is fired, you can see the time consumed by each individual callback (click image to enlarge)

init_breakdown

One tiny drawback

The traditional way to do profiling would be to run the code in a specific profiling tool that needs to be installed on the same server as your code is running on. In the case of WordPress, the challenge is that many production installations are running in hosted environments where the web developers can’t just go and install debugging and profiling extensions at will. This plugin is really an attempt to overcome this limitation by actually modifying how WordPress is executed in a controlled way. Three core WordPress files are copied to the plugin directory and are modified to (1) collect data on timing and memory consumption and (2) alter the include paths a little to avoid the standard version of those files. Feel free to check the modified files, they are stored under /path/to/plugins/loadtimeprofiler/resources and have the suffix _custom.php

The drawback of this should be fairly obvious, since the code is modified, it’s not the exact same as in production and therefore, the results will differ ever so slightly between what’s reported and reality. So as long as you keep this in mind and use the tool sensibly, I think you can draw some

Download

I swear I will start the process to get the plugin into the official repository at wordpress.org asap, in the meantime click here to download the current version of the plugin.

I’m eager to hear back from your. I’ll answer technical questions or listen to your critique. Whatever feedback you think is appropriate. Use the comments below to let me know what you think.

 

WordPress load time analysis

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on Reddit

Load time profiler ‹ Walltool — WordPress

UPDATE Dec 8th 2013: I’ve updated the plugin even more. Read about it in part 2.

UPDATE Dec 3rd 2013: While testing the plugin on a few installations, I discovered a couple of bugs. If you downloaded the plugin on Dec 2nd 2013, you may want to try the improved version available below.

I’ve been working a lot with WordPress lately and doing so I’ve sometimes needed to trouble shoot slow WordPress installations. Naturally, I’ve googled for things like “wordpress performance”, “wordpress is too slow” and similar phrases. Almost always, those searches will take me to a page listing the top-10 things you should do to speed up your WordPress website. Those lists of tips are usually quite good, you’ll typically learn that you should install a caching plugin, clean up your database and get rid of unneeded plugins etc. Mostly quite useful information…. but with some important exceptions.

Installing a caching plugin such as W3 Total Cache will often solve most of your performance problems as long as you have mostly a “read only” website. However, if your website is inherently slow when used without any caching, your users will notice it and suffer from it whenever they do anything that can’t be cached as easily, like posting comments or doing custom searches. The most scary example  I’ve experienced was an e-commerce website that was screaming fast as long as you were just browsing products (good) but was terribly slow when adding things to the cart (bad), entering a coupon code (worse) or checking out (flat out terribly bad). In that case, it didn’t matter much that the front page got a 90/100 score on Google Speed since the users had a terrible experience just as they were about to place their orders. So sometimes, a WordPress site need performance beyond what you can get from a good caching plugin.

Maybe it’s time for a little clarification. When people talk about performance it’s common that a few important concepts are mixed up. For the remainder of this post, when I say performance I mean the time needed to create the main HTML document that WordPress generates and that IS the page. Specifically, I don’t talk about the size of or number of other resources (images, css-files, js-files etc) that your page needs. Those are almost always static and the webserver will seldom require the PHP  scripting engine to serve them to your users, and if your webserver actually is too slow, static files can easily be moved to a CDN anyway.

When a user requests a page from (or makes an Ajax call to) your Wordpres site and that request can’t be cached, the entire WordPress system needs to initialize in order to generate the response. For the sake of argument, let’s divide the response generation process into two phases:

  1. Internal WordPress init. In this phase. WordPress will load itself into the PHP process memory, it will set up the database connection and read various options from the database. It will initialize your theme, meaning it loads the theme’s function.php into memory and allow it to register the hooks it want. It will also load the main php-file from all your active plugins and they will also typically register some hooks.
  2. Theme processing When phase 1 is ready, your theme will be called into action. If it’s a standard post or page, Wordpres will typically load your single.php or page.php and let it execute it’s code. That code will call internal WP functions such as ‘wp_head()’ or get_bloginfo() to do it’s job and sometimes, calling an internal function will call back into your theme’s function.php, it all depends on the theme.

During these two phases, you really don’t have a lot of information about what WordPress spends the most time with and that makes it terribly difficult to know what you can do to optimize it. I found this very frustrating so at one point, I started hacking a few of the files in WordPress core in to insert debug information about what it’s doing. Specifically, I was inserting profiling code into wp-settings.php like this:

require( ABSPATH . WPINC . '/version.php' ); // <--- existing line
$profiledata['post_require_version.php'] = microtime(TRUE); // <--- my line

Then in my footer.php, I’d output the content of the $profiledata array into HTML to review it. Naturally, modifying core files like that gets messy quite fast. You can easily break the entire site by accident  and any changes will be overwritten on the next WordPress upgrade. So even if I believe that I was gathering useful information this way, I needed to do it cleaner. So, (since this is WordPress) I wrote a plugin, I now have a working plugin that will do the following using a bunch of Ajax calls from an admin-page:

  1. Copy wp-settings and wp-config into a separate plugin folder
  2. Rewrite wp-settings and wp-config so that they contain profiling code as shown above and some modified path information.
  3. Via a special bootstrap php file, load wordpress using the modified versions of wp-settings and wp-config and at the end, output the profile data using json
  4. Submit the data back to the server for storage, and render an HTML table with all the profiling data.

This is what it looks like:

Load time profiler ‹ Walltool — WordPress

And the complete content of the analysis can be downloaded here (tab separated text)

One interesting thing is that this is not limited to just displaying internal WordPress load time analysis, if you want to, you can add additional profiling statements into your own theme code and have them displayed in the same table. I’d even say it’s the preferred thing to do. One thing that I’ve seen so far is that in a lot of cases, the WordPress internal stuff takes roughly 40-55% of the total load time, so to get the full story of what happens during load time.

I’ve just finished writing this plugin so it’s really quite rough at the moment. It’s not been tested with a lot of WordPress versions and the UI is not at all what I’d want it to be. I’m in the process of adding it to the WordPress repository, should you want to look at it before that, feel free to download it from here:

Download Loadtimeprofiler

Feedback, comments questions? Use the comments below.

 

 

post

WordPress file permissions

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on Reddit

 

In order for WordPress to be able to install a plugin and plugins or themes automatically there are a number of conditions that have to be met. If all those conditions aren’t met, one-click installations or upgrades won’t happen, instead, whenever you try to upgrade, WordPress will show you the FTP credentials input form. If you’re anything like me, you hate it.

I sometimes run into this problem. My first instinct is to check the obvious file permissions. Will the web server have write access to all the important places. As long as we’re only talking about plugins and themes, important places means the wp-content folder. When I’m certain that the web server have write access, I typically try again and successfully upgrade my plugin.

Every once in a while, installing or upgrading still won’t work even if I’m 100% certain that WordPress should be able to write everywhere it needs to. I end up searching for a solution for about 10 minutes, give up and resort to manually uploading plugins via ssh and get on with my life. Today I decided to find out the root cause of this problem and solve it. Writing this blog post about it servers as much as a ‘note to self’ as assistance to anyone else that trouble shoots this without finding a solution.

The rules

So, the rules for WordPress to be able to install and upgrade plugins and themes:

  1. The web server needs to have write access to the wp-content folder. For example on a Debian based system (i.e Ubuntu), this will be user ‘www-data’, on RedHat/Fedora, it’s typically user ‘httpd’ (plese correct me here if I’m wrong). WordPress will test this by writing a temporary file to wp-content and then remove it. There are plenty of blog posts, howtos and forum posts about this. They usually points back to this article: http://codex.wordpress.org/Changing_File_Permissions
  2. The files in wp-admin needs to be owned by the web server user. WordPress will test this by using PHP function getmyuid() to check if the owner of the currently running PHP script is that same as the owner of the newly created temporary file. If it’s not the same, WordPress will select another method of installation or upgrade.

Rule #2 is what typically gets me. Whenever I move an existing WordPress installation to a new home, I’m sometimes (obviously) not careful with setting file permissions and file ownership and end up in this situation. Rule #1 is extremely intuitive, checking for write permission is close to second nature. But Rule #2,  checking file ownership in wp-admin… well, I’d even say it’s slightly unintuitive. If anything is worth protecting it should be the admin area, and being more restrictive with file ownership and permissions under wp-admin would even kind of make sense.

Anyway. Comments, questions or other feedback. Please post a comment below.

 

[wysija_form id=”3″]

 

LoadImpact

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on Reddit

1-loadimpact

I’ve just started blogging as a guest writer at LoadImpact.com. If you’re not already familiar with LoadImpact, go check them out. They provide the word leading load test as cloud service solution and is free to try out.

Today my first post was published about the difference between Node.js and PHP as server side languages/environments.

So, get out of here already and read about it.

Debugging your phpunit test cases in CodeIgniter

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on Reddit

I don’t know why it feels ironic, but it does. Sometimes I need to debug my phpunit test cases and it wasn’t very very self explanatory to understand how to set it up . The solution however, is quite easy.

I’ve previously written about how to enable the php debugger xdebug from a command line script. The end result from reading that article should be that you have a php5d command on your system that will trigger xdebug to hook into your IDE (mine is Sublime Text 2, yours may differ). For the rest of this article, I’m going to assume you have the php5d command available.

Next step is to prepare your test classes for execution via a php command rather than via the phpunit framework (don’t worry, it will be included). The solution to this was found at Stack Overflow (naturally, read it, it’s good), but I  found out that two simplifications can be made when used in CodeIgniter with CI_Unit.

The foundation of the StackOveflow trick is to make sure that a couple of PHPUnit classes are loaded, either via explicit statements as the sample suggests, or via the PHPUnit/Autoload functionality. Turns out that when bootstraping PHPUnit via CI_Unit, it already brings in PHPUnit/Autoload.php. That makes it one less requre_once statement to forget about.

The second simplification is to minimize the room for copy / paste related errors. As long as you are a bit obsessive with class names and make sure that your file name is always classname.php (so class FooTest is implemented in the file FooTest.php), then you can avoid typing the class name in one additional place. That’s exactly what I need to do myself to avoid hard to catch errors.

My test cases are now modeled after this template:

<?php
/**
* Tests for the Foo class
*/
require_once('../application/third_party/CIUnit/bootstrap_phpunit.php');

class FooClassTest extends CIUnit_TestCase
{
static function main() 
{
  $suite = new PHPUnit_Framework_TestSuite( __CLASS__);
  PHPUnit_TextUI_TestRunner::run( $suite);
}

public function setUp()
{

}

public function testSomething()
{
  $this->assertTrue(FALSE);
}
}

if (!defined('PHPUnit_MAIN_METHOD')) {
  $class = str_replace('.php','', basename(__FILE__));
  $class::main();
}

And to actually debug it (assuming that the above test class is stored in tests/lib and is naturally named FooClassTest.php), I type:

$ cd tests
$ php5d libs/FooClassTest.php

And to run it under PHPUnit, it’s works just as you’re used to already.

/E

Using CodeIgniter migrations with PHPUnit

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on Reddit

Even some of the CodeIgniter developers are not especially happy about how Migrations are implemented in the current version. Never the less, if you have a CodeIgniter 2.x code base that you want to write unit tests for, you may want to use them.

In a PHPUnit test class, you can use setUp() and tearDown() methods to prepare, run fixtures, create mock objects or whatever else you need to do. Since testing always should be targeted at a test database, one of the things I do is to run migrations. In the setUp() method, I execute migrations to create tables and insert data, in the tearDown() function, I do the opposite. Something like this:

public function __construct($name = NULL, array $data = array(), $dataName = '')
{
	parent::__construct($name, $data, $dataName);
	$this->CI->load->library('migration');
}

public function setUp()
{
	this->CI->migration->version(3);
}

public function tearDown()
{ 
	$this->CI->migration->version(0);
}

Please note: Calling migrations from the setUp() or tearDown() functions may or may not be a very bright idea. It depends a lot on how you organize your tests. setUp() and tearDown() are called once before/after every individual test function in your test class, so static methods setUpBeforeClass() and tearDownAfterClass() may be a lot better:

class InflowLibTest extends CIUnit_TestCase
{
	static public function setUpBeforeClass()
	{
		$CI =& get_instance(); 
		$CI->load->library('migration');
		// Also, make sure that the test db is up to the correct level:
		$CI->migration->version(0);
		$CI->migration->version(1);
	}

	static public function tearDownAfterClass()
	{
		$CI =& get_instance(); 
		$CI->load->library('migration');
		// Tear it down.
		$CI->migration->version(0);
	}

Anyway, I discovered that in the current version,  CodeIgniter Migrations doesn’t do this vey well. The problem is in system/libraries/Migration.php. Line 160 in my file (version 2.1.3), but line 227 in the current Github version.

// Cannot repeat a migration at different steps
if (in_array($match[1], $migrations))
{
$this->_error_string = sprintf($this->lang->line('migration_multiple_version'), $match[1]);
return FALSE;
}

include $f[0];
$class = 'Migration_' . ucfirst($match[1]);

if ( ! class_exists($class))
{
$this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class);
return FALSE;
}

$f[0] is the variable holding the name of the Migration file to load and execute next. Problem is that that line assumes that the file in question isn’t already loaded. Probably an OK assumption in most cases. But when running in context of PHPUnit the way I do it, both setUp() and tearDown() will be run in the same PHP session. So the second time around, when tearDown() executes, all the migration modules will already be included into the PHP process. Simply changing include into require_once fixes the problem. The resulting code should look like this

// Cannot repeat a migration at different steps
if (in_array($match[1], $migrations))
{
$this->_error_string = sprintf($this->lang->line('migration_multiple_version'), $match[1]);
return FALSE;
}

require_once $f[0];
$class = 'Migration_' . ucfirst($match[1]);

if ( ! class_exists($class))
{
$this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class);
return FALSE;
}

 

Enjoy,

 

/E

 

[tags2products]

Debug PHP-cli scripts with Xdebug and Sublime Text 2

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on Reddit

In my previous post, I explained how I’ve set up debugging PHP scripts with Xdebug and Sublime Text  2 in a web based environment. In this part, I’ll outline how I debug PHP command line scripts.

If you want to follow this guide, make sure you have everything setup as explained in the previous post.

Triggering Xdebug

When using Xdebug from a web browser, I use the Chrome extension Xdebug Helper to send a valiid XDEBUG_CONFIG parameter string to the PHP process. The magic part is to set the idekey parameter to sublime.xdebug (sent via the cookie). To do the  same thing when running a script from the command line, the magic trick is to use the environment variables. This is explained in the Xdebug manual, like this:

export XDEBUG_CONFIG="idekey=session_name"
php myscript.php

Oh, how cumbersome to type. Let’s do that in a script instead. Create a file php5d like this:

#!/bin/sh
export XDEBUG_CONFIG="idekey=sublime.xdebug"
php5 $@

Make the file executable:

chmod +x php5d

Then give it a try, let’s debug the test script we created in the previous post, test.php:

  1. Open test.php in Sublime Text 2
  2. Start a debugging session by hitting Shift+F8
  3. Set a breakpoint on a suitable line (must be a non-blank line)
  4. Run the script: php5d test.php

You should see something like this:

Debugging_sublime

One last thing

With the php5d script in place, it’s easy and straight forward to debug command line scripts without doing too much damage on the normal environment. The last thing I did in my environment was to put the script in my /home/erik/bin folder to make it callable from everywhere on my machine:

Make sure I’ve got a central place for your personal scripts. At the end of your ~/.bashrc, make sure you have a line like this (you may already have something similar in place, I’m using subfolder bin, you may use something else):

## Additional personal scripts etc.
PATH=$PATH:"~/bin"

Then, copy the php5d script to the intended folder:

mv php5d ~/bin

And reload .bashrc (or just start a new terminal window)

. .bashrc

There you go, a globally available php5d command that triggers debugging in Sublime Text 2 for whatever PHP script you launch. Enjoy

/E

 

 

 

 

CodeIgniter for PHP CodeSniffer gets better

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on Reddit

Just a quick note, my PHP CodeSniffer standard for CodeIgniter improves gradually, since I originally mentioned it a month ago, the following improvements have been made to the repo:

  1. Improved indentation checks in switch statements, works with tabs now
  2. Correct file and class naming when creating libraries (CodeIgniter expects capitalized file names for libraries)
  3. Support for accepting a range of short (less than 4 characters) variable names. Common and meaningful names such as $sql, $id, $ret etc.
  4. (kind of a hack) Accept the public function name _init(). Only because it’s a requirement when using GasOrm.

So, go update your installations, all 3 of you 🙂

/Erik