Xdebug and other non compiled PHP extensions on CentOS

As some of you might know, I’m quite a fan of uberspace, a small German hosting company. They allow you a lot on a shared space like having Node.js available, running Apache, Nginx or lighttp as host and so on. But it all comes with a minor drawback: They are running on CentOS 6. The OS per se isn’t bad, it just has a lot less docs and tutorials available as opposed to Ubuntu for example.

I had a hard time figuring out how to install Xdebug properly, so I thought I might share it with you. First, when you ssh into your box, you end up in your user directory. And this is right where we will start as it is outside of your public www/html directory and a nice fit for the extension. For that we will use wget to fetch the archive from the official repository. Hint: Check the last modified date as the names might be confusing and indicate a later version when it isn’t.

; Grab Xdebug
wget http://xdebug.org/files/xdebug-2.2.5.tgz
; We could use pecl as well, but it will fail 
; due to missing permissions on uberspace
; pecl install xdebug

Depending on if we are on an uberspace-space, a VPS, your local VM or a dedicated server we will chose the next steps: Unpacking time.

; Unpack the archive
tar -xzf /home/${USER}/xdebug-2.2.5.tgz
; If we used the pecl installer, then look into the Pear downloads dir
; tar -xzf /home/${USER}/pear/download/xdebug-2.2.5.tgz

Now we should have a new folder named xdebug-2.2.5 in our user directory. Let’s cd into that folder and utilize the phpize command to prepare our environment. Upfront a quick quote from PHP.net that will give you some important insights:

Sometimes, using the pecl installer is not an option. This could be because you’re behind a firewall, or it could be because the extension you want to install is not available as a PECL compatible package, such as unreleased extensions from SVN. If you need to build such an extension, you can use the lower-level build tools to perform the build manually.

; PHPize the unpacked archive
/package/host/localhost/php-${VERSION}/bin/phpize xdebug-2.2.5

The installation task always will be the same no matter what:

./configure
make
make install
; Check if it worked
make test

Then we just have to adjust our php.ini file as we can read in the following quote from php.net

A successful install will have created extname.so and put it into the PHP extensions directory. You’ll need to and adjust php.ini and add an extension=extname.so line before you can use the extension.

To find our .ini file, we simply enter php --ini on the command line to get our path. Then things get even more easy.

; Open the php.ini file with nano/pico/vim
nano /home/${USER}/etc/php.ini

And at the end of that file, we add the following lines. You can configure them to your needs:

; The extension itself
zend_extension="/home/${USER}/xdebug-2.2.5/modules/xdebug.so"
; Default settings for Remote Debugging with PHPStorm
xdebug.default_enable=1
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_host=vagrant.local
xdebug.remote_port=9000
xdebug.remote_autostart=0
xdebug.remote_connect_back=1
xdebug.idekey=PHPSTORM

html_errors=On

; No limits - we want it all
xdebug.var_display_max_children=-1
xdebug.var_display_max_data=-1
xdebug.var_display_max_depth=-1

That’s it.

WordPress Password protected posts – feature or security leak?

WordPress Post Password

TL;TR Password protected pages aren’t really “protected”. Let me explain what you have to look out for when using them.

The internals

First we take a quick look at how this feature currently is implemented in core. The post_password is part of a sites posts table. It stores the password as plain text. This is because they are meant to be shared.

Hint: Don’t ever use any page password that you already use for a real login/authentication.

Not every password is a real password.

When you enter a password into a form built by get_the_password_form(), the form targets ~/wp-login.php with a query argument named postpass which is the $action the login file uses to switch. There the PasswordHash class gets into use and a cookie gets set:

setcookie(
    'wp-postpass_' . COOKIEHASH,
    $hasher->HashPassword( wp_unslash( $_POST['post_password'] ) ),
    $expire,
    COOKIEPATH
);

After that a safe redirect gets performed. A brief explanation of what happens: You enter a password and WP saves the password in a hashed version as Cookie. Later on it compares the has against the plain text password using post_password_required(), again using the PasswordHash class.

Things to watch out for

