You are on page 1of 18

Chapter 2 Your First Yii Application

This chapter is a starter step to learning the Yii framework. You will be building a Hello World application but with a kick to learn your way around the framework using the integrated Yiic tool, figuring out how models, views and controllers all tie together. Its based off the tutorial I made as my first introduction to the Yii framework myself; its called Where to Start with Yii. This chapter will provide all the code for you and show you where to place it. There is nothing complex in the logic behind how it works, so everyone including beginners should have no problem understanding whats going on. If you know how to operate the Yiic shell and have coded in the Yii framework building your own classes and tying in controller-model pairs, then you could safely skip this section without being lost or confused on how to work through the rest of the guide. If youre looking to dive right into the website step by step guide, youll want to jump to chapter 3 anyway. Note: This section is based off of an earlier tutorial I made, which may be more in depth and useful to you with its simplicity. If you would prefer to check it out, check the resources below.1

Planning
If youre familiar with programming languages, then you probably know that the famous Hello World application is nothing more than printing out that string statement with the language. As such youre probably thinking, what on earth is there to plan about that? Well youre right in regards that Hello World really is that simple, but unfortunately to build on it and make it a get to know sort of application to the framework means youre going to have to go up, around and out of your way just to do the simple things. If you cant see what I mean now, dont kill yourself because it really is a different way of thinking on how to do an application so simple. However the fundamental learnings youll build will help you build much more complex applications later. So lets dig in. What were going to build here is a model that gets manipulated by a controller. That seems so overkill for Hello World but the reason why its a good idea is because every application you will build in Yii will be with a model that gets manipulated by a controller. So why not make it something simple? Now before you pluck your brains out because of this suggestion, yes this is a complete waste of effort and code lines to do something so simple. However the emphasis is not on the efficiency of the code but more on learning the framework and you cant put a time limit or effort limit on that. Now because this is a simple application and Hello World merely does just print out Hello World, Ive added a modification allowing you to edit the message that gets printed. So this will help add to the learning phases of the framework; but enough chit chat, lets get our hands dirty.

http://www.sterlingsavvy.com/tutorials/index.php

Getting Started Now before you start any application (and this one is no exception) you should plan out your goals to achieve the application. This means understanding what resources youll need (how many models, how many controllers, views etc.) and building them or for future implementation of them. This will not always be so easy to see and do and often youll find yourself building new resources on the fly which will mean going back to modify already existing resources. Were going to try and teach you how to avoid this but some things are inevitable. When you look at this simple hello world application, you have to think about what it is youre trying to do and what youll need to do it. Sometimes I find it helps having paper and a pen around to collect your logic together to figure out what it is youre doing. For this example, were going to need to create a model and a controller. The model will hold the information about the message and the controller would operate the action to display it, just like a normal model-controller relationship. So I named MessageController.php as my controller file and Message.php as my model file. Please note I have not coded nor created these files yet, well get to that shortly. Now to go one step further I have noted that our MessageController has two actions, show message and edit message. With our Message model, I established that we will have a variable to define the message, a variable to define an author and a rule set that state that when the action edit is called, form fields message and author are required. A little side note: rules exists to models specifically. They allow you to define certain trigger events to happen at certain times or with certain variables. These can include the length of a variable (a username), if two variables match or compare (passwords), when a variable is required for input (email address on registration). There are many different applications to the rules feature of a model and well explore them later more in depth. Getting back on track let me just say that thats it for the planning. One model, one controller, 2 actions, 2 attributes and a set of rules doesnt seem like much. Once again very overboard however by teaching yourself to approach all problems this way you will ensure that when you do develop complex Yii applications you will do it with precision and properly.

Yiic
Now that we have planned out our course of action for our small application, we can proceed to operate with the powers of the Yii framework. Our first stop will be the integrated command console tool Yiic. This tool will become mighty useful to you as it will speed up the tedious work of templates. The best part about the Yiic is that its customizable (well investigate that later) in which you can help make your projects move more quickly by having custom templates made. Ok so before we begin youll need to navigate to your local root folder. Since command prompt access is usually only available to local machines were making the assumption youre on your own developing machine and have your own web server setup done. If you dont have one set up you can always take a look online on how to set up your own personal web server.

From this point on, that local root folder will be our reference to web root. Open up a command prompt window and navigate to your root folder.

Step 1 Navigating to your web root folder

Now based on personal experience, I find it easier to build Yii applications from the root folder as opposed to navigating to the Yii framework folder and then trying to build the application backwards in folder hierarchy. So with that in mind, lets take step two: building a template webapp. With your root folder as your directory type the following command in the prompt: .\yii\framework\yiic webapp test Now to describe what just happened. \yii\framework refers to the folder in which the Yii framework is actually in (for you this may be different but most people with common sense make the folder yii and then have the framework inside it, easier to remember). \yiic calls the Yiic tool with the parameters webapp (which makes a template web application). Finally test refers to the folder our template web application will be made in. Test will be located within your local root folder because thats where we currently are. Once you process this command youll be asked yes or no to create the directory. Choose yes.

Step 2 Making the webapp template

After that youll see a confirmation that all the files were created and your webapp is now available and functional cool!

Step 3 Webapp template created

Ok so now we need to navigate to our test folder. This should be easy, just type in cd test and you should be there.

Step 4 Navigating to test webapp folder

Were now going to access the Yiic shell which uses the Yiic information within the framework, however is local via the shell to the current webapp youre accessing, so all commands apply to just that webapp folder. While in your test directory, type the following command: .\protected\yiic shell This should now bring you in a dialogue of the Yiic shell.

Step 5 Opening Yiic Shell

Within the Yiic shell is where youll build on to your template webapp. This is how you can create template models and controllers and have all the tedious coding already done for you. Ok so now were going to create our controller class. To save time we would use the Yiic shell to build our model class and then modify it however, this requires an active and working database connection. Since were not setting that up, youll get a chance to play with model creation and CRUD functions later in the guide.

The following sequence of code will build your controller template and add two actions to your controller class. Note: Feel free to alter the naming scheme of what you want to call your files. controller message show edit

Step 6 Building your controller class

Now you can see from the image that the Yiic shell created 4 files, a MessageController.php, then three view files for the actions within that controller; show.php, edit.php and index.php (which is created by default as there is always a default action for a controller). If you havent done so already, feel free to check out your sample web application which can be found at the http://hostname/path/to/index.php and as the image shows you can now view the creation of your controller as well by adding ?r=message And that concludes our introduction to the Yiic tool. Now you know how to navigate to it and use it, later well show you how to build lots of powerful pre-built templates and even build your own templates to run in the shell.

Building a Model
Since we couldnt build a model template with the Yiic shell tool without being connected to a database, well have to create it from scratch. Now Im going to do this in steps, explaining each step along the way but at the end I will collectively post the whole class so you could essentially copy and paste for a quick look. I would highly suggest working through however to learn how to build a class properly. With your favourite code editor, open up a new PHP file (if you use notepad or some text file editor, create the file and save it appropriately). This new PHP file should share the name of what you called your controller and should be located within the protected/models/ folder. In my case my ID for my controller was message, thus my ID for my model will also be message. However because were going to be applying some form like attributes and extending from a CFormModel class, our model file will be named: IDForm.php so in my case MessageForm.php The first step to our model creation is the PHP open / close tags, without them our PHP code is no good to our editor. After that well create our class and extend the parent class of CFormModel.

<?php /* * MessageForm Class * Basic Model that holds our "Hello World" String * and the rules and attributes to change that String. */ class MessageForm extends CFormModel { } ?>

Notice how we have defined our model with the same ID as the controller, and have added Form to it because were extending the CFormModel. Having Form attached to the naming scheme does nothing but help keep tabs on how each model is defined. Those with CActiveRecord as their parent class will just be the model ID while those with CFormModel are referenced with IDForm. Ive also included documentation about our class, its always important to document your code so you or other coders can understand what you were doing with a block of code. The next stage would be to define our variables, in other words our model attributes. Based on our planning stage, we established wed be creating a message variable and an author variable. So heres the code to plug it in.
<?php /* * MessageForm Class * Basic Model that holds our "Hello World" String * and the rules and attributes to change that String. */ class MessageForm extends CFormModel { /** * define public variables to manipulate model */ public $message; public $author; } ?>

Both these attributes were defined publically so that other classes can access and use these variables, which are needed because the User will alter them. The last step is to define our rule sets. The following is the complete code for the MessageForm model with the rules in place.
<?php /* * MessageForm Class * Basic Model that holds our "Hello World" String * and the rules and attributes to change that String.

*/ class MessageForm extends CFormModel { /** * define public variables to manipulate model */ public $message; public $author; /** * @return array validation rules for model attributes. */ public function rules() { return array( // author and message are required array('author, message', 'required'), ); } } ?>

And that completes our model, extremely simple; now to give a little detail about the rules function. In the Yii framework, as described in chapter 1 there are lots of different rules to use for your applications. Rules will help maintain the integrity of the data you use and manipulate within your model. They can perform certain PHP functions and actions on data and the works. In fact the many capabilities the rules function has is what makes the Yii framework so powerful and flexible in coding quick, efficient and easy applications. Youll see further on that it takes far less code then you could imagine completing rather complex applications.

Building a Controller
Now the fun stuff starts to happen. As you manipulate the code in the controller you can actually take a look via your web URL to see the changes and features that are now being applied to the site. So well get a good look at what were doing while we code. To start off first heres a look at what our web site looks like so far:

Figure 1 Our web site so far

As you can see, nothing fancy and nothing different from the template that was built; you have your home, a contact and a login menu link. Now navigate yourself to the protected/controllers folder and open up MessageController.php in your code editor. Given we pre-built this code with the Yiic tool, youll see some documented code for purposes of modifying default functions if you require to do so (as seen below). Since we arent tampering with those functions, were just going to remove this clutter all together. Later in the document youll learn about them and what to customize them.
<?php class MessageController extends CController { public function actionShow() { $this->render('show'); } public function actionEdit() { $this->render('edit'); } public function actionIndex() { $this->render('index');

} // ----------------------------------------------------------// Uncomment the following methods and override them if needed /* public function filters() { // return the filter configuration for this controller, e.g.: return array( 'inlineFilterName', array( 'class'=>'path.to.FilterClass', 'propertyName'=>'propertyValue', ), ); } public function actions() { // return external action classes, e.g.: return array( 'action1'=>'path.to.ActionClass', 'action2'=>array( 'class'=>'path.to.AnotherActionClass', 'propertyName'=>'propertyValue', ), ); } */ }

Once you remove your commented code, youll be left with a far smaller controller class and itll look nice and neat like so:
<?php class MessageController extends CController { public function actionShow() { $this->render('show'); } public function actionEdit() { $this->render('edit'); } public function actionIndex() { $this->render('index'); } }

Now we can get on building the code to manipulate the data from our MessageForm model. As you look at the code youll notice that every function is referenced with actionID. This is the naming convention for the public methods in a controller class. When navigating through URLs to access these functions, you will simply call their ID. The code within each function shown as: $this->render(ID); is just the code that calls up the appropriate view file. There is a different view file for each function, but there doesnt always have to be, you can customize this however you like with your own more complex applications. Lets via the controller so far by going to: http://hostname/path/to/index.php?r=message.

Figure 2 View at our message default action

Now you can see our controller doesnt do anything fancy at this point. Normally you would just display the message on the index action, meaning we would just print out our hello world on this page. However because were learning the framework and we did create two functions, an edit function to edit the message and then a show function to show it; were going to just create some links on the index action that point to either action respectively (since they wont be up on the top main menu). We could put them on the main menu links but instead well just have one pointing to the index action of our message controller and then on that page have two links pointing to the show and edit actions. Since all were going to edit on the index function is add links to the view, we dont need to manipulate any code in the controller side of it. So well start with our show function. The first step here is to create an instance of our message model class. Without one, we dont have any data to work with or manipulate. You can see how this is done as followed:
public function actionShow() { // create a new instance of MessageForm model $message=new MessageForm; }

Thats how you call a new instance of a model class, or any class you want to use. This will allow us access to the message and author variables within the message model. The next step is to check if the form values were set. Because were using a child class extending CFormModel, we can check if the form values are set when we access that page. Using the simple PHP isset() function we check to see if the message variable part of the message model class is set with any data. After all if the message is blank, whats the point of printing out our message? Heres how:

public function actionShow() { // create a new instance of MessageForm model $message=new MessageForm; /* * check to see if the MessageForm fields were filled in * * If they were, then print out the message and author * with the show render - based on what the user inputted * * If not, then print out the default hello world and * default author with the show render. */ if(isset($message->message)) $this->render('show',array('message'=>$message)); else { $message->message = "Hello World"; $message->author = "Default Author"; $this->render('show',array('message'=>$message)); } }

Now what do we want it to do if the message variable is set? Well well rend the page passing the message variable over to the view file so it can print it out. However we also want to setup an else statement in case the message variable isnt set. In that case well set the variables ourselves and then display the rendered view. Take a look at the complete code for the show action:
public function actionShow() { // create a new instance of MessageForm model $message=new MessageForm; /* * check to see if the MessageForm fields were filled in * * If they were, then print out the message and author * with the show render - based on what the user inputted * * If not, then print out the default hellow world and * default author with the show render. */ if(isset($message->message)) $this->render('show',array('message'=>$message)); else { $message->message = "Hello World"; $message->author = "Default Author"; $this->render('show',array('message'=>$message)); } }

So now you could go and check out the URL to see your changes. However unfortunately I lied to you earlier a little bit. While we are changing our controller class and the changes will alter how we see our page or what it does more specifically, until we alter the view files respectively for those actions you wont see much change. The only difference is if we had of did a CRUD operation in which case default view files are already made with pretty looking features, or even if we copied one of the already made form views (from login form or the contact form) from the template. Since we didnt do either, well have to wait till we modify our view files to see our changes. But dont be fooled! We completed a lot already and set up our function to print out our default Hello World. The next stage is to edit our final action, the edit action. This will be different in regards that we wont just be assigning variables and displaying them accordingly. Instead we have to establish if the form is set, and if its not display it. The following code is the full edit action:
public function actionEdit() { // create a new instance of MessageForm model $message=new MessageForm; /* * check to see if All the fileds are filled in on the form * if so proceed to assign the values to the variables in * the message model (author and message) * * If they validate (no errors) then render the show page * with the new data values * * If there's errors, return to the edit form showing the * errors * * Finally if the form wasn't set then we render the edit * page so that the user can input field values. */ if(isset($_POST['MessageForm'])) { $message->attributes=$_POST['MessageForm']; if($message->validate()) $this->render('show',array('message'=>$message)); else $this->render('edit', array('message'=>$message)); } else $this->render('edit', array('message'=>$message)); }

Rather than code step by step, this action here is the full action because it would be easier to explain to you whats going on and why if you see the big picture. To break it down you have your instance declaration of the MessageForm model class. After that you set yourself up with your first if statement. Like before this if statement uses the isset() function of PHP, however because Yii has built in integration with this, it recognizes that instead of looking for just one field or variable, it checks all the variable fields

associated with the MessageForm class. If nothing is set, then the action displays the edit render page so the user can fill out the form. If the fields were filled out then we assign all the field values to the attributes of the MessageForm model class. This works similar to the way the isset function did on all the fields, it pulls all the fields and transfers the data to the appropriate variables based on naming convention. After we have set all the variables with the data from the form, we call the model classs validate function. This is a default function that can be overridden to alter what it does, but essentially it checks to see if every value entered meets the criteria of the rules set in the model class. Remember those rules we set? The ones that said the author and the message variables are required? This is where it comes into play. If when the validate function is called, those variables do not have some sort of input in them, the validate function will return false. In the event it does, our code redisplays the edit render page with the error fields highlighted (thanks to Yiis Ajax features). If the validate function passes (meaning all our rules were met) then the show page is rendered instead, rending the new values of our MessageForm attributes. And that completes our controller class. Now we are ready to display our action packed application. One thing to note however, we did not make a database setup and these variables are not stored in a database. Once you change from the page of the edit or show actions, the message will be erased and replaced with the default message the next time the show page is accessed. This isnt a big issue since this application was only meant to show you the framework however dont get confused when you notice it doesnt store your messages for later keeping.

Building a View
Ok so now the fun stuff starts to happen. I would have posted an image of our web site so far, however nothing changed graphically so youd be very upset. Well thats about to change when we tamper with our view files. As you remember from chapter 1, view files hold the presentation logic; they define how to display a page and data. If you navigate to the protected/views/message folder youll see we have three view files to customize. So lets get started. The first view file well fix up will be the index view. This is because well be able to access the other two views via links from this index view as opposed to having to type in the links manually. When you open up the view file youll see the sample text that was presented to us earlier when we navigated to the message default action on our URL. Deleted everything so that way its a clean file and then code the following into your view file:
<h1>Welcome</h1> <p> To view our message go to <?php echo CHtml::link('Here', array('message/show'))?> </p> <p> To edit our message go to <?php echo CHtml::link('Here', array('message/edit'))?> </p>

Nothing fancy, just two links pointing to the show and edit functions. However you do get a glimpse of the power of the Yii framework with its easy to build URL scheme. Sure echo CHtml::link(. Array()) ?> might seem like a lot longer than <a href=></a> however this method is cleaner because the framework knows that in the array message/show actually means head to index.php?r=message/show. That doesnt seem like much of an advantage now, but when you start building more links and complex ones, youll see how useful that feature actually becomes. Now we can check to see how our web site change, Oh Boy! Navigate to http://hostname/path/to/index.php?r=message and voila!

Figure 3 Voila! Our default message action

Nothing fancy once again of course but you can see some change and some progress. As soon as we fix up the view files for the edit and show actions youll be saying this is the greatest page in my application! Ok maybe not that excitedly but still, youll be impressed with what you did and how easy it was to do. Next well tackle the show action since its already got the setup to print out the default hello world string. Opening up the show view file youll see the same text that was there in the index file, remove all of it as well because were going to replace it with the following code:
<?php $this->pageTitle=Yii::app()->name . ' - Show Message'; ?> <p><?php echo CHtml::link('Back', array('/message')?> </p> <h1>Our Message</h1> <p> <?php echo $message->author; ?> - " <?php echo $message->message; ?> " </p>

Ok so a lot of weird code in this box lets break it down for you. The top line accesses the title aspect of your current page. You know <title></title> that gets located within the <head></head> tags of HTML. The beauty however is while the title is still the title defined for the whole site (by default My

Web Application) this feature allows us to add our own custom message for the specific page after that. So in our case the page now becomes My Web Application Show Message. Pretty cool! The next line is another link that basically just offers you the option to go back to the message index, makes navigation easier. Finally we have our title and then two lines that access the variables within the MessageForm model class. Remember that instance of the model we created with the variable $message? Well when you call $message (since we passed it to the render files) you can access the variables respectively, or even functions within the model class. This is a trait of OOP. So to conclude here, the first line prints the author then a space and a dash then another space and of course our message its formatted to look like a quote. Thats it! Heres a view of the site now:

Figure 4 View of our Show action

Ok so to complete the views, lets fix up the edit view file. This one will be a bit trickier because were implementing a form like appearance. So as usual open the file and then remove all the contents to place in the following code:
<?php $this->pageTitle=Yii::app()->name . ' - Edit Message'; ?> <p><?php echo CHtml::link('Back', array('/message'))?> </p> <h1>Edit Our Message</h1> <p> <div class="yiiForm"> <?php echo CHtml::beginForm(); ?> <?php echo CHtml::errorSummary($message); ?> <div class="simple"> <?php echo CHtml::activeLabel($message,'author'); ?> <?php echo CHtml::activeTextField($message,'author'); ?> </div> <div class="simple"> <?php echo CHtml::activeLabel($message,'message'); ?> <?php echo CHtml::activeTextField($message,'message'); ?> </div> <div class="action"> <?php echo CHtml::submitButton('Submit'); ?> </div>

<?php echo CHtml::endForm(); ?> </div><!-- yiiForm --> </p>

Ok so to break down our final coded file. Just like with the show file, we have our title page setup again just with Edit Message this time and of course you have the back link again. After that we now have our form setup. The form is defined between the div with the yiiFrom class. Within it we have a bunch of CHtml functions. Well go through each one step by step. The beginForm function starts of the HTML to a form, so it probably looks like <form method= action=> and so. Next we have the Ajax implementation with errorSummary passing in the value of the message model. If the message model finds errors when validating (remember our controller) then it will display here, via Ajax. After that we have a simple class div setup to define our label and field. The activeLabel displays the title of the field you are inputting into. The activeTextField thus is the field youre inputting into. As you can see the first field is the author. We repeat these steps for the next field, the message. Finally we have the action class to display the submitButton with a title of Submit. To close it off we call the endForm which probably calls </form> and close off the yiiForm div. Easy as pie, well eating pie anyway, and forget the math gig theres nothing simple about that pi. Lets take a look at our page shall we?

Figure 5 Our edit view completed

So that concludes our project, go ahead tamper with it and youll see it works, you can change the message and itll display that changed message for you, if nothings set you already saw the default message prints. Even though Hello World really is so simple, we still managed to learn a little about the framework doing it the round-about way. But wait were not finished, lets add a few touch ups.

Touching Up Our Application


Everything is complete, so what else do we need to add? Well sure the application is done but unless you want to navigate to index.php?r=message everytime, Id say we have one more job to do. Thats right, were going to put a main menu button up linking to our message page. The main menu can be accessed from the protected/views/layout folder and opening up the main.php file. Youre going to have to navigate yourself to this section:
<div id="mainmenu"> <?php $this->widget('application.components.MainMenu',array( 'items'=>array( array('label'=>'Home', 'url'=>array('/site/index')), array('label'=>'Contact', 'url'=>array('/site/contact')), array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest), array('label'=>'Logout', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest) ), )); ?> </div><!-- mainmenu -->

Now well add our button. You can add yours wherever youd like on the menu list, but I think Im going to place mine after the index page like followed:
<div id="mainmenu"> <?php $this->widget('application.components.MainMenu',array( 'items'=>array( array('label'=>'Home', 'url'=>array('/site/index')), array('label'=>'Our Message', 'url'=>array('/message/index')), array('label'=>'Contact', 'url'=>array('/site/contact')), array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest), array('label'=>'Logout', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest) ), )); ?> </div><!-- mainmenu -->

And that folks is all she wrote. Congratulations and check out your final site product where you can now navigate to your message and edit it. I hope you enjoyed this little learners stage to the Yii framework and enjoy the more complex site building features to come in this guide.

Figure 6 Our Message linked!

You might also like