Vous êtes sur la page 1sur 32

Version 0.

7 (8th September 2011)

&

MVC architecture
... Practically, in examples

A brief introduction for greenhorns


. By a Yii greenhorn:

Content
1. 2. 2.1. 2.1.1. 2.2. 2.3. 3. 4. 4.1. 5. 5.1. 5.2. 5.2.1. 5.2.1. 5.2.2. 5.3. 5.3.1. 5.3.1.1. 5.3.1.2. 5.3.1.3. 5.4. 5.4.1. 5.4.2. 5.4.3. 5.4.4. 5.4.5. 5.4.5.1. 5.4.5.2. 5.4.5.3. 5.5. 5.5.1. 5.5.2. Prerequisites.................................................................................................................................... 4 MVC - Architecture description ....................................................................................................... 4 Controller..................................................................................................................................... 5 Action ...................................................................................................................................... 5 Model .......................................................................................................................................... 6 View ............................................................................................................................................. 6 What is it a Framework (and why to use it) .................................................................................... 7 Yii framework .................................................................................................................................. 7 The demo project in Yii (why and how to use it)......................................................................... 7 Using Yii in praxis ............................................................................................................................. 9 Create demo project and set it up .............................................................................................. 9 Create database for your project ................................................................................................ 9 DB design tool ....................................................................................................................... 10 Run yiic shell .......................................................................................................................... 12 Define relations in Models manually..................................................................................... 12 How to create your first Controller ........................................................................................... 13 Controller - notes from praxis .............................................................................................. 14 Session ............................................................................................................................... 14 Using relations ................................................................................................................... 14 Setting HTML page title ..................................................................................................... 14

View ........................................................................................................................................... 15 Grouped drop down list ........................................................................................................ 15 Creating links: ........................................................................................................................ 16 Sending variables to View from Controller ........................................................................... 17 Send form using hyperlink (not button) + confirm ............................................................... 17 Ajax (operations on background, real time form validation) ................................................ 18 textBox dropDownList .................................................................................................. 19 dropDownList dropDownList ........................................................................................ 20 textBox textbox ............................................................................................................. 21

Models and using them - in praxis (new!) ................................................................................. 22 basic overview of models code ............................................................................................ 22 overview of another useful methods .................................................................................... 26

5.5.2.1. 5.5.2.2. 5.5.2.3. 6. 7.

Scope() ............................................................................................................................... 26 defaultScope() ................................................................................................................... 27 Other things ....................................................................................................................... 29

Themes (new!)............................................................................................................................... 30 Used links ...................................................................................................................................... 31

1. PREREQUISITES
I suppose the reader is familiar with PHP and databases (DB). He should be able to write SQL query, use DB in PHP and create at least a simple web using PHP, HTML, CSS and DB. If you dont know anything about PHP and DB, I recommend that you stop reading and have a look at it. And whats also important is OOP (Object oriented programming). This means classes, overriding functions, using constructor, public and private methods and properties, etc Can be practiced in PHP, Java, C#

2. MVC - ARCHITECTURE DESCRIPTION


First of all, we will generally look at the MVC abbreviation used above. MVC (Model-ViewController) is a type of application architecture. Its used in Yii framework. When your application uses MVC architecture, it is divided into 3 basic parts. M = Model = Part that defines relations among data in DB and rules that must be

followed when saving data do DB. It also gives us tools to read/save data from/to DB. V = View = Part that is used just to show data to user. It doesnt write to DB or count

difficult things. It just receives data and shows them using HTML, CSS, JS C = Controller = Part that processes and changes the data, handles users actions and decides, counts, thinks It simply acts.

DB

Model

Controller

View

Image 1) MVC schema

Notice the arrow directions in picture above. Controller can read/write data from/to database only via Model. Controller also evaluates user inputs, combines it with data, counts new values and sends outputs and results to the View and DB. View formats given data and shows them. (For example draws table etc.) 4

As we can see, the Controller is the central point. Its the boss. Whatever you do - Controller processes it and decides what to do next. Asks for appropriate data from DB and does what you wanted to do. We can see that Model and View dont do anything, unless they are asked to. In some cases, Model and View do not have to be used. So lets focus on Controller now.

2.1.

CONTROLLER
Controller is initiated whenever you enter any address in browser. When you use

MVC architecture (in Yii framework), addresses have special format. They include parameter that specifies which controller will be used. Yes, you can have more controllers. Each controller can be used to work in different part of your web. One controller can work with user accounts, another one with products you sell etc. And what does the web address look like when you use MVC? www.myweb.com/index.php?r=myController Parameter r says that you want to use Controller named myController. And here we can see another speciality of MVC (or Yii). Addresses contain only index.php. No other files. All the navigation is done by the r parameter and controllers.

2.1.1.

ACTION
Controller can have one or more sub-controllers. Each does something else.

If our controller edits users than his one sub-controller can delete users, another one can add users, third one changes them These sub-controllers are called Actions. You can (have to) specify action using the r parameter. As we saw above, controller was specified like this: ?r=myController. If our controller had action called myAction, and if we wanted to run it, we would write this address: www.myweb.com/index.php?r=myController/myAction We can rewrite this address for example like this: www.myweb.com/index.php?r=users/edit

If you do not specify action and run only controller like this ?r=myController than the default action will be run. The default action has to be specified in the controller using function actionIndex().

2.2.

MODEL
Model is very simple thing in Yii. You dont have to write a single line of its code, it

can be created automatically using command line. Each table in DB has its own model. This model has the same (or similar) name like the table. Each model has 2 important functions. Find data and Save data. Thats all we usually need. When you need to read data from DB to controller you just write something like ModelName.FindAll() and thats it. No SQL queries, no fetching array (as you would have to do in PHP). Thats the advantage of Yii and its objectoriented access to DB. When you want to write to table, the command looks cca like this: ModelName.column=value; ModelName.Save(). Thats it again. Another thing that the Model provides is relations. These relations enable you to tunnel through one table to another. Important are Foreign Keys. Relation is something like SQL Join. When every employee has in its table the ID of his department, you can easily get info about this department by writing something like this: $employee->department. Where the word department is name of the relation.

2.3.

VIEW
As I wrote above, view has no intelligence. It just receives data from Controller and

shows them. This is the only place where we use HTML, CSS, JavaScripts etc. We of course can use FORs, WHILEs, Ifs, models But the only aim is to show data to user. Correction: Described View is an ideal view. In praxis its much easier not to send data from Controller to it, but to read data from DB in View (using model) and show then.

3. WHAT IS IT A FRAMEWORK (AND WHY TO USE IT)


In a shortcut. Framework is a set of functions that can ease your work. Functions are usually grouped into Classes. One example for all. In Yii framework there is available class named CHtml. Its obvious, that it provides functions for creating HTML code. (Tables, lists, forms...). You dont have to use HTML and solve its validity. You just call function CHtml::beginForm(); and it creates this html code: <form method=post action=thisScriptName>. And why to use frameworks? It makes your work easier. You dont have to program every single detail, framework does something for you automatically. Yii for example integrates formvalidation functions, it handles user logging and much more. You just have to discover its possibilities and learn to work with them. But its the hardest thing. (Sometimes its faster to create your own function than to try to understand a prepared solution) And thats why I write this manual. To show some possibilities in one place and in praxis so you wont have to google the basics.

4. YII FRAMEWORK
Yii framework has its web [1] and documentation [2]. All you need to do (if you want to use it) is to download and extract it to your localhost-folder. You of course need a PHP and MySQL server (I use WAMP: [3]. If you want to try it, turn off Skype for the moment when Wamp is starting. Otherwise it wont start.)

4.1.

THE DEMO PROJECT IN YII (WHY AND HOW TO USE IT)

Now you have Yii installed (= you copied all files to localhost-folder). And what next? It may look useless now The best way to become a friend with Yii is to try the Demo project, go through it and look what its code looks like. Every manual describes it, but doesnt explain why you should use the Demo project. I didnt understand why everybody was pushing me into some boring demo project, while I wanted to do a real one. The demo project is good because you will see the folder structure, which is important. When you walk through the code and files, you will understand how you can send data from Controller to View or how forms are validated. You will see how works navigation using the r parameter etc.