There’re quite some glitches. Here’s a (probably incomplete) list of them.

  1. If passwords are shared between pages, the saved Cookie will give a user access to all pages sharing the same password.
  2. A search query does not return password protected posts. The reason was pointed out by Andrey “Rarst” Savchenko and Chip Bennet in a discussion: You don’t want to expose any details about a pages content. Finding them in the search results page allows guessing what’s inside. But there’s more to it: If a user is logged in, it will appear in the SERPs. And it doesn’t distinguish by role. When you got a role with no capabilities at all or your protected pages are targeting only specific roles, you should alter your search query accordingly.
  3. Attachments that have a password protected parent are not protected.
  4. The same goes for comments.
  5. One of the next versions of WordPress will feature query arguments that allow you to query by has_password or by explicitly by post_password.
  6. There might be another feature coming where you can allow crawlers to access the content. We hope this doesn’t happen. Even, as Andrey pointed out, some magazines with paid content still might want crawlers to index their content without exposing the content to non paying readers. You know how to work around that, don’t you?

Those are just some notes I want to leave you with, so use this feature with caution and get your theme or plugin to consider those facts.

Meet the new Loop – a lesson about the PHP SPL

A single Query for all loops

Some days ago I found an interesting question about displaying posts. The user wanted to first show posts that have a thumbnail and then those that don’t have one. To add on that he as well wanted to show posts which got different categories assigned on different parts of the page. Overall a pretty common request.

Take your time as I’m going into detail. You’ll need approximately 6 minutes to read the post without reading the code. The result of the approach explained in this post can be used in themes. It can be used as library, included from within your `functions.php` file or as a stand alone plugin. Either way, it will greatly simplify your life when crafting a new theme from scratch or altering an existing one.

Multiple Loops: The basics

The first thing that a novice designer who read some (painfully wrong) tutorials would do is to try to use one call to query_posts() for each loop. A more seasoned designer or developer would then maybe add multiple get_posts() calls after the primary loop where s/he just skipped the posts that were of no use. Or s/he would just use the main loop, pushing all unused posts into a new array and then using a simple foreach()-loop for those left over posts later on.

Advanced Loops

A good developer would suggest to use the WP_Query class. And a really good dev would alter the output using the pre_get_posts or (if s/he knows a bit about SQL or can spend some time) the posts_clauses and similar filters to reduce the impact on the database. Real master might even extend the WP_Query class to reduce the footprint, wrap everything up as a nice little package and make it portable and easy to share. Here’s an example of such a “master”-query object:

class My_Book_Query extends WP_Query
{
    function __construct( $args = array() )
    {
        add_filter( 'posts_fields', array( $this, 'posts_fields' ) );

        // Forced/default args
        parent::__construct( wp_parse_args( array(
            'posts_per_page' => -1
        ) ), $args );
    }

    public function posts_fields( $sql )
    {
        return "{$sql}, {$GLOBALS['wpdb']->terms}.name AS 'book_category'";
    }
}

You can then use it like this:

$book_query = new My_Book_Query();
if ( $book_query->have_posts() )
{
    while ( $book_query->have_posts() )
    {
        $book_query->the_post();
        # ...do stuff...
    }
    wp_reset_postdata();
}

Thoughts about “advanced”

Now all this is nice. But often it takes quite some time to alter the query and get it right. And then there’s the huge problem that you never know if there isn’t a plugin or theme adding another callback to the same filter, messing up your carefully crafted query. And finally there’s the need to call those queries in templates and loop over them. And if you’re into the separation of concerns, then you probably already split those queries off of your theme, moved them into a plugin and are calling them with a filter in your templates. And then you got a real pile of code that needs documentation, maybe unit tests and so on.

As a result of all that, I thought about going down a different route and asked myself the following question: What’s the purpose of the loop? The answer is simple. It helps people to avoid the depth of WordPress core code and offers an easy way to adjust the look of your site by just adding or removing some function calls. Now all those functions rely on the global $wp_query object. So calling a “template tag” in fact just calls something from what’s currently inside the global $post. And the conclusion is, that if I want to simplify things, then I only need to get something that constantly sets the global to the object the WP Query object would currently point to. Then it would give us all the easiness of Template Tags and I only have to care about simplifying how to actually split one query into multiple loops. Easy, right?

Going beyond “advanced” – Meet the SPL

And the solution is right in front of us: The PHP SPL, or Standard PHP Library. This library, which is part of PHPs core and is activated per default for PHP 5.2.x. (It still can be turned off, but why would anyone do that.), brings us a nice set of interfaces like Countable and one extremely useful thing: Iterators.

Iterators are something like “advanced” loops. They exist above the basic foreach, while, etc. loops, but basically do the same thing – looping over “things”. By utilizing them you’re able to be much more specific and have access to lots of information. In other words: No workarounds need as you got every bit of needed info at your fingertips.

