Easy Package Management for CodeIgniter with Sparks

Easy Package Management for CodeIgniter with Sparks

Tutorial Details
  • Program: CodeIgniter
  • Version (if applicable): 2+
  • Difficulty: Intermediate
  • Estimated Completion Time: 30mins

Sparks is a new package-management system for CodeIgniter that extends the core with support for gem-like sparks.

This tutorial interweaves an entry-level overview of the architecture and usage of the sparks system with the creation of dovecote—a simple spark for managing RSS data.


Introduction

Packages are blocks of recyclable code that can make developers’ lives a whole lot easier.

CodeIgniter’s developers have long salivated over package managers like gems and npm, systems that empower their respective communities with tools and a central repository for developing, recycling, and sharing useful application components with each other. Now, the wait is over. Thanks to a new system—sparks—CodeIgniter developers can finally rejoice, as a growing package management system is finally their own.

Overview

If you haven’t worked with them before, just think of packages as blocks of recyclable code that can make developers’ lives a whole lot easier. Maybe you need an interface to an storage bucket in Amazon’s cloud? Skip the late nights pouring over S3 documentation and just grab the spark.

For its part, the sparks system consists of three parts:

  1. A central repository (getsparks.org) for storing and sharing sparks
  2. A utility for managing the sparks installed in a given CodeIgniter app
  3. The sparks themselves

For the purposes of this tutorial, we’ll introduce the first two but focus on spark development and some basic considerations in developing a spark. Sound good? Let’s see how it’s done.


Step 1: Installing Sparks

It’s official: sparks is slated for integration into CodeIgniter’s core, possibly as soon as the upcoming 2.1 release. But since it isn’t part of a default installation—yet—you’ll need to set the system up manually.

If you’re on OSX or Linux, or if you have PHP’s command-line interface installed on Windows, installation is as simple as installing a clean copy of CodeIgniter and issuing the following in the installation directory:

$ php -r "$(curl -fsSL http://getsparks.org/go-sparks)"

If all went well, you should see something like this:

Installing the sparks system

If for some reason that didn’t work, or if you’re on Windows and haven’t added PHP to your command path, you can also install sparks manually. It’s a little more work, but the result is the same:

  1. Adding a directory named sparks in the root of your codeigniter directory
  2. Adding a custom Loader Class to application/core/MY_Loader.php
  3. (optional) Downloading and extracting the sparks command line utility into your codeigniter directory

Your CodeIgniter installation should now be patched to support sparks.


Step 2: Getting Started

In medieval Europe, every manor house included a small outbuilding for pigeons to nest called a dovecote. Since we’ll be building a spark that involves both tweeting and feed, the name is appropriate enough. But it also meets the only requirement on naming: to be included in the repository at GetSparks.org,

GetSparks project names must be unique

Outlining the Spark

Before we can code, we’ll need to layout a project. In the sparks directory in the root of your CodeIgniter installation (create it, if it doesn’t exist), add a new folder to hold the spark:

/sparks/dovecote

Convention dictates that sparks are organized by version, so we’ll need a subfolder to hold the first draft. 0.0.1 is a good place to start.

/sparks/dovecote/0.0.1

This folder is where all the action will take place. When the rest of the tutorial refers to our “spark directory”, this is it.

The spark.info File

Things are looking pretty bare so far, but we’re ready to start filling them out. The first piece in the spark–and the only file technically required by the spark utility—is spark.info. Create a new file called spark.info in your spark directory, and add the following:

name: dovecote
version: 0.0.1
compatibility: 2.0.2
dependencies: 
   Atomizer: 0.0.1
tags: ["twitter","api","social"]

These fields represent all the information the spark utility needs manage the version and dependencies of all the sparks in this CodeIgniter installation. The utility will look for five things, but only the first three are required:

  • name — the unique spark id
  • version — current version
  • compatibility — minimum CodeIgniter version
  • dependencies — (optional) other sparks required by this spark
  • tags — (optional) tags that describe this spark

Even if you aren’t planning to use the spark utility yourself, it’s still polite to include a spark.info file with any spark you plan on distributing. One of the real advantages to managing sparks this way, rather than pasting them directly into the sparks directory, is that the spark manager can use the compatibility, dependency, and version information in each spark to ensure nice play with the current CodeIgniter installation—and each other. There’s another benefit, too, as we will see in a moment: sparks installed outside of the manager utility must have their dependencies installed manually.

