Page 2 of 368. Agile Web Application. Development with Yii 1.1. and PHP5. Fast-track your web application development by
Agile Web Application Development with Yii 1.1 and PHP5
Fast-track your web application development by harnessing the power of the Yii PHP Framework
Jeffery Winesett
BIRMINGHAM - MUMBAI
Agile Web Application Development with Yii 1.1 and PHP5 Copyright © 2010 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book. Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: August 2010 Production Reference: 1030810 Published by Packt Publishing Ltd. 32 Lincoln Road Olton Birmingham, B27 6PA, UK. ISBN 978-1-847199-58-4 www.packtpub.com
Cover Image by Vinayak Chittar (
[email protected])
Credits Author Jeffery Winesett Reviewers Imre Mehesz
Editorial Team Leader Aanchal Kumar Project Team Leader Priya Mukherji
Jonah Turnquist Kyle Ferreira Acquisition Editor Usha Iyer Development Editors Dhwani Devater Reshma Sundaresan Technical Editors Aditya Belpathak Hyacintha D'Souza Indexer Hemangini Bari
Project Coordinator Prasad Rai Proofreader Lesley Harrison Graphics Geetanjali Sawant Production Coordinator Melwyn D'sa Cover Work Melwyn D'sa
About the Author Jeffery Winesett is the director of software engineering and application
development at Control Group Inc., a New York based consulting firm specializing in delivering technology for big ideas. He has spent the last five of his twelve years of software development focused on delivering large-scale PHP-based applications. Jeffery also writes articles on the topics of PHP, web application frameworks, and software development. He has enjoyed being a Yii evangelist since its early alpha version. I'd like to thank all of the technical reviewers, editors, and staff at Packt for their fantastic contributions, suggestions, and improvements. I'd like to thank Qiang Xue and the entire Yii Framework developer team for creating and maintaining this brilliant framework. Ryan Trammel at Scissortail design for his attention to detail and CSS assistance. My lovely wife Tiffany, for her endless patience throughout this project and Lemmy and Lucie for providing me with an endless supply of sunshine.
About the Reviewers Imre Mehesz is a long-time open source and PHP enthusiast. He started with
the classic LAMP stack around 2000 and grew into the MVC world with CakePHP, ZendFramework, and now Yii. He brought Yii into his professional life and runs the Yii Radio podcast. I would like to thank Qiang for creating this framework, and my wife who puts up with my craziness for open source development.
Jonah Turnquist is a self-taught web developer and a college student. He is a part of the developer team for the Yii Framework, mainly contributing to the official extension library, Zii. Meanwhile, he is attending a junior college in California, and he is on his way to being transferred to a four year degree in college in the Fall of 2010. He is studying Electrical Engineering and Computer Sciences. Kyle Ferreira is a student at the University of Ontario, Institute of Technology
taking a four year degree in IT (BIT) under Network Security. As a student, he has spent a lot of time researching IT security-related topics, and has valued experience working with various computer languages and equipment. He's currently running his own business in web design and development, using the Yii Framework as the basis for a lot of large projects. I would like to thank Packt Publishing and its staff for this opportunity to contribute to this production. I'd also like to thank Qiang Xue for his exceptional devotion to a well designed and functioning framework, and for his guidance in helping me learn and contribute to the framework.
Table of Contents Preface Chapter 1: Meet Yii
Yii is easy Yii is efficient Yii is extensible MVC architecture The model The view The controller Stitching these together: Yii request routing Blog posting example Object-relational mapping and Active Record Active Record The view and controller Summary
Chapter 2: Getting Started
Installing Yii Installing a >Goodbye!
This does work, but it tightly couples the view code implementation to a specific URL structure, which might change at some point. If the URL structure were to change, these links would become invalid. Remember in Chapter 1, Meet Yii when we went through the blog posting application example? We used URLs that were of a different, more SEO friendly format than the Yii default format, namely: http://yourhostname/ControllerID/ActionID It is a simple matter to configure a Yii web application to use this path format as opposed to the querystring format we are using in this example. Being able to easily change the URL format can be important to web applications. As long as we avoid hardcoding them throughout our application, changing them will remain a simple matter of altering the application configuration file.
Getting a little help from Yii CHtml
Luckily, Yii comes to the rescue here. It comes with myriad helper methods that can be used in view templates. These methods exist in the static HTML helper framework class, CHtml. In this case, we want to employ the helper method link which takes in a controllerID/actionID pair, and creates the appropriate hyperlink for you based on how the URL structure is configured for the application. As all these helper methods are static, we can call them directly without the need to create an explicit instance of the CHtml class. 1. Using this link helper, our helloWorld view becomes: Hello, World!
[ 32 ]
Chapter 2
2. Save your changes, and view the Hello, World! page at: http://yourhostname/demo/index.php?r=message/helloWorld
You should see the hyperlink, and clicking it should take you to the Goodbye page. The first parameter in the call to the link method is the text that will be displayed in the hyperlink. The second parameter is an array that holds the value for our controllerID/actionID pair. The results are displayed in the following figure:
3. We can follow the same approach to place a reciprocal link in our goodbye view: Goodbye, Yii developer!
4. Save and view the Goodbye page at the following link: http://yourhostname/demo/index.php?r=message/goodbye
You should now see an active link back to the Hello, World! page from the Goodbye page, as shown in the following screenshot:
[ 33 ]
Getting Started
Summary
In this chapter, we constructed an extremely simple application to demonstrate: •
How to install the Yii Framework
•
How to use the yiic command to bootstrap the creation of a new Yii application
•
How to use the yiic command to create a new controller within the application
•
How Yii turns incoming requests into calls to your code
•
How to create dynamic content within a controller and have it accessible to the view files for display to the browser
•
How to link internal application pages together
We have demonstrated ways to link web pages together in our simple application. One approach added an HTML tag directly to the view file and hardcoded the URL structure. The other (preferred approach) made use of Yii's CHtml helper class to help construct the URLs based on controllerID/actionID pairs, so that the resulting format will always conform to the application configuration. This way, we can easily alter the URL format throughout the application without having to go back and change every view file that happens to have internal links. Our simple Hello, World! application really reaps the benefits of Yii's convention over configuration philosophy. By applying certain default behavior and following the recommended conventions, the building of this simple application, (and our entire request routing process) just fell together in an easy and convenient way. While this incredibly simple application has provided concrete examples to help us better understand using the Yii Framework, it is far too simplistic to demonstrate Yii's ability to ease the building of our real-world applications. In order to demonstrate this, we need to build a real-world web application (and we will do just that). In the next chapter, we will introduce you to the project task and issue tracking application that we will be building throughout the remainder of this book.
[ 34 ]
The TrackStar Application We could continue to keep adding to our simple demo application to provide examples of Yii's features, but that won't really help us to understand the framework in the context of a real-world application. In order to do that, we need to build something that will more closely resemble the types of applications web developers actually have to build. That is exactly what we are going to be doing throughout the rest of this book. In this chapter, we introduce the project task tracking application called TrackStar. There are many other project management and issue tracking applications out there in the world, and the basic functionality of ours will not be any different from many of these. So why build it, you ask? It turns out that this type of user-based application has many features that are common to a great many web applications out there. This will allow us to achieve two primary goals: •
Showcase Yii's incredible utility and feature set as we build useful functionality and conquer real-world web application challenges
•
Provide real-world examples and approaches that will be immediately applicable to your next web application project
Introducing TrackStar
TrackStar is a Software Development Life Cycle (SDLC) issue management application. Its main goal is to help keep track of all the many issues that arise throughout the course of building software applications. It is a user-based application that allows the creation of user accounts and grants access to the application features, once a user has been authenticated and authorized. It allows a user to add and manage projects.
The TrackStar Application
Projects can have users associated with them (typically the team members working on the project) as well as issues. The project issues will be things such as development tasks and application bugs. The issues can be assigned to members of the project and will have a status such as not yet started, started, and finished. This way, the tracking tool can give an accurate depiction of projects with regard to what has been accomplished, what is currently in progress, and what is yet to be started.
Creating user stories
Simple user stories are a great way to identify the required features of your application. User stories, in their simplest form, state what a user can do with a piece of software. They should start simple, and grow in complexity as you dive into more and more of the details around each feature. Our goal here is to begin with just enough complexity to allow us to get stared. If needed, we'll add more detail and complexity later. We briefly touched on the three main entities that play a large role in this application: users, projects, and issues. These are our primary domain objects, and are extremely important items in this application. So, let's start with them.
Users
TrackStar is a user-based web application. There will be two high-level user types: •
Anonymous
•
Authenticated
An anonymous user is any user of the application that has not been authenticated through the login process. Anonymous users will only have access to register for a new account or to log in. All other functionality will be restricted to authenticated users. An authenticated user is any user that has provided valid authentication credentials through the login process. In other words, authenticated users are logged-in users. They will have access to the main features of the application such as creating and managing projects, and project issues.
Projects
Managing the project is the primary purpose of the TrackStar application. A project represents a general, high-level goal to be achieved by one or more users of the application. The project is typically broken down into more granular tasks (or issues) that represent the smaller steps that need to be taken to achieve the overall goal.
[ 36 ]
Chapter 3
As an example, let's take what we are going to be doing throughout this book, that is, building a project and issue tracking management application. Unfortunately, we can't use our yet-to-be-created application as a tool to help us track its own development. However, if we were using a similar tool to help track what we are building, we might create a project called Build The TrackStar Project/Issue Management Tool. This project would be broken down into more granular project issues such as 'Create the login screen' or 'Design colors="false" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnFailure="false"> [ 46 ]
Chapter 3
Now, as long as you have installed PHPUnit (see earlier Unit test section) and have ensured that Selenium Server is running (mentioned previously), and then we can navigate to our tests folder at the command prompt and run this functional test: % cd protected/tests/ % phpunit functional/SiteTest.php
What should happen is that you will see your browser being automatically invoked, as the Selenium Server platform is using the browser to access the end-user functionality of the site that we configured in the WebTestCase.php file. As it runs through the test methods, it actually automates the behavior of a real user of the site. Pretty cool! If everything worked, the end results should display back in the command line window where we executed the test. Something similar to the following will be displayed:: Time: 19 seconds, Memory: 10.25Mb OK (3 tests, 10 assertions) Being able to automate these end-user functional tests is a fantastic way to begin to automate your quality assurance testing (QA testing). If you have a separate QA team on the project, it would be very beneficial to show them how to use this tool to test the application. As mentioned, we will be focused more on writing unit tests than these end-user browser executed functional tests, as we employ a test-driven approach. However, having a test suite that covers both unit and functional tests is the best approach to ensuing the best quality in the application development. It might be the case that one of your functional tests failed when running the SiteTest.php tests. If the results of your test indicated a failure at line 44 of the SiteTest.php file, you may need to slightly alter this line to get your tests to pass. This depends on the way the logout link in the main menu displays. The autogenerated test might expect the link read just Logout rather than Logout (demo). If your functional test fails for this reason, simply change that line to read just as the logout link would read if you had logged in as demo/demo, like this: $this->clickAndWait('link=Logout (demo)');
Hello TDD!
Let's briefly revisit Hello World! demo application that we built in the previous chapter to provide an example of testing in Yii following a TDD approach. As a reminder, we have a working application that displays Hello World! and Goodbye, Yii Developer. The two action methods handling the requests to display these messages are in our MessageController class. [ 47 ]
The TrackStar Application
Let's add some new behavior to MessageController.php. Let's enhance it be able to take in any message string, and simply return that exact message string back to the caller. That sounds simple enough. We should just open up MessageController. php and add a new public method, maybe called repeat() and have it do what we just described, right? Well, not quite. As we are taking a TDD approach, we should start by writing a test for this new behavior. As we are testing the behavior of a class method, we need to write a unit test. Following the Yii defaults, this unit test should reside in the protected/tests/ unit/ folder and be called MessageTest.php. Taking small steps, let's just add a new class by this name and have it extend the base Yii Framework class for unit tests, CTestCase. Create the new file, protected/tests/unit/MessageTest.php and add to it the following code: