Professional Documents
Culture Documents
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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';
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
III. To controller
-Vo th mc ng dng M:
%cd /Webroot/devyii
C:/ Cd C:/xampp/htdocs/devyii
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
-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>
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
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
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
)); <?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>
Longt8x-Phamducbact1k10@gmail.com
Page 209
<?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
<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
-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
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
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
' ), ); }
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
- 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
('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
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
'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
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
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
<?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
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:
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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:
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
), */ 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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
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
{ 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.
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
); }
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
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Tip theo bn nhn preview -> generated. Chng ta c th vo protected/models kim tra v s thy Issue.php
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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', ); }
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
{ 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
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
</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>
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
// 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'), ); }
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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 :
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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.
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.
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
{ $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 ?
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
} 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,
Longt8x-Phamducbact1k10@gmail.com
Page 209
* 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
//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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
January 1, 2013
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
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.
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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()); ?>
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
<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
<?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
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.
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
)); $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.
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
)); ?>
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
<?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:
January 1, 2013
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
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)'),
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
{ $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>
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
'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
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', ), )); ?>
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
// 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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
$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
{ $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
// 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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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.
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
<?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
); } } 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
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
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
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
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.
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
{ 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; }
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
</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:
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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', ),
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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) ); }
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
*/ 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; }
January 1, 2013
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; } } }
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
{ $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
} return $usernames; } }
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
$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
'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
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
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
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 {
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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:
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
<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
<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
<?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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
} ... } 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
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
$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
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
?>
Kt qu:
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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 .
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
//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
y l kt qu: http://localhost/devyii/index.php?r=comment/feed
January 1, 2013
'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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
), ), 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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
'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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
'dataProvider'=>$dataProvider, )); } Bn s thy on sau u th head: <link rel="alternate" type="application/rss+xml" href="/commentfeed. xml" />
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
{ $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.
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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);
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
// 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;
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
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.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:
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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.
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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]-->
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
<?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.
<?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
<?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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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.
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
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
$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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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',
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
<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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
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.
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
$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
<?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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
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
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('*'), ), ); }
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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).
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
$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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
), ), ), );
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', ), ),
January 1, 2013
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
{ //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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
$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;
January 1, 2013
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.
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
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
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
$this->endCache(); } ?>
Longt8x-Phamducbact1k10@gmail.com
Page 209
January 1, 2013
'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
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
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
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
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
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
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