web developer. dublin, ireland.

Suggestions For You:

Leveraging Composer to write a more maintainable Object Orientated WordPress plugin

03/04/2014

As your wordpress plugin grows it can quickly become a nightmare to maintain. To add a feature you just write callback function and wire it into a hook using wordpress’s global functions. Simples! But because it’s so easy, your plugin soon grows into a monolithic class or script, with unrelated functions and features.

WordPress’s core is starting to show it’s age when you compare it to modern PHP practices and tools but we can use these tools to bring some sanity to the maddening rabbit hole your plugin can become.

Here I’ll rewrite Hello Dolly in a more Object Oriented fashion. Full source here.

Step 1 – Create your wordpress plugin file.

Create a folder for your plugin files to reside, I’ve created a folder hello-dolly-oop and inside that a file hello-dolly-oop.php with the appropriate annotations as outlined on wordpress.org.

https://github.com/bgallagher/hello-dolly-oop/blob/5a00c1042d85f5b403a8833601973e72799a32e4/hello-dolly-oop.php

Step 2 – Create your main class

Create a folder src/HelloDollyOOP in the root of your plugin, in here we’ll put all our classes. Our main class we’ll call HelloDollyOOP_Plugin. Save the file as Plugin.php inside the HelloDollyOOP source folderHere we’re using PHP 5.2 style PSR0 underscore namespacing for autoloading as wordpress’s minimum version is still 5.2.x.

Step 3 – Autoloading classes with Composer

We’ll use composer to set up our autoload for us. This means we don’t have to litter our files with require_once statements.

There are lots to great composer articles out there, but basically create a file called composer.json in the root of our plugin.

Then download composer.phar to the root of our plugin and run ./composer.phar update -o . This will create a vendor/composer folder for us containing classes for autoloading.

Now back in our hello-dolly-oop.php file add the line:

This will register the autoloader so that our classes can be found seamlessly.

https://github.com/bgallagher/hello-dolly-oop/commit/eac1868240ed40310f5030858b3c6a73fa1282bd

Step 4 – Instantiating our main plugin class

With our autoloading in place, we can now instantiate our main plugin class in our plugin file.

Here we’re instantiating HelloDollyOOP_Plugin and passing in the location of the plugin file, many WordPress function take this path as an argument, so it’s handy to have a reference to it.

Step 5 – Write a class for Dolly

Next we’ll place the same Hello Dolly logic from the original plugin in a class of it’s own called HelloDollyOOP_Lyrics. Save the file as src/HelloDollyOOP/Lyrics.

https://github.com/bgallagher/hello-dolly-oop/blob/3f4d98edd89a230a79049bc9556dc43cffb18b56/src/HelloDollyOOP/Lyrics.php

Step 6 – Prepare to register the hooks

Now we need to wire the callback functions up.

Create a static method in HelloDollyOOP_Lyrics called registerHooks. In here we’ll wire up the appropiate callbacks.

This way the class itself it responsible for registering it’s callbacks – this is a nice approach because as your plugin grows you can encapsulate all related functionality together.

Step 7 – Register the hooks

Now in the constructor of our main plugin class just call the static method HelloDollyOOP_Lyrics::registerHooks like so:

 

All done. Now you have a good foundation for a plugin that can grow over time.

Share

Note to self

04/26/2013

git config --global credential.helper "cache --timeout=3600"

Share

Hostname/Subdomain URLs and routing using ZF2

01/29/2013

The Problem