For example a RecursiveIteratorIterator allows looping through a multidimensional array, accesses all levels and lets you identify them by calling $this->getDepth() easily. You also got stuff like GlobIterator or its multidimensional pendant RecursiveDirectoryIterator() which is kind of an advanced glob function that lets you loop through directory structures and easily skip . and .. filesystem pointers. The list of Iterators is long and you should really give it some time and play around with it to see its full power. Of course there’re other benefits we gain. Normally a foreach loop over an object would just expose public properties. With iterators we can exactly tell which part of an object is loopable (or Traversable).

Let’s get back to our task and look into the benefits we’d gain from using Iterators on our loop. First, let’s sketch out a possible scenario: We’re building a special category page for a category named books with the ID of 25. The template would be named either category-books.php or category-25.php and be used as archive for book reviews. Then we want to first show all books that have a featured image and later show a list of the ten recent reviews that we haven’t already displayed in our Thumbnail list.

Book Preview Archive MockUp

MockUp for our fictional book review archive page – crafted in MS Paint.

As I’ve written previously, the default thing to do would be to do add a meta_query to the main query from inside a callback to pre_get_posts and search only those posts that have _thumbnail_id set. Then we’d need to figure out how to order those that have that meta value set, etc. Or we could use a FilterIterator.

The FilterIterator is an abstract class. This means that it’s not meant to be used directly. You need to implement it in your own class by extending it and adding the mandatory method accept(). This method tells the iterator (while looping through our Array or Object) whether we want to add/loop a property of current key/value pair or not. Let’s take a look at our real world example and the ThumbnailFilter class – the explanation follows below:

class ThumbnailFilter extends FilterIterator
{
    protected $wp_query;

    protected $allowed;

    protected $total = 0;

    public function __construct( Iterator $iterator, WP_Query $wp_query )
    {
        NULL === $this->wp_query AND $this->wp_query = $wp_query;

        $this->total = $this->wp_query->query_vars['posts_per_page'];

        // Save some processing time by saving it once
        NULL === $this->allowed
            AND $this->allowed = $this->wp_query->have_posts();

        parent::__construct( $iterator );
    }

    public function accept()
    {
        if (
            ! $this->allowed
            OR ! $this->current() instanceof WP_Post
        )
            return FALSE;

        // Switch index, Setup post data, etc.
        $this->wp_query->the_post();

        // Last WP_Post reached: Setup WP_Query for next loop
        $this->wp_query->current_post === $this->total -1
            AND $this->wp_query->rewind_posts();

        // Return whether it does meet the criteria:
        return $this->deny();
    }

    public function deny()
    {
        return ! has_post_thumbnail( $this->current()->ID );
    }
}

Basically it’s nothing more than a plain vanilla FilterIterator. But the part that makes it “compatible” with the WP_Query – and therefore allows the usage of Template Tags – is the important bit. I added a private property named $wp_query. So when you call an instance of our ThumbnailFilter, you have to add the global $wp_query, which holds the main query object, as second argument. That way we have access to this object and can keep track like WordPress native loop does. Let me quickly walk you through what happens:

  1. We have the private $wp_query property. If it’s not set and the argument is provided, it gets set to the one and only global $wp_query object. It got a type hint to WP_Query to let PHP throw read- and understandable error messages when we provide the wrong object.
  2. The private $allowed property gets set: It is set to the result of WP_Query::have_posts(), so we don’t run into an empty query result by accident.
  3. Inside the accept() method, the $allowed property gets checked. Additionally we check if the current()ly looped object really is an instance of the WP_Post object. If so, we proceed. If not, we skip forward to the next object. Everything that isn’t a WP_Post clearly isn’t anything that we want to loop.
  4. If we passed our test at the beginning of accept(), we call $wp_query->the_post(). This triggers WP_Query::the_post(), which then sets up the first post, calls any callbacks attached to loop_start and sets the internal pointer to the next post in the main loop.
  5. Next we check if we already reached the end of all posts for this request. If so, we let WordPress reset the query and all its pointers.
  6. Finally we call the deny() method. And this is what it all is about. Hint: $this->current() always points to our currently looped WP_Post object. To target a post, we need to call the ID as property of this method: $this->current()->ID() for e.g.

The deny() method is there for one single reason: The ability to extend our *Filter class. It contains only one thing: The native WordPres Conditional Tags that tell if we want to output that post or not. Doing so, we simplify things massively for our (fictional) designer who crafts the final templates. Let’s take a look at the specific implementation in the category-books.php template:

global $wp_query;
$loopObj = new ArrayObject( $wp_query->get_posts() );
$primaryLoop = new ThumbnailFilter( $loopObj->getIterator(), $wp_query );
 
foreach ( $primaryLoop as $post )
{
    the_post_thumbnail();
    the_title( '<h2>', '</h2>' );
}

And we’re done. We haven’t had to deal with separating any query with WP_Query args nor fighting with any SQL statements to get our stuff in the right order. And as benefit on top, our template file is nice and clean. Yes, we could go even further and separate and abstract the ArrayObject creation to a template tag like get_loop_object() or similar, but so far we’ve already done a big step.

But there’s another, maybe even more interesting part: We can reuse that pattern for later loops and even tell our designer how he can easily use that pattern without the need to learn anything new. As explained above, we separated the deny() method out of accept(). We now take a look at how a secondary query might look like to give you a better understand the reason behind this:

class NoThumbnailFilter extends ThumbnailFilter
{
    public function deny()
    {
        return has_post_thumbnail( $this->current()->ID );
    }
}

This second class extends our previous ThumbnailFilter and does nothing else than define the conditional tag that keeps our Iterator from looping through. In above case, we want to loop every post that we haven’t looped before. And this would be all posts that don’t have a Thumbnail. Example implementation in the template:

// global $wp_query; -> Already set earlier in our template file
// $loopObj = new ArrayObject( $wp_query->get_posts() ); -> Set earlier
$secondaryLoop = new NoThumbnailFilter( $loopObj->getIterator(), $wp_query );
 
foreach ( $secondaryLoop as $post )
{
    the_title( '<h2>', '</h2>' );
    the_excerpt();
}

Quite easy, isn’t it? You can easily extend the base filter iterator by just defining deny() with the Conditional tags. You can even go one step further, abstract the base class without defining it to get a more general approach. You could as well implement Countable and $counter that counts up on each accepted post and return it inside a count() method to easily output the number of posts for the current loop. Overall everything I’ve shown in this post is just a starting point. This Gist contains a proof-of-concept plugin. If you want to see how far I get with this approach, just follow me on Github. If I manage to build a base theme, then I’ll publish it there and announce it on this blog.

Happy crafting!

A new year, a new chance

A new year, a new chance

In some hours there will be a new year. And as things – as usual – came different than expected, I got time for a quick last post this year. The year that is ending just now showed me a lot of new things. So let’s quickly go over it.

Community

Maybe the best part of this year have been the times where I could participate in two WordCamps (WCEU in Leiden/Netherlands & WPCamp Berlin) and one DrupalCamp (Vienna). In short: It was awesome! I met and talked with a lot of people that I previously only new from the SE Network, Chats, Instant Messengers and Mail contact. In Leiden we managed to get together our WPSE crowd for dinner which was one of the most memorable moments to me this year. Sitting, eating, joking with Thomas “toscho” Scholz, Andrey “Rarst” Savchenko, Stephen Harris, Tom J. Nowell and Frank Bültge was just great and will surely pop up in every “you know, back then” discussion in the next years. Meeting Floor, our WPMeetUp Vienna Lady was some (quite welcome) surprise – yes, I didn’t really check the speakers list up front. I attended some more or less interesting talks with Daniel Hüsken, Birgit Ölzem and Stephen Harris and had some interesting talks in between. The party was much better than expected (yes, people who code can dance!) and I had some very funny (and drunken) moments with Paolo Belcastro, Paul de Wouters and “Otto” Wood, which also left me with some interesting insights into what’s going on over at Automattic and the dot org site. Over all really a nice trip that was worth the time. And if you haven’t read your name by now: I have to meet people in some minutes and just try to make it fast – you’re not forgotten :)

The Berlin Camp was a great one too. I met Marco Heijnen again, whom I already learned to know at Leiden Airport as he was so kind to pick us up together with Andi Nacin, Andrey/Rarst and Konstantin Obenland, which was a pleasure. (Still sorry that I forgot the tin foil for Andi at home.) Then there were Toscho and Frank again, Birgit, Daniel, … and there goes the time. Again: I haven’t forgotten you. Last, but not least, a big sorry to Caspar Hübinger: Sorry for dropping my talk. I promised my girl to spend some time with her in Berlin.

DrupalCamp was a very refreshing experience as well. A friend who works in a Drupal focused company pushed me to grab a ticket – and I didn’t regret it. Aside from some very good tech talks (like the ones by Sebastian Göschkess and Sebastian Simssen), I learned to know some interesting people. I was invited to the speakers dinner on the first evening and Günter/@gue spent the second half of the second day talking with John O’Nolan from the Ghost Blogging Project. In between I met an old friend which I hadn’t seen for more then ten years and lots of other great people with interesting stories, projects and ideas. But the best part was there never was a single word that wasn’t exceptionally interested and friendly when people got around the fact that I was more a WordPress and never even had taken a look at the Drupal code base before. Thanks for giving me the feeling of being welcome that to all of you Drupal girls & guys!

Code, Projects and…

…personal evolution was a big part this year. Maybe more than in every other year before. In short, I managed to learn JavaScript to a point where I can actually code in that scripting language properly. And I got around using dependency managers like Composer, npm and bower and dropped as much of git submodule usage as possible. Learning this was one of the best decisions this year. Another, equally good decision was to finally learn how to handle Grunt. This allowed me to drop all my Ruby Gems + Bash Script stuff and replace it with a nice, maintainable setup that handle so much more, is so much easier to update and makes my projects faster, more predictable and smaller. And it opened the doors to things that I’ve never used outside the IDE. This means that I now can publish open source projects where people can participate at eye height without having to read pages of documentation.

When I look back I’m not sure if the better decision was to learn JavaScript, Require.js and Angular.js or if it was diving more into PHP OOP concepts. But what I learned between and from the discussions with toscho and hakre and from what I can read when I look at my current code and compare it with some from 2012, I can say that I just named the two people who had the most influence on how I look at things now. Thanks for that! And for everybody else: Head over to our WPKrauts Project site and bookmark/add it to your TODO list for the next year.

A Last Word!

Now go, get some beer, wine or Champagne and celebrate! See you next year!

How to move WordPress core JavaScript to the footer

How to make your SearchEngine happy

]1 How to make your SearchEngine happy

Every time I register a script and add jquery as dependency, it gets added to the <head> in the finally rendered HTML page. As this blocks page rendering time – the included script might modify the DOM – I want to add it to the end of the page to prevent this behavior. This will make Google happy and positively influence my page rank as page loading time should decrease.

class RegisterScripts
{
    public function __construct()
    {
        add_action( 'wp_enqueue_scripts', array( $this, 'scripts' ) );
    }
    
    public function scripts()
    {
        wp_enqueue_script(
            'requirejs',
            get_stylesheet_directory_uri().'/assets/scripts/vendor/requirejs/require.js',
            array( 'jquery' ),
            filemtime( plugin_dir_path( __FILE__ ).'assets/scripts/vendor/requirejs/require.js' ),
            true
        );
    }
}

So what does core do then? Actually it’s quite easy. The WP_Scripts class is an extension for the class WP_Dependencies. And when you make a call to wp_enqueue/register_script(), it just uses the add_data() method from there.

$wp_scripts->add( $handle, $src, $deps, $ver );
if ( $in_footer )
    $wp_scripts->add_data( $handle, 'group', 1 );

As you can see, it adds “data” with the script name as a first argument and sets some group to 1. This just tells the class where to put the the script data in the global array. Then, when looping through the array, WP just checks the current hook and prints either the default part or, in case of the end of the page, the wp_footer hook, all scripts that have a group equal and/or higher than 1. That’s it.

Now to the part where we quickly fix that:

// Move jQuery to the footer
global $wp_scripts;
$wp_scripts->add_data( 'jquery', 'group', 1 );

Of course you can do that with every other script as well. A (maybe incomplete) list of default scripts can be found in Codex. If you want to have the real list, you’ll have to dump $GLOBALS['wp_scripts'] and look through the array. In case you want to wrap all this up in a standalone plugin, you of course can do. I recommend using a mu-plugin.

/* Plugin Name: jQuery to the footer! */
add_action( 'wp_enqueue_scripts', 'wcmScriptToFooter', 9999 );
function wcmScriptToFooter()
{
    global $wp_scripts;
    $wp_scripts->add_data( 'jquery', 'group', 1 );
}

Keep in mind that there might be plugin or theme scripts doing things wrong(!) and this solution might break. Normally this would happen if the custom scripts are loaded into the header or if the whole WP Dependency API is bypassed and the script hard coded. Conclusion: Test before you add that mini plugin to an already live page. If it doesn’t work, inspect where and how the script loading works. Then fix that and try to load those blocking scripts to the footer as well. Google will love you.

If you want to go further, here’s a related recommendation. If you want to create JavaScript classes, take a look at JavaScript++.