You are on page 1of 206

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Web.Application.Development.with.Yii.and.PHP 2ND Edition


Public: Packpub Year: 2013 Translate: Longt8x Support: quynhanh_long@yahoo.com Email: phamducbact1k10@gmail.com Li ni u : u tin xin chc cc bn mt nm mi ngp trn nim vui, cuc sng hnh phc bn gia nh v ngi thn.

i vi nhng ngi mi bt u ti ngh cc bn hc quyn Yii cookbook development xem r hn cu trc h thng ca Yii v khm ph phn khung xng ca n trc khi thc hin hc ebook ny.
Vi nt v Yii framework Yii framework do mt tn tu kha xy dng ln da vo vic ly nhng ci hay ca rt nhiu framework tng hp li thnh mt framework ring, n ch yu da trn l thuyt Agile v Prado, Zend framework v mt s th vin hu ch m thnh, tn ca anh ta l Quiang Xue. Mc : N rt thch hp cho cc d n tm trung v cc d n nh gip xy dng nhanh qun tr v thao tc vi ngi dng, c th xy dng lm vic theo nhm , tuy nhin nu bn xy dng d n ln th ng ln s dng framework ny v n khng thch hp cho lm.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Phn 1 : Ci t cu hnh yii framework


Bn vo trang ch : http://www.yiiframework.com/download/ Download phin bn mi nht v sau gii nn (extract here), sau rename li l cookbook, copy folder cookbook mi gii nn vo C:\xampp\htdocs\, bn phi down xampp v ri ci t setup thnh cng th chy xampp center thit lp apache v mysql running.
http://localhost/appyii/requirements/index.php Phn mm chy local: Xampp, Wamp, ko nn dng appserv v b li( nguyn nhn mnh ko bit, tt nht nn trnh). Hoc xi lun host tht nu nh c iu kin. 1. Chun b Trc tin bn phi cu hnh windows s dng c php vi cmd -Gi s bn ci apache mc nh trn WinXP (C:\xampp\htdocs). -Bn thit lp li bin mi trng (Environment Variables) bng cch vo: Start -> My Computer (right click!) -> Advanced Tab -> Environment Variables -> Click Path in System variables (windows 7 l Path) -> Edit. -Click vo bin PATH v chn Edit. Lu l ng c xo b cc ng dn tn ti trong textbox m ngn cch chng vi nhau bng du ";". -Tip bn thm vo nhng ng dn sau: "C:\xampp\php" v " C:\xampp\htdocs\appyii\framework". Lu sa ng dn cho ph hp vi my bn nha . -Khi ng my tnh li. 2.To ng dng Yii mi -YiiRoot l th mc ni bn ci t Yii -Webroot l th mc gc cha web -T dng lnh, n webroot ca bn v thc hin: Vo start -> run->cmd C:\ Cd\ Cd C:\xampp\htdocs\ C:\xampp\htdocs\>appyii/framework/yiic webapp devyii Nu khng c th g tip cd appyii

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

G tip cd framework -> g yiic webapp devyii. [devyii]-> Tn ng dng Create a Web application under '/Webroot/devyii? [Yes|No] Yes[y] Vy l khung xng ca Yii c to ra thnh cng Trch dn:devyii/ index.php file ng dng index-test.php file kim tra chc nng assets/ cha ti nguyn ng dng css/ cha CSS images/ cha hnh nh themes/ cha giao din protected/ cha cc file c bo v Vo appyii/framework/ chuyn folder mi to l devyii ra ngoi folder website C:/xampp/htdocs. ng dn mi ca app l C:/xampp/htdocs/devyii. copy folder framework ca appyii sang devyii. Vo file index.php thay i ng dn thnh :
$yii=dirname(__FILE__).'/framework/yii.php';

Bn c th truy cp vo ng dng t trnh duyt http://localhost/devyii/index.php

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Ok, hon tt cu hnh tin hnh coder.

III. To controller
-Vo th mc ng dng M:
%cd /Webroot/devyii

C:/ Cd C:/xampp/htdocs/devyii

-Khi ng Yii Shell M:


%YiiRoot/framework/yiic shell

Cd C:/xampp/htdocs/devyii C:/xampp/htdocs/devyii> C:/xampp/htdocs/devyii/framework/yiic shell To th controller tn message c hnh ng l helloWorld C php: controller <controller-ID> [action-ID] VD: M:
controller message helloWorld

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

-MessageController c to thnh cng th mc: protected/controllers/ -Bn cnh n cng to ra view ti th mc: protected\views\message -Chng ta cng c th truy cp vo hnh ng helloWorld t trnh duyt Default: http://localhost/devyii/index.php?r=message -> chy vo index http://localhost/devyii/index.php?r=message/helloWorld

VIII. To lin kt
-Yii c h tr sn hm to lin kt trong class CHtml -VD: To lin kt ti View goodbye M:
<p><?php echo CHtml::link("Goodbye",array('message/goodbye')); ?></p>

To lin kt ti View Hello M:


<p><?php echo CHtml::link("Hello",array('message/helloWorld')); ?></p>

IX.Ci t database
1.Yii h tr cc dalabase sau: -MySQL 4.1 or later -PostgresSQL 7.3 or later -SQLite 2 and 3 -Microsoft SQL Server 2000 or later -Oracle 2. Kt ni vi database -Thc hin file /protected/config/main.php -Mc nh n ang kch hot ng ny l database ca khung xng Yii M:
'db'=>array( 'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/testdrive.db', ),

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

- Gi s ta c 1 bng trong Mysql nh sau: M:


CREATE TABLE IF NOT EXISTS `tbl_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(128) NOT NULL, `password` varchar(128) NOT NULL, `email` varchar(128) NOT NULL, PRIMARY KEY (`id`) );

- Chng ta phi kch hot ng sau trong /protected/config/main.php kt ni vi Mysql (b /* */ v sa li cu hnh)

M:
// uncomment the following to use a MySQL database 'db'=>array( 'connectionString' => 'mysql:host=localhost;dbname=devyii', 'emulatePrepare' => true, 'username' => 'root', 'password' => '', 'charset' => 'utf8', ),

-Ngoi ra ta c th kt ni vi ci database khc (thay i dng 'connectionString') SQLite: sqlite:/path/to/dbfile MySQL: mysql:host=localhost;dbname=testdb PostgreSQL: pgsql:host=localhost;port=5432;dbname=testdb SQL Server: mssql:host=localhost;dbname=testdb Oracle: oci:dbname=//localhost:1521/testdb

XI. To CRUD
- CRUD l cc chc nng create, read, update v delete 1 bng trong database 1. Kch hot cng c Gii - Gii h tr sinh m t ng cc chc nng nh Controller, Crud, Form, Model,

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Module. - kch hot Gii ta vo file config /protected/config/main.php - Kch hot on code sau M:
// uncomment the following to enable the Gii tool 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'1111', // If removed, Gii defaults to localhost only. Edit carefully to taste. 'ipFilters'=>array('127.0.0.1','::1'), ),

- i password mi ng nhp Gii - Vo Gii thng qua url: http:// localhost/devyii/index.php?r=gii 2. To user Model -Vo mc Model Generator to Model cho bng user - Table Prefix: vit phn tin t ca bng (nu c) vo y, y bng ca ta tn l tbl_user nn tin t s l tbl_ - Table Name: phn cn li ca tn bng l user (ta c th to t ng tt c bng bng cch nhp du * vo y) - Model Class: tn lp ca model l User (t sinh ra) - Cn li mc nh v click Preview - Sau click Generate to file Model ca User ti th mc /protected/models/User.php 3. To CRUD: - Vo mc Crud Generator - Model Class: in chnh xc tn lp Model va to l User - Controller ID: in user (khng vit hoa) - Cn li mc nh v click Preview - Sau click Generate to Crud 4. Truy cp CRUD - Vo url: http://localhost/devyii/index.php?r=user - Click vo cc chc nng nh Create User, Manage User, n s bt ta ng nhp, ta c th s dng user v pass sau: demo/demo (ti khon bnh thng) hay admin/admin (ti khon admin) - Vi ti khon admin ta c th truy cp vo trang qun l sau http://localhost/devyii/index.php?r=user/admin 5. URL Thn thin

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Vo protected/config/main.php b comment urlManager..


$yii=dirname(__FILE__).'/framework/yii.php';

XII CC TRNG D LIU TRONG FORM


$this->pageTitle=Thay i tiu trang ti y; Cch 1: Dng form bng cch dng widget.
//Khi to widget s dng Ajax cho Form Active $form=$this->beginWidget('CActiveForm',array( 'id'=>'user-form', 'enableAjaxValidation'=>tru e, 'enableClientValidation'=>t rue, 'focus'=>array($model,'name ')

)); <?php //Kim tra u vo model ng cha ? echo $form->errorSummary($model); ?> <div class="row"> <?php //Khi to trng name echo 'Tn truy cp:'; echo $form->textField($model,'name'); echo $form->error($model,'name'); ?> </div>

Thm Captcha cho form


-Nu cha bt "gd2" th ta vo file php.ini ri sa li dng ny

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013 M PHP:


extension=php_gd2.dll

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<?php $this->widget('CCaptcha',array( 'buttonLabel' 'Ly code mi', 'clickableImage' true, 'imageOptions' > array('id' => 'captchaimg') )); ?> = => =>

RE: [C Bn] To form trong view Xem thm cc Method add cc Field khc cho form Here Ngoi cch dng 'CActiveForm' ta c th dng 'Chtml' d to form: CHtml Vit Li form trn bng cch dng 'CHtml': M PHP:
<div id='form'> <?php echo CHtml::beginForm(); ?> <div id='row'> <?php echo CHtml::activeLabel($model,'name');?> <br/> <?php echo CHtml::activeTextField($model,'name')?> </div> <div id='row'> <?php echo CHtml::activeLabel($model,'email');?> <br/> <?php echo CHtml::activeTextField($model,'email')?> </div> <div id='row'> <?php echo CHtml::activeLabel($model,'pass');?> <br/> <?php echo CHtml::activePasswordField($model,'pass')?> </div> <div id='row'> <?php echo CHtml::activeLabel($model,'repass');?> <br/> <?php echo CHtml::activePasswordField($model,'repass')?> </div> <div id='row'> <?php echo CHtml::activeLabel($model,'date');?> <br/> <?php echo CHtml::activeTextField($model,'date')?> </div>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<div id='send'> <br/> <?php echo CHtml::submitButton('ng K ',array('id'=>'frmReg','name'=>'frmReg'));?> </div> <?php echo CHtml::endForm(); ?> </div>

Sau khi to form xong th ti bc tip theo l add cc rng buc cho thng tin m user nhp vo v d nh:

Cc text box khng c b trng Email phi ng dng Pass phi ln hn 6 nh hn 15 Repass phi y chang Pass Date: phi hp l theo kiu (dd-mm-yyyy) hay (mm-dd-yyyy) Add thm captcha chng ng k hng lot

Thm Captcha cho form


-Yii c h tr sn th vin captcha cho chng ta, v captcha th nhn cng rt l cool.

Test xem c th render captcha hay khng


-u tin truy cp th link ny test xem c captcha hay khng ci . http://localhost/devyii/index.php?r=site/captcha nu ra nh vy l ok

-Nu n khng hin captcha th ta nn check li xem load "gd2" hay cha bng cch chy mc test ca Yii

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

ging nh hnh l load ri, n vng hay th xem li cu hnh webserver -Nu cha bt "gd2" th ta vo file php.ini ri sa li dng ny M PHP:
extension=php_gd2.dll b du ";" trc n, my ci khc defaut ng ty my, restar webserver v test li, nu vn li --> thi ci li win cho n lnh

- to captcha ta thm vo phn view on code sau: M PHP:


<?php $this->widget('CCaptcha',array( 'buttonLabel' 'Ly code mi', 'clickableImage' true, 'imageOptions' > array('id' => 'captchaimg') )); ?> = => =>

Vi:

'buttonLabel' : hin th mt link vi ni dung m ta set, khi click vo s i string ca captcha 'clickableImage': khi click vo image s i sang hnh khc. 'imageOptions': set cc thuc tnh Html ca captcha

- Mt captcha c rendered bi mt hnh ng ca lp CCaptchaAction, do nu ch add bn view s khng hin th hnh nh, v captcha khng c render. Do ta vit thm bn Controller: M PHP:
public function actions() { return array( 'captcha'

=>

array

( 'class'

=>

'CCaptchaAction',

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]


'backColor' =>'#fff

' ), ); }

Vi

'backColor': mu nn nh #fff l mu en, 'foreColor': mu ch captcha. 'height': chiu cao nh 'width': Chiu rng 'maxLength': chiu di ti da ca ch captcha 'minLength': di ti thiu ca string. 'verifyCode': ly gi tr m xc nhn

Cui cng ra ci form nh vy:

- rng buc cc thng tin m e nhp vo ta vit mt phng thc trong Model nh sau: M PHP:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

public function rules() { return array array

('code','captcha', 'allowEmpty'=>! CCaptcha::checkRequirements(), 'message' => 'M Xc Nhn Nhp Kh ng ng' ), array('email','email','message' =>'{attribute} khng h p l'), array('name,email,pass,repass,date,code','required','me ssage'=>"{attribute} khng c b trng"), array('repass','compare','compareAttribute'=>'pass','me ssage'=>"{attribute} phi chnh xc"), array('pass','length','min'=>'6','message'=>"{attribute } khng di "), array('date','date','format'=>'dd-mmyyyy','message'=>"{attribute} phi chnh xc dng {dd-mm-yyyy}"), ); }

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Chng 1 Bt u vi Yii Framework


1. Cun sch ny dnh cho ai ? Nu bn l mt lp trnh vin php vi cc k nng hiu bit v OOP (Lp trnh hng i tng) v mun xy dng h thng hin i vi cc ng dng web th cun sch ny dnh cho bn,khng c bt k mt yu cu g c cun sch Yii ny. 2. To controller helloworld to nn mt controller trong yii bn c 3 cch, cch mt l nu bn lm vic quen vi yii bn c th to t mt file mi v khai bo n vi tn class c k tha t Ccomponent, cch hai l to t dng lnh trong cmd cch ny bn c th tham kho t ebook yii cookbook hoc trn din n yiivn.com, cch 3 ny c phn d hn cho cc bn mi tm hiu yii l to controller t mt cng c trong yii c tn l Gii.

Cu hnh Gii Trc khi s dng Gii chng ta cn phi config ng dng , chng ta phi truy cp vo cu hnh ng dng chnh ti file trong a ch : protected/config/main.php (Full cu hnh C:\xampp\htdocs\devyii\protected\config\main.php) cc bn lu ln sau ti ch g tt a ch bn phi t vo webroot (th mc web gc) tm.
Chng ta vo file v thy dng code sau y : return array( 'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', 'name'=>'My Web Application', //load thnh phn log 'preload'=>array('log'), // t ng load model v thnh phn class 'import'=>array(

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'application.models.*', 'application.components.*', ), 'modules'=>array( // Khng comment sau khi kch hot cng c ny /* 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'Enter Your Password Here', //Nu xa i Gii s mc nh t localhost.Hy iu chnh cn thn. 'ipFilters'=>array('127.0.0.1','::1'), ), */ ), Bn b hai dng check comment i v in mt khu ca bn, hoc bn c th lm theo ti vi mt khu l : 1111 Khi on module c thay i nh sau: 'modules'=>array( 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>1111, 'ipFilters'=>array('127.0.0.1','::1'), ), Chng ta vo trnh duyt kim tra th : http://localhost/devyii/index.php?r=gii Sau nhn pass l 1111 bn s truy cp vo c Gii

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Bn c th nhn thy 5 cng c chnh


Controller Generator (To ra controller) Crud Generator (To ra CRUD (Cp nht-sa-xa)) Form Generator (To ra Form) Model Generator (To ra Model) Module Generator (To ra Module)

D nhin to mt controller ta click vo link Controller Generator menu ti y c 2 trng l ControllerID v ActionID bn vit vo controller v action bn mun to ,vi ti th ti to controller message v action l helloworld hon tt chng ta nhn vo Preview sau Generate chng ta s to ra c. kim tra cc bn vo protected/controller/ cc bn s thy file MessageController.php , kim tra trong protected/views bn s thy folder message v trong folder l action helloworld.php Kim tra trn trnh duyt bn g : http://localhost/devyii/index.php? r=message/helloworld bn thy kt qu sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Nh vy l bn c th to c 2 file controller v action helloworld bn c th vo file MessageController tin hnh code theo ca bn .Lc ban u bn s thy nhng dng code sau: class MessageController extends Controller { public function actionHelloworld() { $this->render('helloworld'); } } Nu bn g http://localhost/devyii/index.php?r=message my s tr v thng bo li 404 Thng thng khi chy vo controller theo m hnh MVC h thng s tm theo action u tin l index, v th nn controller hin ti bn khi to cha c actionIndex() v khi bn cn thm action mc nh bng dng lnh:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<?php class MessageController extends Controller { public $defaultAction = 'helloworld'; Nh vy th khi chy link trn n s khng cn bo li 404 na bi v h thng nhn action mc nh l helloworld

Giai on cui cng


Views l giai on cui cng xut ra dng thng tin tng tc trc tip ti ng dng v th nn n gin l bn m file protected/views/message/helloword.php v custom ty v d: <h1>Hello World!</h1> Trn trnh duyt s hin th nh sau: http://localhost/devyii/index.php? r=message

Thm ni dung ng
Trong views file bn c th lm bt k cng vic lin quan ti php bng cch s dngctec cc th m th ng ca php nh bnh thng <?php , ?> V d thm thi gian ca h thng:

<h3><?php echo date("D M j G:i:s T Y"); ?></h3>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Refresh li trnh duyt bn s thy ngy gi ca h thng. Ngoi cch nhng m php hin th ngy gi ra ta cn c mt cch khc cc k quan trng l generate d liu t model ra view thng qua controller l phng thc hot ng theo m hnh MVC. Chng ta cng xem v d sau: bn vo protected/controller/MessageController.php v thy actionHelloworld(): public function actionHelloworld() { $this->render('helloworld'); } Chng ta khai bo mt bin mi v render n sang views bng cch sau: public function actionHelloworld() { $theTime = date("D M j G:i:s T Y"); $this->render('helloworld',array('time'=>$theTime)); } Tip bn vo protected/views/message/helloworld.php v hin th bin time nh sau : Bay gio la:<h3><?php echo $time; ?></h3> Lu li file view v vo trnh duyt xem kt qu: http://localhost/devyii/index.php?r=message

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Nh vy l cc bn va lm quen vic thao tc d liu theo m hnh MVC , by gi ta lm th cch mt l t to action mi theo mnh ,gi s ti to action goodbye: class MessageController extends Controller { public function actionGoodbye() { $this->render('goodbye'); } ... } Tip theo ta vo trong protected/views/message/ v to mi file goodbye.php mt cch n gin l bn copy file helloworld.php v paste ti sau rename thnh goodbye.php v thm vo file mi vi ni dung sau y: <a href="/helloworld/index.php?r=message/goodbye">Goodbye!</a> kim tra bn vo http://localhost/devyii/index.php?r=message/goodbye

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Tin hnh mt s s tr gip ca Yii Chtml Tht may mn, Yii h tr cc phng thc c th s dng trong views template cc phng thc tnh tn ti t s tr gip ca framework vi class CHtml. Trong trng hp chng ta mun to cc link tnh vi controllerID /actionID thay v cc cu trc links c bn ca HTML. s dng link helper chng ta thm on m sau vo file helloworld.php trong folder protected/views/message/helloworld.php: <p><?php echo CHtml::link('Goodbye',array('message/goodbye')); ? ></p> Vo trnh duyt xem kt qu : http://localhost/devyii/index.php?r=message s hin th tng t nh hnh bn trn. Tng t bn th sa trong file goodbye.php trong protected/views/message/goodbye.php: <h1>Goodbye, Yii developer!</h1> <p><?php echo CHtml::link('Hello',array('message/helloworld'));?></p> Vo trnh duyt ta c kt qu : http://localhost/devyii/index.php? r=message/goodbye

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Chng 2 - Gii thiu ng dng Developer Yii Xy dng mt d n mi trn Yii framework
Chng ta c th tip tc gi vic thm cc ng dng n gin nh hello,world t Yii, nhng iu s khng thc s gip bn hiu c v yii framework trong ng cnh ca ng dng ngoi i thc, lm c iu ny chng ta cn xy dng mt ng dng mi, l ni dung ca chng ny. Chng ta s gii thiu project-task-tracking application ( d n : task(nhim v)- tracking (cch thc) ca ng dng c gi l Developer Yii. C nhiu project qun l khc v issue-tracking-application ( cc vn - cch thc ca ng dng trong ngoi i thc. Bn s t ra cu hi : Ta sao phi xy dng n ?, bi v n tr v cc thuc tnh c bn ca ng dng v xa hn c tp lnh trong ng dng. Gii thiu v Developer Yii Developer Yii bao gm 3 yu t chnh l d n (project) , ngi s dng (user), cc vn (issue). Trong user bao gm hai trng thi : -Anonymous l mt khch ngoi ng nhp vo h thng khng cn phi thng qua vic xc thc quyn truy cp h ch c quyn ng k ti khon v kch hot ti khon, khng c quyn qun tr. - Ngi dng c xc thc (authenticated) l bt k ngi dng no c xc thc cc tiu chun thng qua qu trnh ng nhp vo h thng,ngi s dng ny c cc quyn y v qun tr d n, thit lp d n, cp nht d n. Cc d n (Projects) Qun tr cc d n chnh thc hin trong ng dng TrackStar, mt d n c th hin di nhiu mc c thc hin bi mt hay nhiu ngi Cc vn (issue): Cc vn trong d n gm 3 loi sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Xa hn: Cc item c trnh din xa hn trong th gii thc khi c thm vo ng dng v d : thc thi hm login xc thc user. Cc chc nng: Item c hin th cn phi hon thnh cc cng vic khng gp li v s c. Cc li: Item khng hot ng hon ho do li pht sinh trong h thng hoc tc ng bn ngoi. C 3 trng thi chnh trong cc vn l : Cha bt u, Bt u, Kt thc.

Thnh vin ca d n c th thm nhiu vn ti d n cng nh vic iu chnh v xa item.Chng c th c ng k t bn thn ngi vit hoc thnh vin ca d n. By gi chng ta s xem khung lm vic ca ng dng mi:

T biu ny ta c th nhn s qua chi tit ca d n

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Khi mt ngi dng bt u truy cp ng dng, h phi ng nhp v xc thc quyn truy cp ti ng dng, nu ng nhp thnh cng h s c xem cc d n hin ti ca h hoc h c th thm mi. Khi la chn mt d n no s kch hot vo chi tit ca trang ,chi tit ca d n s hin th thng tin danh sch cc vn trong d n,ngoi ra h cng c th thm mi, chnh sa, xa i. l tt c nhng g trong ng dng bn cn phi quan tm.

Quan h d liu
Chng ta cng phi quan tm v m hnh d liu s lm vic ,chng ta s s dng active-record c k tha t Yii n s lu d d liu m chng ta mun chuyn ti Model. Chng ta c th nhn s qua v biu ca d n :

Chng ta c th nhn s qua vo bng biu v thy c cc thuc tnh sau: Mt ngi dng s c nhiu vn khc nhau v th bng biu s c lin kt 0 hoc nhiu. Mt ngi dng cng s c nhiu d n nhng mi mt d n c to ra bi t nht mt ngi bi th nn c quan h 1..* lin quan ti 0 nhiu.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Mi mt d n s c nhiu vn khc nhau, nhng mt vn khc nhau ch thuc trong mt d n m thi v vy nn c quan h 0 ..* vn cha ng trong 1 d n

Kt ni ti c s d liu (database)

Yii h tr hu ht cc csdl dng DBMS , PDO bao gm: SQLite: sqlite:/path/to/dbfile MySQL: mysql:host=localhost;dbname=testdb PostgreSQL: pgsql:host=localhost;port=5432;dbname=testdb SQL Server: mssql:host=localhost;dbname=testdb Oracle: oci:dbname=//localhost:1521/testdb Ti y ti s s dng mysql lm c s d liu. Bn vo protected/config/main.php v tm dng sau: 'db'=>array( 'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/testdrive.db', ), // uncomment the following to use a MySQL database /* 'db'=>array( 'connectionString' => 'mysql:host=localhost;dbname=testdrive', 'emulatePrepare' => true, 'username' => 'root', 'password' => '', 'charset' => 'utf8',
Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

), */ Bn c th nhn thy hin ti mc nh yii s dng sqlite , tuy nhin ti li mun s dng mysql nn bn sa li thng s v b dng check comment ca mysql, thay vo bn thm dng check comment vo sqlite v bn c kt qu sau: /* 'db'=>array( 'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/testdrive.db', ), */ // uncomment the following to use a MySQL database

'db'=>array( 'connectionString' => 'mysql:host=localhost;dbname=devyii', 'emulatePrepare' => true, 'username' => 'root', 'password' => '', 'charset' => 'utf8', ) Ti y ti khai bo cc thng s ca mysql gm username, password, database c tn l devyii, cng vic tip theo ca bn l vo phpmyadmin v to database c tn devyii:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Nhn create v database ca bn c to ra.

3.Xy dng CRUD cho project


K hoch nh sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

kt thc chng ny, d n ca bn cn phi cho php user to mi project, la chn item trong danh sch project, cp nht v sa xa cc project . Cng vic ca chng ta by gi l : Thit k c s d liu h tr cho project Xy dng cc bng biu cn thit v cc i tng d liu khc c nh ngha trong bng To Yii AR (Active-Record) (Kch hot Bn ghi) model class cho php ngi dng d dng thao tc vi bng csdl To Yii controller class s l ngi nh cha cc hm sau: 1. To mi project 2. Lit k ra danh sch d n 3. Cp nht d liu lin quan vi project 4. Xa cc d liu trong project To file Views trong yii v hin th cu trc c bn sau: 1. Hin th form cho php ngi dng to mi project 2. Hin th danh sch tt c project 3. Hin th form cho php user cp nht thng tin trong project 4. Thm mt nt xa user c th xa project Vy l OK, chng ta bt u tin hnh xy dng theo cu trc trn

3.1 To bng cho project


Chng ta hy quay tr li ci biu m hnh user-project-issue cha cc kt ni v chng ta thit k bng theo m hnh , bng project bao

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

gm nhng trng sau: id (integer) index ,name (varchar 255) tn project, description text not null m t project, create_time datetime- ngy to,create_user_id integer ngi dng to ra project ,update_time datetime- ngy cp nht li project,update_time_user_id integer m user cp nht d n , v tt nhin id s l kha chnh, bn c th t to bng bng query sql hoc n gin hn l chp on di y ri dn vo tab query Sql trong phpmyadmin CREATE TABLE tbl_project ( `id` INT(11) NOT NULL auto_increment, `name` varchar(255) NOT NULL, `description` text NOT NULL, `create_time` DATETIME default NULL, `create_user_id` INTEGER default NULL, `update_time` DATETIME default NULL, `update_user_id` INTEGER default NULL, PRIMARY KEY (`id`) ) ENGINE = InnoDB;

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

3.2 To AR (Active-Record) model class


Sau khi chng ta c bng d liu tbl_project ri chng ta cn to Yii model class cho php chng ta d dng qun tr d liu trong bng. Chng ti xin gii thiu layer Yiis ORM, Active-Record Bn cn ng nhp vo http://localhost/devyii/index.php? r=gii/default/login g mt khu 1111 sau nhn enter vo Gii

to model bn click vo Model Generator, Ti y gm cc trng sau: Table Prefix - Bng chng ta va to l tbl_project v c prefix (tin t ) l tbl_ Table Name : Tn thc ca bng chng ta va to l tbl_project Model class s t sinh ra l Project nu khng bn hy iu chnh ng nh vy (nhiu bn mc li sai ng ngn on ny nn n khi vo trong code thc mc l sao em generate t trong gii m khng hin th c d liu) Tip bn in y s ging hnh sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Cng vic cn li n gin l click vo Preview -> Generate l bn hon thnh thit k model nhanh chng trong yii . kim tra bn vo protected/models s thy file mi c to ra c tn Project.php ni y l th m yii t ng sinh ra model cho bn Bn c th m file project.php ra xem cu trc, n l mt class project c k tha t database layer l CactiveRecord Tip theo l hm khi to tr v model cha: public static function model($className=__CLASS__)

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

{ return parent::model($className); } Tip theo l hm khai bo tn bng trong CSDL (tn bng ny trong database phpmyadmin/devyii) public function tableName() { return 'tbl_project'; } Tip theo l hm rules() cung cp cc quy tc cng l ni nh ngha cc phn t trong bng Hm tip theo l relations() s to ra cc mi quan h gia bng ny vi cc bng khc mi th cc bn s c hc ht trong cc chng ti y. Tip theo l khai bo nhn ca cc phn t trong bng attributeLabels() V hm mc nh cui cng l hm Search (tm kim ) theo tiu chun c k tha t CdataProvider.

3.3 Kch hot CRUD cho project

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Chng ta va to ra AR model, tip n l g ?, theo m hnh MVC th r rng chng ta cn phi c controller thc thi cc hnh ng t model hoc x l u vo t user nh danh, tip chng ta phi generate cc bin d liu v item t model sang view thc hin trng by d liu.K hoch ny tng chng kh khn nhng tht n gin vi Yii nh cng c CRUD (Create-to mi,Read c, Update cp nht, Delete Xa) Chng ta quay tr li Gii v click vo ng link menu: Crud Generator kch hot tnh nng ny: Ti y s xut hin 2 trng l Model class l tn Model bn mun generate l Project, v controller class s t ng c sinh ra vi tn Project (lu nu khng vit hoa ch P th phi sa li thnh vit hoa),

tip theo bn nhn preview-> generate. H thng s phn hi thng bo thnh cng tht n gin ng khng bn c th vo trong protected/controller v bn s nhn thy file mi c tn ProjectController.php , tip theo bn vo protected/views/ cc bn cng s nhn thy folder project vi cc file view y , tm kim, cp nht, sa, xa

3.4 To mi project
Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Sau khi c hon thnh y m hnh CruD ri bn c th tin hnh kim th v to mi mt project bng vic vo trnh duyt g : http://localhost/devyii/index.php?r=project Tt nhin ban u s khng c bn ghi no v bn s nhn thy dng ch no result found, ta click vo create project menu bn tay phi theo hnh sau:

H thng s yu cu bn ng nhp v bn s ng nhp vi ti khon mc nh ca Yii framework l : Account: demo , Password: demo y l mt ti khon test user trong yii v g xong bn s thy mt form yu cu nhp cc d n, cc bn in ba vo s c kt qu ging sau y:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

iu ny ngha l h thng thc hin thnh cng mt bn ghi v i vo chi tit bn ghi , by gi ta to thm vi bn ghi na ri quay tr li ng link http://localhost/devyii/index.php?r=project/index s c kt qu tng t sau:

y chnh l list item ca d n, khi bn thm mi bn chuyn sang link ca action Add, bn chnh sa th tc l bn ang thc thi action edit, v bn click vo chi tit mt bn ghi bn i vo action detail

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

3.5 Xc thc hp l cc trng d liu trong Form


Khi lm vic vi AR model class khng ch c Form trong Yii, thit lp xc thc cc quy tc xung quanh cc trng d liu ca Form l cn thit, iu gip cho vic kim tra nhng d liu c bit v hn ch li trong csdl, n c thc hin y trong mt mng nh ngha hm rules() nh ti ni trong model Project.php Chng ta vo Protected/models/Project.php v chng ta thy hm ny c nh ngha mc nh khi generate vi mt s quy tc: /** * @tr v mng d liu xc thc cho cc phn t ca model */ public function rules() { // Bn ch nh ngha cc quy tc cho cc phn t khi m chng // s nhn c thng tin t form input (u vo chng ta va nhp ) return array( array('name, description', 'required'), //tn v m t c yu cu array('create_user_id, update_user_id', 'numerical', //yu cu kiu s nguyn 'integerOnly'=>true), array('name', 'length', 'max'=>255),//yu cu ti a khng qu 255 k t array('create_time, update_time', 'safe'), // Sau y l khai bo quy tc thng c s dng bi search // Vui lng xa i cc phn t khng mun tm kim. array('id, name, description, create_time, create_user_id, update_time, update_user_id', 'safe', 'on'=>'search'),

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

); }

Phng thc Rules() tr v mt mng nhng quy tc,mi quy tc l theo nh dng sau: Array(Danh sch phn t, Xc thc, on=>Danh sch kch bn, thm nhiu thng tin khc); Sau y l mt lot cc tiu chun xc thc c nh ngha t Yii version 1.1.12 boolean: nh danh ca CBooleanValidator, Kim tra phn t c cha gi tr true hoc false (ng-sai) captcha: nh danh ca CCaptchaValidator, Kim tra gi tr ca phn t c ging vi hnh nh captcha nhp vo hay khng compare: nh danh ca CCompareValidator, So snh hai phn t v kim tra chng ging nhau hay khc nhau email: nh danh ca CEmailValidator, Kim tra gi tr phn t dng e-mail address date: nh danh ca CDateValidator, Kim tra gi tr phn t dng date, time, or date-time value default: nh danh ca CDefaultValueValidator, thm vo mc nh gi tr phn t exist: nh danh ca CExistValidator, Kim tra gi tr phn t c tn ti trong table column trong database file: nh danh ca CFileValidator, Kim tra gi tr phn t c cha tn uploadfile hay khng filter: nh danh ca CFilterValidator, chuyn i gi tr phn t vi gi tr mi ca filter in: nh danh ca CRangeValidator, validates if the data is within a prespecified
Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

range of values, or exists within a specified list of values //cc dch na mt qu , on cui bao gm kim tra di (length), kim tra ng vi biu thc ton hc (math), kim tra dng s nguyn (numerical), kim tra gi tr c c yu cu bt buc hay khng(required), kim tra thuc tnh c thuc dng c bit hay khng (type), kim tra gi tr c phi l duy nht hay khng (unique), kim tra d liu c phi l on URL hay khng(url) length: Alias of CStringValidator, validates whether the length of the attribute value is within a specified range match: Alias of CRegularExpressionValidator, uses a regular expression to validate the attribute value numerical: Alias of CNumberValidator, validates whether the attribute value is a valid number required: Alias of CRequiredValidator, validates whether the attribute value is empty or not type: alias of CTypeValidator, validates whether the attribute value is of a specific data type unique: Alias of CUniqueValidator, validates that the attribute value is unique, and is compared against a database table column url: Alias of CUrlValidator, validates whether the attribute value is a valid URL

3.6 c project
y chnh l chi tit ca mt item bn c th vo ng link sau xem th mt item: http://localhost/devyii/index.php?r=project/view&id=1

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

3.7 Cp nht v xa project

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Khi cc bn nhn vo menu bn tay phi s thy hng lot cc link menu nh

sau: Khi bn cp nht v to, xem danh sch, c chi tit u c nhng khng th xa hoc qun l v b bo li access denid bi v bn ang s dng account dnh cho user khng c quyn xc thc, v th bn logout ra ngoi v ng nhp li bng account mi l : Account: admin , Password: admin , bn s hon ton c th xa v xem mc qun l c.

Bn c th nhn thy bn trn c hng lot cc lc tm l do bn khai bo bn hm rules(), bn c th vo trong v xa i ch li 2 trng l id, name th c v hp l hn.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Chng 3 . Qun l cc vn (Issue)


Vy l hm nay l nm mi 14h-52 pht ngy 01/01/2013, ti ang ngi gh bn cnh i din vi tng i Hng o Vng Trn Quc Tun, hm nay tht ng ngi i cu may cu lc, cn ti th vn lm vic, cng vic mang con ngi ta n s cht chc, mt mi cng thng nhng lao ng l vinh quang hy n nhn n, ng ph ng nght ngi c hoa ging kn nhng bng cc vng v bng hng rc, cc i tnh nhn tay trong tay do bc, bn b quy qun bn nhau,nhn sang bn tay tri l i din vi thp ra c knh, mt s yn lng v tnh mch nh vn c ca n,c l chm gi nhiu ch c li ch g cho vic hc ca cc bn nn chng ta tp trung vo cng vic bt u xy dng bng d liu th 2 l issues . qun trc khi vo lm cng phi chc mi ngi nm mi vui v hnh phc ch hehe!

Trong cc chng trc chng ta thc thi hm c bn xung quanh thc th project, by gi chng ta thc hin vi issues chng ny kh di v vy cc bn c gng tp trung. Project l thnh phn ch o ca ng dng mi tuy nhin mi d n t chng khng tht s hon ho, project cha ng nhng vn lin quan khi chng ta mun qun tr ng dng,lc qun tr cc vn trong d n l mc tiu chnh thc hin trong ng dng, chng ta s mun thm mt s hm cha vn qun tr c bn.

K hoch xa hn
Chng ta to c thnh phn qun tr project, nhng chng ta cha c cch no qun l cc vn (issue) lin quan n d n , khi kt thc chng ny chng ta mong mun l thc hin c tt c CRUD trong vn ca d n hoc cc nhim v (task).trong d liu model,mt nhim v (task) s lun lun ch c mt thuc tnh ca issue. Chng ta cng mun trch ra tt c CRUD trong issues cng vi project, iu c ngha l issues thuc v (belong to) project (Lu y l quan h - relationship). User phi la chn cc d n tn ti v lm vic, lit k danh sch thc hin CRUD vi cc vn trong d n. Chng ta hy nhn danh sch ngh bn cn lm nh sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

1. Thit k biu d liu v xy dng i tng h tr cc vn trong d n 2. To Yii model class cho php ng dng d dng khi to kt ni vi d liu trong bng 3. To controller class s cha cc hm cho php chng ta thc hin : To mi vn

Lc danh sch cc vn tn ti trong project t database Cp nht/iu chnh cc vn Xa cc vn 4. To views folder render giao din ngi dng cho cc action By gi chng ta i vo thc hin

III.1 Thit k biu


Trong chng trc chng ta c th nhn s qua v tng ca thc th issues, chng ta thc hin n c cc trng d liu gm : name tn vn , type thuc tnh vn , owner bn thn, requestor ngi yu cu, status trng thi, v description miu t. Chng ti cng ngh sau khi to bng tbl_project chng ta cn mt s thng tin khc nh dates, times,v user cp nht bng .Tuy nhin type , owner, requestor, status bn thn chng l nhng thc th. Trong owner bn thn, requestor ngi yu cu l hai ngi dng s dng h thng v h s tc ng vo bng d liu thng qua bng tbl_user. Chng ta bt u lin tng ti user trong bng tbl_project l create_user_id v update_user_id l nhng nh danh ca user cp nht hay to ra d n, xc thc c chng ta cn kha ngoi (foreign key) tham chiu ti bng tbl_user, lc owner_id v requestor_id trong bng tbl_issues cng s c kha ngoi tham chiu ti bng tbl_user. D hiu con m ln c

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

III.1.1 nh ngha mt s quan h (relationships)


T khi chng ta gii thiu bng tbl_user , chng ta cn nh ngha li quan h gia user v project, trong chng trc cc user s lin quan ti 0 hoc nhiu project, chng ta cng c th thit lp project c 1 hoc nhiu user. Chng ta gi quan h gia hai bng trn l quan h nhiu nhiu (many to many). Tht d dng xy dng quan h many-to-many trong model, chng ta c th nhn s qua v quan h c bn ca thc th- quan h gia user, project, issues. Project c th c 0 hoc nhiu user,mt user cn lin quan ti t nht mt project nhng c th lin quan nhiu,Issues (belong to) thuc v mt v ch mt project , khi project c th c t 0 n nhiu user. Mt vn c kt thc v c ng k bi (ngi yu cu) v ch duy nht mt user.

1 Or More : 1 hoc nhiu 0 or More : 0 hoc nhiu Exactly One: Ch mt

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

III.1.2 xy dng i tng t nhng quan h trc


Chng ta s phi to ra 3 bng mi bao gm tbl_issue, tbl_user v bng trung gian tbl_project_user_assignment Bng tbl_issue create table tbl_issue( id int(11) not null primary key auto_increment, name varchar(255) not null, description text, project_id int(11) DEFAULT NULL, type_id int(11) DEFAULT NULL, status_id int(11) DEFAULT NULL, owner_id int(11) DEFAULT NULL, requester_id int(11) DEFAULT NULL, create_time datetime DEFAULT NULL, create_user_id int(11) DEFAULT NULL, update_time datetime DEFAULT NULL, update_user_id int(11) DEFAULT NULL )ENGINE=InnoDB; Copy v paste to bng cho n nhanh nhng ch nhn cc trng d liu m nh. Tip theo l table tbl_user create table tbl_user( id int(11) not null primary key auto_increment, username varchar(30) not null unique key, email varchar(1000) not null,

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

password varchar(255) not null, last_login_time datetime DEFAULT NULL, create_time datetime DEFAULT NULL, create_user_id int(11) DEFAULT NULL, update_time datetime DEFAULT NULL, update_user_id int(11) DEFAULT NULL )ENGINE=InnoDB;

V cui cng l bng trung gian create table tbl_project_user_assignment( project_id int(11) NOT NULL auto_increment, user_id int(11) NOT NULL, PRIMARY KEY (`project_id`,`user_id`) )ENGINE=InnoDB;

To kha ngoi quan h gia tbl_issue v tbl_project Alter table tbl_issue Add constraint fk_issue_project foreign key(project_id) references tbl_project(id) on delete cascade on update restrict To kha ngoi quan h gia user vi owner (bn thn ngi ) tbl_issue v tbl_user alter table tbl_issue add constraint fk_issue_owner foreign key(owner_id) references tbl_user(id) on delete cascade on update restrict

To kha ngoi quan h gia user v ngi yu cu (requestor)

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

alter table tbl_issue add constraint fk_issue_requester foreign key(requester_id) references tbl_user(id) on delete cascade on update restrict To kha ngoi quan h gia bng trung gian vi project alter table tbl_project_user_assignment add constraint fk_project_user foreign key(project_id) references tbl_project(id) on delete cascade on update restrict To kha ngoi quan h gia bng trung gian v user alter table tbl_project_user_assignment add constraint fk_user_projects foreign key(user_id) references tbl_user(id) on delete cascade on update restrict Sau khi thc hin xong cc query xong bn hy m mt s cng c theo di m hnh schema database c th nhn thy m hnh d liu vi cc kha

III.1.3 To AR (Active Record) model class


By gi chng ta c y cc bng, bc tip theo l to model vi Yii model AR cho php chng ta d dng thao tc vi bng trong ng dng, chng ta cng lm vic ny trong vic to model ca Project chng trc v th nn thao tc s khng c g thay i nhiu, chng ta vo Gii

III.1.4 To Issue Model class


Vo Gii vi ng dn : http://localhost/devyii/index.php? r=gii/default/login v nhn 1111 chng ta s vo menu generate Chng ta click vo Model Generator , ti trng table prefix chng ta in tbl_ (y l tin t bng) Ti trng table name ta in : tbl_issue, ti trng Model class ta in Issue

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Tip theo bn nhn preview -> generated. Chng ta c th vo protected/models kim tra v s thy Issue.php

III.1.5 To User model class


Vic to User model class l khng cn thit bi v bn thn Yii h tr thao tc vi user khi s dng Yiis DAO , AR model cung cp mt Biu quan h i tng (Object Relational Mapping- ORM) cho ng dng gip chng ta d dng qun l i tng trong domain.

III.1.6 To Issue CRUD operation


Bn vo Gii v click vo menu link CRUD Generator sau in vo trng Model Class : Issue, in vo trng controller id : Issue (Lu I u c vit hoa) -> preview -> generated.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Sau khi thc hin xong ta hon thnh v vo trnh duyt kim tra: http://localhost/devyii/index.php?r=issue

III.1.7 To mi Issue
Sau khi thc hin xong bn to mi mt vi bn ghi v vo ng nhp vi acc: admin pass: admin khi h thng yu cu ng nhp

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

III.1.8 Thm thuc tnh drop down


Chng ta s to 3 thuc tnh dropdown bao gm Bugs,Features, Tasks. Khi chng ta to mi issue s c 3 la chn cho form field. Vo protected/models/Issue class v nh ngha cc hng sau: const TYPE_BUG=0; const TYPE_FEATURE=1; const TYPE_TASK=2;

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Tip theo xy dng hm getTypeOptions() s tr v gi tr cho cc thuc tnh trn: public function getTypeOptions() { return array( self::TYPE_BUG=>'Bug', self::TYPE_FEATURE=>'Feature', self::TYPE_TASK=>'Task', ); }

III.1.9 Thm thuc tnh drop-down vo views


Vo protected/views/issue/_form.php v tm trng Type trong form: <div class="row"> <?php echo $form->labelEx($model,'type_id'); ?> <?php echo $form->textField($model,'type_id'); ?> <?php echo $form->error($model,'type_id'); ?> </div> Tip theo bn nhn ln on u ca file s c on khai bo form: <?php $form=$this->beginWidget('CActiveForm', array( 'id'=>'issue-form', 'enableAjaxValidation'=>false, )); ?> y l cch nh ngha mt form s dng CactiveForm trong Yii. Tip theo bn vo IssueController.php trong protected/controller/IssueController v nhn vo hm actionCreate().

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

public function actionCreate() { $model=new Issue; // Uncomment the following line if AJAX validation is needed // $this->performAjaxValidation($model); if(isset($_POST['Issue'])) { $model->attributes=$_POST['Issue']; if($model->save()) $this->redirect(array('view','id'=>$model->id)); } $this->render('create',array( 'model'=>$model, )); } Ti y chng ta c th nhn thy views c render, n ang tr v mt khi to ca Issue model, v gi tr tr v gi l $model. By gi chng ta quay li file views xem cch x l ca trng Type trong form. Dng u l : $form->labelEx($model,'type_id'); Dng ny s dng CactiveForm::labelEx() phng thc chuyn qua nhn HTML cho issue model vi phn t type_id. N cng c khi to trong model class v s l cc nhn phn t cho nhng nhn ta mun thay i. l hm Issue::attributeLabels() c s dng quyt nh la chn label, nu chng ta nhn vo form th nhn ca type_id l Type c chuyn qua t hm attributeLabels(). public function attributeLabels()

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

{ return array( 'id' => 'ID', 'name' => 'Name', 'description' => 'Description', 'project_id' => 'Project', 'type_id' => 'Type', 'status_id' => 'Status', 'owner_id' => 'Owner', 'requester_id' => 'Requester', 'create_time' => 'Create Time', 'create_user_id' => 'Create User', 'update_time' => 'Update Time', 'update_user_id' => 'Update User', ); } Tr li view vi trng type_id ta c th nhn s qua nh sau: <?php echo $form->labelEx($model,'type_id'); ?> S dng labelEx() cng c th x l c dng tch khi fields d liu c yu cu. labelEx() s thm mt css class tn CHtml::requiredCss vi mc nh l required v CHtml::afterRequiredLabel vi mc nh l <span class=required>*</span> sau mi phn t c yu cu. Dng tip theo <?php echo $form->textField($model,type_id);?> s dng CactiveForm::textField() phng thc chuyn qua dng text-input field cho phn t type_id trong Issue model.Bt k quy tc kim tra d liu u c nh ngha trong Issue::rules() , phng thc ny s xc thc cc quy tc vi form u vo.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Cui cng l <?php echo $form->error($model,type_id);?> c s dng CactiveForm::error() chuyn qua xc thc li lin quan vi phn t type_id. Bn th nhn li tnh xc thc cc thuc tnh d liu , type_id ct c nh ngha l integer trong bng MySql v vy Gii generated vi quy tc xc thc trong Issue::rules() phng thc ny nh ngha nh sau: public function rules() { // NOTE: you should only define rules for those attributes that // will receive user inputs. return array( array('name', 'required'), array('project_id, type_id, status_id, owner_id, requester_id, create_user_id, update_user_id', 'numerical', 'integerOnly'=>true), Chnh v xc thc quy tc ny nn khi bn in dng ch trong form vi trng Type s gp bo li sau y:

Tip theo hin th dropdown list chng ta cn thay th dng c ca type_id trong protected/views/issue/_form.php: <div class="row"> <?php echo $form->labelEx($model,'type_id'); ?> <?php echo $form->textField($model,'type_id'); ?> <?php echo $form->error($model,'type_id'); ?>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

</div> Thay th thnh : <div class="row"> <?php echo $form->labelEx($model,'type_id'); ?> <?php echo $form->dropDownList($model,'type_id', $model->getTypeOptions()); ?> <?php echo $form->error($model,'type_id'); ?> </div>

Xong xui vo trnh duyt xem kt qu: http://localhost/devyii/index.php? r=issue/create

xc thc type_id trong form bn cn gii hn xc thc (Range Validation) vi CrangeValidator ca Yii h tr, bn thm vo hm Issue::rules() dng sau: array('type_id', 'in', 'range'=>self::getAllowedTypeRange()), public function rules() {

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

// NOTE: you should only define rules for those attributes that // will receive user inputs. return array( array('name', 'required'),
array('type_id', 'in', 'range'=>self::getAllowedTypeRange()),

array('project_id, type_id, status_id, owner_id, requester_id, create_user_id, update_user_id', 'numerical', 'integerOnly'=>true), array('name', 'length', 'max'=>255), array('description, create_time, update_time', 'safe'), // The following rule is used by search(). // Please remove those attributes that should not be searched. array('id, name, description, project_id, type_id, status_id, owner_id, requester_id, create_time, create_user_id, update_time, update_user_id', 'safe', 'on'=>'search'), ); }

Ta xy dng thm hm getAllowedTypeRange() trong class:

public static function getAllowedTypeRange() { return array( self::TYPE_BUG, self::TYPE_FEATURE,

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

self::TYPE_TASK, ); }

Hm validator rules ny kim tra input u vo tr v c nm trong danh sch hay khng, khi bn sa i thng tin vi u vo l 6 kt qu s th ny :

III.1.10 Sa li trng d liu owner v requester


Mt vn chng ta gp phi vi vic to form Issue l field owner v requester l freeform text-input . Tuy nhin chng ta bit rng gi tr integer trong bng issue ang gi nh danh kha ngoi (foreign key) ti ct id ca bng tbl_user. V th nn chng ta cn thm drop-down field cho chng. Chng ta khng th bit ch xc mi k hoch chng ta lm cho phn t type v status, cng nh owner v requesters c tin hnh t tbl_user. Nh vy mi ngi dng trong h thng s lin quan vi project bi nhng vn (issue) lin quan. V nhng issue khng th dropdown vi d liu t bng tbl_user. Chng ta cn lc ra danh sch u vo ca nhng ngi dng c lin quan ti project . iu ny c ngh trong k hoch xa hn chng ny, chng ta cn qun l vn vi khng ch ni dung ca project c bit. Ngha l project c bit s c chn trc khi bn c th to vn (issue) mi. Khi mt project c chn chng ta cn chc chn c bn thn (owner) v ngi yu cu (requester) dropdown la chn c trch lc ra nhng user lin quan ti d n.

III.1.11 Kim tra ni dung project


Chng ta mun chc chn rng ni dung project hp l c hin th trc khi chng ta cho php truy cp ti qun tr Issue. lm iu ny

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

chng ta cn lm vic thc thi ci gi l b lc (filter). Mt b lc trong yii l nhng iu chnh cu hnh c thc hin trc khi hoc sau khi mt controller action c thc hin. Mt v d v lnh l nu chng ta mun chc chn ngi dng ng nhp t vic thc hin controller action method. Chng ta c th vit n gin b lc truy cp s kim tra cc yu t trc khi action c thc hin.

III.1.12 nh ngha filters (b lc)


Mt filters(b lc) c th c nh ngha nh mt controller class hoc n c th l mt class. Khi s dng k hoc n gin (simple-method), tn phng thc phi bt u bng t filter v c mt k t c bit. Cho v d nu chng ta ang to mt b lc phng thc : someMethodName, ta s vit filter nh sau: public function filterSomeMethodName($filterChain) { ... }

C mt k hoch khc s dng filter l dng class thc hin filter logic, khi s dng class filter phi c k tha t Cfilter v c ti t nht preFilter() hoc postFilter() method quyt nh mc logic thc hin trc hoc sau mt action c khi to.

III.1.13 Thm mt Filter


By gi chng ta s thm mt filter trong IssueController class iu khin kim tra mt project hp l. Chng ta tin hnh k hoch: M protected/controllers/IssueController.php v vit hm filter sau on di gm class (sau function search). public function filterProjectContext($filterChain)

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

{ $filterChain->run(); } Ok, by gi chng ta nh ngha mt filter, tuy nhin cha c g nhiu y n gin ch l thc thi filter ($filterChain->run()), ci m x l filter v cho php thc hin cc phng thc action c lc bi method, iu ny mang ti mt im khc, Lm cch no chng ta nh ngha ci action method c s dng filter ?

III.1.14 Action filters c bit


Yii framework c class c bn ca controller l Ccontroller. N l mt filter method cn c ti sau mi thc n c bit ca action trong ci filter cn c p dng. Thc t phng thc ny c ti trong IssueController class.iu c lm y khi chng ta s dng Gii tool t ng to ra class ny. N to ra accessControl filter ci m c nh ngha trong Ccontroller, s l mt s hnh ng c bn chc chn rng ngi dng ang s dng c phn quyn s dng acction ny.Nu bn khng ng nhp v click vo link Create Issue bn s b chuyn hng ti trang login v c nh danh cho ti khi bn c php to mi issue.Access controll filter x l iu ny. Chng ta s khm ph nhiu hn v filter . bt u chng ta cn thm mi filter cho mng cu hnh IssueController::filters() (cho vo cnh hm filter c cng c)

public function filters() { return array( 'accessControl', // perform access control for CRUD operations 'projectContext + create', //check to ensure valid project context );

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

} Filters ny tr v mng cu hnh , trong hm filters trc chng ta to projectContext filter ci m c nh ngha nh mt phng thc v p dng thm c action create . Cu hnh ny cho php vi cc c php +, - s dng vi cc filter c p dng v khng c p dng. Cho v d chng ta mun p dng vi tt c cc action ngoi tr action Update() v actionView() ta lm nh sau: Return array( projectContext update, view, ); Bn s khng cng + hay cng - c hai action cng mt lc,

III.1.15 Thm mt filter logic


Ok, by gi chng ta nh ngha filter v chng ta cu hnh n gi khi actionCreate() c kch hot vi Issue controller class. Tuy nhin n vn khng thc hin theo logic,khi chng ta mun chc chn project context filter trc khi action c khi ng,chng ta cn t logic filter trc khi gi $filterChain->run(). Chng ta s thm thuc tnh project t controller class,Chng ta s s dng query string (chui truy vn) t tham s trong URL nh danh project.Ngoi preAction filter s kim tra xem phn t trong project c tn ti hay null,nu ng n s s dng query string tham s khi ng vic la chn project trong nh danh kha chnh (primary key). Nu thnh cng action s thc thi, nu tht bi ngoi l s c xut ra, sau y l code : Bn hy thay th ni dung cc hm filter bng cc hm mi di y trong protected/controller/IssueContrller.php
class IssueController extends CController { .... /** * @var private property containing the associated Project model instance.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013 */ private $_project = null; /**

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

* Protected method to load the associated Project model class * @param integer projectId the primary identifier of the associated Project * @return object the Project data model based on the primary key */ protected function loadProject($projectId) { //if the project property is null, create it based on input id if($this->_project===null) { $this->_project=Project::model()->findByPk($projectId); if($this->_project===null) { throw new CHttpException(404,Yeu cau project khong ton tai.'); } } return $this->_project; } /** * In-class defined filter method, configured for use in the above filters() * method. It is called before the actionCreate() action method is run in * order to ensure a proper project context */ public function filterProjectContext($filterChain) {

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

//set the project identifier based on GET input request variables if(isset($_GET['pid'])) $this->loadProject($_GET['pid']); else throw new CHttpException(403,Chi cac project dac biet hien ra truoc khi thuc hien action nay.'); //complete the running of other filters and execute the requested action $filterChain->run(); }

... }

Sau khi thay th hon chnh bn vo trnh duyt kim tra: http://localhost/devyii/index.php?r=issue/create

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

III.1.16 Thm Project ID


chng to project chng ta thm nhiu project kim tra h thng, tuy nhin nhng ai cha to th vui lng vo http://localhost/devyii/index.php? r=project to khong vi project chun b cho cng vic tip theo ny.Bi v cng vic tip theo yu cu phi c ID ca project c th thm id ny ti vic to mi issue URL. Tip theo chng ta cn iu chnh links trong view file issue : protected/views/issue/index.php. Nhn pha trn u file bn s thy ni links c nh ngha qua mng menu items: $this->menu=array( array('label'=>'Create Issue', 'url'=>array('create')), array('label'=>'Manage Issue', 'url'=>array('admin')), ); thm chui tham s truy vn (query string paramter) ti links chng ta n gin thm trng name=>value trong phn nh ngha mng tham s url, chng ta th lm vi project id=1 , iu chnh dng Create Issue: array('label'=>'Create Issue', 'url'=>array('create', 'pid'=>1)), By gi khi bn xem trang issue listing , bn s nhn thy Create Issue vi link url nh sau: http://localhost/devyii/index.php?r=issue/create&pid=1 y l chui tham s truy vn cho php lc thuc tnh thit lp project context, lc ny khi bn click vo link http://localhost/devyii/index.php? r=issue/create s hin li 403 v ch c link trn mi hin th

III.1.17 iu chnh chi tit trang project


Vic thm project_id ti url cho vic to mi issue (Create new issue) link l thc s cn thit cho giai on u chc chn rng b lc lm vic hiu qu. Tuy nhin chng ta lun lun nhn thy link url khi to mi issue lun vi project id l 1, tt nhin khng phi iu chng ta mun. Nhng g chng ta mun lm l c mt menu option cho vic to mi issue tr thnh mt phn ca trang chi tit project. Vi cch ny,bn c th la chn mt

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

project t danh sch project , project context c bit s c hin th v chng tay thm ng project id to mi links issue, hy lm n thay i. M protected/views/project/view.php. Nhn trn u file bn s thy mng menu $this->menu=array(.). Chng ta cn thm link khc to mi issue v tr kt thc danh sch menu
$this->menu=array( array('label'=>'List Project', 'url'=>array('index')), array('label'=>'Create Project', 'url'=>array('create')), array('label'=>'Update Project', 'url'=>array('update', 'id'=>$model->id)), array('label'=>'Delete Project', 'url'=>'#', 'linkOptions'=>array('s ubmit'=>array('delete','id'=>$model->id),'confirm'=>'Are you sure you want to delete this item?')), array('label'=>'Manage Project', 'url'=>array('admin')), array('label'=>'Create Issue', 'url'=>array('issue/create', 'pid'=>$model->id)), ); Vo trnh duyt g http://localhost/devyii/index.php?r=project/view&id=1

Bn s nhn thy cui menu l link to issue,

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

By gi chng ta c thuc tnh project context c thit lp khi to mi issue, chng ta c th remove trng form project cng nh trng form user input. M protected/views/issue/_form.php xa b on sau: <div class="row"> <?php echo $form->labelEx($model,'project_id'); ?> <?php echo $form->textField($model,'project_id'); ?> <?php echo $form->error($model,'project_id'); ?> </div> Tuy nhin dng nh project_id s khng c submit t form,chng ta s cn thit lp tham s project_id t b lc (filter) m chng ta mi thc thi. Sau chng ta bit c project_id lin quan,hy thit lp gi tr ca Issue::project_id t gi tr ca id bng project c ci t bi filter trc . V vy chng ta cn iu chnh IssuesController::actionCreate() method: public function actionCreate() { $model=new Issue; $model->project_id = $this->_project->id; Bn to mi issue vi project_id = 2 v s c kt qu :

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

III.1.18 Tr li vi dropdown owner requester


Cui cng , chng ta tr li vi nhng g chng ta thit lp trc ,vi s thay i owner v requester khi la chn dropdown hp l khi la chn project. Trong thc n ny chng ta cn mt s user lin quan ti project, sau qun tr user trong focus ca chng sau,chng ta s lm nhiu hn vic thm ng dn lin quan ti database vi ng dn sql chng ta cn thm 2 user vo mysql: INSERT INTO tbl_user (email, username, password) VALUES ('test1@ notanaddress.com','User One', MD5('test1')), ('test2@notanaddress. com','User Two', MD5('test2')); Khi bn chy ng dng mi ny, bn s to 2 user mi trong h thng vi id l 1 v 2. Chng ta cn assign (ng k) hai user ny ti project INSERT INTO tbl_project_user_assignment (project_id, user_id) VALUES (1,1), (1,2); Mt iu tuyt vi ca quan h trong Active Record vi Yii l kh nng truy cp hp l thnh vin ca ng dng vi issue vi quan h thuc v (belong to),tham chiu t issue model khi to.Sau khi chng ta s dng Gii
Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

tool khi to issue model class, chng ta chc chn tch vo check box trng Build Relations thng l mc nh tch ri.iu ny cho php chng ta xy dng mi quan h gia cc bng. Chng ta c th nhn hm relations() t protected/models/Issue.php Sau chng ta to class sau khi thm mi qun h trong database : public function relations() { //NOTE: you may need to adjust the relation name and the related // class name for the relations automatically generated below. return array( 'requester' => array(self::BELONGS_TO, 'User', 'requester_id'), 'owner' => array(self::BELONGS_TO, 'User', 'owner_id'), 'project' => array(self::BELONGS_TO, 'Project', 'project_id'), ); } y quan h requester thuc v user.requester_id bi issue.requester tham chiu ti bng tbl_user, tng t vi 2 trng cn li.

y l cu hnh c khi to t AR model, vi quan h ny chng ta c th truy cp vo AR class lin quan mt cch d dng.cho v v, chng ta mun truy cp mt project t mt issue lin quan: //create the model instance by primary key: $issue = Issue::model()->findByPk(1); //access the associated Project AR instance $project = $issue->project; Khi chng ta to Project model class vi nhng bng khc c nh ngha c mi quan h (relashionship), tuy nhin by gi chng ta c mt s quan h

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

c nh ngha, chng ta cn thm Project::relations(). M /protected/models/Project.php v thay th ni dung trong hm relations(): public function relations() { return array( 'issues' => array(self::HAS_MANY, 'Issue', 'project_id'), 'users' => array(self::MANY_MANY, 'User', 'tbl_project_user_assignment(project_id, user_id)'), ); } Issues: //mt issue c th c mt hoc nhiu trong 1 d n Users: //mt user c th mt hoc nhiu trong mt hoc nhiu d n Vi s thay th trn chng ta d dng truy cp tt c issue hoc user lin quan ti project mt cch d dng. $project = Project::model()->findByPk(1); $allProjectIssues = $project->issues; $allUsers = $project->users; $ownerOfFirstIssue = $project->issues[0]->owner; Thng thng chng ta c th vit lnh SQL trng thi ni truy cp ti d liu lin quan,s dng quan h trong AR Yii gip chng ta d dng v nhanh gn hn. Chng ta c th truy cp quan h d dng d c v d hiu.

III.1.19 Generating the data to populate the dropdowns


Theo k hoch chng ta cn dropdown d liu ca status v type . Chng ta s thm hm getUserOptions() ti Project model class:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

M protected/models/Project.php v thm on sau vo di class: /** * @return array of valid users for this project, indexed by user IDs */ public function getUserOptions() { $usersArray = CHtml::listData($this->users, 'id', 'username'); return $usersArray; } y chng ta s dng Yiis CHtml class gip chng ta to mng id=>username t cc user lin quan ti project. Nh rng thuc tnh users (nh ngha trong method relations()) trong project class khi s dng AR model. CHtml::listData() l phng thc c th tin hnh trong danh sch v s dng mng hp l t CactiveForm::dropDownList(); By gi chng ta c hm getUserOptions() tr v d liu chng ta cn, chng ta thc thi dropdown hin th d liu tr v,chng ta s s dng filter thit lp project id lin quan t request $_GET,v chng ta s dng gi tr thit lp project_id khi to mi issue lc bt u thc hin IssueController::actionCreate() method, by gi bn c cm thy AR thc s d dng v nhanh gn khng ? Chng ta hy thay i trong form issue: M protected/views/issue/_form.php v tm hai trng text-input owner_id v requester_id v thay th n vi on sau: <?php echo $form->textField($model,'owner_id'); ?> Tr thnh
<?php echo $form->dropDownList($model,'owner_id', $model->project>getUserOptions()); ?>

V thay th : <?php echo $form->textField($model,'requester_id'); ?>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Thnh : <?php echo $form->dropDownList($model,'requester_id', $model->project->getUserOptions()); ?>

Vo trnh duyt g : http://localhost/devyii/index.php?r=issue/create&pid=1 Nu khng vo c v bo li vui lng vo Gii, click menu : Model generator sau ti trng table prefix : tbl_ , ti trng table name : tbl_user , ti trng model class : User sau preview->generated. Nu vn cha vo c vui lng vo Gii, click menu : Model generator sau ti trng table prefix : tbl_ , ti trng table name : tbl_project_user_assignment , ti trng model class : ProjectUserAssignment sau preview->generated.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

III.1.20 Lm ln thay i cui cng


Sau khi chng ta bt u to issue form ,hy lm nhanh mt ln thay i cui cng,Vic to time v user cng nh time update v user update field chng ta c trong mi bn ghi l c s history (lch s) v nh du ngi dng no cp nht bn ghi. Sau chng ta s iu chnh ng dng logic mt cch t ng ph bin vi field x l insert hoc update. By gi , hy xa i field input trong form ca chng: Vo protected/views/issue/_form.php xa cc on sau:

<div class="row"> <?php echo $form->labelEx($model,'create_time'); ?> <?php echo $form->textField($model,'create_time'); ?> <?php echo $form->error($model,'create_time'); ?> </div> <div class="row"> <?php echo $form->labelEx($model,'create_user_id'); ?> <?php echo $form->textField($model,'create_user_id'); ?> <?php echo $form->error($model,'create_user_id'); ?> </div> <div class="row"> <?php echo $form->labelEx($model,'update_time'); ?> <?php echo $form->textField($model,'update_time'); ?> <?php echo $form->error($model,'update_time'); ?> </div> <div class="row">

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<?php echo $form->labelEx($model,'update_user_id'); ?> <?php echo $form->textField($model,'update_user_id'); ?> <?php echo $form->error($model,'update_user_id'); ?> </div> Sau khi thc hin xong form ca chng ta ch cn nh sau:

III.1.21 X hi vi CRUD
Phn ch ca chng ny l thc thi tt c CRUD operation cho Issue. Chng ta c kt thc vic to ra cc hm, nhng chng ta vn cn

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

hon thnh phn chi tit (read), cp nht (update), v xa (delete) cho Issue, Tht may mn hu ht tiu chun ny thc thi trong Gii CRUD khi generated cc hm. Tuy nhin sau chng ta mun qun l tt c Issue vi khng ch vn cnh ca project, chng ta cn lm mt s iu chnh sao cho chng ta c th truy cp vo cc hm chc nng.

III.1.22 Danh sch vi Issue


Mc d chng ta tng ngh v actionIndex() method trong IssueController class n hin th danh sch tt c issue trong CSDL, chng ta khng mun iu ny trong hm chc nng.Dng nh khng tht s tt khi m tt c danh sch cc issue trong CSDL c hin th ra,V th nn chng ta s iu chnh ng dng hin th danh sch ca mt phn issue lin quan ti project trong chi tit trang. Lc chng ta tin hnh thay i quan h AR model trong Yii, n s lm biu thay i. III.1.23 iu chnh project controller Trc tin chng ta s iu chnh actionView() method trong ProjectController class. Sau chng ta mun hin th danh sch cc issue lin quan vi cc d n c bit m chng ta chn, chng ta c th lm iu ny vi cng mt trang chi tit project. Method actionView() l method c hin th trong chi tit project. Chnh li method sau: protected/controller/ProjectController.php public function actionView($id) { $issueDataProvider=new CActiveDataProvider('Issue', array('criteria'=>array( 'condition'=>'project_id=:projectId', 'params'=>array(':projectId'=>$this->loadModel($id)->id), ), 'pagination'=>array('pageSize'=>1,),

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

)); $this->render('view',array('model'=>$this->loadModel($id), 'issueDataProvider'=>$issueDataProvider, )); } Ti y chng ta s dng CactiveDataProvider (Kch hot nh cung cp d liu do Yii to ra) framework class cung cp d liu s dng i tng ca Cactive Record (kch hot bn ghi), n s s dng cc quan h AR model lin quan trch lc d liu t CSDL trong v chng ta s s dng n mt cch d dng. Bng vic xy dng thnh phn danh sch gi l ClistView. Chng ta s dng thnh phn ny hin th danh sch ca issue trong view file. Chng ta s dng thuc tnh tiu chun quyt nh iu kin s ch lc danh sch issue lin quan ti project ang c hin th, chng ta cng s dng thuc tnh phn trang (pagination) gii hn bn ghi trong danh sch issue c lc ra. Th cui cng chng ta lm thm d liu c cung cp ny vo mng nh ngha c gi l render(), lm n hp l khi chuyn sang view file vi bin $issueDataProvide.

III.1.23 Chnh li file View ca project


Nh chng ti ngh ,chng ta s s dng thnh phn trong framework gi ti ClistView hin th ngoi danh sch cc issue trong project chi tit trang. M protected/views/project/view.php v thm on sau di cng file: <br /> <h1>Project Issues</h1> <?php $this->widget('zii.widgets.CListView', array( 'dataProvider'=>$issueDataProvider, 'itemView'=>'/issue/_view',

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

)); ?>

Vy l chng ta thit lp thuc tnh dataProvider trong ClistView t issue dataprovider m chng ta to trong controller.V sau chng ta cu hnh n s dng t protected/views/issue/_view.php file nh mt templates cho render mi item trong data provider. File ny c to cho chng ta bi Gii tool khi chng ta generated CRUD cho Issue.Chng ta s dng n ti y hin th issue trong project chi tit trang. Chng ta cng cn lm s thay i protected/views/issue/_view.php file chng ta iu chnh c bit nh mt layout templates cho mi issue. Chnh li ni dung thc th ca file nh sau: <div class="view"> <b><?php echo CHtml::encode($data->getAttributeLabel('name')); ?>: </b> <?php echo CHtml::link(CHtml::encode($data->name), array('issue/ view', 'id'=>$data->id)); ?> <br /> <b><?php echo CHtml::encode($data->getAttributeLabel('descripti on')); ?>:</b> <?php echo CHtml::encode($data->description); ?> <br /> <b><?php echo CHtml::encode($data->getAttributeLabel('type_id')); ?>:</b> <?php echo CHtml::encode($data->type_id); ?> <br /> <b><?php echo CHtml::encode($data->getAttributeLabel('status_id')); ?>:</b>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<?php echo CHtml::encode($data->status_id); ?> </div> Ok, bn vo trnh duyt g : http://localhost/devyii/index.php? r=project/view&id=2 xem kt qu:

III.1.24 Tin hnh status v type text hin th


Trc chng ta va thm public method Issue AR class, trch lc status v type option ti dropdown issue form chng ta cn thm mt s method trong AR class tr v text cho status v type c bit hoc type id. Vo protected/models/Issue.php :
Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

public function getStatusText() { $statusOptions=$this->statusOptions; return isset($statusOptions[$this->status_id]) ? $statusOptions[$this->status_id] : "unknown status ({$this->status_ id})"; } /** * @return string the type text display for the current issue */ public function getTypeText() { $typeOptions=$this->typeOptions; return isset($typeOptions[$this->type_id]) ? $typeOptions[$this->type_id] : "unknown type ({$this->type_id})"; } Ti y s tr v cc trng thi value (Chua san sang,San sang,ket thuc) v thuc tnh text (bug,feature,task) ci t cho issue.

Bn vo protected/model/issue.php thm on khai bo sau: const STATUS_NOTYET=0; const STATUS_YET=1; const STATUS_FINAL=2;

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

public function getStatusOptions() { return array( self::STATUS_NOTYET=>'Chua San Sang', self::STATUS_YET=>'Sang Sang', self::STATUS_FINAL=>'Hoan Thanh', ); } public static function getAllowedStatusRange() { return array( self::STATUS_NOTYET, self::STATUS_YET, self::STATUS_FINAL, ); }

Thm on sau vo array trong function Issue::rules() array('status_id','in','range'=>self::getAllowedStatusRange()), Trong Issue::relations() bn thm on sau: 'users'=>array(self::MANY_MANY,'User','tbl_project_user_assignment(project _id,user_id)'),

public function getUserOptions()

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

{ $usersArray=CHtml::listData($this->users,'id','username'); return $usersArray; } Vo protected/views/issue/_form.php chnh li nh sau: <div class="row"> <?php echo $form->labelEx($model,'status_id'); ?> <?php echo $form->dropDownList($model,'status_id',$model>getStatusOptions()); ?> <?php echo $form->error($model,'status_id'); ?> </div>

III.1.25 Thm on hin th text ti form


Vo protected/views/issue/_view.php Thay th this <?php echo CHtml::encode($data->type_id); ?> thnh: <?php echo CHtml::encode($data->getTypeText()); ?> V <?php echo CHtml::encode($data->status_id); ?> thnh <?php echo CHtml::encode($data->getStatusText()); ?> (ch mi to xong status v type th bn phi vo link menu manage v click vo hnh edit trong view list ri chn cc trng to ra cc id cho 2 trng ny, nu khng kt qu hin ra s l unknow hoc s b bo li khng nhn din c kt qu tr v v khng i tng c khi to ) V y l thnh qu:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

III.1.26 Thay i chi tit khung nhn Issue


Chng ta hy vo http://localhost/devyii/index.php?r=issue/view&id=1 v thy cc trng thi vn cn nm dng s 0 , 1, iu c ngha chng ta vn cha thay i v y l cng vic chng ta phi lm

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Ti v chng ta s dng view file mc nh nn cha cu hnh ht, iu chnh chng ta cn vo protected/views/issue/view.php Chng ta s s dng Zii c k tha t widget CdetailView, ci m chng ta nhn thy trc file view project m chng ta thm ClistView, V chng ta c th nhn thy on sau trong protected/views/issue/views.php <?php $this->widget('zii.widgets.CDetailView', array( 'data'=>$model, 'attributes'=>array( 'id', 'name', 'description',

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'project_id', 'type_id', 'status_id', 'owner_id', 'requester_id', 'create_time', 'create_user_id', 'update_time', 'update_user_id', ), )); ?> Ti y chng ta thit lp d liu cho model Cdetail View widget t Issue Model class c khi to ( l khi to c bit khi chng ta mun hin th chi tit) v sau khi thit lp danh sch ca phn t khi model c khi to hin th trong render chi tit views, mt phn t c th c trng ging nh chui nh dng : tn : thuc tnh: nhn, vi c hai i tng type v label hoc array, trong trng hp ny chng ta ch s dng tn ca phn t. Nu chng ta thy mng phn t ny, chng ta c th custom vic hin th tt hn t vic nh ngha li cc yu t. Chng ta s tin hnh k hoch trong thc n c bit ca model class method Issue::getTypeText() v Issue::getStatusText() c s dng hin th gi tr text cho type v status field.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Hy thay i trong CdetailView nh sau: <?php $this->widget('zii.widgets.CDetailView', array( 'data'=>$model, 'attributes'=>array( 'id', 'name', 'description', array( 'name'=>'type_id', 'value'=>CHtml::encode($model->getTypeText()) ), array( 'name'=>'status_id', 'value'=>CHtml::encode($model->getStatusText()) ), 'owner_id', 'requester_id', ), )); ?>

Sau khi thc hin xong vo http://localhost/devyii/index.php? r=issue/view&id=1 xem kt qu:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

III.1.27 Hin th tn owner v requester


T nh trn bn cng c th nhn thy, bn ch mi nhn thy id ca user to ln hoc user yu cu n, cng vic ca bn by gi l thay th n bng tn ca user trong bng user. S dng Quan h AR Sau khi Issues v users c trnh din li ging nh bng d liu v mi quan h bi kha ngoi (foreign key) chng ta c th truy cp c vo owner v requester username t $model trong view file nh cng c mnh ca Yii AR , by gi cng vic ca chng ta l nh ngha li mi quan h trong Issue::relations()

'owner' => array(self::BELONGS_TO, 'User', 'owner_id'),

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

// on ny s dng lin kt thuc v,bn thn mt user nm trong bng user 'requester' => array(self::BELONGS_TO, 'User', 'requester_id'), // on ny s dng lin kt thuc v,ngi yu cu nm trong bng user on ny c khi to ri v bn khng cn phi vo iu chnh li, Thay vo bn cn quay li file protected/views/issues/view.php lm nt s thay i <?php $this->widget('zii.widgets.CDetailView', array( 'data'=>$model, 'attributes'=>array( 'id', 'name', 'description', array( 'name'=>'type_id', 'value'=>CHtml::encode($model->getTypeText()) ), array( 'name'=>'status_id', 'value'=>CHtml::encode($model->getStatusText()) ),

array( 'name'=>'owner_id',
Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'value'=>isset($model->owner)?CHtml::encode($model->owner>username):"unknown" ), array( 'name'=>'requester_id', 'value'=>isset($model->requester)?CHtml::encode($model>requester->username):"unknown" ), ), )); ?> V y l kt qu: http://localhost/devyii/index.php?r=issue/view&id=1

III.1.28 S thay i cui cng vi navigation


M protected/views/issue/view.php v thay i menu config nh sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

$this->menu=array( array('label'=>'List Issues', 'url'=> array('index', 'pid'=>$model->project->id)), array('label'=>'Create Issue', 'url'=> array('create', 'pid'=>$model->project->id)), array('label'=>'Update Issue', 'url'=> array('update', 'id'=>$model->id)), array('label'=>'Delete Issue', 'url'=>'#', 'linkOptions'=> array('submit'=>array('delete','id'=>$model->id), 'confirm'=>'Are you sure you want to delete this item?')), array('label'=>'Manage Issues', 'url'=> array('admin', 'pid'=>$model->project->id)), ); Tip theo chng ta cn thay i IssueController::filters() public function filters() { return array( 'accessControl', // perform access control for CRUD operations 'projectContext + create index admin', //perform a check to //ensure valid project context ); } Tip theo ta chnh li IssueControlller:actionIndex(): public function actionIndex()

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

{ $dataProvider=new CActiveDataProvider('Issue', array( 'criteria'=>array( 'condition'=>'project_id=:projectId', 'params'=>array(':projectId'=>$this->_project->id), ), )); $this->render('index',array('dataProvider'=>$dataProvider,)); } Tip theo bn cn vo protected/views/issue/admin.php S dng kt qu ca model class Issues::search() method c cung cp danh sch issues.Bn vo IssueController::actionAdmin(): public function actionAdmin() { $model=new Issue('search'); if(isset($_GET['Issue'])) $model->attributes=$_GET['Issue']; $model->project_id = $this->_project->id; $this->render('admin',array('model'=>$model)); } Tip theo bn thay i trong Issues::search()

public function search() { // Warning: Please modify the following code to remove attributes that

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

// should not be searched. $criteria=new CDbCriteria; $criteria->compare('id',$this->id); $criteria->compare('name',$this->name,true); $criteria->compare('description',$this->description,true); $criteria->compare('type_id',$this->type_id); $criteria->compare('status_id',$this->status_id); $criteria->compare('owner_id',$this->owner_id); $criteria->compare('requester_id',$this->requester_id); $criteria->compare('create_time',$this->create_time,true); $criteria->compare('create_user_id',$this->create_user_id); $criteria->compare('update_time',$this->update_time,true); $criteria->compare('update_user_id',$this->update_user_id); $criteria->condition='project_id=:projectID'; $criteria->params=array(':projectID'=>$this->project_id); return new CActiveDataProvider(get_class($this), array( 'criteria'=>$criteria, )); }

y chng ta va xa $criteria->compare() s dng project_id vi $criteria>condition() so snh vi project_id trong project context.vi nhng thay i ny danh sch issues thc s b chi phi bi project

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Chng 4: Qun l ngi dng v qu trnh xc thc

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

(User Management and Authentication) K hoch xa hn


Khi chng ta s dng dng lnh yii to ra ng dng ny, n cho php chng ta ng nhp bi 2 account l demo demo v admin-admin ,chng ta c th thc hin li qu trnh xc thc t CRUD v ta c k hoch sau: To controller class cho php: 1. To mi user 2. Lc danh sch user tn ti trong csdl 3. Cp nht/chnh sa bn ghi 4. Xa user tn ti To view file v thc hin trnh by : 1. Hin th form cho php ngi dng to mi 2. Hin th danh sch user tn ti 3. Hin th form cho php chnh sa user 4. Thm hoc xa user Chnh li qu trnh xc thc s dng database kim tra qu trnh login

IV.1 User CRUD


Trc tin bn vo Gii : http://localhost/devyii/index.php? r=gii/default/index Chn Model Generated v in ging nh hnh sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Click Preview - > Generated. Sau khi hon thnh bn vo protected/models/ kim tra file mi to bn s thy User.php Tip theo bn vo Gii chn CRUD Generator , ti Model class : in vo : User , ti Controller ID in vo : User, sau chn preview -> generated. Tip theo bn vo http://localhost/devyii/index.php?r=user kim tra bn thy 2 user c to sn ban u

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Chng ta cng c th to mi user ngay by gi t link menu create user: http://localhost/devyii/index.php?r=user/create Nu hin ti bn khng ng nhp bn s c router login s dng vi 2 ti khon l demo/demo v admin/admin.

IV.2 Thnh phn Behavior


Behavior trong Yii class c thc thi giao din ca Ibehavior, v phng thc ca n c th k tha t hm thnh phn bi vic kch hot component. L do chng ta s dng component ny bi v User, Project, Issue cng c cng cu trc, ta thay th hm behavior c sn

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

v kch hot n t model class,n cho php chng ta thit lp cc trng d liu trong AR class . Thc t trong th vin Zii, gi nh trong Yii framework tn ti behavior cho vic cp nht thi gian create_time v update_time. Behavior ny c tn CtimestampBehavior. Bn vo protected/models/User.php thm hm sau: public function behaviors() { return array('CTimestampBehavior' => array( 'class' => 'zii.behaviors.CTimestampBehavior', 'createAttribute' => 'create_time', 'updateAttribute' => 'update_time', 'setUpdateOnCreate' => true, ), ); }

y chng ta va kch hot th vin Zii CtimestampBehavior ti class User model. Chng ta c th nhn thy s khc bit ca 2 phn t create_time v update_time c cu hnh trong behavior thit lp thi gian cho mi bn ghi c to hoc cp nht.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Sau ny khi bn ng nhp vo user mi th bn s thy 2 phn t s c t cp nht:

iu ny tht tuyt chng ta cn lp li n trong model class, tuy nhin chng ta c th thc hin k hoch khc tt hn na , l tin hnh s dng Active record (kch hot bn ghi) bi s kin beforeSave (trc khi lu), v thit lp nhng g cn thit cho trng d liu. v chng ta c th thc hin cc lnh kt ni vi AR model class.Bn s la chn k hoch ny tt hn cho ng dng Yii c a bn. lm vic chng ta cn to mi AR model class, trc tin xa b hm behaviors() chng ta va to trong User.php model. Tip theo bn vo protected/models/ bn to file DevYiiActiveRecord.php vi ni dung sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<?php abstract class DevYiiActiveRecord extends CActiveRecord { protected function beforeSave() { if(null !== Yii::app()->user) $id=Yii::app()->user->id; else $id=1; if($this->isNewRecord) $this->create_user_id=$id; $this->update_user_id=$id; return parent::beforeSave(); } public function behaviors() { return array( 'CTimestampBehavior' => array( 'class' => 'zii.behaviors.CTimestampBehavior', 'createAttribute' => 'create_time', 'updateAttribute' => 'update_time', 'setUpdateOnCreate' => true, ),

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

); } } Ti y chng ta ti phng thc CactiveRecord::beforeSave(), y l mt trong nhiu even m CactiveRecord xy dng cho php custom trong qu trnh thc hin project. (Chi tit vui lng vo quyn Yii cookbook nh ti dch ri vo Yiivn.com m tm trong phn ebook), c hai phng thc h tr cho php chng ta chuyn d liu bn ghi trc khi chng ta thc hin nhng g cn thit trc khi hoc sau khi kch hot bn ghi gm 2 hm : beforeSave() v afterSave() (Trc khi lu v sau khi lu). Trong trng hp ny chng ta quyt nh lu tm 2 bin time trc khi tin hnh lu vo CSDL. Chng ta quyt nh vic khng ch gii quyt vic to mi bn ghi hay cp nht bn ghi s dng thuc tnh $this->isNewRecord v thit lp d liu. Khi chng ta chc chn khi to tr v parent::beforeSave() l chng ta thc hin xong mi th c lm trong hm. Chng ta thc hin Yii::app()->user x l nhng khi to ni ngoi ng dng hn ch truy cp. Chng ta c th di chuyn behaviors() method lm class c bn cho cc AR model k tha n vi vic kch hot behaviors Ta th iu ny, chng ta cn chnh li mi 3 AR class model l Project, user, Issue k tha hm khi to t CactiveRecord. V d: class User extends CActiveRecord { } Chng ta cn thay bng class User extends DevYiiActiveRecord { }

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Lm tng t vi class Project v Issue model class. Tip theo chng ta cn vo protected/views/project/_form.php v protected/views/issue/_form.php v protected/views/user/_form.php tm v xa nhng on sau: <div class="row"> <?php echo $form->labelEx($model,'create_time'); ?> <?php echo $form->textField($model,'create_time'); ?> <?php echo $form->error($model,'create_time'); ?> </div> <div class="row"> <?php echo $form->labelEx($model,'create_user_id'); ?> <?php echo $form->textField($model,'create_user_id'); ?> <?php echo $form->error($model,'create_user_id'); ?> </div> <div class="row"> <?php echo $form->labelEx($model,'update_time'); ?> <?php echo $form->textField($model,'update_time'); ?> <?php echo $form->error($model,'update_time'); ?> </div> <div class="row"> <?php echo $form->labelEx($model,'update_user_id'); ?> <?php echo $form->textField($model,'update_user_id'); ?> <?php echo $form->error($model,'update_user_id'); ?> </div>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

V t form user: protected/views/user/_form.php ta xa thm phn t last_login_time <div class="row"> <?php echo $form->labelEx($model,'last_login_time'); ?> <?php echo $form->textField($model,'last_login_time'); ?> <?php echo $form->error($model,'last_login_time'); ?> </div> Tip theo vo model ca 3 class Issue, Project, Users trn xa cc phn t trn trong hm rules v hm attributeslabel v hm search. Tip theo ta vo model User.php :: rules() v thay i nh sau: public function rules() { return array( array('email', 'required'), array('email, username, password', 'length', 'max'=>255, array('email, username', 'unique'), array('email', 'email'), // The following rule is used by search(). // Please remove those attributes that should not be searched. array('id, email, username, password', 'safe','on'=>'search'), ); }

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

IV.3 Thm trng G li password


Chng ta khai bo trn u class User.php model trong protected/models/User.php: public $password_repeat; Thm User::rules() dng sau vo mng array: array('password', 'compare', 'compareAttribute'=>'password_repeat'), array('password_repeat', 'safe'), V thay i array('email, username, password, password_repeat', 'required'), Thm on sau vo protected/views/user/_form.php sau password field: <div class="row"> <?php echo $form->labelEx($model,'password_repeat'); ?> <?php echo $form->passwordField($model,'password_repeat', array('size'=>60,'maxlength'=>255)); ?> <?php echo $form->error($model,'password_repeat'); ?> </div> V y l kt qu: http://localhost/devyii/index.php?r=user/create

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

IV.4 Hash (Bm) mt khu


Ln thay i cui cng chng ta c th lm trc khi di chuyn ti vic to mi user l to hm bm cho mt khu ca ngi dng, khi chng ta nht n vo database. Chng ta s thm logic vo User.php nh vic iu khin CactiveRecord cho php chng ta custom mc nh kch hot bn ghi , iu ny c ti vi phng thc afterValidate() sau khi xc thc cc trng d liu u vo hp l, Vo model User.php protected/models/User.php thm on sau di class:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

protected function afterValidate() { parent::afterValidate(); if(!$this->hasErrors()) $this->password = $this->hashPassword($this->password); } /** * Generates the password hash. * @param string password * @return string hash */ public function hashPassword($password) { return md5($password); } Bn hy to mi ti khon tn admin, password admin v s thy kt qu sau: ( Bc ny m khng to th on sau khi phi vo h thng lun ^_^) http://localhost/devyii/index.php?r=user/view&id=3

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

IV.5 Xc thc User kt ni ti Database


Nh chng ta bit, form ng nhp c bn ngi dng xc thc truy cp c to n gin bi lnh Yii khi to mi ng dng, Chng ta truy nhp vo website nh hai ti khon l demo/demo v admin/admin, cng vic ca chng ta by gi l chuyn ton b ti khon xc thc trong CSDL m bn va to vo qu trnh xc thc h thng Yii.

Gii thiu Yii authentication model (Xc thc m hnh CSDL)


Trung tm ti xc thc user ca Yii l mt thnh phn ng dng gi l user, n l mt i tng c thc thi t giao din IwebUser, class c bit ny c s dng bi vic thc thi CwebUser, thnh phn user ny l thng tin tt c nh danh user hin ti c trong ng dng. Thnh phn ny c cu hnh cho chng ta nh mt phn t ng trong h thng khi ng dng

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

c to bi yii tool, cu hnh n bn vo protected/config/main.php v nhn on ny: 'user'=>array( // enable cookie-based authentication 'allowAutoLogin'=>true, ),

Lc ny n c cu hnh nh mt thnh phn ng dng,vi tn user, chng ta c th truy cp bt k ni no trong ng dng bi vic s dng: Yii::app()->user. Yii t ng nh ngha thc th thc hin vic xc thc c bn, n c gi l identity class v n c th hin bi Iuseridentity interface, vai tr chnh ca class ny l xc thc v phn quyn user. Bn m protected/components/UserIdentity.php y chnh l n v bn c th nhn s qua n : <?php class UserIdentity extends CUserIdentity { public function authenticate() { $users=array( 'demo'=>'demo', 'admin'=>'admin', ); if(!isset($users[$this->username])) $this->errorCode=self::ERROR_USERNAME_INVALID;

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

elseif($users[$this->username]!==$this->password) $this->errorCode=self::ERROR_PASSWORD_INVALID; else $this->errorCode=self::ERROR_NONE; return !$this->errorCode; } }

Ton b cng vic ca n nm trong function authenticate() v bn c th nhn thy mng cha 2 phn t demo/demo v admin/admin chnh l 2 user chng ta c th ng nhp vo website hiu r hn v quy trnh ca n bn hy xem s sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Quy trnh bt u vi vic thit lp class trong form model LoginForm.php (protected/models/LoginForm.php ) , v khi form c submit, n s s dng hm LoginForm->validate() xc thc ci input t form nhp vo c nh ngha trong rules() public function rules() { return array( array('username, password', 'required'), array('rememberMe', 'boolean'), array('password', 'authenticate'), ); } Kt thc vic xc thc chnh l vic s dng custom method authenticate(): public function authenticate($attribute,$params) { $this->_identity=new UserIdentity($this->username,$this->password); if(!$this->_identity->authenticate()) $this->addError('password','Incorrect username or password.'); } Sau khi thc hin xong vic xc thc ca n n gi ti hm khi to nh danh trong protected/components/UserIdentity.php v gi ti hm authenticate() y chnh l lc user c phn quyn v xc thc user trong h thng,mc nh ang c 2 user l demo v admin n s tr v true.Sau khi thnh cng n s tr v SiteController::Login() method,

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

public function login() { if($this->_identity===null) { $this->_identity=new UserIdentity($this->username,$this->password); $this->_identity->authenticate(); } if($this->_identity->errorCode===UserIdentity::ERROR_NONE) { $duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days Yii::app()->user->login($this->_identity,$duration); return true; } else return false; } Sau khi hon thnh n tr v true hoc false v chuyn hng ti URL c nh danh sn.

IV.6. Thay i thc thi xc nhn


By gi chng ta i vo phn thay i sao cho n nhn ti khon mt khu ngi dng trong bng tbl_user. u tin hy vo protected/components/UserIdentity.php v thay i ton b ni dung ca n thnh nh sau: <?php

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

class UserIdentity extends CUserIdentity { private $_id; public function authenticate() { $user=User::model()>find('LOWER(username)=?', array(strtolower($this->username))); if($user===null) $this->errorCode=self::ERROR_USERNAME_INVALID; else if(!$user->validatePassword($this->password)) $this->errorCode=self::ERROR_PASSWORD_INVALID; else { $this->_id=$user->id; $this->username=$user->username; $this->setState('lastLogin', date("m/d/y g:i A", strtotime($user->last_login_time))); $user->saveAttributes(array('last_login_time'=>date("Y-m-d H:i:s", time()), )); $this->errorCode=self::ERROR_NONE; } return $this->errorCode==self::ERROR_NONE; } public function getId()

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

{ return $this->_id; } }

V sau chng ta i ti protected/models/User.php lm password validation , chng ta cng cn thm method cho User model : public function validatePassword($password) { return $this->hashPassword($password)===$this->password; }

IV.7 k tha phn t User


Vi vic thit lp trong UserIdentity : $this->setState('lastLogin', date("m/d/y g:i A", time($user->last_login_time))); $user->saveAttributes(array( 'last_login_time'=>date("Y-m-d H:i:s", time()),)); Sau ny ta c th dng : Yii::app()->user->lastLogin;

IV.8 Trnh by last login trong home page


Vo protected/views/site/index.php thm vo on sau:

<h1>Welcome to <i> <?php echo CHtml::encode(Yii::app()->name); ?>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

</i></h1> <?php if(!Yii::app()->user->isGuest):?> <p> You last logged in on <?php echo Yii::app()->user->lastLogin; ?>. </p> <?php endif;?> Vo http://localhost/devyii/index.php?r=site/login ng nhp vi ti khon mi to admin/admin, on trc ai cha to th khi phi hc tip, i ng lun i. y l kt qu:

CHNG 5 : iu khin truy cp ngi dng


Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

(UAC User Access Control)


V.1 Cu hnh qun l truy cp
Vo protected/config/main.php v thm on sau vo mng component: 'components'=>array( 'authManager'=>array( 'class'=>'CDbAuthManager', 'connectionID'=>'db', ),

V.2 To bng csdl RBAC


Vo phpmyadmin v to ra cc bng sau vi cc query : To bng auth_item create table tbl_auth_item(name varchar(255) not null,type int(11) not null,description text,bizrule text,data text,primary key(`name`))Engine=InnoDB; To bng auth_item_child create table tbl_auth_item_child(parent varchar(255) not null, child varchar(255) not null,PRIMARY KEY (`parent`,`child`))ENGINE=InnoDB; To kha ngoi tham chiu vi field name alter table tbl_auth_item_child add constraint fk_auth_item_child_parent foreign key(parent) references tbl_auth_item(name) on update cascade on delete cascade

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

alter table tbl_auth_item_child add constraint fk_auth_item_child_child foreign key(child) references tbl_auth_item(name) on update cascade on delete cascade To bng auth assignment create table tbl_auth_assignment(itemname varchar(255) not null,userid int(11) not null,bizrule text,data text,primary key(itemname,userid)) engine=innodb; To kha ngoi lin kt bng vi field itemname alter table tbl_auth_assignment add foreign key(itemname) references tbl_auth_item(name) on update cascade on delete cascade; To kha ngoi lin kt vi userid alter table tbl_auth_assignment add constraint fk_auth_assignment_userid foreign key(userid) references tbl_user(id) on update cascade on delete cascade;

Tip theo vo protected/config/main.php v sa li ni dung trong component array: 'components'=>array( 'authManager'=>array( 'class'=>'CDbAuthManager', 'connectionID'=>'db', 'itemTable' =>'tbl_auth_item', 'itemChildTable' =>'tbl_auth_item_child', 'assignmentTable' =>'tbl_auth_assignment', ),

V.3 To biu nh danh RBAC

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Sau khi to cc bng csdl ri chng ta cn thm cc vai tr (roles) v phn quyn (permission).Chng ta s s dng API c cung cp bi authmanager component. By gi chng ta hy nhn xem qua nh ngha cc bng vi s sau:

y ta c th nhn thy cp cao nht chnh l bn thn chng ta (admin) vi vic to user, cp nht user, xa user, to project, cp nht project v xa project, n c phn quyn nh hng t c hai member (thnh vin) v reader(Ngi c) .Thnh vin ch c php cp nht sa xa d liu ca bn thn v cc quyn li ca ngi c l xem thnh vin, c project, c issue. Ngi c (anonymous) l ngi khch vng lai truy cp vo web h c php c thng tin user, c thng tin c a project v issue

V.4 Thc thi project AR method mi


Trc tin vo phpmyadmin thm ct mi cho tbl_project_user_assignment

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

alter table tbl_project_user_assignment add column role varchar(255) not null Vo protected/models/Project.php v thm vo hm sau: public function assignUser($userId, $role) { $command = Yii::app()->db->createCommand(); $command->insert('tbl_project_user_assignment', array( 'role'=>$role, 'user_id'=>$userId, 'project_id'=>$this->id, )); } Thm hm xa User: public function removeUser($userId) { $command = Yii::app()->db->createCommand(); $command->delete( 'tbl_project_user_assignment', 'user_id=:userId AND project_id=:projectId', array(':userId'=>$userId,':projectId'=>$this->id) ); }

V.5 Thm User ti Project

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

1. Thm hm tnh (static) getUserRoleOptions() t Project AR tr v danh sch hp l vi role option s dng getRoles() method trong manager. Chng ta s cho user la chn dropdown 2. Thm hm mi gi l isUserInProject($user) t Project AR quyt nh user c lin quan ti project Chng ta s dng rules validation thm user ti project 3. Thm form mi tn l ProjectUserForm k tha t CformModel to input form model. Thm vo form ny 3 phn t l $role,$project, $user. 4. Thm file mi trong protected/views/project gi l adduser.php hin th form mi to t user ti project. 5. Thm controller action method mi tn actionAdduser() t ProjectController.php v iu chnh c accessRules() phng thc truy cp nh danh t user. By gi chng ta bt tay vo cng vic

V.5.1 Chnh li Project model class


T Project Model chng ta to thm 2 hm mi: /** Returns an array of available roles in which a user can be placed *when being added to a project */ public static function getUserRoleOptions() { return CHtml::listData(Yii::app()->authManager->getRoles(), 'name', 'name'); } /* * Determines whether or not a user is already part of a project

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

*/ public function isUserInProject($user) { $sql = "SELECT user_id FROM tbl_project_user_assignment WHERE project_id=:projectId AND user_id=:userId"; $command = Yii::app()->db->createCommand($sql); $command->bindValue(":projectId", $this->id, PDO::PARAM_INT); $command->bindValue(":userId", $user->id, PDO::PARAM_INT); return $command->execute()==1; }

V.5.2 Thm model Form class


Vo protected/modes to mi file tn ProjectUserForm.php vi ni dung sau: <?php class ProjectUserForm extends CFormModel { public $username; public $role; public $project; private $_user;

public function rules() { return array(


Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

array('username, role', 'required'), array('username', 'exist', 'className'=>'User'), array('username', 'verify'), ); } public function verify($attribute,$params) { if(!$this->hasErrors()) { $user = User::model()->findByAttributes (array('username'=>$this->username)); if($this->project->isUserInProject($user)) { $this->addError('username','This user has already been added to the project.'); else { $this->_user = $user; } } }

public function assign() { if($this->_user instanceof User)

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

{ $this->project->assignUser($this->_user->id, $this->role); $auth = Yii::app()->authManager; $bizRule='return isset($params["project"]) && $params["project"]>allowCurrentUser("'.$this->role.'");'; $auth->assign($this->role,$this->_user->id, $bizRule); return true; } else { $this->addError('username','Error when attempting to assign this user to the project.'); return false; } }

public function createUsernameList() { $sql = "SELECT username FROM tbl_user"; $command = Yii::app()->db->createCommand($sql); $rows = $command->queryAll(); $usernames = array(); foreach($rows as $row) { $usernames[]=$row['username'];

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

} return $usernames; } }

V.5.3 Thm action ti ProjectController


public function actionAdduser($id) { $project = $this->loadModel($id); if(!Yii::app()->user->checkAccess('createUser', array('project'=>$project))) { throw new CHttpException(403,'You are not authorized to perform this action.'); } $form=new ProjectUserForm; if(isset($_POST['ProjectUserForm'])) { $form->attributes=$_POST['ProjectUserForm']; $form->project = $project; if($form->validate()) { if($form->assign()) {

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Yii::app()->user->setFlash('success',$form->username . " has been added to the project." ); $form->unsetAttributes(); $form->clearErrors(); } } } $form->project = $project; $this->render('adduser',array('model'=>$form)); }

Chnh li accessRules() function: public function accessRules() { return array( array('allow', // allow all users to perform 'index' and 'view' actions 'controllers'=>array('issue','project','user'), 'actions'=>array('index','view','addussser'), 'users'=>array('@'), ), Tip theo vo protected/views/project to view file mi tn adduser.php <?php $this->pageTitle=Yii::app()->name . ' - Add User To Project'; $this->breadcrumbs=array(

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

$model->project->name=>array('view','id'=>$model->project->id), 'Add User', ); $this->menu=array( array('label'=>'Back To Project', 'url'=>array('view','id'=>$model>project->id)), ); ?> <h1>Add User To <?php echo $model->project->name; ?></h1> <?php if(Yii::app()->user->hasFlash('success')):?> <div class="successMessage"> <?php echo Yii::app()->user->getFlash('success'); ?> </div> <?phpendif; ?> <div class="form"> <?php $form=$this->beginWidget('CActiveForm'); ?> <p class="note">Fields with <span class="required">*</span> are required.</p> <div class="row"> <?php echo $form->labelEx($model,'username'); ?> <?php $this->widget('zii.widgets.jui.CJuiAutoComplete', array( 'name'=>'username', 'source'=>$model->createUsernameList(),

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'model'=>$model, 'attribute'=>'username', 'options'=>array( 'minLength'=>'2', ), 'htmlOptions'=>array( 'style'=>'height:20px;' ), )); ?> <?php echo $form->error($model,'username'); ?> </div> <div class="row"> <?php echo $form->labelEx($model,'role'); ?> <?php echo $form->dropDownList($model,'role', Project::getUserRoleOptions()); ?> <?php echo $form->error($model,'role'); ?> </div> <div class="row buttons"> <?php echo CHtml::submitButton('Add User'); ?> </div> <?php $this->endWidget(); ?> </div>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Tip theo vo protected/views/project/view.php thm on sau vo menu: $this->menu=array( array('label'=>'Add User To Project', 'url'=>array('project/adduser', 'id'=>$model->id)), ); Tip theo bn vo phpmyadmin thm mi 1 bn ghi trong tbl_auth_item vi name: member, type: 1, data: member Sau g vo trnh duyt : http://localhost/devyii/index.php? r=project/adduser&id=2

CHNG 6 THM USER COMMENT K Hoch:


1. Thit k v to bng CSDL h tr comment

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

2. To Yii AR class lin quan vi commnt ngoi bng 3. Thm form ti issue cho php user submit comment 4. Hin th tt c danh sch comment lin quan ti issue trong trang chi tit 5. Tin hnh tiu chun ca Yii widget hin th danh sch ca comment gny trong trang danh sch project.

VI.1 To model
Trc tin ta s cn phi to bng comment trong csdl , vo phpmyadmin v thc hin cc query sau: To bng tbl_comment create table tbl_comment( id int(11) not null primary key auto_increment, content text not null, issue_id int(11) NOT NULL, create_time datetime DEFAULT NULL, create_user_id int(11) DEFAULT NULL, update_time datetime DEFAULT NULL, update_user_id int(11) DEFAULT NULL )ENGINE=InnoDB

To kha ngoi vi tbl_issue alter table tbl_comment add constraint fk_comment_issue foreign key(issue_id) references tbl_issue(id) on delete cascade on update restrict To kha ngoi vi tbl_user create_user

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

alter table tbl_comment add constraint fk_comment_owner foreign key(create_user_id)references tbl_user(id) on update restrict on delete restrict To kha ngoi vi tbl_user update_user alter table tbl_comment add constraint fk_comment_update_user foreign key(update_user_id) references tbl_user(id) on update restrict on delete restrict Tip theo vo Gii http://localhost/devyii/index.php?r=gii/default/index Click vo menu : Model Generator v to Comment

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Sau nhn Preview -> Generated. kim tra vo protected/models/Comment.php chng ta c th nhn thy mi quan h c khi to trong relation: /** * @return array relational rules. */ public function relations() { // NOTE: you may need to adjust the relation name and the related // class name for the relations automatically generated below. return array( 'updateUser' => array(self::BELONGS_TO, 'User', 'update_user_ id'), 'issue' => array(self::BELONGS_TO, 'Issue', 'issue_id'), 'createUser' => array(self::BELONGS_TO, 'User', 'create_user_ id'), ); } Chng ta c th nhn thy quan h c bit ca comment thuc v issue. Nhng chng ta cng cn nh ngha quan h one-to-many (mt nhiu) gia mt issue v nhng comment, mt issue c th c nhiu comment,hy thay i Issue class model: public function relations() { return array( 'requester' => array(self::BELONGS_TO, 'User', 'requester_id'), 'owner' => array(self::BELONGS_TO, 'User', 'owner_id'), 'project' => array(self::BELONGS_TO, 'Project', 'project_id'), 'comments' => array(self::HAS_MANY, 'Comment', 'issue_id'), 'commentCount' => array(self::STAT, 'Comment', 'issue_id'), );

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Chng ta cng cn thay i k tha u tn class Comment <?php /** * This is the model class for table "tbl_comment". */ class Comment extends DevYiiActiveRecord {

VI.2 To comment CRUD


By gi chng ta c AR model , tip theo vo Gii to CRUD generator vi tn Comment. -> Preview -> Generated Bn c th vo http://localhost/devyii/index.php?r=comment/create xem cc field d liu c generated sn, v vo protected/controllers/CommentController.php xem qua cu trc ca n.

VI.3 Thm mt comment


Theo hng dn sn,chng ta c cc khi to ra comment, chng ta cn thm method trong Issue AR class (protected/model/Issue.php) : public function addComment($comment) { $comment->issue_id=$this->id; return $comment->save(); }

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Phng thc ny s tr v gi tr ca issue->id trc khi mt comment mi c lu vo csdl. Tip theo chng ta cn vo protected/controller/IssueController.php::actionView() method chng ta s cn thm comment AR chuyn sang view:

public function actionView($id) { $issue=$this->loadModel($id); $comment=$this->createComment($issue); $this->render('view',array( 'model'=>$issue, 'comment'=>$comment, )); }

VI.4 Hin th Form


Ta thy comment l mt thnh phn nm gn nh tt c mi ni trong ng dng ca bn v vy nn mt comment khng nn ch nm mt file view ring bit, bn nn to mt file view chung c th ti s dng n nh partial views. S dng renderPartial() s ch render ra ni dung cha ng trong views file. thc hin ta vo trong protected/views/issue/ to file mi c tn : _comments.php vi ni dung sau y: <?php foreach($comments as $comment): ?> <div class="comment"> <div class="author"> <?php echo CHtml::encode($comment->author->username); ?>: </div>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<div class="time"> on <?php echo date('F j, Y \a\t h:i a',strtotime($comment->create_ time)); ?> </div> <div class="content"> <?php echo nl2br(CHtml::encode($comment->content)); ?> </div> <hr> </div><!-- comment --> <?php endforeach; ?>

File ny chp nhn mng array comment c khi to trong input form v hin th chng. Chng ta cn iu chnh views file cho issue detail khi s dng file mi. Chng ta vo protected/views/issue/view.php v thm on sau vo di cng ca file: <div id="comments"> <?php if($model->commentCount>=1): ?> <h3> <?php echo $model->commentCount>1 ? $model->commentCount . ' comments' : 'One comment'; ?> </h3> <?php $this->renderPartial('_comments',array( 'comments'=>$model->comments, )); ?> <?php endif; ?>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<h3>Leave a Comment</h3> <?php if(Yii::app()->user->hasFlash('commentSubmitted')): ?> <div class="flash-success"> <?php echo Yii::app()->user->getFlash('commentSubmitted'); ?> </div> <?php else: ?> <?php $this->renderPartial('/comment/_form',array( 'model'=>$comment, )); ?> <?php endif; ?> </div>

Ln thay i cui cng chng ta lm vi comment input form . Form c to s cha nhng field input c nh ngha trong table tbl_comment.Chng ta s lm mt form n gin bng vic vo Protected/views/comment/_form.php v iu chnh n nh sau: <div class="form"> <?php $form=$this->beginWidget('CActiveForm', array( 'id'=>'comment-form', 'enableAjaxValidation'=>false, )); ?> <p class="note">Fields with <span class="required">*</span> are required.</p> <?php echo $form->errorSummary($model); ?> <div class="row">

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<?php echo $form->labelEx($model,'content'); ?> <?php echo $form->textArea($model,'content',array('rows'=>6, 'cols'=>50)); ?> <?php echo $form->error($model,'content'); ?> </div> <div class="row buttons"> <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?> </div> <?php $this->endWidget(); ?> </div> Vo trnh duyt http://localhost/devyii/index.php?r=project Chn mt id bt k ri nhn vo menu bn phi chn Create Issue nhn vo menu bn phi chn Manage Issue sau click vo chi tit mt trang s nhn thy kt qu sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

VI.5 To widget comment gn y VI.5.1 Names scopes


bt u to widget , chng ta s chnh li Comment AR (model) tr v comment gn y, lm iu ny chng ta s tin hnh chnh li tiu chun Yii model class khc c tn l Scopes. Scopes cho php chng ta s dng tn t kha ring,n cung cp cch nh ngha cc iu kin cu lnh SQL trch lc danh sch trong AR model. Name scopes c nh ngha bi CactiveRecord::scopes() , v d nu bn mun nh ngha name scope gi tr v 5 comment gn y chng ta c Comment::scopes(): class Comment extends DevYiiActiveRecord { ... public function scopes() { return array( 'recent'=>array( 'order'=>'create_time DESC', 'limit'=>5, ), );

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

} ... } Sau chng ta d dng lc danh sch trong AR model: $comments=Comment::model()->recent()->findAll(); Hoc n gin hn na chng ta ch thc hin nh sau: public function recent($limit=5) { $this->getDbCriteria()->mergeWith( array( 'order'=>'t.create_time DESC', 'limit'=>$limit, ) ); return $this; }

VI.5.2

Nhiu hn v quan h AR query trong Yii

Vi nhng phng thc trn ta c th s dng d dng vi namescope kt

ni vi AR model, cho v d chng ta c th xem query sau: $comments = Comment::model()->with(array('issue'=>array('condition'=>' project_id=1')))->recent(10)->findAll(); By gi chng ta quay li bi hc ca chng ta, vo protected/controller/IssueController.php v chnh li trong function loadModel() li nh sau: public function loadModel($id, $withComments=false) { if($withComments)

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

$model = Issue::model()->with(array('comments'=>array('with'=>'a uthor')))->findByPk($id); else $model=Issue::model()->findByPk($id); if($model===null) throw new CHttpException(404,'The requested page does not exist.'); return $model; } Trong actionView() thm vo true trong loadModel(): public function actionView($id) { $issue=$this->loadModel($id, true); .... }

VI.5.3 To widget
Vo protected/models/Comment.php thm hm sau: public function findRecentComments($limit) { return self::model()->with('issue')>findAll(array('order'=>'t.create_time DESC','limit'=>$limit,)); } Vo protected/components/ to mi file RecentComments.php vi ni dung sau: <?php class RecentComments extends CWidget { private $_comments; public $displayLimit = 5; public $projectId = null; public function init() { $this->_comments = Comment::model() ->findRecentComments($this->displayLimit, $this->projectId); } public function getRecentComments() { return $this->_comments; }

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

public function run() { // this method is called by CController::endWidget() $this->render('recentComments'); } } ?> Tip theo vo protected/components/ to views/recentComments.php : (to mi file): <ul> <?php foreach($this->getRecentComments() as $comment): ?> <div class="author"> <?php echo $comment->createUser->username; ?> added a comment. </div> <div class="issue"> <?php echo CHtml::link(CHtml::encode($comment->issue->name), array('issue/view', 'id'=>$comment->issue->id)); ?> </div> <?php endforeach; ?> </ul> Cui cng vo protected/views/project/index.php thm on sau vo cui file: <?php $this->widget('RecentComments'); ?> Kt qu sau: http://localhost/devyii/index.php?r=project

Vy l ngon lnh cnh o, tip tc ta s thm u v cui widget vi Cportlet: thay th on trn trong protected/views/project/index.php bng on sau: <?php $this->beginWidget('zii.widgets.CPortlet', array('title'=>'RecentComments',)); $this->widget('RecentComments'); $this->endWidget();
Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

?>

Kt qu:

VI.5.4 Thm widget vo mt trang khc


Tip theo chng ta s thm comment gn y vo protected/views/project/view.php vo cui trang: <?php $this->beginWidget('zii.widgets.CPortlet', array( 'title'=>'Recent Comments On This Project', )); $this->widget('RecentComments', array('projectId'=>$model->id)); $this->endWidget(); ?> V y l kt qu, http://localhost/devyii/index.php?r=project/view&id=1 Vi cch ny ta c th d dng nhng mt widget ti bt k v tr no trong ng dng mt cch hiu qu.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

CHNG 7 THM RSS WEB FEED K HOCH


1. Ti ci t ZendFramework vo ng dng Yii 2. To mi action trong controller class x l nh dng Feed 3. Chnh li URL sao cho d s dng 4. Thm vic to mi feed ti c danh sch project ln trang chi tit project

VII.1 Ci t Zend Framework


Vo trang ch ca Zend v chn bn ZendFramework 1.12 minimal (Lu s dng Zend 1 , k s dng Zend 2 nu k hu qu rng chu) Cu trc th mc ca n nh sau:
INSTALL.txt LICENSE.txt README.txt bin/ library/

Vo protected to mi th mc vendors. Bn vo th mc library copy folder Zend vo protected/vendors, v th mc ca n s l protected/vendors/Zend Lu , ngoi vic s dng Zend Feed t v d ny bn cng c th s dng Zend mail gi mail ti khch hng trong cc ng dng, bi vy nn hy ch .

VII.2 S dng Zend_Feed


Zend_feed l thnh phn nh trong Zend component c chc nng to web feed d dng v nhanh chng, chng ta s s dng Zend_feed trong Yii mt cch d dng , Vo protected/controllers/CommentController.php to mt action tn actionFeed().

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

public function actionFeed() { if(isset($_GET['pid'])) { $comments = Comment::model()->with(array( 'issue'=>array( 'condition'=>'project_id=:projectId', 'params'=>array(':projectId'=>intval($_GET['pid'])), )))->recent(20)->findAll(); } else $comments = Comment::model()->recent(20)->findAll(); $entries=array(); foreach($comments as $comment) { $entries[]=array( 'title'=>$comment->issue->name, 'link'=>CHtml::encode($this->createAbsoluteUrl('issue/ view',array('id'=>$comment->issue->id))), 'description'=> $comment-> createUser->username . 'says:<br>' . $comment->content, 'lastUpdate'=>strtotime($comment->create_time), 'author'=>CHtml::encode($comment->createUser->username), ); }

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

//now use the Zend Feed class to generate the Feed // generate and render RSS feed $feed=Zend_Feed::importArray(array( 'title' => 'Development Yii Comments Feed', 'link' => $this->createAbsoluteUrl(''), 'charset' => 'UTF-8', 'entries' => $entries, ), 'rss'); $feed->send(); } Tip theo ta cn lm mt s thay i trong controller CommentController class trong zend c th lm vic , u trang class bn thm on sau: Yii::import('application.vendors.*'); require_once('Zend/Feed.php'); require_once('Zend/Feed/Rss.php'); Tip theo CommentController::accessRules() method on feed public function accessRules() { return array( array('allow', // allow all users to perform 'index' and 'view' actions 'actions'=>array('index','view','feed'), 'users'=>array('*'), ), cho php user xem

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

y l kt qu: http://localhost/devyii/index.php?r=comment/feed

VII.3 To URL Thn thin vi User


Mc nh ca Yii bn thng nhn thy tham bin chnh l r v tip theo l controller_id v action_id, v d vi url ca feed http://localhost/devyii/index.php?r=comment/feed n thc s khng p v khng tt cho qu trnh SEO pht trin, ta cn c mt url p hn na nh kiu: http://localhost/devyii/commentfeed hoc http://localhost/devyii/commentfeed.xml lm c iu ny chng ta cn phi nh s tr gip ca Yiis URL Management chnh li nh dng ca URL.

VII.3.1 S dng URL Manager


xy dng cu hnh li URL bn cn vo protected/config/main.php file nh ngha url manager: 'urlManager'=>array(
Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'urlFormat'=>'path', ), Mc nh th n nm trong array component v b dng comment /* -*/ b kch hot n. Cng vic ca bn l b 2 dng comment kch hot urlManager. 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( '<controller:\w+>/<id:\d+>'=>'<controller>/view', '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller >/<action>', '<controller:\w+>/<action:\w+>'=>'<controller>/<actio n>', ), ), By gi th bn c th vo c url : http://localhost/devyii/index.php/comment/feed mt cch d dng, v t nay khi vo cc cng c bn vui lng b on r= i khi vo Gii v d: http://localhost/devyii/index.php/gii/default/index Hoc vo project : http://localhost/devyii/index.php/project . b nt c index.php bn cn phi nh ngha li Url v thit lp controller/action tr n url nh danh , iu ny c vit trong Yii development Cookbook ebook ti dch ri, bn vui lng vo xem li nh

VII.3.2 Cu hnh li Routing rules (Quy tc routes)


Router l g : L mt gi url tr v m trnh duyt yu cu h thng x l, n cha c phn s v phn ch, v d nh cc bin $_GET, $_POST, hoc n gin l cc tiu ni dung ca mt bi no m trnh duyt yu cu h thng tr li vi gi , thc hin cng vic ny Yii s dng Url manager

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

nh ngha cc khai bo truy nhp router quyt nh xem controller no v action no c thc hin . Vi nhng quy tc URL, thit lp CurlManager file s tr v cc thuc tnh quy tc theo mng array vi nh dng pattern=>route. V y l v d qua v mt quy tc: Thm on sau vo urlManager: //khai bo ng dn issue tr v controller/action (issue/index) //khai bo ng dn chi tit issue theo dng issues/id (dng s) tr v (issue/view). 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( 'issuehello'=>'issue/index', 'issue/<id:\d+>/*'=>'issue/view', ), ) Vi khai bo issuehello bn c th vo trnh duyt xem kt qu: http://localhost/devyii/index.php/issuehello n nhn ng khng ^_^. ng thi vi cch ny bn c th vo c http://localhost/devyii/index.php/issue/4 m khng cn phi g http://localhost/devyii/index.php/issue/view/4 mt ng dn rt xu.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Tip theo nu chng ta mun c ng dn nh sau: http://localhost/devyii/index.php/commentFeed.xml Tht n gin ta vo url Manager khai bo nh sau: 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( 'commentfeed'=>array('comment/feed', 'urlSuffix'=>'.xml', 'caseSensitive'=>false),

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

), ), Trong commentfeed l url alias v urlsuffix l hu t sau url alias , caseSensitive chnh l trng hp u tin chn router y l mc nh (k u tin) v bn vo trnh duyt thng thc thnh qu. http://localhost/devyii/index.php/commentfeed.xml

VII.3.3 Loi b kch bn index.php t URL

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

By gi chng ta s xa thnh phn index.php trc url, iu ny cn lm theo 2 bc: 1. Chnh li webserver cu hnh router tt c cc request s khng x l file tn ti hoc ng dn lin quan ti index.php 2. Thit lp url manager component v chn thuc tnh: showScriptName l false. Khi chng ta s dng Apache HTTP server chng ta c th thc hin giai on u tin vi file .htaccess trong th mc gc ca ng dng v chng ta to file .htaccess nh sau: # Turning on the rewrite engine is necessary for the following rules #and features. # FollowSymLinks must be enabled for this to work. <IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine On </IfModule> # Unless an explicit file or directory exists, redirect all request to #sssYii entry script <IfModule mod_rewrite.c> RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php </IfModule> By gi chng ta vo http://localhost/devyii/commentfeed.xml ^_^!

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

http://localhost/devyii/project ^_^ c p ln hn khng ?

Bc th 2 n gin ri chnh li urlManager vi dng sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( 'commentfeed'=>array('comment/feed', 'urlSuffix'=>'.xml', 'caseSensitive'=>false), ), //tt hn index.php 'showScriptName'=>false, ), qu, th l li c framework na xi ri hehe i vi nhng url iu khin vi ch s ID nh Project ID, chng ta c th lm theo cch sau: 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( '<pid:\d+>/commentfeed'=>array('comment/feed', 'urlSuffix'=>'.xml', 'caseSensitive'=>false), 'commentfeed'=>array('comment/feed', 'urlSuffix'=>'.xml', 'caseSensitive'=>false), ), 'showScriptName'=>false, ), Vo trnh duyt : http://localhost/devyii/2/commentfeed.xml xem kt qu:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

VII.3.4 Thm Feed Links


By gi chng ta s to url feed cu trc thn thin hn cho ngi dng,chng ta cn thm subscribe feed,vo projectController::actionIndex() Chnh li nh sau: public function actionIndex() { $dataProvider=new CActiveDataProvider('Project'); Yii::app()->clientScript->registerLinkTag( 'alternate', 'application/rss+xml', $this->createUrl('comment/feed')); $this->render('index',array(

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'dataProvider'=>$dataProvider, )); } Bn s thy on sau u th head: <link rel="alternate" type="application/rss+xml" href="/commentfeed. xml" />

VII.3.5 Gi mail ti user vi Zend_Mail()


Chng ta s lm v d thc hin vic gi email ti user bng cch s dng Zend_mail ti CommentController.php ::actionMail() Bn vo protected/controller/CommentController thm on sau vo u class: require_once('Zend/Mail.php'); require_once('Zend/Mail/Transport/Smtp.php'); require_once('Zend/Mail/Protocol/Smtp/Auth/Login.php'); Ti function accessRules() { array('allow', // allow all users to perform 'index' and 'view' actions 'actions'=>array('index','view','feed','mail'), 'users'=>array('*'), ),

} Xy dng hm mail: public function actionMail()

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

{ $content='i love you'; $addto='mylove@gmail.com'; $subject='Dear love!'; $emailfrom='longt8x@gmail.com'; $tr = new Zend_Mail_Transport_Smtp ('smtp.gmail.com', array('auth' => 'login', 'username' => 'longt8x@gmail.com', 'password' => 'password user', 'ssl' => 'ssl', 'port' => 465 )); Zend_Mail::setDefaultTransport($tr); $mail = new Zend_Mail('UTF-8'); $mail->setBodyHtml(($content)); $mail->addTo($addto); $mail->setSubject($subject); $mail->setFrom ($emailfrom); $mail->send (); } Vo trnh duyt xem thnh qu : http://localhost/devyii/comment/mail Do khng c host nn nu bn g vo s bo li khng th m gi trn v user name v password khng chnh xc, v bn phi c host thc trn mng mi c th gi socket. Tuy nhin n giai on ny l bn hon ton c th gi mail online c khi bn chy trn website thc.

VII.3.6 To File PDF Vi Zend_PDF

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Bn vo th mc gc devyii to mt folder c tn pdf ngang hng vi protected cha file to pdf Bn vo protected/controller/CommentController.php thm on sau vo u class: require_once('Zend/Pdf.php'); require_once('Zend/Pdf/Page.php'); require_once('Zend/Pdf/Font.php'); Sa li function accessRules() thm vo actionPdf: public function accessRules() { return array( array('allow', // allow all users to perform 'index' and 'view' actions 'actions'=>array('index','view','feed','mail','pdf'), 'users'=>array('*'), ),

To CommentController:: actionPdf(): public function actionPdf() { $pdf = new Zend_Pdf(); $page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);

// define font resource $font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_COURIER);

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

// thiet lap font , kich co font // viet noi dung pdf $page->setFont($font, 24) ->drawText('I miss you,', 72, 720) ->drawText('Because I love You', 72, 620);

$pdf->pages[] = $page;

// luu file vao folder pdf $pdf->save('pdf/miss.pdf'); }

Vo trnh duyt g : http://localhost/devyii/comment/pdf Vo folder pdf mi to s thy mt file tn miss.pdf v m ra s c hnh sau:

Vi cch ny bn c th to ra mt file pdf v to ng link ti file user c th download c mt s trang theo kiu ha n thanh ton.

CHNG 8 : LM NG DNG P HN

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

K HOCH
To theme mi cho ng dng bng vic to layout mi,CSS v folder v cc ti sn khc cn c cung cp trong ng dng vi thit k frontend mi. S dng tiu chun ngn ng vng min ca Yii chuyn dch ngn ng mi trong ng dng. By gi chng ta s i vo thc hin

VIII.1 Thit k layout


Mt layout trong Yii l mt file views c bit n s dng cc views file khc, c tnh layout cha ng giao din ngi dng v cc thnh phn, m lnh ca nhiu views file,khi s dng layout chuyn ti mt views file, Yii nhng file views vo layout.

VIII.1.2 To mt layout
C hai cch chnh c th to ra layout v khai bo layout mi, mt l gi thuc tnh $layout ca CwebApplication, mc nh t protected/views/layouts/main.php .Cng nh vic la chn vi ton ng dng n c th ti t cu hnh main trong protected/config/main.php V d chng ta cn to layout mi trong protected/views/layouts/newslayout.php bn mun s dng n cho ton ng dng bn cn vo protected/config/main.php khai bo nh sau vo u mng array:

return array( ... 'layout'=>'newlayout',

Layout ny c k tha $layout Path thuc tnh ca CwebApplication vi mc nh protected/views/layouts.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Mt ni khc cng thit lp thuc tnh layout l trong controller class. y l cch n to layout c bit khi ng dng c khi to,s dng Yii tool to t ng ra c protected/components/Controller.php , khi bn m file ny ra bn s thy ct khai bo layout c thit lp layout c tn column1. Cc thit lp ny c iu khin bi thit lp t Cwebapplication class.

VIII.1.3 S dng layout


Khi s dng layout file ta cn gi Ccontroller::render() method, khi bn lm vic gi render() method gi mt file views, Yii s nhng ni dung ca file views vo layout ca bn cng nh controller class hoc mc ng dng.Bn t rnh th bt k layout no c render views file khi gi bi phng thc Ccontroller::renderPartial(). Chng ta vo protected/views/layout/newlayout.php m chng ta mi to v thm vo ni dung sau: <!DOCTYPE html> <html> <head> <title>Title of the document</title> </head> <body> <div id="header"> Some Header Content Here </div> <div id="content"> <?php echo $content; ?> </div> <div id="footer"> Some Footer Content Here
Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

</div> </body> </html>

By gi chng ta th t n vo site controller s dng layout mi, m protected/controller/SiteController.php v ti $layout vo class nh sau: class SiteController extends Controller { public $layout='newlayout'; By gi chng ta vo trnh duyt g : http://localhost/devyii/site/login

VIII.1.4 Gii thiu BluePrint CSS Framework


BluePrint css framework c thm vo ng dng khi bn khi to ng dng t dng lnh Yii tool,chng tr gip tiu chun CSS cho bn, cung cp

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

tiu chun nh ngha HTML gip cho phn nh ngha CSS gp t li, n ti vi nhiu screen print friendly layout, nhng n vo trang bn s cn s dng on lnh sau: <!-- blueprint CSS framework -->
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()>request->baseUrl; ?>/css/screen.css" media="screen, projection" /> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()>request->baseUrl; ?>/css/print.css" media="print" /> <!--[if lt IE 8]> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()>request->baseUrl; ?>/css/ie.css" media="screen, projection" /> <![endif]-->

VIII.1.5 Hiu v thit lp css BluePrint


Blueprint nm sn trong webroot/css v n c 3 file chnh l: Ie.css Print.css Screen.css Nhng thit lp c bn u cha nhng file ny ri,v chng ta s s dng css bng vic to thm mt file mi cho ng dng ca bn, Bn khng nn vit thm css vo 3 file ny.

VIII.1.6 Thit lp tiu trang


thit lp tiu trang bn ch cn s dng on code sau: <title><?php echo CHtml::encode($this->pageTitle); ?></title>

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Cn nh l views file s tr v khi to cho controllers class thuc tnh c thit lp trong views,$pageTitle l phn t nh ngha trong Ccontroller s cha tn action lm mc nh

VIII.1.7 nh ngha header


Mt la chn thng l ni dung header thng lp li trong nhiu trang,v th nn ta cn nh ngha header trong layout n ti s dng: <body> <div class="container" id="page"> <div id="header"> <div id="logo"><?php echo CHtml::encode(Yii::app()->name); ?> </div> </div><!-- header --> i tn project bn vo protected/config/main.php v thay th nh sau: 'name'=>'My Web Application', tr thnh 'name'=>'Development Yii Project', Kt qu: http://localhost/devyii/site/login

VIII.1.8 Hin th menu navigation


Thanh iu hng th ng xut hin lp li nhiu trang v th nn n thng nm trong layout bn c th nhn on code sau: <div id="mainmenu">

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<?php $this->widget('zii.widgets.CMenu',array( 'items'=>array( array('label'=>'Home', 'url'=>array('/site/index')), array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about')), array('label'=>'Contact', 'url'=>array('/site/contact')), array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest), array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest) ), )); ?> </div><!-- mainmenu --> Ti y chng ta s dng widget Cmenu c gi t Zii component.

VIII.1.9 To breadcrumbs navigation


Chng ta ti protected/views/layouts/main.php xem cu trc code v bn s nhn thy c 3 dng nh ngha breadcrumb bi Zii component vi Cbreadcrumbs:

<?php if(isset($this->breadcrumbs)):?> <?php $this->widget('zii.widgets.CBreadcrumbs', array( 'links'=>$this->breadcrumbs, )); ?><!-- breadcrumbs -->

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<?php endif?>

y l widget khc ca Zii thng c s dng hin th link iu hng ti trang, v d : project>>project 1>>Edit s dng widget ny bn cn phi cu hnh thuc tnh links , ci m bn mun hin th. Thuc tnh ny c tr v t mng array c nh ngha trong phn breadcrumbs, chng ta s s dng v d vi breadcrumb project>project 1>>Edit: array( 'Projects'=>array('project/index'), 'Project 1'=>array('project/view','id'=>1), 'Edit', ) V mc nh Yii s t ng to breadcrumbs da vo tn project v action project. Nu bn mun custom breadcrumbs da theo ca bn thn hy vo Protected/views/project/update.php v xem cu trc file bn s tm thy dng nh ngha breadcrumbs sau: $this->breadcrumbs=array( 'Projects'=>array('index'), $model->name=>array('view','id'=>$model->id), 'Update', ); Ti y bn khai bo cu trc breadcrumbs nh sau: Project>>Project Name >>Update Bn vo : http://localhost/devyii/project/update/id/2

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

VIII.1.10 nh ngha footer


Bn c th vo protected/views/layouts/main.php v xem khai bo cui on : <div id="footer"> Copyright &copy; <?php echo date('Y'); ?> by My Company.<br/> All Rights Reserved.<br/> <?php echo Yii::powered(); ?> </div><!-- footer -->

VIII.1.11 Phn chia layouts


Thng th khi vo website ng dng s nhn layout mc nh t protected/views/layouts/main.php , nhng ch l mt phn, khi ng dng c khi to, tt c controller c to s k tha t protected/components/Controller.php Nu chng ta m file ny ra chng ta s thy phn nh ngha layout c khai bo layout cho controller l : $layout='//layouts/column1' nhng n khng phi l layout chnh dng nh layout column1 l layout file mc nh cho tt c cc class con.Bn c th vo protected/views/layouts/ v s nhn thy 3 file layout sau: Column1.php

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Column2.php Main.php V t y ta c th thy cc controller ti layout l column1.php : <?php /* @var $this Controller */ ?> <?php $this->beginContent('//layouts/main'); ?> <div id="content"> <?php echo $content; ?> </div><!-- content --> <?php $this->endContent(); ?>

Ti file ny bn c th thy n ti layout main.php v ton b ni dung ca cc controller s nm trong phn content ca main.php Lu : Trong code ta c nhn thy on khai bo layout c thm tin t // , trong trng hp ny file layout trong views s tm ti thnh phn views chnh (protected/views/) c kch hot bi module hin ti, cch ny s khin h thng s dng ng dn views chnh trong ng dng hn vic s dng ng dn t modules. Chng ta s hc v modules trong chng ti y.

Chng ta hy cng xem v d cch ti views file vi SiteController::actionLogin(): $this->render(login);

Ti y h thng s thc hin: Ti tt c ni dung trong file protected/views/site/login.php v lm content chp nhn gi tr $content t layout file trong controller , l column1.pphp

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Sau column1.php s gi ti layout chnh l main.php, ni dung nm gia beginContent() v endContent() s chuyn gi tr v layout main.php vi bin $content. Layout file main.php s ti ln v tr v giao din ti ngi dng, nh vy ta c th nhn thy thnh phn controller nhn c file main.php v column1.php ch khng phi duy nht layout chnh nh bn ngh. Mt layout khc s t ng c ti khi to mi ng dng l layout column2.php , khi bn ng nhp admin xong bn vo trong qun tr project bn s thy ct menu navigation nm bn tay phi l cu hnh ca layout column2.php , bn vo protected/controller/ProjectController.php s thy dng khai bo sau: public $layout='//layouts/column2';

Ni dung ca file column2.php <?php /* @var $this Controller */ ?> <?php $this->beginContent('//layouts/main'); ?> <div class="span-19"> <div id="content"> <?php echo $content; ?> </div><!-- content --> </div> <div class="span-5 last"> <div id="sidebar"> <?php $this->beginWidget('zii.widgets.CPortlet', array( 'title'=>'Operations', ));

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

$this->widget('zii.widgets.CMenu', array( 'items'=>$this->menu, 'htmlOptions'=>array('class'=>'operations'), )); $this->endWidget(); ?> </div><!-- sidebar --> </div> <?php $this->endContent(); ?> Bn c th nhn thy ngoi vic ti layout chnh main.php ra n cn thm phn bn phi to ra mt widget cha menu qun tr vi danh sch items c lc t Zii component :: Cportlet Sau ny khi bn nh ngha tng thnh phn trong layout bn cng s lm tng t,, thm nhng thnh phn cn thit xung quanh content nh vic s dng cc widget ca Yii

VIII.1.12 Xy dng theme Yii


Theme c s dng custom cc thit k layout trong mt ng dng web,mt trong nhiu ng dng n trong m hnh kin trc MVC l trnh din cc thng tin bn ghi trong qun tr (backend). V mc nh tt c themes c nh ngha cn phi nm trong webroots/themes (folder themes ngang hng vi protected) . Tt nhin n c la chn trong cu hnh ng dng v n c iu chnh bi thuc tnh basePath v baseUrl trong themeManager component Tt c cc file views s phi nm trong th mc /views/, layout s phi nm trong views/layouts/ v file h thng phi nm trong views/system/. V d nu bn to theme gi l custom v thay th views update ca project bn cn to view file update.php v lu n trong themes/custom/views/project/update.php

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

VIII.1.13 To mt themes
Chng ta s to mt theme mi c tn l newtheme, trong /themes To tip folder tn newtheme, to hai ng dn con l css v views Trong views folder bn s to mi layouts folder Cu trc folder mi nh sau: --protected --themes Trong folder themes: --themes\newtheme --themes\newtheme\css --themes\newtheme\views --themes\newtheme\views\layouts By gi chng ta s tin hnh thay i, copy ton b file trong /css chuyn sang ng dn trong theme mi l /themes/newtheme/css/ Tip theo copy /protected/views/layouts/main.php ti ng dn theme mi: /themes/newtheme/views/layouts/main.php Vo protected/config/main.php thm on khai bo theme: 'name'=>'Development Yii Project', 'theme'=>'newtheme',

Bn vo /themes/newtheme/views/layouts/main.php v chnh li on khai bo ng dn css v js li nh sau:


<!-- blueprint CSS framework --> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request>baseUrl; ?>/themes/newtheme/css/screen.css" media="screen, projection" />

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request>baseUrl; ?>/themes/newtheme/css/print.css" media="print" /> <!--[if lt IE 8]> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request>baseUrl; ?>/ssthemes/newtheme/css/ie.css" media="screen, projection" /> <![endif]-->

<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request>baseUrl; ?>/themes/newtheme/css/main.css" /> <link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request>baseUrl; ?>/themes/newtheme/css/form.css" />

Bn vo file main.php trong themes/newtheme/css/main.css v chnh li thuc tnh background trong body l mu : body { margin: 0; padding: 0; color: #555; font: normal 10pt Arial,Helvetica,sans-serif; background: red; } Vo http://localhost/devyii/site/login xem kt qu

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

VIII.1.14 Chuyn website sang ngn ng khc


nh ngha Locale v language Locale (vng min) c thit lp t nh ngha user language , quc gia,v bt k giao din ngi dng hin th ni dung vn cnh ca vng min , ngi ta thng gi l Locale id v d : en_US l nhng vng min tiu chun cho ngi M ni ting Anh (United States) , vi_VN thng ch nh cho ngi vit. Trong Yii d liu vng min trnh din trong Clocale class, n cung cp vng min ring c thm vo h thng t ngi dng, nh cc k t, s, ngy thng,time, trnh din vng min ring ta s dng Clocale::getInstance($localeID) . Sau y l v d s dng vng min en_US trong thnh phn ng dng: Yii::app()->getLocale('en_us'); Yii c th lm vic vi hu ht vi vng min ngn ng khc nhau, xem ngn ng ca bn c h tr hay khng bn vo framework/i18n/data bn s nhn thy file vi_vn.php dnh cho vit nam. Tr li v d trc nu bn mun xem ngy thng bng ting Anh (United States) bn ch cn lm nh sau:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

$locale = Yii::app()->getLocale('en_us'); print_r($locale->monthNames); Kt qu l:

Vi Italia: $locale = Yii::app()->getLocale('it'); print_r($locale->monthNames);

Tt nhin ti a ra v d cho bn cc bn xem ch khng cn phi test tht v n qu n gin, nu bn mun test bn ch cn vo file views bt k v g dng lnh trn ri vo trnh duyt kim tra. Tuy nhin bi ti y th tt nhin l bn phi ng tay chn

VIII.1.15 Thc hin chuyn dch ngn ng


Trong on trc gii thiu i18n ta c th thy h thit k cung cp gn nh y , Yii cung cp c message translation (chuyn dch tin nhn) theo kiu ngn gn d dng, nh dng text theo kiu tin nhn, v cui cng l chuyn dch ngn ng t file message language . Mt message c khi to t Cmessagesource v n cung cp cc thuc tnh sau: CphpMessageSource: y l message source mc nh, li nhn cn chuyn dch c lu di dng key=>value trong mng php ,mi cp i km s ng thi km theo s chuyn dch ca n theo vng min cn chuyn Cgettext MessageSource: Li nhn chuyn dch c lu di dng GNU Gettext File CdbMessageSource: c lu trong bng database.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Mt message s c load vo thnh phn ng dng,Yii s nh ngha n trong thnh phn ng dng v tr v message m n cn c tr v.Bi mc nh chng ta s dng CphpMessageSource v thnh phn c bn s phi nm trong protected/messages. Chng ta s lm mt v d sau: chuyn dch ngn ng ca form field Login sang ting Anh v ting Vit. Chng ta s xem qua nhn (label) thng tin ca form nh sau: English Username Password Remember me next time Ting Vit Tn ng nhp Mt khu Nh ti ln ng nhp ti

Chng ta s s dng CphpMessageSource chuyn dch tin nhn trn. Cng vic u tin bn cn lm l to file PHP cha ng ni dung cn chuyn dch. Ti s lm LocaleID vi tn l vi , chng ta s gi danh mc mc nh ca n by gi. Chng ta s to file mi di th mc protected/messages/ theo cu trc /LocaleId/CategoryName.php Bn vo protected/messages/vi/default.php v thc hin on sau: <?php return array( 'Username' => 'Tn ng nhp', 'Password' => 'Mt khu', 'Remember me next time' => Nh ti ln ng nhp ti, );

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Ch bn m son tho l UTF-8 nu khng sau khi thc hin s m ha ton k t l. Tip theo chng ta cn thit lp ngn ng mc nh l Vit Nam, bn vo protected/config/main.php v thay i u on if(2+1==0) { $language='en'; }else $language='vi'; return array( 'layout'=>'newlayout', 'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', 'name'=>'Development Yii Project', 'language'=>$language,

By gi cng vic cui cng bn cn lm l gi hm Yii::t() (t() ->Translate) trong form field label Login, bn hy vo protected/models/LoginForm.php Tm hm attributeLabels() thay th li nh sau: /** * Declares attribute labels. */ public function attributeLabels() { return array( 'rememberMe'=>Yii::t('default','Remember me next time'), 'username'=>Yii::t('default', 'Username'),
Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'password'=>Yii::t('default', 'Password'), ); } V y l kt qu: http://localhost/devyii/site/login

Cu hi tip theo l lm th no khi bn click vo biu tng c English th file t ng chuyn sang ting anh v c vit nam th n s tr v ting vit nh hnh trn ng khng ? Bn ch cn to thm trong protected/messages/ mt folder en v mt file php l : default.php v thc hin y ht nh bc to file vi, khi cc bn to hai l c chuyn dch bn s to thm mt trng xc nh u l en v u l vi sau bn thay th trong protected/config/main.php c on 2+1==0 , nh vy l ton b ni dung s chuyn dch.

CHNG 9 S DNG YII MODULE


Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

K HOCH
To module mi t admin To kh nng admin c th thm tin nhn m rng t h thng cho ng dng ngi dng, hin th ti trang danh sch project Th theme mi ti module To bng csdl mi lu cc tin nhn ca h thng To tt c Crud cho tin nhn h thng Hn ch truy cp tt c cc hm k c module mi t admin Hin th tin nhn h thng trong danh sch project

IX.1 Lm vic vi module


Mt module Yii s cha rt nhiu mini-ng dng trong ,n cha ng ton b cu trc views, model, controller, v c cc thnh phn widget cn h tr, Tuy nhin module khng th trin khai bn thn chng nh mt ng dng. to mt module v cng n gin chng ta s s dng Gii http://localhost/devyii/gii/default/index Bn click vo Module Generator: Ti trng Module ID bn g admin -> preview->generated Bn vo protected/modules/ s thy folder mi hin ra c tn admin, s dng bn cng cn phi vo protected/config/main.php v khai bo n : 'modules'=>array( 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'1111', // If removed, Gii defaults to localhost only. Edit carefully to taste.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'ipFilters'=>array('127.0.0.1','::1'), ), 'admin', ), By gi bn c th vo trnh duyt xem kt qu: http://localhost/devyii/admin/default/index

IX.2 Module layout


Mt th chng ta s phi nhn li chng trc l newtheme, n cng cn c p dng vo module,l do cho vic ny l ngoi module controller class c k tha t protected/components/Controller.php, nhng layout mi nh :$layout=//layouts/column1. Quan trng l du // pha trc layout ny, n quy nh c th vic chng ta s dng ng dn ng dng chnh hn so vi ng dn ca mt

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

module c th khi tm kim tp tin, v th chng ta cn p dng cho nhng layout ngoi module ng dng ca chng ta d lm vic hn. Nu chng ta ch thc hin mt du gch cho / trc phn nh ngha tn layout cn tm, ta s thy module admin s khng c p dng trong tt c mi ni,l do iu ny l do du /, khi b tr /layouts/column1 n s tm kim cc tp tin trong module ch khng phi nm trong ng dng chnh. Chng ta s thay i iu ny vi vic s dng module: Bn c th cu hnh hu ht mi th trong module , v d thm thnh phn layout file, mc nh layout cho module s nm trong protected/modules/ [moduleId]/views/layouts, [moduleId] y l admin chng hn Chng ta c th nhn thy lc khi to s khng c file ny v th nn module s nhn layout mc nh t ng dng

IX.3 Th mt layout
Trc tin bn cn vo protected/views/layouts/column1 v i li nh sau: <?php $this->beginContent('//layouts/main'); ?> i thnh <?php $this->beginContent('/layouts/main'); ?> u tin hy thit lp layout mc nh cho module, chng ta s thc hin bi hm init() trong protected/modules/admin/AdminModules.php class AdminModule extends CWebModule { public function init() { // this method is called when the module is being created // you may place code here to customize the module or the application // import the module-level models and components

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

$this->setImport(array( 'admin.models.*', 'admin.components.*', )); $this->layout = 'main'; } Vi cch ny bn khng cn lo ti layout file mc nh trong module na, m module s nhn file mc nh ging nh class controller.php, cn nu bn mun thay i bn ch cn to file mi v nh ngha layout cho n v thm layout trong protected/modules/admin/views/layouts. Tip theo bn copy 2 file protected/views/layouts/main.php v protected/views/layouts/column1.php t ng dng chnh, v vt n vo protected/modules/admin/views/layouts Sau bn chnh li column1.php trong protected/modules/admin/views/layouts/column1.php Xa phn tham chiu ti main.php file ch cn: <?php $this->beginContent(); ?> <div id="content"> <?php echo $content; ?> </div><!-- content --> <?php $this->endContent(); ?> Tip theo bn vo protected/modules/admin/views/layouts/main.php v thm nhng on in m sau; ... <div class="container" id="page"> <div id="header"> <div id="logo"><?php echo CHtml::encode(Yii::app()->name) . " Admin Console"; ?></div> </div><!-- header --> <div id="mainmenu">

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

<?php $this->widget('zii.widgets.CMenu',array( 'items'=>array( array('label'=>'Back To Main Site', 'url'=>array('/project')), array('label'=>'Admin', 'url'=>array('/admin/default/index')), array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest), array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest) ), )); ?> </div><!-- mainmenu --> Vo trnh duyt t sng: http://localhost/devyii/admin/default/index

IX.4 Hn ch truy cp admin

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Mt vn bn c th nhn thy l bt k ai cng c th truy cp c vo admin module,chng ta s xy dng sao cho ch nhng user c cho php mi c kh nng vo admin module Bn vo protected/modules/admin/AdminModule::beforeControllerAction() method v chnh li nh sau: public function beforeControllerAction($controller, $action) { if(parent::beforeControllerAction($controller, $action)) { // this method is called before any module controller action is performed // you may place customized code here if( !Yii::app()->user->checkAccess("admin") ) { throw new CHttpException(403,Yii::t('application','You are not authorized to perform this action.')); } return true; } else return false; }

Hu qu l : http://localhost/devyii/admin/default/index

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Tip theo ta s vo /themes/newtheme/views/layouts/main.php v chnh li widget menu nh sau: <div id="mainmenu"> <?php $this->widget('zii.widgets.CMenu',array( 'items'=>array( array('label'=>'Projects', 'url'=>array('/project')), array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about')), array('label'=>'Contact', 'url'=>array('/site/contact')), array('label'=>'Admin', 'url'=>array('/admin/default/index'), 'visible'=>Yii::app()->user->checkAccess("admin")), array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest), array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest)

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

), )); ?> </div><!-- mainmenu -->

R rng khi bn cha ng nhp s khng hin link menu admin, nhng khi bn ng nhp h thng th h qu nh sau: http://localhost/devyii/project

IX.5 Thm mt tin nhn m rng t h thng


Mt module c th cha ng nhng mini-ng dng v bn thn n cng s truy nhp ti nhng hm main application, ta hy thm mt s hm mi cho administrator, chng ta s thm kh nng qun l tin nhn m rng t h thng khi h mi ng nhp vo website.

IX.5.1 To bng trong CSDL


CREATE TABLE tbl_sys_message ( id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, message TEXT NOT NULL, create_time DATETIME,

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

create_user_id INTEGER, update_time DATETIME, update_user_id INTEGER )

Copy v paste cho nhanh, nhng nh cc trng d liu.

IX.5.2 To CRUD v model cho bng mi


http://localhost/devyii/gii/default/index chn Model Generator link, tip theo ti trng Table prefix chn tbl_, ti trng Table Name chn : tbl_sys_message, ti trng model class chn : SysMessage , ti Model Path chn : application.modules.admin.models (ch khng mc nh) sau -> chn preview ->generated.

Tip theo nhn vo CRUD Generator ,ti trng Modelclass chn : Application.modules.admin.models.SysMessage, Ti controller_id : chn admin/SysMessage

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Sau nhn preview->generated.

IX.5.3 Thm mt links ti hm chc nng mi


Hy thm menu item mi vo layout main trong module admin phn navigation mainmenu. M file protected/modules/admin/views/layouts/main.php array('label'=>'System Messages', 'url'=>array('/admin/sysMessage/ index')), Sau bn vo trnh duyt xem kt qu: http://localhost/devyii/admin/sysMessage/create

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Nu h thng bo li khng hin ra bng ny bn vo modules/admin/controllers/sysMessageControllers v sa khai bo: class SysMessageController extends Controllers class SysMessageController extends Controller V nhn xung di phn nh ngha layout ta thy : $layout=//layouts/column2; Chnh bi iu ny m front ca admin vn s dng layout ca hm chnh gm 2 ct l 1 ct cha ni dung controller v mt ct l mt widget menu bn phi, chng ta s cng chnh li layout bin ni dng trong controller t mt ct thnh hai ct.Cch thc hin nh sau: thnh

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

1. Copy t protected/views/layouts/column2.php ti protected/modules/admin/views/layouts/column2.php 2. Xa //layouts/main trong phn u vo ca hm beginContent() trong column2.php mi copy v. 3. Chnh li sysMessage model k tha t DevYiiActiveRecord u on khai bo class 4. Chnh li SysMessageController s dng column2.php layout file vi vic nh ngha li khai bo layout l :$layout=/layouts/column2; 5. Sau khi chng ta k tha DevYiiActiveRecord chng ta s xa b mt s trng d liu khng cn thit khi c t ng to ra, v d xa on sau trong modules/admin/views/sysMessage/_form.php <div class="row"> <?php echo $form->labelEx($model,'create_time'); ?> <?php echo $form->textField($model,'create_time'); ?> <?php echo $form->error($model,'create_time'); ?> </div> <div class="row"> <?php echo $form->labelEx($model,'create_user_id'); ?> <?php echo $form->textField($model,'create_user_id'); ?> <?php echo $form->error($model,'create_user_id'); ?> </div> <div class="row"> <?php echo $form->labelEx($model,'update_time'); ?> <?php echo $form->textField($model,'update_time'); ?> <?php echo $form->error($model,'update_time'); ?> </div> <div class="row"> <?php echo $form->labelEx($model,'update_user_id'); ?> <?php echo $form->textField($model,'update_user_id'); ?> <?php echo $form->error($model,'update_user_id'); ?> </div> Sau xa b quy tc trong SysMessage::rules() AR:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

array('create_user, update_user', 'numerical', 'integerOnly'=>true), and array('create_time, update_time', 'safe'),

Ln thay i cui cng bn vo SysMessageController::accessRules() public function accessRules() { return array( array('allow', // allow only users in the 'admin' role access to //our actions 'actions'=>array('index','view', 'create', 'update', 'admin', 'delete'), 'roles'=>array('admin'), ), array('deny', // deny all users 'users'=>array('*'), ), ); }

Sau khi t hc hin xong bn vo : http://localhost/devyii/admin/sysMessage/create

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

R rng form tr ln p hn rt nhiu, v bn c th to mt s tin nhn ring cho bn ngay lc ny (lu s dng chun b d liu test bn ghi cc phn sau).

IX.5.4 Hin th tin nhn ti ngi dng


By gi chng ta c mt tin nhn t h thng , hy hin th n ti ngi dng trong trang ch.

Thm model class cho ng dng truy cp


Vo protected/config/main.php v thm v model ca module admin: // autoloading model and component classes 'import'=>array(

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'application.models.*', 'application.components.*', 'application.modules.admin.models.*', ),

Chn tin nhn gn nht c cp nht


Chng ta s ch tr v mt tin nhn gn nht t h thng, nh trng d liu update_time trong bng, sau ta thm n vo danh sch project. Chng ta s chnh sa li ProjectController::actionIndex(): Vo protected/controller/ProjectController.php sa li actionIndex nh sau: public function actionIndex() { $dataProvider=new CActiveDataProvider('Project'); Yii::app()->clientScript->registerLinkTag( 'alternate', 'application/rss+xml', $this->createUrl('comment/feed')); //get the latest system message to display based on the update_ time column $sysMessage = SysMessage::model()->find(array( 'order'=>'t.update_time DESC', )); if($sysMessage !== null) $message = $sysMessage->message; else $message = null;

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

$this->render('index',array( 'dataProvider'=>$dataProvider, 'sysMessage'=>$message, )); } By gi chng ta cn chnh views file , vo protected/views/project/index.php v thm vo trn u on <h1>Project</h1> trong view file <?php if($sysMessage !== null):?> <div class="sys-message"> <?php echo $sysMessage; ?> </div> <?php Yii::app()->clientScript->registerScript( 'fadeAndHideEffect', '$(".sys-message").animate({opacity: 1.0}, 5000). fadeOut("slow");' ); endif; ?> Sau khi hon thnh xong chng ta vo trnh duyt t sng: http://localhost/devyii/project

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Thm CSS cho tin nhn


Bn vo themes/newtheme/css/main.css v thm vo on css sau: div.sys-message { padding:.8em; margin-bottom:1em; border:3px solid #ddd; background:#9EEFFF; color:#FF330A; border-color:#00849E; } Hu qu l: http://localhost/devyii/project

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Bn ch 5 giy n s t ng mt nh Jquery animate.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

CHNG 10

Caching

D liu b nh m l phng thc rt tt gip cho vic phc v hiu nng s dng ca mt ng dng website.Nu nhng ni dung c bit c yu cu bi nhiu ngi dng cng mt lc,s dng b nh m lu tr v phc v ni dung trong mt thi im nht nh lc d liu v truy cp d liu. Yii cung cp hu ht cc tiu chun caching,bn c th bt u cu hnh cache vo ng dng ca bn, nhng thnh phn u c k tha t Ccache trong yii,class c bn ca cache vi cc thit b cache khc c thc thi. Yii cung cp nhiu tiu chun cache khc nhau nhm lu tr d liu, sau y l danh sch cc cache m Yii cung cp thc thi: 1. Cmemcache: S dng PHP Memcache extensions 2. CapcCache: S dng PHP APC extensions 3. CXCache: S dng PHP Xcache extensions 4. CEAcceleratorCache: S dng PHP Eaccelerator extensions 5. CdbCache: S dng bng c s d liu lu tr cache,bi mc nh n s to v s dng SQLite3 databse di dng th mc.Bn c th s dng cch thc ny thng qua khai bo kt ni connectionID 6. CzendDataCache: S dng Zend Data Cache nh mt b nh m va phi 7. CfileCache: S dng file lu gi d liu cache,y l cch thc lu tr d liu ln v m rng (ging nh mt trang) 8. CdummyCache: Gii thiu giao din cache,nhng khng lun thc hin caching,l do cho s thc thi ny l cc nh pht trin khng h tr n thc hin caching,bn ch c th testcode vi cc cache hp l khc
9. CwinCache: Cwincache c thc thi t thnh phn ng dng cache

c bn trong Wincache,thng tin nhiu hn bn vo http://www.iis.net/downloads theo di

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Tt c nhng loi cache trn u phi k tha t thnh phn Ccache

X.1 Cu hnh cache


Bn vo protected/config/main.php v cu hnh cache bn mun s dng v d vi Cmemcache (Lu rng s dng memcache th apache ca bn phi tch hp memcache ri nh,vo phpinfo v xem thng s , cc cache khc cng tng t phi tch hp vo apache) y l thng s ca ti sau khi cu hnh xong memcache:

array( ...... 'components'=>array( ...... 'cache'=>array( 'class'=>'system.caching.CMemCache', 'servers'=>array( array('host'=>'server1', 'port'=>12345, 'weight'=>60), array('host'=>'server2', 'port'=>12345, 'weight'=>40),

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

), ), ), );

Tuy nhin gi quan h n gin cho ngi c trong ng dng DevYii chng ta s s dng CfileCache lm v d. CfileCache cung cp caching c bn, khi s dng loi cache ny mi d liu thc thi s c lu trong mt file, v mc nh n s tr file v ng dn protected/runtime/cache (bn vui lng to folder cache trong folder runtime) , thay i cu hnh thit lp bn vo protected/config/main.php v thc hin nh sau: // application components 'components'=>array( 'cache'=>array( 'class'=>'system.caching.CFileCache', ), ),

Vi s thay i ny mi ni trong ng dng bn c th gi n bng : Yii::app()->cache.

X.2 S dng cache file


Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

By gi chng ta s s dng file cache trong thnh phn ng dng, hy vo protected/modules/admin/models/SysMessage.php AR model class lc tin nhn cui cng trong bn ghi. Chng ta s thm hm sau vo model class: /** * Retrieves the most recent system message. * @return SysMessage the AR instance representing the latest system *message. */ public static function getLatest() { //see if it is in the cache, if so, just return it if( ($cache=Yii::app()->cache)!==null) { $key='DevYii.ProjectListing.SystemMessage'; if(($sysMessage=$cache->get($key))!==false) return $sysMessage; } //The system message was either not found in the cache, or //there is no cache component defined for the application //retrieve the system message from the database $sysMessage = SysMessage::model()->find(array( 'order'=>'t.update_time DESC', )); if($sysMessage != null)

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

{ //a valid message was found. Store it in cache for future retrievals if(isset($key)) $cache->set($key,$sysMessage,300); return $sysMessage; } else return null; }

Sau bn vo ProjectController::actionIndex() thay i : $sysMessage = SysMessage::model()->find(array('order'=>'t.update_time DESC',)); Thnh on: $sysMessage = SysMessage::getLatest(); Vo li website: http://localhost/devyii/project sau vo protected/runtime/cache bn s thy nhng file cache c to ra:

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

X.3 Cache Dependencies


Tham s ph thuc cho php thay th khc v phc tp hn nhiu cch tip cn quyt nh c hoc khng c cc d liu c lu tr trong b nh cache lm mi. Hn l tuyn b mt khong thi gian n gin cho ht thi hn lu tr d liu, chin lc b nh m ca bn c th yu cu rng cc d liu tr nn khng hp l da trn nhng th nh ngi s dng c th lm theo yu cu, ch chung, trng thi ca cc ng dng, hoc xem mt tp tin trn h thng tp tin c cp nht gn y. iu ny cho php bn xc nh cc quy tc xc nhn b nh cache Tham s ph thuc c khi to t CcacheDependency ,yii chp nhn cc thuc tnh sau: CfileCacheDependency: d liu trong cache s l mt file hp l thay i thi gian v thay i t khi cache thc hin CdirectoryCacheDependency: Ging nh file trc nhng kim tra tt c cc file v ng dn con ti ng dn ring CDbCacheDependency: d liu trong b nh cache s khng c hiu lc nu kt qu truy vn mt cu lnh SQL quy nh c thay i k t khi tra cu b nh cache trc . CGlobalStateCacheDependency: Cc d liu trong b nh cache s khng hp l nu gi tr ca trng thi public quy nh c thay i. Mt trng thi public l mt bin lin tc trn nhiu yu cu v nhiu phin trong mt ng dng. N c nh ngha thng qua CApplication :: setGlobalState (). CChainedCacheDependency: iu ny cho php bn chui li vi nhau nhiu ph thuc. Cc d liu trong b nh cache s tr thnh khng hp l nu c ca cc ph thuc vo chui c thay i. CExpressionDependency: d liu trong b nh cache s khng c hiu lc nu kt qu ca biu thc PHP quy nh c thay i. Chng ta s chnh li function getLatest() trong sysMessage.php: $cache->set($key, $sysMessage, 0, new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_sys_message'));

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

X.4 Query Caching


B nh m truy vn cch tip cn b nh m kt qu c s d liu nh vy l thng xuyn cn thit trong cc ng dng c s d liu theo nh hng m Yii cung cp d dng hn truy vn b nh m.Truy vn b nh m lu tr kt qu ca mt truy vn c s d liu trong b nh cache v tit kim thi gian thc hin truy vn trn cc yu cu tip theo v y l nhng phc v trc tip t b nh cache. kch hot mt truy vn, bn cn phi m bo ti sn queryCacheID ca ti sn CDbConnection cp n ID thuc tnh ca mt thnh phn b nh cache hp l. N cp n 'cache' theo mc nh, l nhng g chng ti c cu hnh t v d b nh cache trc. s dng b nh m truy vn, chng tai ch n gin l gi b nh cache() t phng thc CDbConnection. Phng thc ny mt trong mt thi gian, xc nh s giy truy vn c vn cn trong b nh cache. Nu thi gian c thit lp l 0, b nh m c v hiu ha. Bn cng c th ch nh mt trng hp CCacheDependency nh l mt i s th hai, v xc nh c bao nhiu truy vn tip theo nn c lu tr nh l mt i s th ba. i s th ba ny mc nh l 1, c ngha l ch c cc truy vn SQL tip theo s c lu tr. s dng query cache ta vo SystemMessage::getLatest() thc hin thay i ton b hm li nh sau: //use the query caching approach

$dependency = new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_sys_message'); $sysMessage = SysMessage::model()->cache(1800, $dependency) ->find(array('order'=>'t.update_time DESC',)); return $sysMessage;

X.5 Phn mng Caching


Longt8x-Phamducbact1k10@gmail.com Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Cc v d trc y chng minh vic s dng cc d liu b nh m. y l ni m chng ta to ra mt phn mnh duy nht ca d liu v lu tr n trong b nh cache. C nhiu phng php khc c sn trong Yii lu tr cc phn mnh ca cc trang c to ra bi mt phn ca mt kch bn xem hay thm ch l ton b trang chnh n. Fragment b nh m l b nh m mt on ca mt trang. Chng ta c th tn dng li th ca mnh b nh m bn trong cc tp tin view. lm nh vy, chng ta s dng CController :: beginCache () v CController :: endCache ().hai phng php c s dng nh du s bt u v kt thc ca cc trang kt xut ni dung c lu tr trong b nh cache. Cng nh l trng hp khi s dng mt b nh m d liu phng php tip cn, chng ta cn mt cha kha duy nht xc nh cc ni dung c lu tr. Nhn chung,c php s dng b nh m mnh bn trong mt kch bn xem l nh sau: ...... <? php if ($ this-> beginCache ($ id)) { / / ... Ni dung bn mun cache y $ this-> endCache (); } > ...... BeginCache () tr v false khi c mt phin bn lu tr c sn, v ni dung c lu trong b nh cache s c t ng chn vo ti ni , nu khng,ni dung bn trong c thc hin v s c lu tr khi endCache () c gi.

X.6 nh ngha thng s phn mnh caching


Khi gi beginCache (), chng ta c th cung cp mt mng nh l tham s th hai bao gm b nh m ty chn ty chnh b nh m mnh. Nh mt vn ca thc t, beginCache () v endCache () phng php l mt wrapper thun tin ca COutputCache b lc / widget. V vy, cc ty chn b nh m c th l cc gi tr ban u cho bt k thuc tnh no ca lp COutputCache. Ngi ta c th cho rng mt trong nhng la chn ph bin nht quy nh

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

khi b nh m d liu thi gian, ch nh di ni dung c th vn c gi tr trong b nh cache. l tng t nh cc thng s thi gian chng ti s dng khi b nh m thng bo h thng ca chng ti. Ta c th ch nh tham s thi gian khi gi beginCache () nh sau: $ this-> beginCache ($ key, array (duration'=> 3600)) Ci t mc nh cho cch tip cn ny phn mnh b nh m l khc nhau hn so vi d liu b nh m. Nu chng ta khng thit lp thi gian n mc nh l 60 giy, c ngha l ni dung c lu trong b nh cache s ht hiu lc sau 60 giy. C rt nhiu la chn khc bn c th thit lp khi s dng b nh m. bit thm thng tin, hy tham kho cc API ti liu hng dn cho COutputCache cng nh mnh phn b nh m ca cc Yii http://www.yiiframework.com/doc/guide/1.1/en/caching.fragment

X.7 S dng phn mnh cache


Hy thc hin iu ny trong ng dng DevYii. Chng ta mt ln na s tp trung vo list project. bn c th nh li, pha di cng ca trang list project c mt list comment c ngi dng comment vi vn lin quan tng d n. Danh sch ny ch cho thy nhng ngi cn li mt bnh lun v vn no. Thay v hi phc danh sch ny mi khi c yu cu, chng ta hy s dng mnh b nh m cache danh sch ny hai pht. Cc ng dng c th chu ng cc d liu ny hi c, v hai pht l thc s khng phi l di phi ch i cho mt danh sch bnh lun c cp nht.

Vo protected/views/project/index.php: <?php $key="DevYii.ProjectListing.RecentComments"; if($this->beginCache($key,array('duration'=>120))) { $this->beginWidget('zii.widgets.CPortlet', array('title'=>'RecentComments',)); $this->widget('RecentComments'); $this->endWidget();

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

$this->endCache(); } ?>

X.8 Page Caching


Ngoi b nh m mnh, Yii cung cp cc ty chn cache cc kt qu ca yu cu ton b trang. Cch tip cn b nh m trang tng t nh cc b nh m mnh. Tuy nhin, bi v ni dung ca ton b mt trang thng c to ra xem, chng ta c th khng ch n gin gi beginCache () v endCache () trong file. L do l n c p dng trong cuc gi CController :: render () phng php sau khi xem ni dung. V vy, chng ta s lun lun b l c hi ly ni dung t b nh cache. V vy, cache ton b trang, chng ta hon ton nn b qua vic thc hin cc hnh ng to ra cc ni dung trang. thc hin iu ny, chng ta c th s dng lp CoutputCache nh l mt b lc hnh ng trong lp iu khin . V d, chng ta hy s dng cch tip cn b nh m trang b nh cache cc trang kt qu cho mi trang chi tit project . Trang chi tit project trong DevYii c tr li bng request: URL http://localhost/devyii/project/view/id/ [id], trong [id] l ID d n c th chng ta ang yu cu chi tit . Nhng g chng ta mun lm l thit lp mt b lc b nh m s cache ton b ni dung ca trang ny mt cch ring bit cho mi ID yu cu. Chng ta cn phi kt hp ID d n vo gi tr b nh cache. l, chng ta khng mun lm cho mt yu cu cho cc chi tit ca d n # 1 v c cc ng dng tr v mt kt qu c lu trong b nh cache cho d n # 2. Cc b lc CoutputCache cho php chng ta lm iu . M protected/controllers/ProjectController.php v chnh li filters() public function filters() { return array( 'accessControl', // perform access control for CRUD operations array(

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

'COutputCache + view', //cache the entire output from the actionView() method for 2 minutes 'duration'=>120, 'varyByParam'=>array('id'), ), ); }

Cu hnh b lc ny s dng cc b lc COutputCache cache ton b sn lng c to ra bi cc ng dng t mt cuc gi n ProjectController :: ActionView (). Thng s xem + thm ngay sau khi t khai COutputCache, nh bn c th gi li, l cch tiu chun chng ti bao gm cc phng php hnh ng c th m mt b lc nn p dng. Tham s thi gian quy nh TTL l 120 giy (2 pht), sau cc ni dung trang s c ti sinh. Cc cu hnh varyByParam l mt la chn thc s tuyt vi m chng ti m ch n trc. Thay v t trch nhim ln bn, cc nh pht trin, n vi mt chin lc quan trng duy nht cho cc ni dung c lu tr, tnh nng ny cho php s thay i c x l t ng. V d, trong trng hp ny, bng cch xc nh mt danh sch tn tng ng GET cc thng s trong yu cu u vo. V chng ti l b nh m trang ni dung yu cu i vi cc d n do project_id, n lm cho cm gic hon ho s dng ID ny nh l mt phn ca th h cha kha duy nht cho b nh m ni dung. Bng cch xc nh 'VaryByParam' => array ('id'), COutputCache thc hin iu ny cho chng ta da trn input QueryString id. C nhiu la chn c sn t c iu ny loi

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

AutoContent s thay i chin lc khi s dng COutputCache b nh cache d liu ca chng ta. Yii 1.1.12 c sn cc tnh nng sau; varyByRoute: Bng cch thit lp ty chn ny l true, cc request route c th c a vo nh danh duy nht cho cc d liu c lu trong b nh cache. V vy, bn c th s dng s kt hp ca b iu khin c yu cu v hnh ng phn bit lu tr ni dung. varyBySession: Bng cch thit lp ty chn ny tht s, mt session ID duy nht c s dng phn bit cc ni dung trong b nh cache. Mi phin ngi dng c th xem s khc nhau ni dung, nhng tt c cc ni dung ny vn c th c phc v t b nh cache. varyByParam: Nh tho lun trc , iu ny s dng cc u vo GET chui truy vn cc thng s phn bit cc ni dung trong b nh cache. varyByExpression: Bng cch thit lp ty chn ny mt biu thc PHP, chng ta c th s dng kt qu ca biu thc ny phn bit cc ni dung trong b nh cache. V vy, vi cc b lc trn cu hnh trong lp ProjectController ca chng ti, mi yu cu cho mt trang c th chi tit d n c lu tr trong b nh cache trong hai pht trc khi c ti sinh v mt ln na c lu tr trong b nh cache. Bn c th kim tra iu ny bng cch xem d n c th, sau cp nht d n. Cp nht ca bn s khng c ngay lp tc hin th nu c thc hin trong thi gian thi gian b nh cache hai pht. B nh m kt qu ton b trang l mt cch tuyt vi ci thin hiu sut trang web, tuy nhin chc chn n khng c ngha cho mi trang trong tt c cc ng dng c lu tr. Ngay c trong v d ca chng ta, b nh m ton b trang cho trang chi tit d n khng cho php chng ta s dng ng pagination thc hin cho danh sch cc issue. Chng ta

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

s dng iu ny nh l mt v d nhanh chng lm th no thc hin b nh m trang, nhng n khng phi l cch tip cn ng trong mi trng hp. Mt s kt hp ca ba phng php tip cn, d liu, mnh, v b nh m trang, cho php bn iu chnh chin lc b nh m ca bn p ng yu cu ng dng. Chng ta thc s ch khm ph qua tt c cc b nh m ty chn c sn trong Yii. Hy vng rng iu ny kch thch s hc hi ca bn tip tc tm hiu thm ton b nh m c sn.

General performance tuning tips As you are preparing your application for production, there are a few other things to take into consideration. The following sections briefly outline some other areas of consideration when working to tweak the performance of a Yii-based web application. Using APC Enabling the PHP APC extension is perhaps the easiest way to improve the overall performance of an application. The extension caches and optimizes PHP intermediate code and avoids the time spent in parsing PHP scripts for every incoming request. It also provides a very fast storage mechanism for cached content. With APC enabled, you can use the CApcCache implementation for caching content, fragments, and pages. Disabling the debug mode We discussed the debug mode earlier in the chapter, but it won't hurt to hear it again.

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

Disabling debug mode is another easy way to improve performance and security. A Yii application runs in debug mode if the constant YII_DEBUG is defined as true in the main index.php entry script. Many components, including those down in the framework itself, incur extra overhead when running in the debug mode. Also, as was mentioned way back in Chapter 2, Getting Started, when we first created a Yii application, most of your Yii application files do not need to be, nor should they be, in the publically accessible web directory. A Yii application has just one entry script, which is often the only file that needs to be placed in the web directory. Other PHP scripts, including all of the Yii framework files, should be protected. This is why the default name of the primary application directory is called protected/. To avoid security issues, it is recommended to keep it from being publicly accessible. Using yiilite.php When the PHP APC extension is enabled, one can replace yii.php with a different Yii bootstrap file named yiilite.php. This can help to further boost the performance of a Yii-powered application. The file yiilite.php comes with every Yii release. It is the result of merging some commonly used Yii class files. Both comments and trace statements are stripped from the merged file. Therefore, using

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

yiilite.php would reduce the number of files being included and avoid execution of trace statements. Note that using yiilite.php without APC may actually reduce performance. This is because yiilite.php contains some classes that are not necessarily used in every request and would take extra parsing time. It is also observed that using yiilite.php is slower with some server configurations; even when APC is turned on. The best way to judge whether to use yiilite.php or not is to run a benchmark using the "Hello World" demo that is included in the code bundle. Using caching techniques As we described and demonstrated in this chapter, Yii provides many caching solutions that may improve the performance of a web application significantly. If the generation of some data takes a long time, we can use the data caching approach to reduce the data generation frequency; if a portion of page remains relatively static, we can use the fragment caching approach to reduce its rendering frequency; if a whole page remains relative static, we can use the page caching approach to save the rendering cost for the whole page. Enabling schema caching If the application is using Active Record (AR), you can turn on the schema caching

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

in a production environment to save the time of parsing database schema. This can be done by configuring the CDbConnection::schemaCachingDuration property to be a value greater than zero. Besides these application-level caching techniques, we can also use serverside caching solutions to boost the application's performance. The enabling of APC caching that we described here, belongs to this category. There are other server-side techniques, such as Zend Optimizer, eAccelerator, and Squid, just to name a few. Production Readiness [ 304 ] These, for the most part, just provide some good practice guidelines as you work to prepare your Yii application for production or troubleshoot an existing application for bottlenecks. General application performance tuning is much more of an art than a science, and there are many, many factors outside of the Yii framework that play into the overall performance. Yii has been built with performance in mind since its inception and continues to outperform many other PHP-based application development frameworks by a long shot (see http://www.yiiframework.com/ performance/ for more details). Of course, every single web application will need to

Longt8x-Phamducbact1k10@gmail.com

Page 209

January 1, 2013

[WEB.APPLICATION.DEVELOPMENT.WITH.YII.A ND.PHP 2ND EDITION]

be tweaked to enhance the performance, but making Yii the development framework of choice certainly puts your application on a great performance footing from the onset. For further details, see the Performance Tuning section of the Yii definitive guide at http://www.yiiframework.com/doc/guide/1.1/en/topics.performance.

Longt8x-Phamducbact1k10@gmail.com

Page 209

You might also like