Within wripl.com we’re using the our main domain along with a couple of subdomains, i.e api.wripl.com & oauth.wripl.com. The subdomain routing is performed using a Zend\Mvc\Router\Http\Hostname route. I was having 2 issues with this:

  1. My other standard routes eg ‘learn-more’ (‘/learn-more’) was available on the sub domains too. E.g. going to ‘api.wripl.com/learn-more’ would still route to my learn more page :(
  2. While on a subdomain, (be it an actual sub domain page, or a seemingly mis-routed page), the url helpers would generate the url using the current domain. E.g. I’d end up with links like oauth.wripl.com/user/register being generated :(

My Solution

I say my solution because there maybe a better solution that I’m not aware of.

I didn’t want to go down the route (pun intended) of custom helpers, because 3rd party modules wouldn’t work out of the box, and also the urls would still be accessible - however obfuscated.

What I did was create a ‘parent’ hostname route and added all my other pages as child routes.

And in a *.local.php config file I set the hostname routes depending on environment :

So now instead of $this->url(‘learn-more’) I use $this->url(‘wripl-www/learn-more’) and I always get the url with the correct hostname and the request will only get routed if the correct hostname is present, so in my example from before ‘api.wripl.com/learn-more’ now results in a 404. #win.

Share
wripl-v2-final-banner

I’ve added wripl to my site

01/24/2013

Today I’ve added the wripl wordpress plugin to my website. Wripl is a startup I’m working on, wripl centers around the idea of making the web more personal. Wripl gleans your interests from your activity on a web page, and uses this information to recommend other content on that site which you may be interested in.

Wripl hase two key differentiators to other similar offerings

  1. You have control of your interests – you can add, delete, manipulate etc
  2. You interests will work for you across other sites, so for example you read about ZF2 here, and go to another tech site with wripl enabled and it might start recommending php articles etc.

Screen Shot of wripl control

Wripl is still in early stages, but we’re looking for trial sites at the moment to help mold wripl. If you have a wordpress blog, or are interested in playing with the API, get in touch with me on twitter.

Share

Managing forked ZF2 modules with composer

01/20/2013

You’re using composer for your dependency management in your shinny new ZF2 project. Then you notice an issue in a thrid-party module you’re using. You fork it and submit a pull request.

I’ve done this for a few modules recently, and while waiting for the PR to be accepted I simply cloned my fork into my vendors directory. This becomes a pain (especially in teams) as your now using composer to manage some dependancies but you have to manually clone and pull your forks.

A couple of months ago I forked the popular ZfcUserDoctrineORM in order to submit a PR to allow the email field to be null, bringing the module in line with changes to ZfcUser. Unfortunately the PR, along with others, has yet to be merged.

Recently I discovered that composer can pull packages directly from github, bypassing packagist. All you need to do is add your forked repo as a VCS Repository in your project’s composer.json file like so :

Now your forked repos and your other dependancies are all managed by composer.

Share
packagist-logo

Adding your ZF2 module to packagist.org

01/17/2013

I created my first ZF2 (Zend Framework 2) module called BgOauthProvider. I versioned it on GitHub and added it to modules.zendframework.com. All was well. But at the back of my mind it was niggling me that it couldn’t be deployed and managed via composer.

I’d had very little experience with composer (other than it was working), so I found the whole concept of publishing to packagist quite daunting, and couldn’t find any posts explaining the process. I bit the bullet and wen’t ahead and did it.

It’s actually very straight forward

So I thought I’d blog about my experience, and maybe it’ll spur someone else on to do it too. Composer/packagist, and other projects like them are really moving PHP forward.

Step one – register

Register on packagist.org, try and get the same user name as you have on github. This will not only help create symmetry between your packagist and github accounts but will also help later on it the Service Hooks.

Step two – composer.json

Next, before submitting your module to packagist you’ll need a composer.json in the root of your project on github. Here’s mine, I’ll explain it line by line as best I can.

 

  • name: The name for your package. The first half is the vendor name, this will usually be your github username, the second half will be your module name.
  • type: ZF2 doesn’t have a specific package type, so just use “library”.
  • description: A description.
  • keywords: Like tags.
  • homepage: Probably just your modules github address.
  • licence: The Licence used to distribute.
  • authors: An array of authors.
  • require: Your modules dependancies – other packages.
  • autoload: The location of your classes in your project. In ZF2, the convention is to put your PSR0 namespaced classes in a “src” directory. The classmap is needed, so that Zend can load the Module.php file, as now it’ll be one level deeper in the vendors directors. Eg my Module.php file now resides in vendor/bgallagher/bgoauthprovider/Module.php.

Step three – submitting project

Once you have your composer.json file in your project, you can submit your github address. Packagist.org will load in the composer.json file we created above and have you approve the desired name. Once you confirm your project is now listed on packagist.

Step four – auto-updating

It’s suggested that you set up a service hook so that when you push to github, your packagist repo is automatically updated.

Copy your API Token from https://packagist.org/profile/.

Then from your github project go to Settings > Service Hooks > Packagist. If your packagist username is the same as your github username, you don’t have to fill in user, just paste your API Token from packagist.

Screen Shot 2013-01-17 at 16.52.09Done!

Share