Pages

Saturday, June 19, 2010

Dutch PHP (un)Conference 2010





About a week ago Amsterdam was shaking since Ibuildings organized another edition of the Dutch PHP Conference at the RAI, hosted by Lorna Jane (@lornajane).

This year was also the first time uncon sessions were available for the audience to give 15 minutes (lightning) talks or full 45 minutes presentations. Both Stefan Koopmanschap (@skoop) and I (@DragonBe) were given the honor to host these sessions as part of our community involvement with the PHP user group PHPBenelux (@phpbenelux).

Since we were hosting these sessions, most of the awesome tracks I could only follow through Twitter (@dpc_uncon) and IRC, which helped me a lot to get an idea of what I was missing. But on the flip-side I had the privilege of attending the true community at it's best through the uncon sessions.

The thing with uncon sessions is that regular attendees can step up and prove themselves as future conference speaker material. All talks given at these uncon sessions are rated by other attendees on joind.in, and these ratings are looked at by conference organizers to select unknown speakers, especially if they have to invest a lot of money getting these speakers at their gig.

As a result of this feedback system on joind.in, one of our uncon speakers Martin de Keijzer (@martin1982) got himself a spot on next year's Dutch PHP Conference, as was announced at the end of this conference.

All people that talked at these uncon sessions, had interesting stuff to tell and educated the audience in an impressive way. Only a handful of uncon speakers came prepared, but most of them just created some slides during other sessions or had nothing at all, but still got their message out or started a very interesting dialog. If uncon king, Mr. Keith Casey (@CaseySoftware) was with us, he'd say we did a great job.

If you're planning to attend a PHP conference in the future, think about the uncon sessions. They have great content, stir up discussions and can offer you a spot on the main tracks of any given PHP conference.

In my final note I need to thank Stefan Koopmanschap (@skoop)) for covering me during my work related absence. You rock dude!

Big gratitude goes out to Ibuildings, who have given us the room for running the uncon sessions and for providing an uncon main track spot on next year's conference. Clearly you guys set the standard for PHP conferences!

If you attended the Dutch PHP Conference 2010, do give those speaker some feedback on joind.in and don't forget to rate the conference as well. Speakers and conference organizers need your feedback to improve their talks and/organization so they can give you the quality you're paying for.

Looking forward seeing you at DPC11 for your chance to speak !

Location:Rai, Amsterdam

Sunday, May 23, 2010

Looking back at Tek-X

When you go to an IT conference, you expect them to be informative, but not too much so you have a relaxing time while attending it. Well, this year's Tek-X (pronounced tek ten) was a "little" bit more then just informative and relaxing: 1 tutorial day, 3 full days of top sessions by the community's best speakers, workshops (hackatons) and hallway sessions were the ingredients to overload your brain while the social events after the sessions drained you from any energy left.

What follows are my chosen talks and my personal experience that these talks has given me. What's listed is not the complete schedule, since there were too many sessions during Tek X, most of them all at the same time (see schedule).

Tuesday, May 18 2010 - Tutorial days
With the rapid speed technology and processes change, you don't always find time to catch up with the flashy new bells and whistles that might make your job easier. These tutorial sessions are there just for that reason: catching up on new, innovative ideas and products.

Kristina Chodorow (@kchodorow) with her tutorial "Converting Your MySQL App to NoSQL with MongoDB" introduced the audience to a new way of storing data that's more flexible and with better performance compared to traditional databases. It has given me enough food for thoughts for learning more about this NoSQL system.

Allegedly it was (one of) Kristina's first appearances on a conference stage and she pulled it of very well having an interactive session with the audience. The quality of her tutorial and her knowledge on the subject made me forgive the "euhms" and the nervous tremble in her voice. I'm positive that she'll get over those "beginners quirks" once she's more comfortable talking to a large crowd.
Slides are not yet available at the moment, but do check out her pre-tek webcast at http://www.phparch.com/2010/04/27/webcast-mongo-scale/.

Matthew Weier O'Phinney (@weierophinney) and Lorna Jane Mitchel (@lornajane) were educating the audience on best practices with their tutorial session "PHP Best Practices". I had already seen this session before, but the both of them keep adding more interesting ideas and better approaches so it's a session I didn't want to miss.
Slides are available at http://www.slideshare.net/lornajane/best-practices-tekx.

