Upgrading PHPUnit on (X)Ubuntu

When I recently installed Xubuntu 13.04 and added PHPUnit, apt-get installed version 3.6. This is not unusual; the repository is usually running an older version. I happened across this article on upgrading to a newer version and am posting it here (link to original article is at the bottom). All commands should be run via command line, of course:

sudo apt-get install phpunit
sudo pear channel-discover pear.phpunit.de
sudo pear channel-discover components.ez.no
sudo pear channel-discover pear.symfony-project.com
sudo pear upgrade
sudo pear upgrade phpunit/PHPUnit

This upgraded my installation from 3.6.x to 3.7.24 (as of this writing)

Source: http://konradpodgorski.com/blog/213/how-to-install-phpunit-on-ubuntu-11-10-and-get-it-to-work/

Composer, Laravel, PHP-FIG, oh my!

It’s safe to say that my “Comparing Laravel, CodeIgniter, and Cakephp” post is the most popular entry this blog gets! I’m very glad that so many people have found it informative and relatively unbiased as they look for a “toolbox” to help them build their apps.

The downside is that it was written 9 months ago – which, in the world of programming/technology, can make a lot of difference! Since I wrote the original post we’ve seen Composer take off, PHP-FIG becoming more widely adopted, and Laravel being the “it” framework in anticipation of version 4. Because I have no desire to pit framework against framework again, let’s look at these three things ­čÖé

Composer

Composer allows you to add packages to your application by adding a line to a (composer.)json file and running a simple command via command line. I was very leery of it at first but I’ve grown quite fond of it. Being able to update a Markdown or Swiftmailer package by opening my terminal and typing “composer update” is fantastic. Definitely beats the pants off trying to keep up on version number, downloading, extracting, hoping I didn’t miss something critical. The fact that it also snags the dependencies your package will need is pretty nice, too.

The only caveat I’ve found is that you do need to be aware of the dependencies, as it can quickly fill up your vendor folder with a lot of files that only that one package might use. Disk space is certainly cheap, and the number of files you use shouldn’t really matter, but it’s still a form of bloat, and could easily get out of hand — like, “Why do I have 310 folders…oh, that’s for the XYZ package”.

PHP-FIG

PHP-FIG is a group of leading PHP devs who are striving to help our code become more consistent, more┬áinterchangeable┬á and thus easier to read and easier for programmers to use. They have (at the time of this writing) 4 standards for coding – Autoloading, Basic Coding, Coding Style, and Logger Interface.

Many devs are up in arms that someone is “trying to tell me how many spaces to use”, that “Why can’t I use tabs?”, and “No one tells me how to code!”

Personally, I think the things laid out in each standard make sense insofar as creating smooth, consistent code readability. I don’t necessarily think that using snake_case instead of camelCase for function names really matters as long as you can figure out what the code is doing, but as far as the tabs thing goes – seriously, I forgot I was using spaces instead of tabs by the end of the first day. It’s extremely annoying to open a file from someone else and not be able to read it because their tabs are set at 5.5 and the code is all over the place.

So, I feel that we should put on our big girl/boy pants and just try to work together so we can ALL succeed.

Laravel 4

To say that Laravel 4 is on fire in the PHP world is an understatement. It hasn’t even reached stable release yet and has already been nominated for “Open Source Project of the Year” at the .net Awards. That’s an accomplishment!┬áI’ve gone through and played with the L4 code and I both am and am not impressed.

The fact that it has been broken into multiple components and those bits can, theoretically, be used independently of the framework┬áitself┬á is fantastic. The Support and Database packages are perfect examples of this, and I use both in various projects. Being able to swap other packages — for example, Cartalyst’s Sentry package — is also great. It’s interesting to see, too, how they have managed to create a way for non-static classes to be used statically (via the Facade pattern), maintaining testability while allowing easy access to often used classes (like Config, Lang, etc). That said –

L4 is not quite as decoupled as it might seem; for example, to use the Pagination package you need the Http, Support, and View packages as well as the Symfony Http-Foundation and Translation packages. That’s an awful lot of code for something that should be pretty simple, and doesn’t really lend itself to easily using it outside L4.

I also found it difficult to wade through the code to find out how something worked. For example, I wanted to have a dynamic action key in a route – something like

Route::get('foo/{wut}', 'Controller@{dynamic}')->where('wut', '(add|edit)')->where('dynamic', '(add|edit)');

It took me almost an hour to work out how L4 was setting up routes to realize that this was not going to work. I’m okay with it not working, I’m not okay with it taking me that long to follow the trail.

Other,┬ánit-picky┬áthings – I don’t care for the huge App container that is passed around; it doesn’t feel much better than using global $app; or Class::$global or $this->ci->someclass, and makes it difficult when trying to debug one class (if that class has the App instance passed to it).┬áFor the majority of the projects I’ve worked on lately, L4 feels huge and like too much.