These [4] [5] [6] could help you. Manuals describe basic work with Yii like creating demo project, relations among tables etc Important think for Windows! To use command line commands mentioned in manuals (you need them to create the demo project and to use the best things Yii offers = mainly relations between tables), you will have to modify the environmental variables. Right click This computer choose Properties, than Advanced tab and click on button Environmental Variables. A new window with 2 list-boxes will appear. In the lower one find row with variable named Path. Add to its value something like this: (yii framework folder path and php path) C:\Program Files\wamp\www\yii\framework ; C:\Program Files\wamp\bin\php\php5.3.0

5. USING YII IN PRAXIS


Here will be examples of commonly used functions, useful tricks etc. These things are hard to be figured out just so. I will paste here everything I have discovered so far.

5.1.

CREATE DEMO PROJECT AND SET IT UP

If you are a rookie, first of all, you should create the demo project, set connection to your DB [7] and understand how it works. When you already are a friend with Yii, you could be able to create folder structure just by yourself.

5.2.

CREATE DATABASE FOR YOUR PROJECT

Very important thing is database. You should design it first. Before writing any code. When this is done, you will use command line to generate part of your application automatically. Command line can generate models, views and controllers. (I generate only models because I want to make it my way) See this. Its 4th part of a Yii tutorial [8]. In this tutorial [8] is said, how you should name tables and columns to be able to generate relations among tables automatically. But names are not so important. More useful is to declare relations in DB when designing it. If you use PhpMyAdmin, just create a table with foreign keys (FKs) and go to the Structure tab and under the list of columns you will find link to relations creation. When you click it a new screen appears and you can set foreign keys (FKs) relations. Or use software mentioned bellow to design whole DB (I recommend). When SQL relations are defined, Yiis console will recognize them and will automatically create relations among Models. Otherwise you would have to declare these relations manually. Which is not impossible, but more comfortable is to have it in DB definition.

5.2.1.

DB DESIGN TOOL

Very interesting thing is that relations will be created automatically when you define foreign keys using SQL relations. I recommend for example software MySQL Workbench [10] which is freeware. It allows you to design your DB including SQL relations using graphical tool (ER diagram). You can also enter default data to your tables. Its very comfortable mainly when you need to delete DB and create it again, or when it has to be redesigned. You see everything on one screen.

Image 2) MySQL Workbench in action - ER creation

To create relation between 2 tables, create first the tables. Then you will need only 1 button from the toolbar thats on the left side of the screen. Its the one on the bottom. Its name is Place relation using existing columns. No other relations will be needed. Click this button and you will be asked to select FK column in any table. Select it and click the button in the black box that appeared few seconds ago. Then you click appropriate PK column in another table and youre done with this relation

10

When youre done with DB design, you just export the whole DB into an SQL script and paste it to your DB editor (for example PhpMyAdmin), or in new version you can export DB directly to MySQL using shortcut Ctrl+G I think. Finally you run the command yiic shell and create models. Simple and quick. I recommend that you go to menu Tools / Options and set History size to ca 10-30 steps. Default value is 0, which means unlimited number of undo steps. But it slows down the application very very much. In versions released in year 2011 I noticed their instability under Win XP SP3. So be patient.

Image 3) Workbench in action - DB overview

11

5.2.1.

RUN YIIC SHELL

When your DB is ready, set the DB connection in file yourProject/protected/config/main.php. Than go to your web-project folder using Command line and write command: yiic shell. It will enable the Yii console and you will be able to create model for 1 table like this: model tableName, or for all tables at once like this: model * You can use command: crud TableName to generate administration for our table. Than you can, of course, change generated forms and web pages to fit your requirements.

5.2.2.

DEFINE RELATIONS IN MODELS MANUALLY

Now, when you created models for all tables, it may be necessary to define relations (if they were not generated automatically or when you need more of them). This can be done using function relations() in model file.. see the video [5], time 12:15 or manual [9]. What is the relation? As I wrote above, its an SQL Join. You specify Primary key (PK) and foreign key (FK) using these relations and Yii can then tunnel from Employee to his job description via Jobs FK in the Employees table. When you make relation from list of employees to their jobs and name this relation job, you can then write this in Controller to get employees job:
$Employee = Employees::model()->findByPk($employeeId); $myJobName = $Employee->job->jobName; Where: Employees = model of table created using yiic shell. jobName = column in Jobs table. job = relation name. $Employee = 1 returned record from table Employees - only one because we were searching by PK. If we searched using findAll() it would return list of records and it would be necessary to walk through them using foreach. In your model should be cca this function: public function relations() { return array( 'job' => array(self::BELONGS_TO, 'JobsTableName', 'id_job'), ); } But Im not sure with the BELONGS_TO. Second possibility is HAS_ONE. See links and explanations. And as I am never sure, I recommend to specify relations in DB a generate them using command line.

12

5.3.

HOW TO CREATE YOUR FIRST CONTROLLER

You just need one file in folder: protected / controllers. The file must be named like this: NameController.php. Blue is common for all controllers. Green is name of your controller. First letter of the Name is upper case as same as the first letter of Controller. Its necessary for Linux servers. Example. You want to create controller named My first. The filename will be MyfirstController.php. And whats inside? <?php class MyfirstController extends Controller { public function actionIndex() { here is your code for this action } public function actionMyaction() { here is your code for this action $this->render(myview); } public function getEmployeeName() {} } ?> As you can see, controller is a Class and contains definitions of action and non-action functions. Default and important action is actionIndex(); Its used when you dont specify any action in r parameter (as mentioned above). You can add any action you want. For example My action as shown above. The r parameter of actionMyaction would look like this: ?r=Myfirst/Myaction. What does mean the row where is written: $this->render(myview); ? It tells the action to run a view. View is the part of your application, where you use HTML, CSS formatting etc. and its used to show anything to user. Vide infra. (You can also try function renderPartial() can be usefull) Yii will look for this view in folder Views/Myfirst. Where Myfirst is name of controller. Yes, every controller has its own set of views.

13

5.3.1.

CONTROLLER - NOTES FROM PRAXIS

5.3.1.1. SESSION
In controller, you may want to use a Session so you can send data among scripts without using forms, POST or GET. (Session is a PHP term, use Google to understand) If you want to use session in Yii, you just write this: Yii::app()->session[varName] = $value; Thats it. Session variable will be automatically registered, session will be started, etc.

5.3.1.2. USING RELATIONS


If you use relations, you can access one table from another one using command like this: $employees = $department->get_employees; (get_employees = relation name) You can also specify which employees you want to get - by DB column name: $employees = $department->get_employees(array('condition'=>'born<1950')) Or you can join tables and order it by any column:
$subMenuItems = MainMenu::model()->with('relation1.relation2')->findAll(array('condition'=>'id>21 and relation2.tableColumnName = 3', 'order'=>'relation1.tableColumnName'));

Explanation: Model named MainMenu has relation named relation1 which is pointing to another model (to another table in DB). The target model has relation named relation2 referring to a third table. Using command MainMenu::model()->with('relation1.relation2') we join 3 tables.

5.3.1.3. SETTING HTML PAGE TITLE


Every action in every controller does something different. So its good to set page title in every action. You can do this by this command: $this->pageTitle = My page title. If you want to use your project name in this title or anywhere else, you can use this system variable: Yii::app()->name. Its value is set in file: protected/config/main.php

14

5.4.

VIEW

View is a very simple thing so I will just show some tricks.

5.4.1.

GROUPED DROP DOWN LIST

Html code can be generated semi-automatically using static class CHtml. You can create for example drop-down-list like this: Instead of this: <select name="selectName" id="selectName"> <option value="1">item1</option> <option value="2">item2</option> </select> You can write this: echo CHtml::dropDownList($name, $select, $data, $htmlOptions); $name = name that will be used in $_POST when form is send $select = string with selected value $data = content - interesting think, see bellow $htmlOptions = classical string containing ca this: width=100 style=color:red;

$data = CHtml::listData( Model::model()->findAll(),'id_item','item_descr' ) Method listData() just generates following array: array(value1=>caption1, value2=>caption2 )

Explanation: $data is a set of <option> tags. Basically its simple mixed Array with name=>value pairs. This Array can be created automatically using function: listData($listOfItems, $valueColumn, $captionColumn) $listOfItems = its clear, you use for example: findAll(array(condition=>id>4)) $valueColumn = what column will be used to fill the value of <option> tag $captionColumn = what column will be used to fill the caption of <option> tag

15

4th (now not used) parameter is name of a column that is used to group items in dropdown-list.

How works the 4th parameter? Lets say you have a list of countries. Each country belongs to 1 continent. In your drop down list you want to see all the countries. But not mixed together. You want them to be grouped by continents like this:

<optgroup label="Europe"> <option value = 2>England</option> <option value = 1>Germany</option> <option value = 3>Spain</option> </optgroup>

How to do this? If you have 2 tables 1st for countries, 2nd for continents you should create an SQL VIEW that will put these tables together using JOIN. This View will be the source model for your drop-down-list. (SQL Views appear like tables and you can create model for them) Now you can use the 4th parameter in dataList() and set its value to Continent.

Your view should look like this: Continent ID 1 1 1 2 Continent Europe Europe Europe South America Country ID 1 2 3 4 Country Germany England Spain Brasilia

5.4.2.
www links. To

CREATING LINKS:
create urls always use method $this->createUrl(controller/action) or

Here I Will just recommend to use function CHtml::link(). It can solve some problems with

$this->createUrl(action) !

16

5.4.3.

SENDING VARIABLES TO VIEW FROM CONTROLLER

When you want to send something from Controller to a View, you just add 1 parameter to $this->render() method. Like this: $this->render(myview, array(variableName=>$value)); Variable name = In the View you can start using variable of this name. $value = vale of previously introduced variable. It can be integer, string, array, mixed array. Whatever.

5.4.4.

SEND FORM USING HYPERLINK (NOT BUTTON) + CONFIRM

<a onclick="javascript: if(confirm('Really delete?')){ self.document.forms.formName.submit()}" onmouseover="style.cursor='Pointer' " > Delete </a> This will show ordinary hyperlink Delete. When its clicked, a JavaScript confirm-box appears. When you click YES, it does what is written in onclick section. In this case, a form named formName is send to the server. When you put mouse on the Delete caption, your cursor will be changed to classical hand. Dont forget to use escape characters when writing javascript using php echo. JS requires apostrophes instead of quotes. You cannot write this: <?php echo word-in-apostrophes ;?> Apostrophe can be written like this: <php echo \' word-in-apostrophes\' ; ?>

17

5.4.5.

AJAX (OPERATIONS ON BACKGROUND, REAL TIME FORM VALIDATION)

When I say real-time I mean that this real-time operation is done without reloading page. Its used (e.g.) for checking password difficulty (web page changes the difficulty status as you write longer and longer word into the password textbox). Or Google uses it to whisper you while entering searched phrase. If you search the internet for an advice how to work with Ajax, how to create real-time form validation, real-time textbox whispering you find just difficult and uncomfortable solutions. Yii is different. It offers really simple and quick solution. I will show 3 examples I understand now. The first one changes content of a dropDownList based on what you enter into textbox, the second one changes dropDownList based on what you enter into another dropDownList and the 3rd one changes textbox based on what you enter to another textbox.

18

5.4.5.1. TEXTBOX DROPDOWNLIST


Below you can see an example of code in your View. There is a textField which is waiting for you to enter a text. Second item is a dropDownList. Its empty now. It will be filled when you enter a text into the textField and click somewhere else. Important thing is the action mentioned in the URL section. This action must be written in actual controller. Its the controller you used to draw this view.
// CHtml::textField($name, $value, $htmlOptions) echo CHtml::textField('myTextField','', array( 'ajax' => array( 'type'=>'POST', //request type 'url'=>CController::createUrl('myActionName'), //action to call 'update'=>'#updatedDropDownList', // which HTML element to update ) )); // CHtml::dropDownList($name, $select, $data, $htmlOptions) echo CHtml::dropDownList('updatedDropDownList','',array(), array());