Wednesday, May 19 2010 - Day 1
Excellent keynote "The Art of Simplicity" was given by Josh Holmes (@joshholmes), technology evangelist at Microsoft, where he was re-educating the crowd about keeping things simple. And he did a lot of damage swinging his clue bat, but he was right the whole time. Don't over-engineer challenges when the solution is right in front of you and perfect in it's simplicity. If you're organizing an IT conference, make sure to get Josh right out there on main stage !
Slides are available at http://www.slideshare.net/joshholmes/the-lost-art-of-simplicity.

Eli White (@EliW) presented "Anti-spam and anti-gaming" about the challenges you face when you have public facing web applications in regards to spam. In his excellent way, Eli showed simple hints and tips on how to fight off spam, while maintaining a superb user experience. Great content for anyone out there facing similar challenges.
Slides are available at http://eliw.com/presentations/tek-2010/tek-2010-antispamgame.pdf [PDF]

Lorna Jane Mitchel (@lornajane) presented "Subversion in a distributed world" where she compared the simple model of Subversion to the most common distributed versioning systems (GIT, Mercurial, Bazzaar) and how they all have pro's and con's in their distributed nature. An excellent talk that convinced me to at least try-out GIT, just to get a taste of it.
Slides are available at http://www.slideshare.net/lornajane/subversion-in-a-distributed-world.

Travis Swicegood followed right after Lorna's talk with his session on "Getting GIT", where he (the author of the book "Pragmatic Version Control with GIT") showed the many capabilities GIT offers in a distributed way. He also offered a more in-depth session on GIT during the Hackaton the next day, which of course I attended. A great session that provides a solution for those that often work in closed network environments or have no network at all (like in an airplane). Another session that convinced me to look at and apply GIT.

Eli White (@EliW) presented "Code & Release Management" where he went into detail about various RM strategies offering pro's and con's with each strategy. It's a real challenge sometimes to find the right strategy in order to maintain your code base and I feel Eli has done a great job explaining each solution in his own pragmatic way. I learned a lot just by being there and listening to a true expert.
Slides are available at http://eliw.com/presentations/tek-2010/tek-2010-coderelease.pdf [PDF]