All this is not to say that L4 is bad or not “newbie” friendly. If you just need a solid base to get you started, L4 is fantastic and can get you going quite fast. Package development is not very┬ádifficult┬áeither and lets you add to what’s already there.

As always, use what works best for you and your specific project. I would certainly not use L4 for a simple website for the local ice cream parlor, but I might consider it for a local school’s community site for their sports program.

Please note┬áI speak as someone who has programmed at least part-time since 2003 and used a framework since 2006, which is to say I’m by no means an expert but I have worked with a fair amount of code. These are simply my opinions on what I’ve experienced with my usage, and your own mileage may vary.

“Illuminating Your Laravel 3 Application”

“Illuminating Your Laravel 3 Application”

Cool article giving a brief overview of some of the changes/upgrades to Laravel 4

[Quick Tip] Add Composer Dependency Manager Support To Kohana

Composer is a super cool way to manage dependencies for your applications. Kohana’s autoloader does not support Composer’s way of autoloading, so if you’re wanting to use composer packages in your application you’re going to run into issues.

However, it’s really really simple to add support. Simply open your application/bootstrap.php file, and (I added this after Kohana registered its autoloader) add

require [FULL_PATH_TO_COMPOSER_FOLDER].’autoload.php’;

Where, of course,┬á[FULL_PATH_TO_COMPOSER_FOLDER] is the actual absolute path to Composer’s auto-generated auto-loader files.

Voila! You should now have Composer support in your Kohana app! ­čÖé

(CakePHP) Get a Database Connection Instance

In my current project I am working on, I am using CakePHP and need to fetch some data from the database very early in the request cycle (don’t worry; it’s cached to avoid unnecessary queries).

In past versions of Cake you could use ConnectionManager::getInstance(). However, in 2.2 (and possibly in earlier versions of 2.x; I do not have the time to check), this no longer works.

The solution is to use the getDataSource method. So, by calling ConnectionManager::getDataSource('default') I can retrieve an instance of the default database connection and go along my day. Yay!

Quick Tip: Laravel 3.2.0 Auth Driver

I am upgrading a current project to Laravel 3.2 and had a bit of confusion with the (newly implemented) Auth drivers. I’m sure a lot of developers are able to use the Auth class as-is, but because I need some custom stuff returned when logging in/retrieving a user, I needed to figure out how to re-implement this logic.

Previously, the auth.php config file held the logic for logging in and retrieiving a user. Now, that logic has been moved to drivers (which, really, makes much more sense, but that’s just my opinion). With some help from the (awesome) forums, I was able to quickly port my code over.

1. Create a file in /libraries. For example purposes, we’ll call ours nerdy.php
2. The skeleton class for an Auth driver should look like this:

<?php
class Nerdy extends \Laravel\Auth\Drivers\Driver {

public function retrieve($id)
{
}

public function attempt($arguments=array())
{
}
}

2. Add your logic to the 2 methods.
3. Open up your application/start.php file and add the following:
Autoloader::map(array(
// Of course, you would change the class name and path to
// the actual name & path for your app.
'Nerdy' => __DIR__.'/libraries/nerdy.php
));

Auth::extend('nerdy', function() {
// Again, the class name should be the name you chose
return new Nerdy;
});

4. Finally, open your applicatin/auth.php file and change the driver value to (in this example) nerdy and save.

Not so bad once you know what to do! ­čÖé

(Source)

Extending CodeIgniter’s Database Forge Class

UPDATED 2/13: Added License (MIT) Info to code
UPDATED 1/13: Changed ‘required’ ‘required_once’ to avoid errors of redeclaring CI_DBforge

I am working on a project in CodeIgniter that requires use of the database forge class to create/modify/delete database tables. Because the project makes use of database transactions, creating tables with the MYISAM engine was not going to work. So I was faced with two choices: Make all the database creation, etc run by manual queries such as
CREATE TABLE `blah`...
or extend the dbforge class. After some tinkering about I finally managed to successfully do this. Here’s how:
(Note: I am using CI 2. This also assumes you are somewhat familiar with extending CI classes)

  1. Create a MY_Loader.php file in application/core (or open it if you already have one).
  2. If you had to create the MY_Loader file, paste the following:
    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    class MY_Loader extends CI_Loader {
    }
  3. Paste the following in your MY_Loader file:

    /**
    * Extend the Database Forge Class
    *
    * @access public
    * @author (Original) EllisLabs / (Extension) J Elmore
    * @license MIT
    * @version 1.0
    * @return string
    */
    function dbforge()
    {
    if ( ! class_exists('CI_DB'))
    {
    $this->database();
    }

    $CI =& get_instance();
    $class = 'CI_DB_'.$CI->db->dbdriver.'_forge';

    require_once BASEPATH.'database/DB_forge'.EXT;
    require_once BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT;

    if( file_exists(APPPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT) ) {
    require_once APPPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT;
    $class = 'DB_'.$CI->db->dbdriver.'_forge';
    }

    $CI->dbforge = new $class();
    }

    This basically adds the code to find/include the extended class, and instantiate it

  4. Next you need to create some folders in your application directory. First, create the folder database. Then, within the database folder, you’ll need to create a drivers folder. Within the drivers folder you’ll need to create a folder for the database type (mysql, mssql, etc) you are using. Since I am using MySQL, I created a mysql folder. My folder structure, then, looked like this:

    application/
    -->database/
    ----->drivers/
    -------->mysql/
  5. In the driver folder you created (in my case, the mysql folder), create a file in the format _forge.php. In my case I created mysql_forge.php.
  6. Create your extended class:

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    class DB_mysql_forge extends CI_DB_mysql_forge {
    }
  7. Have fun extending the functions! To get my tables to specifically create with the InnoDB engine I used the following code:

    /**
    * Modify _create_table to use InnoDB
    *
    * @access public
    * @author (Original) EllisLabs / (Extension) J Elmore
    * @license MIT
    * @version 1.0
    * @return string
    */
    function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
    {
    $sql = parent::_create_table($table, $fields, $primary_keys, $keys, $if_not_exists);

    $sql = rtrim($sql, ';');
    /* Should note here that I have a custom config file with the key/value pair to hold the
    default database engine to use */
    return $sql.' ENGINE='.config_item('database_engine').';';
    }