Whats also important is the word update. It says that referred dropDownList will be extended. In our case we will add some option values (rows). And here is the code of the underlying action:
public function actionMyActionName() { // CHtml::tag($tagName, $htmlOptions, $content, $closeTag) echo CHtml::tag('option', array('value'=>'1'), // html params of tag CHtml::encode('hello'), // caption, string may be enough. CHtml::encode() may not be necessary. true // close tag ); }

As you can see, this function only prints some text. In our case its the new option for dropDownList. Because we told Yii tu update the dropDownList, this printed option will be added to it. Action can of course be more complex. You can access DB via Model::model() and check something.. Its up to you. The only rule is that you echo something. You can echo more records (options) for example using for cycle. How to work in the action with data you entered in the first field will be shown bellow.

19

5.4.5.2. DROPDOWNLIST DROPDOWNLIST


Typical example of using this is a situation, when you need to select country in first dropDownList and in the second one you want to see appropriate cities. Both the view and action part are pretty the same.
// CHtml::dropDownList($name, $selected, $values, $htmlOptions) echo CHtml::dropDownList('country','',array(1=>'has value I',2=>'has value II'), array( 'ajax' => array( 'type'=>'POST', //request type 'url'=>CController::createUrl('myActionName'), //action to call 'update'=>'#updatedDropDownList', // which HTML element to update ) )); // CHtml::dropDownList($name, $select, $data, $htmlOptions) echo CHtml::dropDownList('updatedDropDownList','',array(), array());

Only the first line is changed in comparison with the first example. Below is appropriate action.
public function actionMyActionName() { $countryID = $_POST[country]; // IMPORTANT .. this is how you access previously entered data $listOfCities = getCitiesOfState($countryID); foreach ($listOfCities as $city) { echo CHtml::tag('option', // tagname array('value'=>$cityID), // html params of tag $cityName, // value from the item selected in the first dropdown is in the POST array true // close tag ); } }

20

5.4.5.3. TEXTBOX TEXTBOX


If we do not want to add values to something (as for example shown in case of dropdowns) we will change only 1 word in the view. This is in the case that we want to show some text in a textbox according to what we enter into the first textbox. We then need to replace the whole textbox with a new one containing the text we need.
echo CHtml::textField('myTextField','', array( 'ajax' => array( 'type'=>'POST', //request type 'url'=>CController::createUrl('myActionName'), //action to call 'replace'=>'#statusTextBox, // which HTML element to update ) )); echo CHtml::textField(statusTextBox,'',array());

In this case is important the replace option. It sais that the original textField named statusTextBox will be replaced with a new one with different properties (text).
public function actionMyActionName() { $status = ''; if (strlen($_POST[myTextField])<5) { $status = 'too small'; } else { $status = 'size is OK'; } echo CHtml::textField('statusTextBox', $status,array()); }

Notice that the name of the new textbox created in Action must be the same as the name of the deleted textbox. Otherwise this action will be done only once.

If something doesnt work repeatedly (only once per page refresh), try to generate the HTML FORM ITEM in Action in a different way. Read more at: [12], [13]

21

5.5.

MODELS AND USING THEM - IN PRAXIS (NEW!)


BASIC OVERVIEW OF MODELS CODE

5.5.1.

As I mentioned earlier, model is something that enables you to work with database. More exactly it is a class that extends class CActiveRecord from Yii core. Each model is declared as follows and contains a few default methods if it was generated automatically.
class MyModel extends CActiveRecord { }

Class is saved in file: protected\models\MyModel.php If you want to read data from DB, you use model for example like this:
$dataFromDb = MyModel::model()->findAll(); // this returns all rows from table that is controlled using model MyModel.

And what means the double-colon :: and arrow ->? Double-colon means that our class MyModel contains static method model(). If you access static methods and static properties, you use :: and if you access methods of instance or property of instance, you do it via arrow -> Example:
$myVariable = new MyClass() $myVariable::myStaticMethod(); $myVariable->myMethodOfInstance();

The static function model() is in the model class and looks like this. (Word parent refers to
CActiveRecord class - your Model is derived from it) You do not need to understand it, just use it. public static function model($className=__CLASS__) { return parent::model($className); }

Another function of your model must be tableName(). It only returns table name that is managed via this model:
public function tableName() { return 'nameOfDbTable'; }

22

Third method is function rules()[14]. It is very important function in case that you want to check data entered into a HTML form (for example when editing goods details, filling contact forms etc.) If user enters something wrong he will be warned and no data will be saved or processed. For example if user should enter his email and forgets @ sign, nothing happens if you specify rules well. Rules are automatically created if you generate model class using command line. Yii takes these rules from DB definition. That is why you should create DB before programming. To be more specific rules just say which attribute should be validated using specified validator. If you have a look bellow, you will see that for example attribute (or column in DB) user_email has to be in form of email. Attribute age has to be integer = without decimal numbers. So now you know 2 validators: email and numerical. But there are more of them, see [14].
public function rules() { return array( array('users_email', 'email'), array('age', 'numerical', 'integerOnly'=>true), ); }

You can of course create your own validator and use it in a rule. If you want to add rule with name myrule than in your model-class create function myrule() and to rules enter this:
array('my_tested_column', 'myrule'),

In demo project you can find this in praxis in file protected/models/LoginForm.php. Next function is relations(). It defines connections to other tables. It is created automatically if you specify PK-FK relations. Thats why I recommend MySQL Workbench for designing DB. See other chapter. Each relation begins with its name than you have to specify cardinality (relation 1:1, 1:N, M:N), target model, target PK. [9]
public function relations() { return array( 'getUsersPosts'=>array(self::HAS_MANY, 'Posts',' author_id '), ); }

23

And finally last default function attributeLabels() defines labels (descriptions) for table columns.
public function attributeLabels() { return array( 'id_user => 'Users ID', 'user_name' => 'Name of user', ); }

If you change this function so that it doesnt return just array but also takes into consideration desired language, it can be used to translate captions in forms based on this model. Example:
public function attributeLabels() { If (Yii::app()->session[lang] == 1) { return array( 'id_user => 'Users ID', 'user_name' => 'Name of user', ); } }

And the best thing is that if you use console (yiic.bat) to generate models than this class will be created automatically for each of your tables. The whole MyModel class will look cca like this:

24

class MyModel extends CActiveRecord { public static function model($className=__CLASS__) { return parent::model($className); } public function tableName() { return 'nameOfDbTable'; } public function rules() { return array( array('users_email', 'email'), array('age', 'numerical', 'integerOnly'=>true), ); } public function relations() { return array( 'getUsersPosts'=>array(self::HAS_MANY, 'Posts',' author_id '), ); } public function attributeLabels() { return array( 'id_user => 'Users ID', 'user_name' => 'Name of user', ); } }

.. And you can add (override) much more usable functions like scopes(), defaultScope(), afterSave(), beforeValidate()

25

5.5.2.

OVERVIEW OF ANOTHER USEFUL METHODS

5.5.2.1. SCOPE()
Scopes are very useful. If I simplify it they allow you to save an SQL command and use it as a function in connection with particular model. Example:
$dataFromDb = MyModel::model()->getOnlySomeRows()->findAll(); // this returns all rows from table that is controlled by model MyModel and that comply with criteria specified by scope getOnlySomeRows.

GetOnlySomeRows() is the scope. Scope [15] is defined like this:


public function scopes() { return array( 'getOnlySomeRows'=>array( 'condition'=>'status=1' ), 'getOtherRows'=>array( 'condition'=>'status=2' ), ); }

And now my experience from praxis: Lets imagine that you have 2 tables. Table Suppliers and table Users. Each supplier or user can be signed as enabled or disabled. We want to show all enabled suppliers and their enabled users. First we will add scopes to Suppliers and Users models like this. In both models the scope will look the same if there is column status. Lets say that user or supplier is enabled when status is 1.
public function scopes() { return array( 'getEnabled'=>array( 'condition'=>'status=1' ), 'getSupplier'=>array(self::BELONGS_TO, 'Supplier','id_supplier'), // this will be in Users model 'getUsers=>array(self::HAS_MANY, 'Users,'id_user'), // this will be in Suppliers model ); }

Now we can write this:


$enabledUsers = Users::model()->getEnabled(); $enabledSuppliers = Suppliers::model()->getEnabled();

But if we wanted to get all enabled suppliers and their enabled users, we would have to use inner join with conditions. In Yii this can be done by command with() like this:

26

$ourJoin = Suppliers::model()->getEnabled()->with(array('getUsers:getEnabled'=>array('joinType'=>'INNER JOIN')))->findAll();

I was showing this just because of the colon. If you want to specify relation:scope you use colon. It took me long hours to find this out so I am mentioning it here. And also notice how to force the inner join.

5.5.2.2. DEFAULTSCOPE()
This is the very the same function as scopes(). But in default scope you can define only one scope - without name (not array of scopes). This scope will be used in every query you will make. It is useful for example if you want to add some calculated attribute to your model or if you want users to see only visible goods etc.
public function defaultScope() { return array( 'select'=>array('*','CONCAT(user_firstname,user_surname) as user_complete_name'), ); }

This default scope adds to each query-result counted column user_complete_name. You than only have to add this column to your model as a property:
public $ user_complete_name';

You could of course use also a JOIN in the default scope like this: (probably useless example, just to show that it is possible and how to use it)
public function defaultScope() { return array( 'with'=>array('getSupplier'), // relation defined in User model 'select'=>array('*', 'CONCAT(getSupplier.supplier_username_prefix,user_username) as user_username_with_prefix' ), ); }

27

In scopes you can use everything from CDbCriteria [16]. I guess that you could also use scopes in the related tables like this:
'getSupplier:scopeName.supplier_username_prefix'

But I am just guessing. And of course everything mentioned here, for default scope, can be used for ordinary scopes too.

28

5.5.2.3. OTHER THINGS


1) If you write a part of sql query manually (in where parts for example) you will probably want to tell Yii which column belongs to which table. Example of a where part:
$something = User::model()->findAll(array(where=>t.id = 4 and relationName.column = \Paul\)) // t = the home table of current model (User model) // relationName = name of relation in your home model

The important thing to remember is the t that refers to the home table. 2) You can use following command to get current name of table. Usable inside a model class for example in scopes to specify THIS table.
$this->_alias // can be used in a scope like this: 'getEnabled'=>array('condition'=>$this->_alias.'.id_status=1'),

3) If you want to see sql query, write something wrong into it. Yii will write the query on the screen:
$something = User::model()->findAll(array(where=>t.id = a4 and relationName.column = \Paul\))

4) If you use an alias for a column and want to filter records by a condition, do not use where, but having clause.

29

6. THEMES (NEW!)
You may want to skin your web and allow users (or yourself) to change the skins on demand. Its very easy. In default state (in automatically created demo project) no theme is set or used. Is used some default appearance. This was the first thing that I did not understand To turn a theme on, you have to specify it in file protected/config/main.php by adding the red line:
return array( 'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', 'name'=>'Hello World !!', 'theme'=>'theme1', );

It means that this variable is readable using Yii::app()->theme->getName(). You can set it programmatically in an ACTION (not in view!!) like this:
Yii::app()->theme = 'theme1'; // = each user can have (select) different theme

If theme is not set (using config file, or programmatically) then method getName() will throw error! Yii::app()->theme->baseUrl will contain your theme path = you can use it in layout file to address your css files, images etc. To use your theme1, you will have to create a new subfolder in themes folder and name it theme1. The themes folder is placed in the root of your project. In folder theme1 will be the same structure as in protected folder. Create there views and CSS folders. If a theme is set, views and controllers will be taken from your theme folder. If Yii do not find them, tries to look for them in ordinary views and controllers folders. But controllers and actions can be the same for all themes. There does not have to be a reason to change them. On the other hand, CSS files will be probably different, so create CSS folder in folder of your new theme and put new CSS files in it.

30

7. USED LINKS
[1] Yii homepage: http://www.yiiframework.com/ [2] Yii documentation: http://www.yiiframework.com/doc/ [3] Wamp server: http://www.wampserver.com/en/ [4] Hello World tutorial: http://code.google.com/p/yii/issues/detail?id=86 [5] First project video: http://www.yiiframework.com/screencast/blog/ [6] How to create a blog: http://www.yiiframework.com/files/yii-blog-1.1.0.pdf [7] Configure Yii: http://blog.dmcinsights.com/2009/11/03/configuring-yii/ [8] Tables in DB: http://blog.dmcinsights.com/2009/11/05/creating-models-views-and-controllers-in-yii/ [9] Relations between models: http://www.yiiframework.com/doc/guide/database.arr [10] MySQL Workbench http://dev.mysql.com/downloads/workbench/5.2.html [11] http://www.sterlingsavvy.com/tutorials/index.php?t=1&l=10 [12] Ajax Yii documentation http://www.yiiframework.com/doc/api/CHtml#ajax-detail [13] Ajax Yii coockbock + discussion ! http://www.yiiframework.com/doc/cookbook/24/

31

[14] Mode: method rules() http://www.yiiframework.com/doc/guide/1.1/en/form.model [15] Active Record http://www.yiiframework.com/doc/guide/1.1/en/database.ar [16] CDbCriteria http://www.yiiframework.com/doc/api/1.1/CDbCriteria

32