Thursday, May 20 2010 - Day 2
Keynote of the day was given by Matthew Schmidt (@mpschmid) called "10 Developer Trends in 2010" where he gave the audience an insight to what he discovered at DZone. Although his predictions were basically the same trends followed by the mainstream PHP community (and much of it wasn't really shocking), it was nice to see the same trends appeared on major developer resource sites.
Slides are not yet available.

Next up was Derick Rethans (@derickr) with his insight session on "XDebug". As he is the creator of this powerful debugger tool, it comes without saying he excels at presenting the insides of XDebug. If you really wanna know more about XDebug, don't go looking for the slides on internet but make sure you're at one of his sessions on other conferences ! That's where you'll find the true value of his talk.

Matthew Turland (@elazar) had taken over the torch to promote SPL (the Standard PHP Library) with his session "New SPL Features in 5.3". His session not only gave us an idea on what's new in PHP 5.3, but he also made sure we got to know why we should choose for SPL. Because it's quicker and more memory friendly. After each specific SPL feature, he included graphs about cpu and memory usage to give us a more visual idea how SPL worked with various amounts of data.
Slides are available at http://www.slideshare.net/tobias382/new-spl-features-in-php-53

In the afternoon I attended hackaton sessions with Travis Swicegood who gave us an real good insight on how to use GIT with a Subversion repository. He showed us how to get code from an SVN repository into GIT, how to use GIT on keeping track of modifications in main branch or sub-branches and how to push those changes back into SVN. It all was a bit quick, but I've made some notes and once I've figured it all out, I'll post my findings right here at my blog.

Since it was also Zend Framework Bug Hunt Day, I stayed the rest of the afternoon in the hackaton sessions to fix bugs listed in the Zend Framework Issue Tracker.

Friday, May 21 2010 - Day 3
Ben Ramsey (@ramsey) was getting things clear in his session "Caching with Memcache and APC" where he described what the benefits are of using a caching engine and showed examples on how to use Memcache and APC.
Slides are available at http://www.slideshare.net/benramsey/caching-with-memcached-and-apc.

Lorna Jane Mitchel (@lornajane) presented "Open Source your Career", which was basically the best session given at Tek-X. She used no slides, no fancy graphics. No, she stood there in front of everyone explaining how open source could boost your career. She explained a bit about her own career experiences, but streched out to many people who use open source daily and build a career out of it.
For those of you who weren't at this session, I've heard she's giving this talk again at the Dutch PHP Conference (DPC) next month. If you want to boost your career using open source, get yourself a ticket and make sure you're there !
No slides were used in this presentation.

The community round table was the final session for me during Tek-X, basically since I was up front in the panel alongside Lorna Jane Mitchel (@lornajane), Rafael Dohms (@rdohms) and Ben Ramsey (@ramsey). Moderation was done by the King of Uncon, Mr. Keith Casey (@CaseySoftware).
This whole round table session was a motivational discussion on how to (re)start a PHP User Group in your geographical area, what pitfalls there were and how to get people come to your meeting. People that were attending showed real interest on how to organize and run a user group and how to get sponsorships. I also found that there were already a lot of people who attended our previous round table discussion and had successfully started a user group.
Side note on this: between Tek-X and the publication of this review, two people who attended our session started their own user group. So, a big hand to Chance Garcia (@ChanceGarcia) and Jeremy Kendall (@JeremyKendall) and to others good luck in your setup !
No slides were used in this talk.

Closing keynote was provided by Mr. Marco Tabinni who told us in not so many words that the community drives PHP and PHP the community. #communityworks

Tek-X was an awesome experience ! If you weren't able to come down to Chicago for this event, try better next year. Tek-X seems to me the place where ideas are born, communities are formed and friendships rise. I am happy I was part of it and I'm hoping to see my old and new friends next year for Tex 2011 !

If you're organizing an event, conference or user group meeting, be sure to have it registered at Joind.in so attendees can give valuable feedback to the speakers and other event organizers can see which talk they can accept. For those who were at Tek-X, don't forget to rate your sessions !

Another interesting feature few of the speakers used, was the QRcode barcode, which is basically a 2D barcode containing a URL, a message, an e-mail or a phone number. Using a tool on your mobile phone, you can quickly register the url for the joind.in rating, the link to the page or twitter account and so much more. You might want to try it out. This barcode on the left points back to my main site.

Thursday, May 13, 2010

Book review: Expert PHP 5 Tools

Two weeks ago I received a copy of Expert PHP 5 Tools with the request if I could review this book. Improving development processes using PHP tools is something I promote myself (see my slides about PHP Power Tools on Slideshare), so I could not refuse this request.

The book
Expert PHP 5 Tools is a new book from Packt Publishing written by Dirk Merkel. In 10 chapters Dirk introduces the reader with several PHP tools that will improve development processes and quality of code from a single developer or a team of developers. From simply syntax checking and code validation to automated testing and deploying, each chapter discusses each tool in detail and contains sample code to put the theory into practice.

Besides describing in detail tools to validate (PHPLint and PHP_CodeSniffer), test (PHPUnit), debug (XDebug) and manage PHP codebases (Subversion) and improve collaboration between developers, Dirk has dedicated a whole chapter on using UML to describe and structure your applications, a whole chapter on using Eclipse IDE with the PHP Development Tools (PDT) and continuous integration with Cruise Control and PHPUnderControl using both Ant as Phing to continuous build and deploy your PHP projects.

I must say I was impressed by the detailed description of each tool and how Dirk used simple examples in order to show the reader how to use the tool in the best possible manner. I found this book an easy read since I already had experience with the tools Dirk describes in the book, but even if I had not yet worked with them, the examples he has given in each chapter are of great value and give the reader a good insight in what each tool does and how it responds.

Conclusion
With PHP becoming increasingly important as a technology within corporate application development and enterprise development structures, using automated tools to improve quality have become very important for many developers.

Expert PHP 5 Tools is a must-read book for every PHP developer involved in professional PHP application development and wants to improve the quality of his work. Also for PHP development teams, this book will convince the reader why it's important to focus on coding standards, unit testing, automated documentation and even automated builds to structure each step in an automated, repetitive way.

Friday, April 16, 2010

Zend Framework context switching for HTML content

I tried to stay away from using javascript as much as I could, but even I could not escape from developing AJAX feature rich applications. I have chosen jQuery as my poison.

But I had already build my apps using static HTML output generated by Zend Framework, so how could I add this richness to my apps without refactoring most of my code ? Simple, by using Zend_Controller_Action_Helper_ContextSwitch, ZendX_JQuery and some minor adjustments to my view scripts.

If you have downloaded the latest Zend Framework package, you'll notice in the extras/library directory the extra jQuery component, so make sure you also include that library path to your application's include path.

The following code was tested with Zend Framework version 1.10.3.

In your controller, you have actions that displays a form and one that processes it. So, to have it processed without refreshing the page in the browser, put the following lines in your controller:

public function init()
{
    $this->_helper->contextSwitch()
         ->setContext(
             'html', array(
                 'suffix'    => 'html',
                 'headers'   => array(
                     'Content-Type' => 'text/html; Charset=UTF-8',
                 ),
             )
         )
         ->addActionContext('index', array('html','xml', 'json'))
         ->setAutoJsonSerialization(true)
         ->initContext();
}

This context switch routine allows me to use my data in HTML, XML and JSON format. Both XML and JSON are default output formats supported by Zend Framework, but the documentation didn't contain a proper example on how to output HTML.

Consider you already have put a lot of time in rendering a table according to the specific form parameters, you don't want to re-do this work to display it again to use XML or JSON formatted data. Easiest (not best) way is to have that data returned in your view without the rest of the layout spoiling your AJAX requests.

Using the context switcher defined above, we only need to add a view template using the "actionname.html.phtml" naming convention. So for indexAction it would have index.phtml for normal displaying, index.xml.phtml for XML generated output, index.json.phtml for json-formated data and index.html.phtml to have your content returned without layout.

In our requesting view template we now only have to add a container where to put that data. Since I return the full generated table, I wrap my "table" tag in a "div" block.

<div id="tableContainer">
<table>...</table>
</div>

In jQuery I use the following function to load data inside that container:

function loadData(link, placeholder)
{
    if (-1 === link.indexOf('/format/html') && -1 === link.indexOf('format=html')) {
        link += '/format/html';
    }
    jQuery.get(link, function(data) {
        var container = '#' + placeholder;
        jQuery(container).html(data);
    });
    return false;
}


A common link like
<a href="/path/to/next/page">next page</a>
becomes
<a onClick="loadData(this.href, 'tableContainer');" href="/path/to/next/page">next page</a>

And with ZendX_JQuery you don't even need to load all the jQuery scripts, Zend Framework does this for you.

First modify your bootstrapper so your view uses the jQuery components:

protected function _initView()
{
    // Initialize view
    $view = new Zend_View();
       
    // Adding jQuery view helpers
    $view->addHelperPath("ZendX/JQuery/View/Helper", "ZendX_JQuery_View_Helper");

    // Add it to the ViewRenderer
    $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
        'ViewRenderer'
    );
       
    $view->doctype('XHTML1_STRICT');
    $view->headMeta()->appendHttpEquiv('Content-Type', 'text/html; Charset=UTF-8');



    // Add a stylesheet for JQuery parts, only when it's required
    $view->jQuery()->addStyleSheet(

        $view->baseUrl('/css/ui-lightness/jquery-ui-1.7.2.custom.css')
    );
 

    $viewRenderer->setView($view);
    Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

    // Return it, so that it can be stored by the bootstrap
    return $view;
}