I tried simply extending the dbforge class but since all the magic happens in the driver classes it was necessary to extend the driver and modify the functions there. Also, I know there are ways to set the mysql server to default to InnoDB creation but since this project may be sold/released at some point it is easier to modify the CodeIgniter files than to try and provide instructions for something most people wouldn’t be able to or know how to do.

Quick Little Tip Regarding Cakephp forms

Occasionally when I am coding something in Cake that requires a form, I run into a problem if I use something like

if( !empty($this->data) ) ...

If there is another method that posts to the URL that the above code rests on (an Auth class trying to preserve the page the person was trying to reach, for example), then chances are good the method will think the user is trying to post to that method as well.

Anyway, my quick solution to ensure that only the data *I* want is posted is this:

if( !empty($this->data['ModelName']) ) { ..

This ensures that the method is only looking for the data that we want to post to it.

Quick 'n' Easy Way to Dynamically Set Per Page Limits with CakePHP's pagination

Maybe this is old news to some Cake veterans, but it took me longer than I would’ve liked to figure this out.

I have a settings table which holds a “per_page” variable and value, to allow admins to set their own per page limits for their site. However, because Cake defines $paginate variable like so:
public $paginate = array(..);
you cannot define a Configure::read or $variable to pass the “limit” key along. And pasting $this->paginate in 4 or 5 actions was not my idea of a good time.

After some head-scratching it dawned on me – define the other keys (fields, order, etc) in the $paginate variable and then simply define the “limit” key in the action itself!

Now here’s what my Controllers look like:
public $paginate = array(
'ModelName' => array(
'order' => ..,
'fields' => ..,
"conditions" => ..
)
);

Then in my action, I simply do a quick check to see if the per page limit has been set (don’t want to limit 0,0!!), and if so, set that as the limit variable:
if( $limit = Configure::read("per_page") AND !empty($limit) ) {
$this->paginate["ModelName"]["limit"] = $limit;
}

I couldn’t believe how easy it was ­čśÇ

Frameworks Part Trois (or, Sometimes when you're right, you're wrong)

Yesterday I posted about my experience trying out CI, Cake, and Kohana side by side while I work on my super-cool-blah-blah-blah idea. I mentioned how I was unable to retrieve lists of things with Cake and Kohana, and how quickly I got through things using CI + DataMapper.

Well, Houston, we hit a problem.

Last night I realized that DM was not encoding passwords before inserting/updating them in the database. I ended up changing it to just encode the posted password value and insert (not an ideal solution, IMO). This morning I was making a few other changes and running some tests and I realized something huge.

DM was not validating any of the data.

Obviously, this is a HUGE concern, and not one I was particularly interested in trying to track down and fix. On a whim I decided to give Kohana one more try, and holy [expletive] am I glad I did.

I have no idea what I was doing wrong yesterday with the ORM library but today it’s been working flawlessly (knock wood). It’s validating things the way it should, inserting and updating the way it should, and (hopefully) will help maintain the relationships the way it should.

As far as the rest of the functions and such, it was extremely easy to switch things from CI to Kohana (the fact that I’m only about 4 files in helps ;)). I’ve been able to find/figure out pretty much everything from the docs on their site and a little googling.

At this point, assuming the ORM continues working the way it should, I feel pretty good that I’ll finish up this project with Kohana.

Side note: I found a module at projects.kohanaphp.com that’s called “Debug Toolbar” and it’s pretty sweet. It shows execution time, memory consumption, all db queries, and other nerdy goodies for the developer to use. It sits at the top of the browser, out of the way, and is slightly transparent. Cool stuff!