Using Composer, Laravel and Guzzle in your WordPress Plugin

Share on Google+Share on FacebookTweet about this on Twitter
Enter Composer. Are you still downloading your PHP libraries as .zip’s? Stop! With Composer, your dependencies become easily manageable, updatable and autoloaded. Worried that your favourite PHP library doesn’t support Composer? Chances are it does. In this tutorial, we’re going to build a simple plugin that utilizes libraries from Laravel and Guzzle. I’ll show you how to autoload these classes, and how to use them inside your plugin. Before we begin, make sure you have Composer installed and updated. Running composer self-update will ensure you have the latest version. Let’s start by using the WordPress Plugin Boilerplate. [code language=”shell”] cd myproject/wp-content/plugins git clone mv WordPress-Plugin-Boilerplate/plugin-name plugin-name && rm -rf WordPress-Plugin-Boilerplate && cd plugin-name [/code] For brevity’s sake, we’ll leave the plugin name as is. Normally you’d go through and change the name and reference all the @TODOs. Inside the plugin-name folder, create a file called composer.json: [code language=”javascript”] { “require”: { “guzzlehttp/guzzle”: “~4.0”, “illuminate/cache”: “4.x”, “illuminate/filesystem”: “4.x”, “illuminate/database”: “4.x” } } [/code] We’re telling composer that we require the following for our project:
  1. Guzzle: great for working with RESTful APIs
  2. Illuminate Cache: Laravel’s caching library
  3. Illuminate Filesystem: Needed to save the cache to a file
  4. Illuminate Database: Useful for tasks that WP_Query chokes at. Includes the great Eloquent ORM
Next, while in the newly created plugin-name in Terminal, we’ll tell composer to install: [code language=”shell”] $ composer install Loading composer repositories with package information Installing dependencies (including require-dev) – Installing guzzlehttp/streams (2.1.0) Downloading: 100% – Installing guzzlehttp/guzzle (4.2.1) Downloading: 100% – Installing nesbot/carbon (1.11.0) Downloading: 100% – Installing illuminate/support (v4.2.8) Downloading: 100% – Installing illuminate/cache (v4.2.8) Downloading: 100% – Installing symfony/finder (v2.5.3) Loading from cache – Installing illuminate/filesystem (v4.2.8) Downloading: 100% – Installing illuminate/container (v4.2.8) Downloading: 100% – Installing illuminate/events (v4.2.8) Downloading: 100% – Installing illuminate/database (v4.2.8) Downloading: 100% Writing lock file Generating autoload files [/code] Next, we need to tell our plugin to autoload these classes. Composer includes a handy autoloader, so all you have to do is require it. Place the following in your plugin-name.php file, before any of the other requires: [code language=”php”] <?php // For composer dependencies require ‘vendor/autoload.php’; [/code] Great, now let’s start using these libraries. In plugin-name/public/class-plugin-name.php, we need to add some use as statements before the class is defined (read about namespace importing here): [code language=”php”] <?php use IlluminateFilesystemFilesystem as Filesystem; use IlluminateCacheFileStore as FileStore; use IlluminateDatabaseCapsuleManager as Capsule; class Plugin_Name { [/code] Next, let’s add some configuration in our __construct() so we can start using Laravel’s database library (including the Eloquent ORM) inside our plugin: [code language=”php”] private function __construct() { $capsule = new Capsule; $capsule->addConnection(array( ‘driver’ => ‘mysql’, ‘host’ => DB_HOST, ‘database’ => DB_NAME, ‘username’ => DB_USER, ‘password’ => DB_PASSWORD, ‘charset’ => ‘utf8’, ‘collation’ => ‘utf8_unicode_ci’, ‘prefix’ => ” )); $capsule->setAsGlobal(); $capsule->bootEloquent(); [/code] Our plugin is going to get records from an external API and cache them on the filesystem. To do so, we’ll create a function called getRecords() that will handle this for us: [code language=”php”] public function getRecords($id) { $cache_name = ‘records_’ . $id; $cache = new FileStore(new Filesystem($cache_name . ‘.txt’), __DIR__ . ‘/cache’); // If cache exists if ($cache->get($cache_name)) { return $cache->get($cache_name); } else { try { // Try to get records $client = new GuzzleHttp(‘’); $request = $client->get()->send(); $records = json_decode($request->getBody(), true); // Save records in cache $cache->put($cache_name, $records, 600); return $records; } catch (GuzzleHttpExceptionBadResponseException $e) { $raw_response = explode(“n”, $e->getResponse()); throw new IDPException(end($raw_response)); } } } [/code] Instead of hitting the API every single request, we check the cache first and serve that as long as it’s not out of date. Next, let’s use Laravel’s database library in the most simplest way possible: inserting a bunch of records. We have a database that stores class information, so we need to send the classes function an array of records, and we’ll do a foreach loop to insert these into the database: [code language=”php”] public function classes($records) { if ($records) { $results = array(); $i = 0; foreach ($records as $k => $v) { $results[$i][‘start_date’] = $v[‘fields’][‘StartDate’]; $results[$i][‘end_date’] = $v[‘fields’][‘EndDate’]; $results[$i][‘program_code’] = $v[‘fields’][‘ProgCode’]; $results[$i][‘program_name’] = $v[‘fields’][‘Program’]; $i++; } Capsule::table(‘classes’)->insert($results); } } [/code] There you have it! Using Composer in your plugin is pretty easy, and opens up a world of libraries for you to use. If you have any questions or comments, please don’t hesitate to leave feedback below.   Contact Us
  • Jack Saat

    Not sure why you want use Laravel with WordPress and not just complete replace wordpress for a more lightweight solution with just the parts you need! But same great article!

    • There are times when it’s not possible to completely switch out WordPress with Laravel (or anything else for that matter!). In those times this is perfect, but sure bloats the WP install a bit :)

      • Laraval is not much heavier than using Gravity Forms or some other turn key Directory themes.

        What I wish was easier to do is use WP as a backend ( Content Store ) and allow Laraval to deal with the rest. Basically putting the WP-Admin on its own domain ( more secure ) and letting Larval server content/data.

        IMP WordPress should be an admin package for Laraval, unfortunately WordPress is not very eloquent.

        • Brett Maxwell Morgan

          Wouldn’t you want to use Laravel as the backend and WP as the frontend, or perhaps Laravel as a subset of WP? I’m not really following what you’re saying here. Also, “Laravel”, not “Larval”. Or am I unaware of some new product called Larval? Excuse my pedantics..

  • Pingback: Laravel5 | SAAS Beginner()

  • Nabeel

    Hi, great article! I have a question: What if you have two plugins that use Composer? Wouldn’t that create a conflict if you have the two enabled at the same time? What happens if they each reference different versions of the same library?


    • Then your code should detect if the composer ClassLoader class exists, and add the proper PSR autoload mappings manually (of your classes and your vendor classes), otherwise you just include the autoload.php file:
      $loader->add(/* whatever */); // $loader or whatever name the other plugin uses for it
      include_once ‘vendor/autoload.php’;

      That’s for Composer, but unfortunately if there is other plugin already using one of your composer dependencies, let’s say an older version of it, there is no simple way of dealing with that unless you do it with feature detections (like checking if a class has a particular method). Sounds ugly, but there is limitations due to the nature of WP.

  • it seems that someone is already working on a framework like this and solved the conflicts problem with a warning

    It’s called Herbert

  • Jamie

    This is really great. It was exactly what I was looking for. Thanks for doing this.