Organizing the Spark

With the info file written, it’s time to give the spark some structure. Create four new folders in the spark directory:

  • config
  • helpers
  • libraries
  • views

If you’ve worked with CodeIgniter before, these are probably familiar names. CodeIgniter’s loader class treats sparks as packages, meaning that the contents of these directories are checked for any application components that can’t be found in the /application directory. For now, this applies to five types of resources:

  • configs
  • helpers
  • libraries
  • models
  • views

Step 3: Writing the Spark

Before we begin coding, take a moment to ensure that your spark directory contains all the necessary pieces.

Installing the sparks system

Everything in order? Let’s proceed.

Create a file in the newly-created config directory and name it dovecote.php. We’ll store a few basic options here to tell the spark where it can find RSS data:

<?php /** config/dovecote.php **/

// Username to retrieve tweets from:
$config[ 'twitter' ]    = 'getsparks';

// API endpoint to query for tweets:
$config[ 'twitterURL' ] = 'http://twitter.com/statuses/user_timeline/%s.rss';

// Feed carrying RSS data:
$config[ 'feedURL' ]    = 'http://feeds.bbci.co.uk/news/rss.xml';

?>

Not much to it—we’ve defined a twitter username (@getsparks) to grab tweets from, provided an API endpoint for Twitter’s Timeline API, and added an additional URL to search for RSS stories.

Now the spark knows where data can be found, it’s time to go retrieve some feeds. To do this, we’ll need to create a library—call it dovecote.php—and save it in the libraries directory:

<?php /** libraries/dovecote.php **/ 

class dovecote {

    protected $ci, $timeline;

    public function __construct() {
        $this->ci = &amp;get_instance();        
    }

    public function retrieve() {

        // build twitter request URL
        $twitterURL = sprintf( $this->option( 'twitterURL' ), $this->option( 'twitter' ) );

        // get RSS Data
        $tweets = $this->ci->atomizer->loadURL( $twitterURL );
        $feed = $this->ci->atomizer->loadURL( $this->option( 'feedURL' ) );

        // set channel information for new feed
        $info = array(
            'title' => 'Convolved feed'
        );

        // mix the two feeds together
        $this->timeline = $feed->convolve( $tweets, $info );

        return $this->timeline;
    }

    public function publish() {
        header('content-type: application/rss+xml');
        echo $this->timeline->save();
    }

    // retrieve an option ($key) from config files
    protected function option( $key ) {
        return $this->ci->config->item( $key );
    }
}

?>