In your layout template, you can add between the head tags the following call:

<head>
...
    <?php echo $this->JQuery() ?>
...
</head>

That's all there is to it. Now you can add nice date pickers and other awesome jQuery and jQuery UI elments to your apps.

I know it's not the best way to AJAX-ify your apps, but it's the easiest way to convert a non-javascripted app into a more user friendly application. A nice side-effect is your app remains working for non-javascript browsers and web spiders (like those for search engines).

If you want to learn more about ZendX_JQuery, be sure to check out a presentation given by Dennis De Cock at one of the PHPBenelux UG meetings. His session has inspired me to take a deeper look at jQuery as a javascript library and ZendX_JQuery as the tool to master it.

Wednesday, February 03, 2010

PHPBenelux conference 2010 wrapup

This past weekend, Belgium was buzzing PHP all the way. PHPBenelux organized the first annual international PHP conference in Belgium and it can be called a true success. Attendees and speakers coming from all parts of the world made this event a true international conference and I was truly happy to be a part of it, this time as member of the organization.

Preparation
The months, weeks and certainly the days prior to the conference were hectic, stressful and sometimes energy draining. With lots of things that still needed to be done last minute, we have learned that we still have lots of room to improve ourselves for future events. But, as it is common to PHP development, we met our deadlines and saw everything was running smoothly.

Airport and train station runs
The conference had a few international speakers on the list, for who we had to ensure a smooth ride to the conference hotel. Stefan Koopmanschap picked up Cal Evans at Schiphol. Thijs Feryn went down to Antwerp Central Station to pick up Fabien Potencier, and had to do this 3 times returning each time without Fabien (read his blog article about what happend). I myself went to Brussels International Airport to pick up David Zülke and Rowan Merewood traveling together with Ben Waine.


Speaker's dinner and pre-conference social
As is custom to events like this, we organized as speaker's dinner where we invited our speakers and sponsors to participate in this socializing event where everyone has the opportunity to get to know each other, discuss topics and exchange ideas. We headed out to Da Giovanni, an Italian restaurant in the center of Antwerp that is known for it's overwhelming tacky design. Red-white blocked cloths everywhere: the shirts of the waiters, the tables and lamps. We had a decent meal and a very good laugh.
Following the dinner we also organized a pre-conference social in De Vagant, one of Antwerp's most known Jenever locations. This was open for everyone that was in the area and could make it to the place. But tiredness and pre-conference jitters had this social ended well before midnight.

The conference
Saturday was the big day, and what a day it was ! Sponsors arrived well in time to set up their booths and at about 8:30am the first attendees were coming in. Since it had snowed during the night, most attendees were a bit late so we started the sessions with a delay of 30 minutes (by lunch time we were already back on schedule).
After a short introduction by Stefan Koopmanschap, Derick Rethans officially opened the conference with his keynote talk "The PHP Universe", which was well accepted by the audience (See reviews on http://joind.in/1240). The following talks followed right after and filled the most of the conference.

Remote presentation
Due to bad weather, Zend's speaker Eric Ritchie couldn't make it to the conference, but by using WebEx we were able to have him present his talk "Generating dynamic PDFs using Zend Framework and JavaBridge" (http://joind.in/1268) from his office as though he was standing in the room. Although it was a bit tough to set up, I have to say it was successful fix for Zend, WebEx and us.

One downside of this approach is that Eric didn't had the chance to interact with the attendees himself during or after his keynote and as shown in the comments on joind.in there were still a few questions that the attendees wanted to clarify with Eric. So, in a technical perspective it can be called a success, but for the conference spirit it has a downside.

Closing Keynote
My personal mentor and dear friend Cal Evans was given the floor to present his closing keynote "Open Teams" (http://joind.in/1251) which was unlike the other talks not a technical subject, but non-the-less a very valuable view on how managers and developers can improve the way they operate. Unfortunately I missed this talk, but I'm looking forward seeing it on an other occasion. You can contact Cal and invite him to give this talk for the managers in your company, so your company can become "Company Awesome" everyone wants to work for.

Ibuildings Conference Social
The people of Ibuildings were really kind to sponsor the after-social event, held in the exhibition hall. Besides drinks and very delicious food, our other sponsors had some goodies to give away and so people walked away with an iPhone and Zend Studio licenses, a ticket for PHPBenelux Conference 2011, a ticket for PHPUK 2010, Windows 7 licenses, a netbook (provided by Nocus) and of course elePHPants. So a big applause to the winners and of course our sponsors for providing these awesome prizes.

Sponsors
This great conference wasn't possible without the help of our sponsors, and we all thank them for making this first conference the best start of 2010. Thank you !!!


PHP is hot !
Apparently PHP is hot, hotter then ever. At the conference, a lot of people not only attended the great sessions, but they were also looking for new PHP developers to join their teams. And they were not just giving you a great job, they even offered some real nice goodies when you signed up:
If you're a company and you're looking for PHP Rock stars, see how you can persuade them to at least talk to you. Make sure you have seen the slides of Cal Evans's talk about "Open Teams", cause if you can offer this, you do have the advantage !

PHPBenelux Team
This conference succeeded because of the never-failing, passionate help and support by the whole PHPBenelux team. I have worked in many teams already, but I have to say that working with these guys on a remote basis (all using Skype, Google docs and e-mail as main communication and collaboration tools) worked very well (as to emphasize what Cal Evans stated in his "Open Teams" talk) and everyone was there to see the result.

Teamies, thanks a lot for this wonderful experience and I'm looking forward doing the things we do best: community relations, meetings and events ! You guys rock !!!

PHPBenelux team by @phpcodemonkey

Conclusion
This was the first conference that I not only attended, but was actually involved behind the scenes. It was a great experience and I have now more respect to organizers of bigger conferences now that we know what kind of challenges they have to overcome.

Read what others had to say about our conference:
I had a blast and I hope you all enjoyed it. See you all next year at the PHPBenelux Conference 2011, and let us know how to improve ourselves for next years' conference at joind.in !!!

Thursday, January 07, 2010

Zend Framework data models

I was struggling getting my data models (as described in the Zend Framework Quickstart) to work with relations. My first solution was to create a database view that merged that data using joins to collect this data in a format that I could use in my data models. This was going great until I looked at my database where it contained over 20 views (along with 20 data models, mappers and db table gateways) ! So I said to myself there had to be another way.

Fortunately there was a solution, hinted by Felix De Vliegher on IRC. He pointed me to the Zend Framework Zend_Db_Table Relationships page on the Zend Framework online manual. And although it's clearly specified how things work, I struggled a bit to see how each component was linked to the other and when I should use what.

So, I decided to work out a small application to test and support this relationship modeling.

Step 1: Preparation
Let's start with creating a new Zend Framework project that we call "datamodels".

zf create project datamodels

This creates a new Zend Framework project that we can use to showcase these examples. We add a few directories to the application structure to store our documentation, our database and our schemas.


These are four tables all related to each other that we use to base our tutorial and test upon.


Translated into SQLite3 this looks like this:
-- filename: schema.sqlite.sql -- 
create table `user` (
    `id` integer primary key autoincrement,
    `username` text not null,
    `password` text not null
);

create table `contact` (
    `id` integer primary key autoincrement,
    `user_id` integer not null,
    `email` text not null,
    `phone` text null,
    `fax` text null
);

create table `address` (
    `id` integer primary key autoincrement,
    `type_id` integer not null default 1,
    `user_id` integer not null,
    `address1` text not null,
    `address2` text null,
    `city` text not null,
    `state` text null,
    `zip` text not null,
    `country` text not null
);

create table `address_type` (
    `id` integer primary key autoincrement,
    `type` text not null
);
Creating the SQLite3 database is now easy as 1,2,3. Just from command line execute sqlite3 ./data/db/datamodels.db &lt; schema.sqlite.sql and see the magic happen. Our database is set and ready to use.

Our test data is also stored in a file, it's contents can be found here:
-- filename: data.sqlite.sql --

-- Data for user table --
INSERT INTO `user` 
    VALUES (1, 'testuser1', 'test123');
INSERT INTO `user` 
    VALUES (2, 'testuser2', 'test234');

-- Data for contact table --
INSERT INTO `contact` 
    VALUES (1, 1, 'test1@example.com', '1-800-555-1234', '1-800-555-1230');
INSERT INTO `contact` 
    VALUES (2, 2, 'test2@example.com', '1-800-555-2234', '1-800-555-2230');

-- Data for address table --
INSERT INTO `address`
    VALUES (1, 1, 1, '1 Test Home', '', 'Testtown', 'ZF', '1234', 'PHP');
INSERT INTO `address`
    VALUES (2, 1, 2, '2 Test Home', '', 'Testtown', 'ZF', '1234', 'PHP');
INSERT INTO `address`
    VALUES (3, 2, 2, 'Test Corp, LTD', '4 Test Ave', 'Testtown', 'ZF', '1234', 'PHP');
    
-- Data for address_type table --
INSERT INTO `address_type`
    VALUES (1, 'Home address');
INSERT INTO `address_type`
    VALUES (2, 'Billing address');


In application/configs/application.ini we need to add the following lines in order to use our newly generated database:

[production]
...
resources.db.adapter = "Pdo_SQLite"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/datamodels.db"

You also need to define our "Default" namespace in the application bootstrap file Bootstrap.php. This is done by adding the following lines there.

protected function _initAutoload()
    {
        $autoloader = new Zend_Application_Module_Autoloader(array (
            'namespace' => 'Default',
            'basePath' => APPLICATION_PATH,
        ));
        return $autoloader;
    }

Creating the four data models along with their mappers and table gateways is a bit of work so I've provided the application as-is on a public SVN repository (https://svn2.hosted-projects.com/in2it/datamodels/tags/step_1). You can export it and start from there.

Step 2: Displaying a user listing
We want to display a listing of users with their contact details and the number of addresses they have, more or less like the following table:

Username
E-mail
Phone
Fax
# addresses
testuser1
test1@example.com
1-800-555-1234
1-800-555-1230
1
testuser2
test2@example.com
1-800-555-2234
1-800-555-2230
2

As you can see now, with this listing we have 3 tables combined and without some relational information between the models it's hard to get this kind of listing.

Let's set up our dbTable classes to work with relationships.
class Default_Model_DbTable_User extends Zend_Db_Table_Abstract
{
    protected $_name = 'user'; 
    protected $_dependentTables = array (
        'Default_Model_DbTable_Contact',
        'Default_Model_DbTable_Address',
    );
}

class Default_Model_DbTable_AddressType extends Zend_Db_Table_Abstract
{
    protected $_name = 'address_type'; 
    protected $_dependentTables = array ('Default_Model_DbTable_Address');
}

class Default_Model_DbTable_Contact extends Zend_Db_Table_Abstract
{
    protected $_name = 'contact';
    protected $_referenceMap = array (
        'User' => array (
            'columns' => array ('user_id'),
            'refTableClass' => 'Default_Model_DbTable_User',
            'refColumns' => array ('id'),
        ),
    );
}

class Default_Model_DbTable_Address extends Zend_Db_Table_Abstract
{
    protected $_name = 'address'; 
    protected $_referenceMap = array (
        'User' => array (
            'columns' => array ('user_id'),
            'refTableClass' => 'Default_Model_DbTable_User',
            'refColumns' => array ('id'),
        ),
        'Type' => array (
            'columns' => array ('type_id'),
            'refTableClass' => 'Default_Model_DbTable_AddressType',
            'refColumns' => array ('id'),
        ),
    );
}

In order to use these relations, we create a new model and mapper for listing these accounts.

class Default_Model_Accounts extends Default_Model_Abstract
{
    protected $_username;
    protected $_email;
    protected $_phone;
    protected $_fax;
    protected $_addressCount;
    
    public function getUsername ()
    {
        return $this->_username;
    }

    public function setUsername ($username)
    {
        $this->_username = (string) $username;
        return $this;
    }

    public function getEmail ()
    {
        return $this->_email;
    }

    public function setEmail ($email)
    {
        $this->_email = (string) $email;
        return $this;
    }

    public function getPhone ()
    {
        return $this->_phone;
    }

    public function setPhone ($phone)
    {
        $this->_phone = (string) $phone;
        return $this;
    }

    public function getFax ()
    {
        return $this->_fax;
    }

    public function setFax ($fax)
    {
        $this->_fax = (string) $fax;
        return $this;
    }

    public function getAddressCount ()
    {
        return $this->_addressCount;
    }

    public function setAddressCount ($addressCount)
    {
        $this->_addressCount = (int) $addressCount;
        return $this;
    }

    public function getMapper()
    {
        if (null === $this->_mapper) {
            $this->setMapper('Default_Model_Mapper_Accounts');
        }
        return $this->_mapper;
    }
    public function populate($row)
    {
        if (is_array($row)) {
            $row = new ArrayObject($row, ArrayObject::ARRAY_AS_PROPS);
        }
        if (isset ($row->id)) {
            $this->setId($row->id);
        }
        if (isset ($row->username)) {
            $this->setUsername($row->username);
        }
        if (isset ($row->email)) {
            $this->setEmail($row->email);
        }
        if (isset ($row->phone)) {
            $this->setPhone($row->phone);
        }
        if (isset ($row->fax)) {
            $this->setFax($row->fax);
        }
    }
    public function toArray()
    {
        return array (
            'id' => $this->getId(),
            'username' => $this->getUsername(),
            'email' => $this->getEmail(),
            'phone' => $this->getPhone(),
            'fax' => $this->getFax(),
            'address_count' => $this->getAddressCount(),
        );
    }
}

class Default_Model_Mapper_Accounts extends Default_Model_Mapper_Abstract
{
    public function getDbTable()
    {
        if (null === $this->_dbTable) {
            $this->setDbTable('Default_Model_DbTable_User');
        }
        return $this->_dbTable;
    }
    
    public function fetchAll($className, $where = null, $order = null, $count = null, $offset = null)
    {
        $entries = array ();
        $model = null;
        if (!is_string($className)) {
            require_once 'Zend/Exception.php';
            throw new Zend_Exception('Model class name should be a string');
        }
        if (is_string($className)) {
            if (!class_exists($className)) {
                require_once 'Zend/Exception.php';
                throw new Zend_Exception('Non-existing model class name provided');
            }
        }
        if (null !== ($resultSet = $this->getDbTable()->fetchAll($where, $order, $count, $offset))) {
            foreach ($resultSet as $row) {
                $model = new $className;
                if (!$model instanceof Default_Model_Abstract) {
                    require_once 'Zend/Exception.php';
                    throw new Zend_Exception('Invalid model class provided');
                }
                
                // let's get contact details first
                $contacts = $row->findDependentRowset(
                    'Default_Model_DbTable_Contact',
                    'User'
                );
                $contact = $contacts->current();
                $model->populate($contact);
                unset ($contacts, $contact);
                
                // let's see how many addresses this contact has
                $addresses = $row->findDependentRowset(
                    'Default_Model_DbTable_Address',
                    'User'
                );
                $addressCount = count($addresses);
                $model->setAddressCount($addressCount);
                unset ($addresses, $addressCount);
                
                // now it's time to add our user details to the model
                $model->populate($row);
                $entries[] = $model;
                unset ($model);
            }
        }
        return $entries;
    }
}

And to view our completed table, we need to modify our view partial userlisting.phtml:

<tr>
  <td><?php echo $this->escape($this->username) ?></td>
  <td><?php echo $this->escape($this->email) ?></td>
  <td><?php echo $this->escape($this->phone) ?></td>
  <td><?php echo $this->escape($this->fax) ?></td>
  <td><?php echo $this->escape($this->address_count) ?></td>
</tr>

Now we have our table set as we want it:



You can download this step from the repo to see the changes yourself: https://svn2.hosted-projects.com/in2it/datamodels/tags/step_2.

Conclusion
Once you have figured out how these relationships work, you can extends your model capabilities without resorting to other solutions (like using database views) or maintaining crappy code.

On the other hand, It would be nice if I could use my already created models with their functionality in one go, so I can link my datamodels instead of my data sources. Need to figure this one out.

Tuesday, December 29, 2009

A great 2009 !

It's that time of year again where one looks back to all the things that have happened in the past 12 months. 2009 has to be the most thrilling, fastest ride ever and I'm really surprised to see it's nearly the end of this year.

PHP
The most thrilling part of 2009 was the release of PHP 5.3 on June 30. With this release, PHP has risen to a new level of development implementing some long awaited features like DateTime, namespaces, closures, gotos (who wants to use that ?!?), late static binding and an improved garbage collection. Also new extensions were added to this release like ext/phar, ext/fileinfo and ext/intl.
I want to express my gratitude to all those developers who have made this release possible and to all the participants of PHP Test Fest for making their contributions worth the while.

Zend Framework
It's also worth mentioning that Supreme Allied Commander Matthew Weier O' Phinney, his team and all developers around the world have done a great job improving Zend Framework. With the release of Zend Framework 1.8, lot's of things changed within the way applications are being bootstrapped and provided a more flexible way to deploy feature rich applications with a very modular structure.

PHP Conferences
For me personal it was a very exciting year where I was speaking at some great conferences on stage and in uncon sessions (thank you Keith!). If budget allows it, I'll be attending these conferences again in 2010.
One conference will be added to this list in 2010 since I'll be co-organizing it: PHPBenelux Conference.
If you ever want to catch up on the hottest game in PHP, be sure to check out these and other great PHP conferences on the PHP website. You'll learn so much from the conference itself, the speakers and the audience itself, it's really worth the money.


Macq Electronique
Since March of this year I've been working as a PHP/Zend Framework consultant for Macq Electronique, a hardware manufacturer in Brussels that provides hardware solutions for governments (like automated traffic panels, speed enforcement cameras, tunnel control and pump installation monitors). I would like to thank the company for giving me inside view of these infrastructures and I'm excited to work with them again in 2010.


Thank you !
I would like to express my gratitude to the following people who have thought me a few valuable lessons that I can use in my personal and professional life:
  • Cal Evans:
    Cal, to you we now have our own PHP conference in January. Without your support, advise and never ending belief in us, we weren't able to pull it off. Thank you !
  • Matthew Weier O'Phinney:
    Matthew, although we never had the chance to sit down and discuss things I do want to thank you for all the good work you have done for Zend Framework and the PHP Community. If it wasn't for you, I'd still be stuck writing crappy code with code replication and re-inventing the wheel all over again. Thank you !
  • Keith Casey:
    Keith, thanks to you I was able to talk about stuff that matters to me and being able to inspire people to become interested in things like SPL and Unit Testing. Thank you !
  • Stefan Koopmanschap:
    Stefan, although it seems I've been giving you lots of advice this year, you have shown me what a true spirit means. With your enormous passion for PHP and your ideas to promote PHP in ways that I never could think possible, I owe you so much. Thank you my friend !
  • Chris Cornut:
    Chris, I would like to thank you for giving us Joind.in. With it's simple interface and it's purpose it has given me so much feedback on how to improve my skills as a speaker. Without it, I would never known what areas I could improve myself. So thank you very much for your efforts !
Conclusion
2009 was a great year and I'm sorry to see it end. But a new year is around the corner and who knows, it might bring even more excitement and fulfillment. Anyways, I wish you all a very happy new year and I hope to see you again at a conference somewhere in the world.