This library provides helper functions to retrieve options from our config file and publish an RSS feed, but the critical piece is retrieve(). This function grabs RSS data from the providers described in dovecote’s configuration file in several steps:

  • First, the address of the Twitter RSS feed is generated. Config outlined a username (twitter) and an endpoint (twitterURL); now, the two are combined using sprintf.
  • Next, the RSS data in each feed are retrieved using the loadURL function the atomizer library. This function returns an “AtomizerFeed” object that provides some useful functions for manipulating RSS data.
  • Finally, AtomizerFeed’s convolve operation is used to combine the two feeds’ items into a single feed, which is returned.
  • At this point, we’re almost ready to fire up dovecote in a live application. We just need to check to make sure that our application includes all of dovecote’s dependencies and that the spark itself will load correctly.


    Step 4: Dependencies

    When we wrote spark.info, recall the line where we described dovecote’s dependencies:

    Dependencies:
       Atomizer: 0.0.1
    

    This means that dovecote relies on another spark—Atomizer—to function. Once sparks are committed to the getsparks.org repository, the manager utility will download dependencies automatically. While we remain in local development, however, we’ll need to do this ourselves.

    If you’re using the sparks manager, you can install Atomizer by navigating to your CodeIgniter directory and invoking the manager’s install function:

    php tools/spark install -v0.0.2 atomizer
    

    Note: If you’re on Windows, you will need to invoke php tools\spark install -v0.0.2 atomizer instead.

    If you aren’t using the manager, or if the installation didn’t complete successfully, you can download Atomizer from Github and extract it into your application’s sparks directory next to the folder containing dovecote.


    Step 5: Autoloading

    Before dovecote will be available to other parts of the application, we’ll need to make sure that it will load correctly. Return to the config folder in your spark directory and paste the following into a new file called autoload.php.

    <?php /** config/autoload.php **/
    
    // load default configuration
    $autoload['config'] = array( 'dovecote' );
    
    // load dependency
    $autoload['sparks'] = array( 'atomizer/0.0.2' );
    
    // load library
    $autoload['libraries'] = array( 'dovecote' );
    ?>
    

    Whenever CodeIgniter loads a spark, it will attempt to load all the resources listed in autoload.php as well. This allows sparks authors to define the resources that users should have immediate access to whenever they load the spark. Because the dovecote library is specified here, for instance, we will have immediate access to the retrieve function as soon as the spark is loaded.

    It’s worth mentioning that the resources described in autoload.php need not reside in the spark directory. As long as they’re located somewhere in CodeIgniter’s search path, the application should be able to find them. Notice atomizer is being loaded in the example above; it wouldn’t do much good to list a spark’s dependencies but be unable to load them!

    Save the autoload file, and let’s load it all up. In the welcome controller in your main application (/application/controllers/welcome.php), add the following:

    public function dovecote() {
        $this->load->spark( 'dovecote/0.0.1' );
        $this->dovecote->retrieve();
        $this->dovecote->publish();
    }

    Let’s walk through that:

    1. We ask CodeIgniter to load dovecote, knowing that all the resources requested in config/autoload.php will be loaded as well
    2. dovecote’s retrieve function is used to get copies of the RSS feeds described in config/dovecote.php
    3. The combined timeline produced by retrieve is served up as an RSS feed using dovecote’s publish function

    See it in Action

    Browse to welcome/dovecote in your browser, and you should be greeted with an RSS feed chronicling the tweets and articles that dovecote has collected.


    Step 6: Building on the Spark

    Let’s make dovecote a little more useful. First, we’ll create a basic view template to show the title of each article in our timeline:

    <?php /** views/dovecote_timeline.php */ ?>
    
    <h3>Recent Happenings:</h3>
    <ol>
    <?php foreach ($items as $item): ?>
        <li><?php echo $item->title; ?></li>
    <?php endforeach; ?>
    </ol>
    

    Next, we’ll make the view accessible by providing a helper function that other parts of the application can use to render the timeline in HTML.

    <?php /** helpers/dovecote_helper.php */
    
    function dovecote_timeline() {
    
        $ci = &amp;get_instance();
    
        $feed = $ci->dovecote->retrieve();
    
        $data = array(
            'items' => $feed->items()
        );
    
        $ci->load->view( 'dovecote_timeline', $data );
    }
    
    ?>
    

    The dovecote_timeline function and its eponymous view can now be used to render the timeline anywhere in our application. But in keeping with CodeIgniter’s only-what-you-need philosophy, we won’t make it automatically available via autoload.php. Instead, we’ll need to load the helper manually whenever it is needed. Return to your application’s welcome controller, and update the dovecote function to generate an HTML version of the feed:

    public function dovecote() {
        $this->load->spark( 'dovecote/0.0.1' );
        $this->load->helper( 'dovecote' );
    
        $this->dovecote->retrieve();
        
        // call the helper function
        echo dovecote_timeline();
    }
    

    Refresh your browser, and you should now see a list of all the items in dovecote’s timeline.

    An HTML version of the dovecote timeline

    Wrapping Up

    Congratulations! You’re now the owner of a very simple spark, but there’s plenty more that can be done. Before sending dovecote out for action, you may consider writing additional functions. The details are up to you, but some useful features might include:

    • caching of API responses
    • views for beautifying the data retrieved
    • data persistence to save older timeline items (check the feed license, first!)

    This tutorial offers the barest outlines of what can be done with sparks and introduces the advantages that sparks can provide in minimizing repetition and speeding up development.

    Working on a spark of your own? Having issues getting started out? Share a little more in the comments below and thank you so much for reading!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://brianswebdesign.com Brian Temecula

    I’ve used CodeIgniter for two and a half years, so I’m not one of the elite veterans, but I can’t believe sparks would be part of the core. What’s next, mommy comes in and holds one hand while we code with the other? CodeIgniter certainly seems to be taking a step in the wrong direction if sparks makes it into the core. CodeIgniter has a reputation for being super easy to use, but as a developer, if you can’t use a class/library you found in the CI wiki, then maybe you should quit and take a job as a cashier at McDonalds or something. CodeIgniter seems overly concerned with backwards compatibility, so if sparks makes it into the core, we can count on it being supported for eternity, which is terrible! I was already disappointed with the path CodeIgniter is on, and this just takes the disappointment to a whole new level. I can’t even imagine the amount of stupid questions people are going to be asking in the forum. I wish there was an advanced version of CI. PHP 5.3+ only that autoloads everything and gets rid of the CI “super object”!

    • Fab

      True, so that’s why we are waiting for FUEL PHP Tut part 2 ;)

    • Kelly Te Huna

      Your wish has been granted. It’s called Kohana.

      • Nicola

        Aahhaha kohana… are u serious? :D

    • Cosmin

      I really don’t understand why you are so pissed to come here and complain. I hoped that on a site like nettuts I won’t see complainers and whiners like on other gaming sites or whatever.
      I thought here were serious developers and/or people that want to learn new languages and programming techniques or tools, and share there knowledge in peace, but it seems I’m wrong.

      If you think you are such a great developer why don’t you write a tutoriale here on nettuts, and why do you use tools like CI, or any other frameworks or cms ? Want “hardcore old school” coding, write raw php or try something called Zendframework.

      • Cosmin

        All these tools are too help you, it doesn’t mean you don’t have to know any php to use them, nor anything like that. When you have to code alot you’re going to repeat alot of code, these kind of tools are here to make your life easier, not make you dumber.

        And if you mean by “peope asking stupid questions” people that want to learn how to code, than I encourage asking questions no matter how “dumb ” to some “experts” might sound. We were all beginners, we all asked questions and still asking, especially in a field like these and things are constantly evolving and changing, even though we might have sounded “naive or dumb”.

      • Robo

        @Cosmin – Well said. I am sick and tired of people moaning and thinking they are the bee’s knee’s. Net tuts seems like a great place for developers to learn and there is no room for Jerks.

    • http://philsturgeon.co.uk/ Phil Sturgeon

      Wow Brian who are you trying to impress with an attitude like that?

      I’m shocked that Sparks has made you so angry, what specifically about the process is it that offends you?

      Let’s walk through a use-case to try and make sense of it. I want to use a Twitter library, so I go to the wiki, copy the first one I find and it’s broken. I copy another and it doesn’t work with my version of CI. So I go to Google and see a bunch of results for the same library on various blogs and whatever else. On page 3 I find another library that does actually work, but the developer is pretty new on the blogosphere and does not have much page rank. Can I trust it? Who knows!

      Then, if there is an update how do I know about it?
      Do I have to bookmark every single library from the wiki and go back and look?
      Is it a new version?
      Is it stable, how does their release management work? Should I grab from master or wait for a tag?
      Where is there code versioned? GitHub or BitBucket?
      Where do I post an issue? Their blog has no comments, should I try and email him or find him on twitter? Should I post on the forums and hope they see it?
      It requires an Asset library, which one theres about 50 on Google?

      Currently CodeIgniter libraries are a mess and arguing against this is an exercise in futility. Resources are disparate and quality is really inconsistent.

      Sparks allows the community to set up a single repository of code. It tracks version numbers, links to GitHub profiles so we know exactly who made it and can use issue trackers, etc, handles dependencies and allows for easy search.

      One code repository, one place for you to go to find it.

      AND they happened to bung a command line tool in there for those that don’t mind doing things that way. It speeds you up (no download, unzip, copy and paste, etc). If you want to pretend you are a real developer but still avoid the command line then feel free to just grab a ZIP file.

      Not an issue, and your angry sarcasm is absolutely not required.

      • Patan

        Oh you Bastard!

      • Dan Bowling

        Phil, that’s a great way to put it, and I can say 100% that Sparks have made my life a little easier in more than just a couple projects.

        I’ll also toss in that Sparks is open source itself, and you can deploy your own copy of it in an Enterprise environment. So with a little extra effort, you can get some benefits in your closed source environment too!

      • http://brianswebdesign.com Brian Temecula

        I wasn’t angry, and I was not being sarcastic. Re-read my comment. Although I do use some external code, I’ve found that I can almost never rely on other people to come to my rescue when there is a bug or I am having problems with a script/class. With pretty rare exception, external code is at least a little different than I want it to be, and I end up tweaking it to suit my needs. I don’t feel that sparks is something that will benefit me, and would like to see something added/changed that does. Yes, there have been changes to CI that I like, so don’t think that I am so sour as to not give credit where it is due, but I want more.

        @Phil, you of all people should sympathize with the desire/need for a different framework … I think you call it Fuel. I’m at the point where I need a different framework, or perhaps a framework of my own, but I’ve been holding on to the idea that CodeIgniter would evolve into something more modern. Fuel is nice, and I also like Kohana a bit, but I end up changing my favorite CI classes to use with them.

        @ others, your comments are friggin hilarious. I think it’s interesting how people have attached a emotion to what I said, but I did not intend to sound angry, arrogant, or offensive in any way. Am I not entitled to an opinion? Is it wrong to want more from CodeIgniter?

      • Cosmin

        No, it’s not wrong to want something more from a framework, but coming here on a tutorial dedicated to sparks and CI just to rant and release your frustration of how much you hate the way CI is going it’s wrong.

        If you visit a page dedicated to a tutorial about something means you are interested and want to learn that particular thing, not the opposite.

        No, I’m not acting emotional, but it’s kind of annoying to see people with such a atittude and comments on a tutorial and learning website. We are all here to learn, not to rant, nor to brag.

        You stated that you weren’t sarcastic, arrogant nor angry, well you either don’t remember what you’ve written, or you can’t explain your feelings, because to me and to other you sounded just like that.
        By the way I recommend a really nice and informative article by Jeff Way.

        http://net.tutsplus.com/articles/do-you-suffer-from-the-dunning-kruger-effect/

    • http://tomschlick.com Tom Schlick

      This comment is so full of fail I dont even know where to start. Under your logic things like PHP’s PEAR library, RoR’s Gems and pretty much every package management system are bad because they reduce complexity in finding, installing, and updating plugins.

      Oh and BTW, the thing you are wishing for in CI (removal of super object & autoloading) are already done in FuelPHP which combines the best of CI, Kohana, Rails, and a bunch of other influencers.

  • http://maomuffy.blogspot.com/ Mfawa Alfred Onen

    @Phil Nicely said. I was actually compiling something similar to what you just described in reply to @Brian. To me, his criticism are lacking facts and all his claims to be this hardcore developer is certainly overdone. Brian, if you feel Codeigniter is not doing things your way, then quit using it and do not discourage new comers with that attitude! Just like @Cosmin mentioned, we are still learning and we were once novice/noobs who asked lots of questions just to learn something!

    • http://brianswebdesign.com Brian Temecula

      So, I claimed to be a “hardcore” developer? Actually, I said the opposite when stating that I was not one of the veteran elite types.

  • Parlays

    Nicely handled Phil. Sparks looks really cool, good job!

  • Jv

    Well Brian it’s obvious you’re probably an expert
    developer. It appears your time might be better
    served visiting web resources that teach you humility
    and empathy. Arrogant developers are a dime a dozen and about as
    unhelpful as novice developers, but novice developers
    can come here to learn and improve their skills.

    I’ve never met a person in this business who
    doesn’t have some information or experience
    I couldn’t learn from.

    I used to believe that the accumulation
    of knowledge was enough. I’m older now and I’ve learned the
    hard way knowledge gets you the jobs, being concerned about
    people and helping them meet their needs gets you the next job
    with that client.

    This business just like all business (and life) is about people.

    All that said…Thanks to all those who make the tutorials here. They’re a huge help.

  • kankuro

    @brian: Ask the codeigniter staff and the developers…. why they include it…..
    @all: guys…. just leave brian what he says…. that’s hes opinion…. concentrate on your own… don’t mind him….

    P.S brian…. no body is perfect…. if they include sparks…. then there’s a reason…. if you want to know, ask them… don’t throw your disappointment on us….

  • http://www.ozweegoville.com kc

    Totally digging sparks! Even sparks I don’t think I’d use, it’s a great place to see how others are using and implementing code igniter.

    Just my .02$
    -kc

  • Janez

    Hi,

    I have a question. How does folder’s structure look like in spark? If I am correct, you put config, helpers, models… under spark/bla bla 0.1 not in application folder anymore.

    • http://rjzaworski.com RJ Zaworski

      @Janez, that’s correct. The Sparks system simply patches Codeigniter’s loader to search the spark directories when looking for libraries, config files, etc. Take a spark (“MySpark”) with the following structure:

      sparks/MySpark
      …/libraries/myspark_lib.php

      Once you’ve loaded the spark, the loader will now search the Myspark/libraries directory for any requested libraries. For instance:

      $this->load->spark(‘MySpark’);
      $this->load->library(‘myspark_lib’);

      @kasakka is also correct in noting that controllers are not yet a part of the Sparks system, but (since both HMVC and Sparks are marked for integration into the Codeigniter core) it seems likely that they will be supported down the line.

  • kasakka

    So this simply treats them as application packages? The current package system has one major flaw: it doesn’t support controllers. I would much rather see this work with the Modular Extensions system.

    https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/wiki/Home

  • Don

    I can’t wait until sparks is part of the CI core.
    This is a great idea to allow me (and others) to add some of the best library’s out there to my projects on a “as needed” basis.

    Nice work by the CI team. Nice work!

  • Frank

    Sparks are awesome. I love how they are so separate from the rest of the code and modular. Easy to maintain, easy to update and easy to handle. Will add some of my own sparks to the site soon!

  • Dave Kennedy

    PHP has had package management for years in the form of PEAR, in its own words

    “PEAR is a framework and distribution system for reusable PHP components.”

    My experience with some PEAR components make me shudder just now… but there are some pretty invaluable ones like PHPUnit. Guess what Im saying is (and forgive me if im wrong) Sparks are not components, but instead “plugins” for CI?

    It’s a great idea, shame it’s CI specific To be able to use sparks (or soemthing similar) in Fuel, Zend and Cake would be pretty awesome.

    • Phil Sturgeon

      PEAR is a tricky one because it gets an incredibl bad rep in the PHP community mainly because a lot of te libraries are poorly written. They’ve improved drastically over the years but still people seem to avoid it like the plague.

      Perl has CPAN.
      Ruby have Gems.

      Both of these are amazing for the communities. We just have a PEAR system that people don’t like. Weird!

      One big difference here though is that a spark is application specific. No need for “gemsets” a’la RVM or application wide upgrades breaking random apps. You can have 5 difference versions of the same spark in. 5 different apps and nothing randomly breaks.

      As for other frameworks, FuelPHP has the exact same thing. We call them “Cells” and thwy’ll launch with 1.1 soon.

      • Dave Kennedy

        “a lot of te libraries are poorly written”

        Yeah hence why some experiences have made me shudder. But saying that there is no reason to use flakey packages, or better still create better quality ones (hands up I haven’t done that either).

        But wouldn’t it be nice to have a universal package manager, for PHP projects without being Framework dependant (lmost Gems don’t depend on Rails, Sinatra etc)?

        Dont get me wrong sparks is great if you are a CI guy, and Cells likewise for Fuel (which is brilliant BTW), it would be better if there was some common ground… pretty sure not all sparks/cells HAVE to be framework specific. But thats a different project altogether :)

      • http://philsturgeon.co.uk Phil Sturgeon

        “But wouldn’t it be nice to have a universal package manager, for PHP projects without being Framework dependant”

        Thats what PEAR is there for. As you say if the libraries aren’t great the make them better or fix them.

        This is not a replacement for PEAR, just an easier way to locate and implement third-party code for your framework applications.

        Cells and Sparks generally rely on code in the framework itself as coupling reduces repetition. It’s the age old “coupled v standalone”. If I can use core libraries instead of writing 100 lines of code then I’ll do that, and sod having it work for CakePHP or some other framework I don’t use. I’m sure most developers would agree :)

  • Abishek

    The above code shows how a spark library is called from within a controller. Can you advice on how the spark library is invoked from a custom library under “application/libraries”?

  • E. Terry

    Looks interesting. I’ll have to give it a try.

    CI may want to remove this as a selling point though, “You are not interested in large-scale monolithic libraries like PEAR.”

  • april

    Im very very beginner, I really thanks, if I could download this fully source code to learn it more. . .

  • dekimpeb

    Can you install it in an existing CI project?