You are on page 1of 64

HTTP://SEODRUPAL.

VN
Lp trnh Drupal, Zend ra!e"#r$, %&& ra!e"#r$
Kim tra tng thch gia Yii vi my ch
http://yourhostname/path_to_yii/requirements/index.php
http://localhost/softvn/requirements/index.php
Phn mm chay local: Xampp, Wamp, ko nn dng appserv v bj li( nguyn nhn mnh ko bit, tt
nht nn trnh).
Hoc xi lun host tht nu nh c diu kin.
'. (hu)n *+
Trc tin ban phi cu hnh windows d s dung doc php vi cmd
-Gi s ban ci apache mc djnh trn WinXP (C:\xampp\htdocs).
-Ban thit lp lai bin mi trng (Environment Variables) bng cch vo:
Start -> My Computer (right click!) -> Advanced Tab -> Environment Variables -> Click Path in
System variables (windows 7 l Path) -> Edit.
-Click vo bin PATH v chon Edit. Lu l dng c xo b cc dng dn d tn tai trong
textbox m ngn cch chng vi nhau bng du ";".
-Tip d ban thm vo nhng dng dn sau: "C:\xampp\php" v "
C:\xampp\htdocs\yii\framework". Lu sa dng dn cho ph hop vi my ban nha .
-Khi dng my tnh lai.
,.T-# .n/ d0n/ %&& !1&
-YiiRoot l th muc ni ban d ci dt Yii
-Webroot l th muc gc cha web
-T dng lnh, dn webroot ca ban v thuc hin:
(:\
(d2
(d (:23a!pp2htd#452
(:23a!pp2htd#45265#7t8n/7ra!e"#r$/9&&4 "e*app de!#
:de!#;<6 T=n .n/ d0n/
(reate a >e* appl&4at&#n under ?/>e*r##t/de!#?@ :%e5AN#;
%e5:9;
Vy l khung xng ca Yii d doc tao ra thnh cng
Trch dn:demo/
index.php file ng dung
index-test.php file kim tra chc nng
assets/ cha ti nguyn ng dung
css/ cha CSS
images/ cha hnh nh
themes/ cha giao din
protected/ cha cc file doc bo v
Ban c th truy cp vo ng dung t trnh duyt
http://localhost/demo/index.php
copy framework sang demo.
Vo file index.php thay di dng dn thnh : $yii=dirname(__FLE__).'/framework/yii.php';
BBB. T-# 4#ntr#ller
-Vo th muc ng dung
M:
%cd /Webroot/demo
C:/
Cd C:/xampp/htdocs/demo
-Khi dng Yii Shell
M:
%YiiRoot/framework/yiic shell
Cd C:/xampp/htdocs/demo
C:/xampp/htdocs/demo> C:/xampp/htdocs/softvn/framework/yiic shell
Tao th controller tn message c hnh dng l helloWorld
C php: controller <controller-D> [action-D]
VD:
M:
controller message helloWorld
-MessageController d doc tao thnh cng th muc: protected/controllers/
-Bn canh d n cng tao ra view tai th muc: protected\views\message
-Chng ta cng c th truy cp vo hnh dng helloWorld t trnh duyt
Default: http://localhost/demo/index.php?r=message -> chay vo index
http://localhost/demo/index.php?r=message/helloWorld
VBBB. T-# l&=n $Ct
-Yii c h tro sn hm tao lin kt trong class CHtml
-VD:
Tao lin kt ti View goodbye
M:
<p><?php echo CHtml::link("Goodbye",array('message/goodbye')); ?></p>
Tao lin kt ti View Hello
M:
<p><?php echo CHtml::link("Hello",array('message/helloWorld')); ?></p>
BD.(E& FGt data*a5e
'.%&& hH trI 4J4 dala*a5e 5au:
-MySQL 4.1 or later
-PostgresSQL 7.3 or later
-SQLite 2 and 3
-Microsoft SQL Server 2000 or later
-Oracle
,. KCt nL& 81& data*a5e
-Thuc hin file /protected/config/main.php
-Mc djnh n dang kch hoat dng ny l database ca khung xng Yii
M:
'db'=>array(
'connectionString' => 'sqlite:'.dirname(__FLE__).'/../data/testdrive.db',
),
- Gi s ta c 1 bng trong Mysql nh sau:
M:
CREATE TABLE F NOT EXSTS `tbl_user` (
`id` int(11) NOT NLL ATO_NCREMENT,
`username` varchar(12) NOT NLL,
`password` varchar(12) NOT NLL,
`email` varchar(12) NOT NLL,
PRMARY KEY (`id`)
);
- Chng ta phi kch hoat dng sau trong /protected/config/main.php d kt ni vi Mysql (b / / v
sa lai cu hnh)
M:
// uncomment the following to use a MySQL database

'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=db_yii',
'emulatePrepare' => true,
'username' => 'root',
'password' => '',
'charset' => 'utf',
),
-Ngoi ra ta c th kt ni vi ci database khc (thay di dng 'connectionString')
SQLite: sqlite:/path/to/dbfile
MySQL: mysql:host=localhost;dbname=testdb
PostgreSQL: pgsql:host=localhost;port=432;dbname=testdb
SQL Server: mssql:host=localhost;dbname=testdb
Oracle: oci:dbname=//localhost:121/testdb
DB. T-# (RUD
- CRD l cc chc nng create, read, update v delete 1 bng trong database
'. KM4h h#-t 4Nn/ 40 O&&
- Gii h tro sinh m tu dng cc chc nng nh Controller, Crud, Form, Model, Module.
- kch hoat Gii ta vo file config /protected/config/main.php
- Kch hoat doan code sau
M:
// uncomment the following to enable the Gii tool
'gii'=>array(
'class'=>'system.gii.GiiModule',
'password'=>'1234',
// f removed, Gii defaults to localhost only. Edit carefully to taste.
'ipFilters'=>array('127.0.0.1','::1'),
),
- i password mi d dng nhp Gii
- Vo Gii thng qua url:
http:// tn host/demo/index.php?r=gii
http://i12.photobucket.com/albums/a22/k...age023.png
http://i12.photobucket.com/albums/a22/k...age02.png
,. T-# u5er P#del
-Vo muc Model Generator d tao Model cho bng user
http://i12.photobucket.com/albums/a22/k...age027.png
- Table Prefix: vit phn tin t ca bng (nu c) vo dy, dy bng ca ta tn l tbl_user nn tin
t s l tbl_
- Table Name: phn cn lai ca tn bng l user (ta c th tao tu dng tt c bng bng cch nhp
du vo dy)
- Model Class: tn lp ca model l ser (tu sinh ra)
- Cn lai d mc djnh v click Preview
- Sau d click Generate d tao file Model ca ser tai th muc /protected/models/ser.php
Q. T-# (RUD:
- Vo muc Crud Generator
http://i12.photobucket.com/albums/a22/k...age02.png
- Model Class: din chnh xc tn lp Model va tao l ser
- Controller D: din user (khng vit hoa)
- Cn lai d mc djnh v click Preview
- Sau d click Generate d tao Crud
R. Tru9 4p (RUD
- Vo url: http://yourhostname/demo/index.php?r=user
- Click vo cc chc nng nh Create ser, Manage ser, n s bt ta dng nhp, ta c th s dung
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://yourhostname/demo/index.php?r=user/admin
. RL Thn thin
Vo protected/config/main.php b comment urlManager..
$yii=dirname(__FLE__).'/framework/yii.php';
DBB (S( TRTUNO DV LBWU TRONO ORP
$this->pageTitle=Thay di tiu d trang tai dy;
(J4h ': DXn/ 7#r! *Yn/ 4J4h dXn/ "&d/et.
//Khi tao widget s dung Aax cho Form Active
$form=$this->beginWidget('CActiveForm',arra9(
'id'=>'user-form',
'enableAaxValidation'=>true,
'enableClientValidation'=>true,
'focus'=>arra9($model,'name')
));
<?php //Kim tra du vo model d dng cha ?
e4h# $form->errorSummary($model);
?>
<div class="row">
<?php //Khi tao trng name
e4h# 'Tn truy cp:';
e4h# $form->textField($model,'name');
e4h# $form->error($model,'name');
?>
</div>
Th=! (apt4ha 4h# 7#r!
-Nu cha bt "gd2" th ta vo file php.ini ri sa lai dng ny
M PHP:
extension=php_gd2.dll
<?php $this->widget('CCaptcha',array(
'buttonLabel' => 'Ly code mi',
'clickablemage' => true,
'imageOptions' => array('id' => 'captchaimg')
)); ?>
RE: :(Z [\n; T-# 7#r! tr#n/ 8&e"
Xem thm cc Method d add cc Field khc cho form Here
Ngoi cch dng 'CActiveForm' ta c th dng 'Chtml' d tao form: CHtml
Vit Lai 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>
<div id='send'>
<br/>
<?php echo CHtml::submitButton('ng K',array('id'=>'frmReg','name'=>'frmReg'));?>
</div>
<?php
echo CHtml::endForm();
?>
</div>
Sau khi tao form xong th ti bc tip theo l add cc rng buc cho thng tin m user nhp vo v
du nh:
Cc text box khng doc b trng
Email phi dng dang
Pass phi ln hn nh hn 1
Repass phi y chang Pass
Date: phi hop l theo kiu (dd-mm-yyyy) hay (mm-dd-yyyy)
Add thm captcha chng dng k hng loat
Th=! (apt4ha 4h# 7#r!
-Yii c h tro sn th vin captcha cho chng ta, v captcha th nhn cng rt l cool.
Te5t 3e! 4] th^ render 4apt4ha ha9 $hNn/
-u tin truy cp th link ny d test xem c captcha hay khng ci d.
http://www.code.com/index.php?r=site/captcha nu ra nh vy l ok
-Nu n khng hin captcha th ta nn check lai xem d load "gd2" hay cha bng cch chay muc test
ca Yii
ging nh hnh l load ri, n vng hay d th xem lai cu hnh webserver
-Nu cha bt "gd2" th ta vo file php.ini ri sa lai dng ny
M PHP:
extension=php_gd2.dll
b du ";" trc n, my ci khc d defaut dng ty my, restar webserver v test lai, nu vn li --> thi ci lai win cho n
lnh
- tao captcha ta thm vo phn view doan code sau:
M PHP:
<?php $this->widget('CCaptcha',array(
'buttonLabel' => 'Ly code mi',
'clickablemage' => true,
'imageOptions' => array('id' => 'captchaimg')
)); ?>
Vi:
'buttonLabel' : hin thj mt link vi ni dung m ta set, khi click vo d s di string ca captcha
'clickablemage': khi click vo image s di sang hnh khc.
'imageOptions': set cc thuc tnh Html ca captcha
- Mt captcha doc rendered bi mt hnh dng ca lp CCaptchaAction, do d nu ch add bn
view s khng hin thj hnh nh, v captcha khng doc render. Do d ta vit thm bn Controller:
M PHP:
public function actions()


return array(
'captcha' => array (
'class' => 'CCaptchaAction',
'backColor' =>'fff
'
),
);

Vi
'backColor': mu nn nh fff l mu den,
'foreColor': mu ch captcha.
'height': chiu cao nh
'width': Chiu rng
'maxLength': chiu di ti da ca ch captcha
'minLength': d di ti thiu ca string.
'verifyCode': ly gi trj m xc nhn
Cui cng ra ci form nh vy:
- rng buc cc thng tin m e nhp vo ta vit mt phng thc trong Model nh sau:
M PHP:
public function rules()

return array (
array ('code','captcha',
'allowEmpty'=>!CCaptcha::checkRequirements(),
'message' => 'M Xc Nhn Nhp Khng ng'
),
array('email','email','message' =>'attribute khng hop l'),
array('name,email,pass,repass,date,code','required','message'=>"attribute khng doc b trng"),
array('repass','compare','compareAttribute'=>'pass','message'=>"attribute phi chnh xc"),
array('pass','length','min'=>'','message'=>"attribute khng d d di "),
array('date','date','format'=>'dd-mm-yyyy','message'=>"attribute phi chnh xc dang dd-mm-yyyy"),
);

PHN X L N T WEBSTE
Cc bc phn tch BackEnd (CMS) vi du n (PROECT)
T_O [`NO PROaE(T
CREATE TABLE tbl_proect
(
id NTEGER NOT NLL PRMARY KEY ATO_NCREMENT,
name VARCHAR(12),
description TEXT,
create_time DATETME,
create_user_id NTEGER,
update_time DATETME,
update_user_id NTEGER
);
Sb d0n/ OBB 3c9 ddn/ Pr#ee4t AR 4la55
Lu : sau tn localhost l tn folder website ca ban, vui lng thay th cho dng.
http://localhost/trackstar/index.php?r=gii.
T-# !1& ' 4la55 !#del t*lfpr#ee4t ta*le, the P#del Oenerat#r <6Oenerate.
Navigate back to the main Gii menu located at http://localhost/trackstar/index.php?r=gii, and choose the (rud Oenerat#r
<6Oenerate gOh t=n *\n/ 8E# $e9"#rd t! di l&ju rk& nhln Oeneratem.
Xem kt qu: http://localhost/trackstar/index.php?r=proect). Tao mt vi d liu d thuc hin vic xy dung DB.
-Thit k gin d d liu (database schema) v xy dung di tong h tro cc sn phm (issues)
ca du n.
- Tao m hnh lp(model class) Yii cho php ng dung d dng tng tc cc bng d liu vi nhau
sau khi tao.
- Tao lp diu khin (controller class) s l khng gian cha cc hm cho php chng ta :
Tao cc sn phm (issues) mi.
Tm v mt danh sch sn phm hin hnh trong pham vi mt du n ly t database.
Cp nht/chnh sa sn phm hin hnh.
Xa di sn phm hin hnh.
- Tao khung nhn (view) d tr lai (render) cho giao din ngi s dung cc hnh dng ( c
trc).
- THT K GN (SCHEMA)
Chng ta gi s n c mt thuc tnh (type), bn thn (owner), mt yu cu (requester), mt
trang thi (status) , v miu t (description). Chng ta s tao bng (tbl_proect) d thm cc
thng tin c bn doc kim tra vi cc bng khc chng ta tao ngy( date), gi(times) v
ngi truy cp update bng .
Tuy nhin thuc tnh(types), bn thn(owner), ngi yu cu(requester) v trang
thi(status) l tu chng.Bn thn chng l thuc th. gi cho m hnh mm do v d dng
m rng, chng ta s tao nhiu m hnh (model) khng dnh dng ti nhau. Bn thn
(developer) (owner) v ngi yu cu (requester) l hai ngi s dung h thng doc tham
chiu t mt hng (row) trong bng doc goi l (tbl_user).
Chng ta c th bt du gii thiu tng v ngi s dung (user) trong bng du n
(tbl_proect) , chng ta thm ct (create_user_id) , (update_user_id) d nhn dang dng di
ca mt ngi s dung lc ban du ho tao du n, tng tu nh vy khi ngi s dung (user)
cp nht chi tit du n ln cui cng. Mc d chng ta cha gii thiu bng d vo lc ny, c
nhng trng d liu doc m hnh chuyn qua kha ngoi ti mt bng d liu khc d lu
tr d liu v ngi s dung (user data). Trng (owner_id) m bn thn, (requester_id) m
ngi yu cu, trong bng (tbl_issue) cng s doc kha ngoi lin kt tr lai vi bng
(tbl_user).
noNH NOHpA (S( PqB rUAN HW
Mt du n c th c nhiu ngi s dung truy cp, v ngi truy cp c th lin kt vi nhiu
du n chng ta goi d l lin kt nhiu nhiu (many to many ).
Cch thc tt nht d m hnh ha quan h nhiu nhiu (many-to-many) trong cc d liu
lin quan d l s dung su kt hop (association) hoc phn quyn cho bng (table).
Di dy l m hnh c bn thuc th quan h gia ngi s dung (users),du n(proect), v
sn phm (issues). Mt du n c th c hoc khng c nhiu ngi dng,. Mt ngi s dung
cn phi kt hop vi t nht mt du n, hoc c th kt hop vi nhiu du n. Sn phm s ch
thuc v mt v ch duy nht mt du n. Khi d mt du n c th c khng -> nhiu sn phm.
Mt sn phm doc phn quyn (hay doc yu cu) bi duy nht 1 ngi dng.
Exactly one: Ch duy nht 1.
1 or More : Mt hoc nhiu
0 or More : Khng hoc nhiu.
Djch : Proect: Du n
ssue: vn d
ser: Ngi dng
Owner: Bn thn.
Ds% DtNO DATA[ASE Vu (S( PqB rUAN HW
Tao 3 bng mi l: tbl_issue,tbl_user,tbl_proect_user_assignment() ( bng trung gian ).
CREATE TABLE F NOT EXSTS 'tbl_issue'
(
'id' NTEGER NOT NLL PRMARY KEY ATO_NCREMENT,
'name' varchar(2) NOT NLL,
'description' varchar(2000),
'proect_id' NTEGER,
'type_id' NTEGER,
'status_id' NTEGER,
'owner_id' NTEGER,
'requester_id' NTEGER,
'create_time' DATETME,
'create_user_id' NTEGER,
'update_time' DATETME,
'update_user_id' NTEGER
) ENGNE = nnoDB
;
CREATE TABLE F NOT EXSTS 'tbl_user'
(
'id' NTEGER NOT NLL PRMARY KEY ATO_NCREMENT,
'email' Varchar(2) NOT NLL,
'username' Varchar(2),
'password' Varchar(2),
'last_login_time' Datetime,
'create_time' DATETME,
'create_user_id' NTEGER,
'update_time' DATETME,
'update_user_id' NTEGER
) ENGNE = nnoDB
;
CREATE TABLE F NOT EXSTS 'tbl_proect_user_assignment'
(
'proect_id' nt(11) NOT NLL,
'user_id' nt(11) NOT NLL,
'create_time' DATETME,
'create_user_id' NTEGER,
'update_time' DATETME,
'update_user_id' NTEGER,
PRMARY KEY ('proect_id','user_id')
) ENGNE = nnoDB
;
T-# 4J4 !L& vuan hj:
-Tao kha ngoai gia 2 bng tbl_issue,tbl_proect tham chiu (id thuc bng tbl_proect) ni vi
proect_id trong bng tbl_issue.
ALTER TABLE 'tbl_issue' ADD CONSTRANT 'FK_issue_proect' FOREGN KEY ('proect_id')
REFERENCES 'tbl_proect' ('id') ON DELETE CASCADE ON PDATE RESTRCT;
-Tao kha ngoai gia 2 bng tbl_issue, tbl_user tham chiu (id thuc bng tbl_user) ni vi
owner_id (kha bn thn) trong bng tbl_issue.
ALTER TABLE 'tbl_issue' ADD CONSTRANT 'FK_issue_owner' FOREGN KEY ('owner_id')
REFERENCES 'tbl_user' ('id') ON DELETE CASCADE ON PDATE RESTRCT;
Tng tu vi cc kha ngoai cn lai:
ALTER TABLE 'tbl_issue' ADD CONSTRANT 'FK_issue_requester' FOREGN KEY
('requester_id') REFERENCES 'tbl_user' ('id') ON DELETE CASCADE ON PDATE RESTRCT;
ALTER TABLE 'tbl_proect_user_assignment' ADD CONSTRANT 'FK_proect_user' FOREGN
KEY ('proect_id') REFERENCES 'tbl_proect' ('id') ON DELETE CASCADE ON PDATE
RESTRCT;
ALTER TABLE 'tbl_proect_user_assignment' ADD CONSTRANT 'FK_user_proect' FOREGN
KEY ('user_id') REFERENCES 'tbl_user' ('id') ON DELETE CASCADE ON PDATE RESTRCT;
T-# A4t&8e Re4#rd P#del 4la55e5 4h# 4J4 *\n/ 8wa t-#:
<T-# AR P#del &55ue5
Navigate to the Gii tool via http://localhost/trackstar/index.php?r=gii, and choose the P#del Oenerat#r link. Leave the
table prefix as t*lf. Fill in the Ta*le Na!e field as t*lf&55ue, which will auto-populate the P#del (la55 field as
B55ue.->preview->generate - Tao ssues CRD operation
Navigate to the Gii generator menu at http://localhost/trackstar/index.php?r=gii, and choose the (rud Oenerat#r
link. Fill out the form using B55ue as the value for the P#del (la55 field. This will auto-populate the (#ntr#ller BD to
also be B55ue. The [a5e (#ntr#ller (la55 and (#de Te!plate fields can remain their predefined default values.
Click the Pre8&e" <6 Oenerate.
Th=! thux4 tMnh Dr#pD#"n Penu
M model/ssue class: du trang class ssue khai bo hng cc thuc tnh:
const TYPE_BG=0;
const TYPE_FEATRE=1;
const TYPE_TASK=2;
Tao hm tr v mng cha cc thuc tnh:
public function getTypeOptions()

return array(
self::TYPE_BG=>'Bug',
self::TYPE_FEATRE=>'Feature',
self::TYPE_TASK=>'Task',
);

Th=! !xt 7&lter g*x ly4m
M protected/controllers/ssueController.php thm ni dung sau vo di lp:
public function filterProectContext($filterChain)

$filterChain->run();

Thm cu hnh cho filter vo mng cu hnh.Vi filter mi doc djnh ngha ta th p dung vi create
action.(Hm tao).
public function filters()

return array(
'accessControl', // perform access control for CRD operations
?pr#ee4t(#nte3t z 4reate?, //check to ensure valid proect context
);

Phng thc trn s tr v cu hnh cho filter proectContext ci m chng ta d djnh ngha ging
nh mt phng thc trong class v n p dung cho actionCreate() method. C php cu hnh
cho php l : '' hoc du '-' k hiu dc bit doc s dung khi chng ta mun hoc khng mun
mt filter no d doc p dung hay khng.
V du nu chng ta quyt djnh mun p dung cho tt c cc action ngoai tr actionpdate()
cp nht, v actionView() (nhn).Chng ta thuc hin :
return array('proectContext - update, view' ,);
Th=! !xt 8E& &lter L#/&4
Chng ta va djnh ngha doc filter mi v cu hnh n thuc hin method actionCreate();
Tuy nhin chng ta cha thuc hin doc su logic cn thit.Chng ta mun chc chn rng vn
bn du n doc thuc hin trc khi cc hnh dng (action) doc kick hoat.Chng ta cn dt filter
logic trc khi goi filterChain->run().
(h{n/ ta 5| 5b d0n/ 4huH& tw $h]a gvuer95tr&n/m lE !xt tha! *&Cn n/#E& URL F}I4 trnh *E9
F^ nhn d-n/ 4J4 dd Jn gpr#ee4tm.
Cc pre-action ca Filter s kim tra d nhn bit.Nu cc thuc tnh ca du n hin tai l
NLL, chng ta s s dung chui t kha(querystring) tham bin d kch hoat su lua chon cc du n
c bn trong kha chnh doc nhn dang (Primary Key indentifier). Nu thnh cng Action s thuc
hin, v nu tht bai mt li ngoai l s doc hin ra.
Chng ta vo ssueController class:
class ssueController extends CController

....
/
@var private property containing the associated Proect model instance.
/
private $_proect = null;
/
Protected method to load the associated Proect model class
@proect_id the primary identifier of the associated Proect
@return obect the Proect data model based on the primary key
/
protected function loadProect($proect_id)
//if the proect property is null, create it based on input id
if($this->_proect===null)

$this->_proect=ssue::model()->findbyPk($proect_id);
if($this->_proect===null)

throw new CHttpException(404,'The requested proect does not exist.');


return $this->_proect;

/
n-class defined filter method, configured for use in the above filters() method
t is called before the actionCreate() action method is run in order to ensure a proper proect
context
/
public function filterProectContext($filterChain)

//set the proect identifier based on either the GET or POST input
//request variables, since we allow both types for our actions
$proectd = null;
if(isset($_GET['pid']))
$proectd = $_GET['pid'];
else
if(isset($_POST['pid']))
$proectd = $_POST['pid'];
$this->loadProect($proectd);
//complete the running of other filters and execute the requested action
$filterChain->run();

...

TH~P PROaE(T BD
Lin kt( link) chng ta cn diu chnh trong view file : /protected/views/issue/index.php.
du trang chng ta s nhn thy link create new .
$this->menu=array(
arra9g?la*el?6?(reate B55ue?, ?url?6arra9g?4reate?mm,
array('label'=>'Manage ssue', 'url'=>array('admin')),
);
Chng ta thm trng pid va tao :
array('label'=>'Create ssue', 'url'=>array('create', 'pid'=>1)),
Truy cp lai vo admin v click vo link lin kt : http://localhost/demo/index.php?
r=issue/create&pid=1. Ta d thuc hin doc.
n&u 4hnh 4h& t&Ct twn/ tran/ 4a dd Jn:
Thm m du n cho tng RL cho vic tao mi sn phm l mt giai doan kh tt d chc chn rng
nhng diu chnh bn ngoi lm vic mt cch hon ho.Tuy nhin, chng ta c mt vn d xy ra vi
m code l proectD lun lun =1 .Tt nhin, diu ny khng phi l nhng g chng ta mun.Chng
ta mun c menu option cho vic tao mi sn phm trong trang chi tit ca du n.Ngha l , khi ban
lua chon mt du n t trang danh sch chi tit cc du n, m du n dc bit s phi doc hiu v
phi c m du n dng . (dynamic proect id).1
M chi tit du n trong : view, /protected/views/proect/view.php. Trong phn du trong ta s tm v
thm pid nh sau :
$this->menu=array(
array('label'=>'List Proect', 'url'=>array('index')),
array('label'=>'Create Proect', 'url'=>array('create')),
array('label'=>'pdate Proect', 'url'=>array('update', 'id'=>$model->id)),
array('label'=>'Delete Proect', 'url'=>'', 'linkOptions'=>array('submit'=>array('delete','id'=>$model-
>id),'confirm'=>'Are you sure you want to delete this item?')),
array('label'=>'Manage Proect', 'url'=>array('admin')),
arra9g?la*el?6?(reate B55ue?, ?url?6arra9g?&55ue/4reate?, ?p&d?6!#del<6&dmm,
);
D]a * 4J4 &nput 7#r! dd Jn gpr#ee4tm.
u tin hy chnh lai ssueController::actionCreate()
public function actionCreate()

$model=new ssue;
!#del<6pr#ee4tf&d th&5<6fpr#ee4t<6&d
...

M /protected/views/issue/_form.
Tm trng: <div class="row">
<?php echo $form->labelEx($model,'proect_id'); ?>
<?php echo $form->textField($model,'proect_id'); ?>
<?php echo $form->error($model,'proect_id'); ?>
</div>
Thay th: <div class="row">
<?php echo $form->hiddenField($model,'proect_id'); ?>
</div>
rua9 l-& 8&j4 *\n thcn g#"nerm 8E n/}& 9=u 4u grevue5term dr#pd#"n.
(h{n/ ta F th=! , u5er lE :
NSERT NTO 'tbl_user'
('email', 'username', 'password')
VALES
('test1@notanaddress.com','Test_ser_One', MD('test1')),
('test2@notanaddress.com','Test_ser_Two', MD('test2'))
;
n^ t-# , u5er tr#n/ hj thLn/ 81& Bd lE ', , ta thd4 h&jn a55&/n:
NSERT NTO 'tbl_proect_user_assignment' ('proect_id', 'user_id')
VALES (1,1), (1,2);
(h{n/ ta 4] th^ nhn !L& vuan hj /&ia 4J4 ta*le tr#n/ /protected/models/ssue.php.
public function relations()

// NOTE: you may need to adust the relation name and the related
// class name for the relations automatically generated below.
return array(
'owner' => array(self::BELONGS_TO, 'ser', 'owner_id'),
'proect' => array(self::BELONGS_TO, 'Proect', 'proect_id'),
'requester' => array(self::BELONGS_TO, 'ser', 'requester_id'),
);

Chng ta s thm quan h: Proect::relations() method.


M: /protected/models/Proect.php, v thay th cc thuc th trong relation() nh sau:
/
@return array relational rules.
/
public function relations()

// NOTE: you may need to adust the relation name and the related
// class name for the relations automatically generated below.
return array(
'issues' => array(self::HAS_MANY, 'ssue', 'proect_id'),
'users' => array(self::MANY_MANY, 'ser', 'tbl_proect_user_assignment(proect_id, user_id)'),
);

Tao D liu t Dropdown Menu


M /issue/models/ssue.php, v thm doan code sau vo di class:
pu*l&4 7un4t&#n /etU5erOpt&#n5gm

u5er5Arra9 (Ht!l::l&5tDatagth&5<6u5er5, ?&d?, ?u5erna!e?m
return u5er5Arra9

Thm ser v ProectserAssignment
Thm doan sau vo di class ca ssueController class:
/
Returns the proect model instance to which this issue belongs
/
public function getProect()

return $this->_proect;

M /protected/views/issue/_form.php v tm trong form cc trng owner_id, requester_id


Thay th: <?php //echo $form->textField($model,'owner_id'); ?>
thnh
<?php echo $form->dropDownList($model,'owner_id',$model->proect->getserOptions()); ?>
Thuc hin thay th:
<?php echo $form->textField($model,'requester_id'); ?>
Tr thnh:
<?php echo $form->dropDownList($model,'requester_id', $this->getProect()->getserOptions()); ?
>
Remove cc trng 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>
Truy cp vo issue vi acc:demo xem th phn create action();
THA% nB PROaE(T (ONTROLLER
Tr}14 t&=n F&u 4hnh a4t&#nV&e"gm tr#n/ 4la55 Pr#ee4t (#ntr#ller /&Ln/ nh} 4h{n/ ta !uLn
tr}n/ *E9 danh 5J4h 5\n ph)! l&=n vuan FCn 4J4 dd Jn FG4 *&jt.(h{n/ ta 4] th^ lE! F&u nE9
tr#n/ !xt 8E& tran/ /&Ln/ nh} tran/ 4h& t&Ct.Ph}Zn/ th.4 A4t&#n V&e"gm lE !eth#d F}I4 dXn/
F^ h&^n th+ 4h& t&Ct 5\n ph)!.
n&u 4hnh !eth#d nh} 5au:
/
D&5pla95 a part&4ular !#del.
/
pu*l&4 7un4t&#n a4t&#nV&e"gm

&55ueDataPr#8&derne" (A4t&8eDataPr#8&derg?B55ue?, arra9g
?4r&ter&a?6arra9g
?4#nd&t&#n?6?pr#ee4tf&d:pr#ee4tBd?,
?para!5?6arra9g?:pr#ee4tBd?6th&5<6l#adP#delgm<6&dm,
m,
?pa/&nat&#n?6arra9g
?pa/eS&e?6',
m,
mm
th&5<6renderg?8&e"?,arra9g
?!#del?6th&5<6l#adP#delgm,
?&55ueDataPr#8&der?6&55ueDataPr#8&der,
mm

Tai dy chng ta s dung CactiveDataProvider class trong framework d cung cp d liu trong obect
ActiveRecord. N s s dung class Model AR lin quan d ly d liu t database trong mt cc d
dng vi Yii widget. ClistView d trng by item trong danh sch doc render trong view file. Chng ta
c th s dung criteria l diu kin dc bit ch d ly cc vn d lin quan ti du n doc trng
by.Chng ta cng c th s dung pagination(Phn trang) d gii han danh sch sn phm trong mt
trang.
nBU (HNH Pr#ee4t V&e" &le
P /protected/views/proect/view.php
Thm doan code sau vo di cng file:
<br>
<h1>Proect ssues</h1>
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$issueDataProvider,
'itemView'=>'/issue/_view',
)); ?>
dy chng ta dang thit lp thuc tnh dataProvider CListView doc vn d cung cp d liu chng
ta d va tao. Sau d chng ta cu hnh n d s dung trong protected/view/issue/_view.php ging
nh mt template cho render item trong d liu doc cung cp.File ny d doc tao cho chng ta bi
Gii tool khi chng ta generate trong CRD ca issues. Chng ta ch s dung n dy d trng by
sn phm trong trang chi tit ca du n.
Chng ta cng phi thay di /protected/views/issue/_view.php s dung template layout cho sn phm
khc. iu chnh ni dung thuc th 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('description')); ?>:</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>
<?php echo CHtml::encode($data->status_id); ?>
</div>
Tai Proect Controller Sa di LoadModule
private $_model;
public function loadModel()

if($this->_model===NLL)

if(isset($_GET['id']))
$this->_model=Proect::model()->findByPk($_GET['id']);
if($this->_model===null)
throw new CHttpException(404,'The requested page does not exist.');

return $this->_model;

Thm d liu vo bn issue/create tao mi 2 bn ghi.


Kim tra kt qu : (http://localhost/tasctrak/index.php?r=proect/view&id=1)
H&^n th+ 4J4 Statu5 8E T9pe te3t tr#n/ BSSUE
VE# : /protected/models/ssue.php
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)";

TH~P nO_N HBN THo TEDT tw #r!


Vo : /protected/views/issue/_view.php:
Thay di : <?php echo CHtml::encode($data->type_id); ?>
thnh
<?php echo CHtml::encode($data->getTypeText()); ?>
V thay di
<?php echo CHtml::encode($data->status_id); ?>
this:
<?php echo CHtml::encode($data->getStatusText()); ?>
THA% nB (HB TBT VBE> BSSUE
P : /pr#te4ted/8&e"5/&55ue/8&e".php
Th=! F#-n 5au:
@php th&5<6"&d/etg?&&."&d/et5.(Deta&lV&e"?, arra9g
?data?6!#del,
?attr&*ute5?6arra9g
?&d?,
?na!e?,
?de54r&pt&#n?,
?pr#ee4tf&d?,
?t9pef&d?,
?5tatu5f&d?,
?#"nerf&d?,
?revue5terf&d?,
?4reateft&!e?,
?4reatefu5erf&d?,
?updateft&!e?,
?updatefu5erf&d?,
m,
mm @6
Tha9 F& thEnh:
@php th&5<6"&d/etg?&&."&d/et5.(Deta&lV&e"?, arra9g
?data?6!#del,
?attr&*ute5?6arra9g
?&d?,
?na!e?,
?de54r&pt&#n?,
arra9g
?na!e?6?t9pef&d?,
?8alue?6(Ht!l::en4#deg!#del<6/etT9peTe3tgmm
m,
arra9g
?na!e?6?5tatu5f&d?,
?8alue?6(Ht!l::en4#deg!#del<6/etStatu5Te3tgmm
m,
?#"nerf&d?,
?revue5terf&d?,
m,
mm @6
[ 5un/ th=! pr#ee4tf&d 8E# 7un4t&#n Ad!&n
pu*l&4 7un4t&#n a4t&#nAd!&ngm

!#delne" B55ueg?5ear4h?m
!#del<6un5etAttr&*ute5gm // 4lear an9 de7ault 8alue5
&7g&55etgfOET:?B55ue?;mm
!#del<6attr&*ute5fOET:?B55ue?;
!#del<6pr#ee4tf&dth&5<6fpr#ee4t<6&d
th&5<6renderg?ad!&n?,arra9g
?!#del?6!#del,
mm

jnh ngha CactiveDataProvider trong indexAction


public function actionndex()

$dataProvider=new
CActiveDataProvider('ssue',array('criteria'=>array('condition'=>'proect_id=:proect_d','params'=>array
(':proect_d'=>$this->_proect->id))));
$this->render('index',array(
'dataProvider'=>$dataProvider,
));

Sb d0n/ vuan hj AR
Nh issues v user l dai din nh nhng bng d liu ring bit, v lin quan dn quan h kha
ngoai, chng ta thuc su truy cp vo owner v requester username truc tip t $model trong view file.
Bng cch s dung sc manh ca Yii AR m hnh quan h, trng by thuc tnh username ca lin
quan dn model ser class.
As we have mentioned, the model class ssue::relations() method is where the relationships are
defined. f we take a peek at this method, we see the following:
/
@return array relational rules.
/
public function relations()

// NOTE: you may need to adust the relation name and the related
// class name for the relations automatically generated below.
return array(
?#"ner? 6 arra9g5el7::[ELONOSfTO, ?U5er?, ?#"nerf&d?m, //*el#n/ t# lE thux4 8
'proect' => array(self::BELONGS_TO, 'Proect', 'proect_id'),
?revue5ter? 6 arra9g5el7::[ELONOSfTO, ?U5er?, ?revue5terf&d?m,
);

Trng by sername ca Owner v requester:
Protected\view\issue\view.php
<?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())
),
arra9g
?na!e?6?#"nerf&d?,
?8alue?6(Ht!l::en4#deg!#del<6#"ner<6u5erna!em
m,
arra9g
?na!e?6?revue5terf&d?,
?8alue?6(Ht!l::en4#deg!#del<6revue5ter<6u5erna!em
m,
)
)); ?>
Thd4 h&jn !xt 5L F&u 4hnh 4uL& 4Xn/.
Pxt F&u chng ta nhn ra l ng dung vn cho php ngi dng doc diu hng ti nhng danh
sch ca sn phm, cng nh tt c du n. V du trong mt trang chi tit sn phm,
http://localhost/trackstar/index.php?r=issue/view&id=1,
Chng ta nhn thy menu diu hng bn phi, gm c Danh sch sn phm, v qun l sn phm
tng ng : http://localhost/trackstar/index.php?r=issue/index and http://localhost/trackstar/index.php?
r=issue/admin
Nh1 rYn/ F^ tru9 4p 8E# tran/ vu\n tr+ *-n 4n 8E# 81& tE& $h#\n ad!&n/ad!&n
Nhng vn cn hin thj tt c cc sn phm, trn tt c cc du n. V vy, chng ta cn phi han ch
danh sch ny d c mt du n cu th.
C nhng lin kt hnh thnh t trang chi tit sn phm (issue) v dc bit sn phm d c du n lin
quan, chng ta c th bt du chnh lai lin kt doc nhn trong proectD v proectD ny nm trong
ssueController::index v ssueController::actionAdmin method.
M dng dn: /protected/views/issue/view.php thay di cu hnh menu:
$this->menu=array(
arra9g?la*el?6?L&5t B55ue?, ?url?6arra9g?&nde3?, ?p&d?6!#del<6pr#ee4t<6&dmm,
arra9g?la*el?6?(reate B55ue?, ?url?6arra9g?4reate?, ?p&d?6!#del<6pr#ee4t<6&dmm,
array('label'=>'pdate ssue', 'url'=>array('update', 'id'=>$model->id)),
array('label'=>'Delete ssue', 'url'=>'', 'linkOptions'=>array('submit'=>array('delete','id'=>$model-
>id),'confirm'=>'Are you sure you want to delete this item?')),
arra9g?la*el?6?Pana/e B55ue?, ?url?6arra9g?ad!&n?, ?p&d?6!#del<6pr#ee4t<6&dmm,
);
Thay di cu hnh filter trong ssueController
public function filters()

return array(
'accessControl', // perform access control for CRD operations
?pr#ee4t(#nte3t z 4reate &nde3 ad!&n?, //per7#r! a 4he4$ t# en5ure 8al&d pr#ee4t 4#nte3t
);

Chnh lai method actionndex()
public function actionndex()

dataPr#8&derne" (A4t&8eDataPr#8&derg?B55ue?, arra9g


?4r&ter&a?6arra9g
?4#nd&t&#n?6?pr#ee4tf&d:pr#ee4tBd?,
?para!5?6arra9g?:pr#ee4tBd?6th&5<6fpr#ee4t<6&dm,
m,
mm
$this->render('index',array(
'dataProvider'=>$dataProvider,
));

THAY DANH SCH TRANG ADMN


iu chnh method admin:
public function actionAdmin()

$model=new ssue('search');
if(isset($_GET['ssue']))
$model->attributes=$_GET['ssue'];
!#del<6pr#ee4tf&d th&5<6fpr#ee4t<6&d
$this->render('admin',array(
'model'=>$model,
));

Thm cc tiu chun mi vo Model/ ssue::search()


public function search()

// Warning: Please modify the following code to remove attributes that
// 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);
4r&ter&a<64#nd&t&#n?pr#ee4tf&d:pr#ee4tBD?
4r&ter&a<6para!5arra9g?:pr#ee4tBD?6th&5<6pr#ee4tf&dm
return new CActiveDataProvider(get_class($this), array(
'criteria'=>$criteria,
));

(HTNO < rU`N TRo NOTUB DNO Vu DJ4 Thd4 rU%N TRU% (P
gU5er Pana/e!ent and Authent&4at&#nm
Khi chng ta s dung cng cu yiic command, chng ta nhn doc hm dng nhp(login) mc c bn
vi cng cu tao sn cho chng ta. Trang dng nhp cho php ngi dng truy nhp vi 2 hnh thc ti
khon (admin/admin) (demo/demo)
Chng ta cn lm mt s thay di diu chnh sao cho chng ta qun l doc nhiu ngi dng.iu
ny s khin ta phi m rng thm bng ngi dng (table user) v thm cc chc nng cn thit d
qun l.
TO CRD ca table ser
Navigate to the Gii tool via http://localhost/trackstar/index.php?r=gii and choose the P#del Oenerat#r link. Leave the table
prefix as t*l. Fill in the Ta*le Na!e field as t*lfu5er, which will auto-populate the P#del (la55 name field as U5er .(l&4$
pre8&e" <6 /enerate.
Navigate to the tool via http://localhost/trackstar/index.php?r=gii.
2. Choose the (rud Oenerat#r link from the list of available generators.
3. Type in U5er for the P#del (la55 name field. The corresponding (#ntr#ller BD will auto-populate with u5er.<
6pre8&e"<6/enerate.
G http://localhost/trackstar/index.php?r=user d xem kt qu hin thj.
Cp nht kim tra ljch s cc ct (columns).
Nh tt c cc thuc th ca chng ti bng tbl_proect, tbl_issue, tbl_user c cc ct tng tu quy
djnh, chng ti s thm vo cc logic cn thit cho mt lp c s chung v sau d c mi ca cc lp
c nhn AR m rng t lp c s mi ny.
L do chng ta dang tao lp mi ny, thay v ch cn thm logic truc tip vo model class proect, l
bi v cc class khc, model ssue v ser, cng cn logic ny. Thay v lp lai trong cc m trong tt
c cc lp m hnh AR, cch tip cn ny s cho php chng ti d thit lp cc lnh vuc ny cho tt
c cc lp m hnh AR ch trong mt ni. Chng ti cng s lm cho lp tru tong mi, v n khng
nn doc khi tao truc tip.
Tao file mi: trong protected/models/ tao CheckserActiveRecord.php
<?php
abstract class CheckserActiveRecord extends CActiveRecord

/
Prepares create_time, create_user_id, update_time and update_user_id attributes before performing validation.
/
protected function beforeValidate()

if($this->isNewRecord)

// set the create date, last updated date and the user doing the creating
$this->create_time=$this->update_time=new CDbExpression('NOW()');
$this->create_user_id=$this->update_user_id=Yii::app()->user->id;

else

//not a new record, so ust set the last updated time and last updated user id
$this->update_time=new CDbExpression('NOW()');
$this->update_user_id=Yii::app()->user->id;

return parent::beforeValidate();

dy chng ta dang ghi d phng thc CactiveRecord::beforeValidate().y l phng thc gip


ngi s dung c th ty bin qu trnh truy cp.
nu ban khng thuc hin sai mt tham s khi goi phng thc save () trn mt lp AR, qu trnh xc
thuc s doc kch hoat. Qu trnh ny thuc hin xc thuc theo quy djnh trong phng php rules ()
trong lp AR. C hai phng php tip xc cho php chng ta d khai thc cc cng vic xc nhn v
thuc hin bt ky logic cn thit, hoc ngay trc hoc ngay sau khi xc nhn doc thuc hin:
beforeValidate () v afterValidate ().
Ch : S dung NOW () trong m trc d l cu th cho MySQL. iu ny c th lm vic nu ban
dang theo cng cch s dung mt c s d liu khc nhau. Ban lun c th c mt cch tip cn
khc nhau d thit lp gi trj ny. V du, bng cch s dung chc nng thi gian PHP v djnh dang n
mt cch thch hop cho loai d liu ca ct: $ this-> createTime = $ this-> updateTime = ngy ("Ymd
H: i: s, time());
by gi chng ta cn phi thay di 3 class hin c ca AR l -Proect.php, ser.php, v ssue.php d
m rng t lp tru tong hn l truc tip t CActiveRecord.3 class ny nm trong
protected/models/.
Chng ta thay th :
class Proect extends CActiveRecord

Thay di thnh
class Proect extends CheckserActiveRecord

Tng tu vi 2 class user v issue.


jnh ngha ln lot cc trng d liu trong form nm trong : protected/views/proect/_form.php v
protected/views/user/_form.php protected/views/issue/_form.php,
Loai b cc trng d liu nh 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>
T form user trong : protected/views/user/_form.php chng ta xa b thuc tnh 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>
chng ta cng nn loai b cc quy tc xc nhn quy djnh cho cc trng ny trong cc method quy
tc lin quan
Trong method ser::rules() method, xa di 2 rules sau:
array('create_user_id, update_user_id', 'numerical', 'integerOnly'=>true),
array('last_login_time, create_time, update_time', 'safe'),
Lm tng tu vi 2 model cn lai l :proect, issue. Xa b cc trng lin quan ti d liu va xa.
Thm trng xc thuc mt khu:
Thm ln bn du trang user:
public $password_repeat;
ser::rules() method thm :
array('password', 'compare'),
array('password_repeat', 'safe'),
Vo protected/views/user/_form thm trng nhp lai mt khu :
<div class="row">
<?php echo $form->label($model,'password_repeat'); ?>
<?php echo $form->passwordField($model,'password_repeat',array('size'=>0,'maxlength'=>2)); ?>
<?php echo $form->error($model,'password_repeat'); ?>
</div>
M ha mt khu:
M CheckserActiveRecord trong protected/models/ v thuc hin:
/
perform one-way encryption on the password before we store it in the database
/
protected function afterValidate()

parent::afterValidate();
$this->password = $this->encrypt($this->password);

public function encrypt($value)

return md($value);

DS( THt( USER 5b d0n/ DATA[ASE


Gii thiu Yii authentication model
l mt thnh phn ng dung, ngi s dung, trong d, trong trng hop chung nht, l mt di tong
thuc hin giao din Webser. Cc lp hoc cu th doc s dung bng cch thuc hin mc djnh ca
chng ti l lp khung, CWebser. Thnh phn ny ngi s dung dng gi tt c cc thng tin nhn
dang cho ngi s dung hin tai ca ng dung. Thnh phn ny d doc cu hnh cho chng ta nh
l mt phn ca m ng dung tu dng tao ra khi chng ti bc du tao ra ng dung ca chng ti
s dung cng cu yiic. Cu hnh c th doc nhn thy trong cc tp tin doc protected / config /
main.php
'user'=>array(
// enable cookie-based authentication
'allowAutoLogin'=>true,
),
V n l cu hnh nh mt thnh phn ng dung, vi key(user) , chng ta c th truy cp n bt ky
ni no trong sut ng dung ca chng ti bng cch s dung Yii:: app () -> user.
Chng ta thy rng allowAutoLogin, dang doc thit lp dy l kh n. Thit lp ny l false theo
mc djnh, nhng vic thit lp n l true cho php thng tin ngi dng doc lu tr trong cc cookie
ca trnh duyt lin tuc. Nhng thng tin ny sau d doc s dung d tu dng xc thuc ngi dng
khi ln gh thm sau ny. y l nhng g s cho php chng ta c mt ti khon Ghi nh hp kim
trn cc hnh thc dng nhp d, nu ngi dng lua chon, ho c th doc tu dng dng nhp vo
ng dung khi ln gh thm sau d vo trang web.
Khung xc thuc Yii djnh ngha mt thuc th ring bit d nh logic thm djnh thuc t. iu ny doc
goi l mt lp hoc nhn dang, v trong hnh thc chung nht ca n l mt lp m thuc hin cc giao
din serdentity. Mt trong nhng vai tr chnh ca lp ny l d dng gi logic xc thuc d dng
cho php trin khai khc nhau. Ty thuc vo yu cu ng dung, chng ti c th cn phi xc nhn
mt tn ngi dng v mt khu di vi gi trj doc lu tr trong mt c s d liu, hoc cho php
ngi dng dng nhp vi OpenD thng tin ca ho, hoc tch hop vi mt phng php tip cn
LDAP hin c. Tch logic d l cu th phng php xc thuc t phn cn lai ca qu trnh dng nhp
ng dung cho php chng ta d dng chuyn di gia hin thuc nh vy.
Vo protected/components/serdentity.php
Xem qua ni dung ca dentity ta thy vic thuc hin ny ch dn gin l s dung tn dng nhp / mt
khu m ha cng cc gi trj ca bn demo / demo v qun trj admin /. N kim tra cc gi trj di vi
tn ngi dng v cc thuc tnh ca lp mt khu (ti sn quy djnh tai cc lp cha me,
Cserdentity) v nu ho khng ph hop, n s thit lp v tr v mt m li thch hop.
M hnh hoat dng ca qu trnh dng nhp doc m t nh sau:
hiu r hn v nhng mnh ph hop vi ton b qu trnh xc thuc end-to-end, chng ta hy
di qua cc logic bt du vi hnh thc dng nhp. Nu chng ta diu hng dn trang dng nhp:
http://localhost/demo/index.php?r=site/login, chng ta thy mt hnh thc dn gin cho php du
vo ca mt tn ngi dng, mt khu v ty chon hp kim cho cc ti khon Ghi nh Thi gian
Tip theo chc nng m chng ti tho lun trc khi. Trnh dn ny goi logic trong
SiteController:: actionLogin () phng php. S d trnh tu sau dy m t su tng tc lp xy ra
trong qu trnh dng nhp thnh cng t thi dim ny di hnh thc
doc gi.
Qu trnh bt du vi vic thit lp cc thuc tnh lp hoc v m hnh hnh thc, LoginForm, vi cc
gi trj hnh thc trnh. LoginForm-> phng thc validate () sau d doc goi, trong d xc nhn cc
gi trj thuc tnh dua trn cc quy tc quy djnh trong phng php quy djnh (). Phng php ny
doc quy djnh nh sau:
public function rules()

return array(
// username and password are required
array('username, password', 'required'),
// rememberMe needs to be a boolean
array('rememberMe', 'boolean'),
// password needs to be authenticated
array('password', 'authenticate'),
);

Cui cng ca cc quy tc ny quy djnh rng thuc tnh mt khu doc xc nhn bng cch s
dung cc ty chnh phng php authenticate (), cng doc djnh ngha trong lp LoginForm nh
sau:
/
Authenticates the password.
This is the 'authenticate' validator as declared in rules().
/
public function authenticate($attribute,$params)

$this->_identity=new serdentity($this->username,$this->password);
if(!$this->_identity->authenticate())
$this->addError('password','ncorrect username or password.');

Tip tuc thuc hin theo cc s d trnh tu, xc nhn mt khu trong LoginForm cuc goi authenticate
() phng php trong cng mt lp. Phng php ny tao ra mt th hin mi ca lp danh tnh xc
thuc doc s dung, trong trng hop ny l / protected/ component/ serdentity.php bo v, v sau
d goi xc thuc ca n authenticate (). serdentity :: authenticate () nh sau:
/
Authenticates the password.
This is the 'authenticate' validator as declared in rules().
/
public function authenticate($attribute,$params)

if(!$this->hasErrors()) // we only want to authenticate when no
input errors

$identity=new serdentity($this->username,$this->password);
$identity->authenticate();
switch($identity->errorCode)

case serdentity::ERROR_NONE:
$duration=$this->rememberMe ? 3002430 : 0; // 30 days
Yii::app()->user->login($identity,$duration);
break;
case serdentity::ERROR_SERNAME_NVALD:
$this->addError('username','sername is incorrect.');
break;
default: // serdentity::ERROR_PASSWORD_NVALD
$this->addError('password','Password is incorrect.');
break;

iu ny doc thuc hin d s dung tn ngi dng v mt khu d thuc hin xc thuc ca n.
Trong vic thuc hin ny, min l su kt hop tn ngi dng / mt khu l mt trong hai bn demo /
demo hoc admin / admin, phng php ny s tr lai dng su tht. Khi chng ta dang di qua mt
dng nhp thnh cng, chng thuc thnh cng v dng nhp () phng php trn cc thnh phn
ng dung ngi dng.
THAY Q TRNH THUC HEN XC THUC
By gi chng ta hiu ton b qu trnh xc thuc, chng ta c th d dng nhn thy ni m chng
ta cn phi thuc hin thay di d s dung bng tbl_user ca chng ti d xc nhn tn ngi dng
v cc thng tin mt khu doc cung cp theo hnh thc dng nhp. Chng ta c th thay di
authenticate() trong class seridentity d xc minh su tn tai ca mt hng ph hop vi tn
ngi dng cung cp v gi trj mt khu. K t khi, vo lc ny, c khng c g khc trong class
serdentity.php ngoai tr authenticate method, chng ta hy thay th hon ton cc ni dung ca
tp tin ny vi cc m sau dy:
<?php
/
serdentity represents the data needed to identity a user.
t contains the authentication method that checks if the provided
data can identify the user.
/
class serdentity extends Cserdentity

private $_id;
/
Authenticates a user using the ser data model.
@return boolean whether authentication succeeds.
/
public function authenticate()

$user=ser::model()->findByAttributes(array('username'=>$this->username));
if($user===null)

$this->errorCode=self::ERROR_SERNAME_NVALD;

else

if($user->password!==$user->encrypt($this->password))

$this->errorCode=self::ERROR_PASSWORD_NVALD;

else

$this->_id = $user->id;
if(null===$user->last_login_time)

$lastLogin = time();

else

$lastLogin = strtotime($user->last_login_time);

$this->setState('lastLoginTime', $lastLogin); $this->errorCode=self::ERROR_NONE;


return !$this->errorCode;

public function getd()

return $this->_id;

Chng ta d thit lp mt thuc tnh mi vo class serdentity cho D ngi dng. Vic thuc
hin mc djnh trong cc lp cha me l d tr lai tn ngi dng cho D. Nh chng ta dang s
dung mt c s d liu, v c cc phm s tiu nhn dang ngi dng duy nht, chng ta phi
chc chn rng D s ny l nhng g doc thit lp v tr lai trong sut cc ng dung khi cc D
ngi dng doc yu cu. l, khi cc m: Yii:: app () -> user-> id doc thuc thi, chng ta phi
dm bo rng D duy nht t c s d liu doc tr v, khng phi tn ngi dng.
K THA n/ d0n/ 4J4 thux4 tMnh U5er
iu th hai xy ra dy l cc thit lp ca mt thuc tnh trn ser dentity l thi gian dng nhp
cui cng tr v t c s d liu. Thnh phn ng dung ngi dng, CWebser, c ngun gc thuc
tnh ngi dng D r rng v cc thuc tnh tn doc djnh ngha trong class indentity , v sau d t
tn => cp gi trj trong mng doc goi t state identity.
chng ti d thit lp cc thuc tnh c tn l lastLoginTime l gi trj ca trng last_login_time
trong c s d liu. Bng cch ny, bt ky ni no trong ng dung, thuc tnh ny c th doc
truy cp thng qua:
Yii:: app () -> user-> lastLoginTime;
Khi cc hng ngi dng ban du vo bng vi cc gi trj null cho thi gian dng nhp cui cng,
c mt kim tra nhanh chng cho null d chng ti c th lu tr mt thi dim thch hop khi
ngi s dung cc bn ghi trong thi gian du tin.
Vi nhng thay di ny tai ch, by gi ban s cn phi cung cp dng tn v mt khu kt hop
cho mt ngi dng doc xc djnh trong bng tbl_user trong c s d liu. S dung demo / demo
hoc admin / qun trj s, tt nhin, cng vic khng cn.Hy cho n mt th. Ban c th dng
nhp nh bt ky mt trong nhng ngi s dung m ban d tao ra trc d trong chng ny.
Nu ban lm theo v c cc d liu ngi dng nh chng ti, cc thng tin sau dy nn lm vic:
Tn dng nhp: Test_ser_One
Mt khu: test1
(P NHT NOTUB DNO ( THUB OBAN nNO NHP (UqB (NO
Nh chng ta d d cp trc d trong chng ny, chng ti loai b thi gian dng nhp cui
cng nh mt trng du vo ca ngi dng tao ra cc hnh thc, nhng chng ti vn cn thm
logic d cp nht lnh vuc ny. Nh chng ta dang theo di thi gian dng nhp cui cng trong
bng c s d liu tbl_user, chng ta cn phi cp nht lnh vuc ny cho ph hop sau khi dng
nhp thnh cng. Khi dng nhp thuc t xy ra trong LoginForm:: login () phng php trong lp
m hnh hnh thc, chng ta hy cp nht gi trj ny. Thm cc dng sau dy nhn manh dn
LoginForm:: login () method:
/
Logs in the user using the given username and password in the model.
@return boolean whether login is successful
/
public function login()

if($this->_identity===null)

$this->_identity=new serdentity($this->username,$this->password);
$this->_identity->authenticate();

if($this->_identity->errorCode===serdentity::ERROR_NONE)

$duration=$this->rememberMe ? 3002430 : 0; // 30 days
Yii::app()->user->login($this->_identity,$duration);
U5er::!#delgm<6update[9P$gth&5<6f&dent&t9<6&d, arra9g?la5tfl#/&nft&!e?6ne"
(D*E3pre55&#ng?NO>gm?mmm
return true;

else
return false;

dy chng ta dang ku goi updateByPk () phng php nh l mt cch tip cn hiu qu d


ch dn gin l cp nht h s ser, ch djnh kha chnh cng nh mt loat cc tn => cp gi trj
cho cc ct m ta mun cp nht.
H&^n th+ ln Fn/ nhp 4uL& 4Xn/ n/#E& tran/ 4h
M : protected/views/site/index.php
<h1>Welcome to <i><?php echo CHtml::encode(Yii::app()->name); ?></i></h1>
@php &7g%&&::appgm<6u5er<6&5Oue5tm:@6
p6
%#u la5t l#//ed &n #n @php e4h# dateg ?l, d, %, /:& a?, %&&::appgm<6u5er<
6la5tL#/&nT&!e m @6.
/p6
@php end&7@6
(HTNO : nBU KHBN Sd Tru9 (p 4a N/}& DXn/
C hai phng php c lin quan dn kim sot truy cp ca ngi dng v du trong
ProectController :, ProectController:: filter () v ProectController:: accessRules (). Cc m cho
phng php du tin doc lit k nh sau:
/
@return array action filters
/
public function filters()

return array(
'accessControl', // thuc hin diu khin truy cp cho CRD operations
);

Phng thc th 2 doc s dung nh sau:


/
Specifies the access control rules.
This method is used by the 'accessControl' filter.
@return array access control rules
/
public function accessRules()

return array(
array('allow', // cho php ngi dng thuc hin 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array(''),
),
array('allow', // cho php chng thuc ngi dng vi 'create' and 'update' actions
'actions'=>array('create','update'),
'users'=>array('@'),
),
array('allow', // cho php admin user thuc hin 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
'users'=>array('admin'),
),
array('deny', // T chi truy cp
'users'=>array(''),
),
);

Method filter () d quen thuc vi chng ta. N l ni m chng ta xc djnh tt c cc filter doc s
dung trong lp diu khin. Trong trng hop ny, chng ti d ch c mt, accessControl, trong d d
cp dn mt b loc doc cung cp bi khung Yii. B loc ny s dung phng php khc,
accessRules (), trong d xc djnh cc quy tc diu khin han ch truy cp.
Trong phng php accessRules () d d cp trc dy, c bn quy tc quy djnh. Mi quy tc doc
th hin nh l mt mng (array) . Yu t du tin ca mng c th cho php (allow) hoc t chi
(deny). Ch ra vic cp hoc t chi truy cp. Phn cn lai ca mng bao gm tn => cp gi trj quy
djnh cu th cc thng s cn lai ca quy tc.
Quy tc truy cp c th doc djnh ngha bng cch s dung mt s cc thng s bi cnh. Cc quy
tc doc d cp trc d xc djnh nhng hnh dng v ngi s dung d tao ra bi cnh quy tc,
nhng c mt s ngi khc doc lit k nh sau:
Controller: Quy tc ny quy djnh cu th mt mng ca cc D controller cc quy tc p dung.
Roles: Quy tc ny quy djnh cu th danh sch cc item y quyn (roles,operation,premission) m
rule p dung. iu ny lm cho s dung cc tnh nng RBAC chng ti s doc tho lun trong phn
tip theo.
ps: Quy tc ny quy djnh cu th danh sch cc dja ch client P m rule ny doc p dung.
Verbs: Quy tc ny quy djnh cu th cc loai yu cu HTTP (GET, POST, v nh vy) p dung cho
quy tc ny.
Expression: Quy tc ny quy djnh cu th mt biu thc PHP c gi trj cho thy c hay khng c quy
tc nn doc p dung.
Action: Quy tc ny quy djnh cu th cc phng thc hnh dng, bng cch s dung D hnh dng
tng ng, m nguyn tc phi ph hop vi.
sers : Quy tc ny quy djnh cu th ngi s dung cc quy tc p dung. Thuc tnh tn ngi s
dung ng dung hin tai doc s dung cho ph hop. Ba k tu dc bit cng c th doc s dung
dy:
: bt ky ngi dng
: v danh ngi dng
@: xc thuc ngi s dung
Thay di ng dung ca chng ta d t chi cc user v danh truy cp vo tt c cc
proect,issue,ser chc nng lin quan l mt snap. Tt c chng ta phi lm l thay di '' k tu dc
bit ca ngi s dung mng gi trj k tu dc bit ca '@'. iu ny ch s cho php xc thuc ngi
dng truy cp vo cc hnh dng diu khin cc actionndex () v ActionView (). Tt c cc hnh dng
khc d doc han ch cho ngi s dung chng thuc.
Hy lm cho thay di ny trong tt c cc b diu khin ca chng ti. M tt c cc ba ca cc tp
tin sau dy: ProectController.php, ssueController.php, v cc tp tin serController.php v thay di
rule du tin trong cc quy tc kim sot truy cp doc:
array('allow', // allow only authenticated users to perform 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array('@'),
),
Sau khi thuc hin nhng thay di ny, ng dung s yu cu dng nhp trc khi truy
cp vo bt ky du n, vn d ca chng ti, hoc chc nng ca ngi s dung.
Chng ti vn cho php ngi dng truy cp v danh vi phng php hnh dng
SiteController lp hoc, chng ti lu gi bi v dy l ni hnh dng ca mnh dng
nhp.
VAB TR KBP SOST TRU% NHP
By gi chng ta d s dung cc b loc accessControl dn gin nh mt nt rng d han ch truy
cp cho ngi s dung chng thuc, chng ta cn d bin tp trung d dp ng mt s nhu cu kim
sot truy cp chi tit hn ca ng dung. Nh chng ta d d cp, ngi dng s dng vai tr nht
djnh trong mt du n. Du n s c ngi s dung ca ch s hu loai, nhng ngi c th doc
dng nh cc qun trj vin du n. Ho s doc cp tt c cc truy cp d thao tc cc du n. Du n
cng s c ngi s dung loai thnh vin, nhng ngi s doc cp mt s chc nng du n, nhng
mt tp hop con ca nhng ch s hu c th thuc hin. Cui cng, du n c th c ngi s dung
loai du doc, nhng ngi ch c th xem ni dung du n lin quan v khng lm thay di n bng bt
c cch no. dat doc diu ny loai m hnh truy cp dua trn vai tr ca mt ngi s dung,
chng ti ln lot cc tnh nng RBAC ca Yii.
RBAC l mt cch tip cn doc thnh lp trong h thng an ninh my tnh d qun l cc quyn truy
cp ca ngi s dung chng thuc. Trong ngn han, cc phng php tip cn RBAC xc djnh vai
tr trong mt ng dung. Quyn s dung d thuc hin mt s hoat dng cng doc xc djnh v sau d
kt hop vi vai tr. Ngi dng sau d doc giao cho mt vai tr v thng qua cc hip hi vai tr, c
doc cc diu khon quy djnh cho vai tr d. C rt nhiu ti liu c sn cho ngi doc t m v cc
khi nim RBAC ni chung v phng php tip cn. Mt ngun thng tin tt l Wikipedia:
http://en.wikipedia.org/wiki/Role-based_access_control. Chng ti s tp trung vo cc chi tit cu th
thuc hin Yii ca RBAC.
Thuc hin Yii ca RBAC
Yii thuc hin cc RBAC l dn gin, thanh ljch, v manh m. Tai nn tng
ca RBAC trong Yii l tng ca cc item y quyn. Cc item u quyn ch dn gin l mt su cho
php lm nhng vic trong ng dung. Cc diu khon c th doc phn loai nh vai tr, nhim vu,
hoc cc hoat dng, v nh vy, tao thnh mt h thng phn cp cho php. Vai tr c th bao gm
cc nhim vu (hoc cc vai tr khc), nhim vu c th bao gm cc hoat dng (hoc cc nhim vu
khc) v cc hoat dng l mc d cho php tit nht.
V du, trong ng dung TrackStar ca chng ti, chng ta cn mt vai tr kiu ca ch s hu. V vy,
chng ta s tao ra mt muc y quyn v vai tr ca loai vi tn ch s hu. Vai tr ny sau d c th
bao gm cc nhim vu nh mt "qun l ngi dng" v "qun l vn d". Nhng nhim vu ny c th
sau d tip tuc bao gm cc hoat dng nguyn t tao nn nhng cng vic ny. V du, cc nhim vu
qun l ngi s dung c th bao gm cc hoat dng tao ngi dng mi, ngi s dung chnh sa,
v xa ngi s dung. H thng cp bc ny cho php k tha cc diu khon nh vy d, da ra v
du ny, nu ngi dng doc phn cng vai tr ch s hu, ho tha hng doc su cho php d
thuc hin tao, chnh sa, v xa cc hoat dng ngi dng.
Djch vn bn hoc trang web
in hnh trong RBAC, ban ch djnh mt ngi s dung mt hoc nhiu vai tr v ngi s dung k
tha cc quyn d doc giao cho nhng vai tr. iu ny dng cho RBAC trong Yii l tt. Tuy nhin,
trong m hnh ny, chng ti c th kt hop ngi dng cho bt ky muc y quyn, khng ch nhng
kiu vai tr. iu ny cho php chng ta su linh hoat d kt hop mt su cho php ngi dng bt
ky mc d granularity. Nu chng ta ch mun cp cc hoat dng ngi s dung xa mt ngi dng
cu th, v khng cung cp cho ho tt c cc truy cp vo mt vai tr ch s hu s c,
chng ti ch dn gin l c th kt hop ngi s dung ny hoat dng nguyn t. iu ny lm cho
RBAC trong Yii rt linh hoat.
(U HNH rU`N L % rU%N
Trc khi chng ta c th thit lp mt h thng phn cp y quyn, phn cng ngi s dung cc
vai tr, v thuc hin kim tra su cho php truy cp, chng ta cn phi cu hnh ng dung cc thnh
phn y quyn qun l, authManager. Thnh phn ny c trch nhim lu tr cc d liu cho php v
qun l cc mi quan h gia quyn
cng nh cung cp cc phng php kim tra c hay khng mt ngi dng khng c quyn truy cp
d thuc hin mt hoat dng cu th. Yii cung cp hai loai ca cc nh qun l u quyn:
CPhpAuthManager v CDbAuthManager. CPhpAuthManager s dung mt tp tin script PHP d lu
tr cc d liu cho php. CDbAuthManager, nh ban c th don, lu tr d liu y quyn trong mt
c s d liu. AuthManager doc cu hnh nh mt thnh phn ng dung. Cu hnh qun l u
quyn bao gm dn gin
ch djnh ca hai loai s dung v sau d thit lp ban du gi trj ti sn lp
Nh chng ta d s dung mt c s d liu trong cc ng dung TrackStar, n lm cho cho chng ti
s dung CDbAuthManager. thuc hin cu hnh ny, m file cu hnh chnh
protected/config/main.php v thm dng sau vo component array:
'authManager'=>array(
'class'=>'CDbAuthManager',
'connectionD'=>'db',
),
Thit lp thnh phn ng dung mi c tn l authManager, quy djnh cu th thuc tnh
ca class l CdbAuthManager,thit lp connectionD l thnh phn kt ni ti CSDL
By gi chng ta c th truy cp ny bt c ni no
ng dung ca chng ta bng cch s dung Yii:: app () -> authManager.
T_O [`NO (SDL R[A( gL}u ..T-# 4\ Q ta*le 8E# tr#n/ data*a5e
(SDLm
Nh d d cp, lp CDbAuthManager s dung cc bng c s d liu d lu tr
cc d liu cho php. N l tiu chun loc d dc bit. l s d doc xc djnh
trong tp tin khun kh YiiRoot / framework / web / auth / schema.sql. N l mt s d
dn gin bao gm ba bng, Authtem, AuthtemChild, v AuthAssignment. Bng
Authtem gi thng tin xc djnh muc y quyn, d l vai tr, nhim vu hoc hoat dng.
Bng AuthtemChild nh cc mi quan h cha / con hnh thnh h thng phn cp ca
chng ta v cc item y quyn. Cui cng, bng AuthAssignment l mt bng lin kt
gi mi lin h gia mt ngi s dung v mt muc cho php. Cc bo co DDL c
bn cho cc bng nh sau:
(Lu dy l loc d mc djnh d doc tao sn khi thuc hin tao khung) d dng
chng ta thuc hin lun vi cc table d c sn.
T_O HW THqNO PHsN (P % rU%N R[A(
Sau khi thm cc bng d d cp _dev v _test cc c s d liu, chng ta cn phi ph bin chng
vi vai tr v quyn truy cp. Chng ta s lm diu ny bng cch s dung AP doc cung cp bi
authManager. gi cho moi th dn gin, chng ta s ch xc djnh vai tr v hoat dng c
bn.Chng ta s khng thit lp bt ky nhim vu RBAC no chnh thc cho by gi. Hnh di dy
hin thj h thng cp bc c bn chng ta xc djnh:
Ngi ch(Admin,Developer)
Create user (tao mi ngi s dung)
pdate user(cp nht ngi s dung)
Delete user(xa b ngi s dung)
pdate proect (cp nht du n)
Delete proect (xa du n)
(tha hng su cho php t c 2 thnh vin v dc gi).
(inherits permission from both member and reader)
AA
AA
2/
Thnh vin
Create ssue (Tao mi sn phm)
pdate ssue(Cp nht sn phm)
Delete ssue (Xa b sn phm)
(Tha hng quyn truy cp t dc gi).
AA
AA
2/
c gi
Read member (oc doc danh sch thnh vin)
Read Proect (oc doc cc du n)
Read ssue (oc doc cc sn phm).
Ch s hu c tt c cc quyn doc lit k, cng vi ho tha hng tt c cc quyn t thnh vin
v vai tr doc. Tng tu nh vy, thnh vin doc tha hng quyn truy cp t Reader. Nhng g
chng ti by gi cn phi lm l thit lp h thng phn cp trong ng dung cho php ny. Nh d
d cp trc d, cch tt nht d lm diu ny l d vit m d s dung cc AP authManager. V du,
cc m sau dy tao ra mt vai tr mi v hoat dng mi v sau d cho bit thm cc mi quan h
gia vai tr v su cho php:
auth%&&::appgm<6authPana/er
r#leauth<64reateR#leg?#"ner?m
auth<64reateOperat&#ng?4reatePr#ee4t?,?4reate a ne" pr#ee4t?m
r#le<6add(h&ldg?4reatePr#ee4t?m
Th=! 8a& tr R[A( 4h# 4J4 dd Jn
By gi chng ta c mt m hnh RBAC y quyn c bn tai ch, nhng nhng mi quan h ny p
dung di vi cc ng dung nh mt ton th. Nhu cu ca chng ti cho cc ng dung TrackStar l
hi phc tap hn. Chng ta cn xc djnh vai tr trong bi cnh ca du n, khng ch trn ton cu
qua cc ng dung. Chng ta cn phi cho php ngi s dung trong vai tr khc nhau, ty thuc vo
du n. V du, ngi dng c th doc trong vai tr ngi doc ca mt du n, thnh vin ca mt du
n th hai, v ch s hu ca mt s du n th ba. Ngi dng c th doc lin kt vi nhiu du n,
v vai tr m ho doc giao nhim vu cn phi doc cu th cho du n.
Cc m hnh RBAC ch nhm muc dch thit lp cc mi quan h gia cc vai tr v quyn truy cp.
N khng bit (v cng khng nn n) bt c diu g v cc du n TrackStar ca chng ti. dat
doc diu ny kch thc thm h thng phn cp y quyn ca chng ti, chng ti s tao ra mt
bng c s d liu ring bit d duy tr mi quan h gia ngi s dung, vai tr v mt du n. Cc
khi tao DDL cho bng ny l nh sau: phi vo (/webroot/framework/web/auth/schema-mysql.sql)
create table tbl_proect_user_role
(
proect_d NTEGER NOT NLL,
user_d NTEGER NOT NLL,
role VARCHAR(4) NOT NLL,
primary key (proect_d,user_d,role),
foreign key (proect_d) references tbl_proect (id),
foreign key (user_d) references tbl_user (id),
foreign key (role) references Authtem (name)
);
Th=! 4J4 vu9 t4 $&nh d#anh R[A(
Mc d cc bng c s d liu trc d s t chc cc thng tin c bn d tr li cc cu hi nh
liu ngi dng doc giao cho mt vai tr trong bi cnh ca mt du n cu th, chng ta vn cn h
thng phn cp y quyn RBAC ca chng ti d tr li cc cu hi lin quan dn user c quyn hay
khng thuc hin chc nng nht djnh. Mc d m hnh RBAC trong Yii khng thit lp v cc du n
TrackStar ca chng ti, n c mt tnh nng rt manh m m chng ta c th tn dung loi th. Khi
ban tao cc y quyn hoc phn cng mt muc cho ngi s dung, ban c th kt hop mt doan m
PHP s doc thuc hin goi Yii:: app() -> user-> checkAccess (). Khi djnh ngha, bit ca m ny phi
tr lai true trc khi user doc cp php.
Mt v du v tnh hu ch ca tnh nng ny l trong bi cnh ca cc ng dung cho php ngi s
dung d duy tr thng tin h s c nhn. Thng thng trong trng hop ny, cc ng dung mun
dm bo rng mt ngi s dung c su cho php cp nht thng tin h s c nhn ca ring mnh v
khng ai khc. Trong trng hop ny chng ta c th tao ra mt muc y quyn doc goi l
updateProfile, v sau d kt hop mt quy tc kinh doanh d kim tra xem D ca ngi s dung hin
tai cng ging nh D ngi s dung kt hop vi thng tin h s.
Trong trng hop ny, chng ta s kt hop mt quy tc kinh doanh vi su phn cng vai tr. Khi
chng ta ch djnh mt ngi s dung c mt vai tr cu th, chng ta cng s lin kt mt quy tc kinh
doanh kim tra cc mi quan h trong bi cnh ca du n. CheckAccess () phng php cng cho
php chng ta vot qua trong mt loat cc thng s b sung cho cc quy tc kinh doanh s dung d
thuc hin logic ca n. Chng ti s s dung diu ny d vot qua trong bi cnh du n hin tai d
cc quy tc kinh doanh c th goi mt phng thc trn lp cc du n AR d xc djnh c hay khng
s dung doc giao cho vai tr d trong du n d.
Nguyn tc kinh doanh chng ta s tao ra phn quyn cho tng vai tr khc nhau. V
du mt ngi dng sau khi doc phn quyn l owner (bn thn) c vai tr ging nh
sau:
$bizRule='return isset($params["proect"]) && $params["proect"]-
>issernRole('owner');';
Mt member(thnh vin) hay mt reader(dc gi) cng thuc hin tng tu.
Chng ti cng s phi hon thnh trong vn cnh du n khi chng ta goi checkAccess (). V vy, by
gi khi kim tra nu ngi dng d truy cp vo, v du, operation createssue ta s dung:
$params=array('proect'=>$proect);
if(Yii::app()->user->checkAccess('createssue',$params))

//tao ra truy cp vi issue logic

Thd4 h&jn !eth#d Pr#ee4t AR !1&


iu chnh Proect::associateserToRole() method d c cc thng s, v lun lun thm mt hng
(row) ti tbl_proect_user_role table:
public function associateserToRole($role, $userd)

$sql = "NSERT NTO tbl_proect_user_role (proect_d, user_d, role) VALES
(:proectd, :userd, :role)";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":proectd", $this->id, PDO::PARAM_NT);
$command->bindValue(":userd", $userd, PDO::PARAM_NT);
$command->bindValue(":role", $role, PDO::PARAM_STR);
return $command->execute;

dy chng ta dang s dung class Yii khung CDbCommand d thuc hin mt cu lnh SQL di vi
c s d liu. mt th hin ca CDbCommand l nhng g doc tr v t hm goi createCommand ()
kt ni c s d liu. Chng ta cng s dung cc gi trj rng buc ca tham s ca chng ta bng
cch s dung bindValue () phng php trn cc CDbCommand. y l mt thuc hnh tt c th lm
gim nguy c cc cuc tn cng SQL inection cng nh gip ci thin hiu sut ca cc cu lnh
SQL doc thuc hin nhiu ln.
Tip dn l : loai b mt mi lin h gia cc du n, ngi s dung v vai tr ca ngi s dung
trong du n.
public function removeserFromRole($role, $userd)

$sql = "DELETE FROM tbl_proect_user_role WHERE proect_d=:proectd AND user_d=:userd AND
role=:role";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":proectd", $this->id, PDO::PARAM_NT);
$command->bindValue(":userd", $userd, PDO::PARAM_NT);
$command->bindValue(":role", $role, PDO::PARAM_STR);
return $command->execute();

iu ny ch dn gin l xa cc hng t bng nh mi lin h gia


vai tr, ngi s dung v du n. N s tr lai s hng bj nh hng, trong d,
nu n thnh cng trong vic xa mt hng.
By gi chng ta cn phi thuc hin logic thch hop d xem nu mt lin kt tn tai. Thay di phng
thc ny trong cc class Proect AR
public function issernRole($role)

$sql = "SELECT role FROM tbl_proect_user_role WHERE proect_id=:proectd AND
user_id=:userd AND role=:role";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":proectd", $this->id, PDO::PARAM_NT);
$command->bindValue(":userd", Yii::app()->user->getd(), PDO::PARAM_NT);
$command->bindValue(":role", $role, PDO::PARAM_STR);
return $command->execute()==1 ? true : false;

TH~P NOTUB DNO tw Dd Jn gpr#ee4tm


Chng ta d c th tao doc ngi dng trong ng dung tuy nhin chng ta cha c cch
gn cho ngi dng mt du n cu th.V hn th na vai tr ca chng trong ng
dung.By gi chng ta tip cn vj tr ca RBAC chng ta cn xy mt hm mi.
Hon thnh cc muc dch chng ta s thuc hin sau dy:
Sb d0n/ ph}Zn/ phJp Fu t&=n : thm method public static
getserRoleOptions() t Proect model class tr lai danh sch hop l vai tr cu hnh
s dung qun l quyn truy cp getRoles() method. Chng ta s s dung ph bin mt
vai tr lua chon dropdown field trong form cho vic thm user ca mt du n (proect).
th=! !1& !eth#d pu*l&4 associateserToProect($user) t
proect model class d lin kt mt ngi s dung vi 1 du n.Thm dng dn ti
table tbl_proect_user_assignment d tao mt su lin kt gia user v proect.
Thm mi method public issernProect($user) t Proect
model class d quyt djnh nu ngi dng bt du lin kt vi proect. Chng ta s s
dung diu d trong mt quy tc ph hop t form d ra quyt djnh chng ta khng kch
hoat thm mt bn sao ngi dng d c trong du n.
THm mi mt form model class ProectserForm m rng t
CformModel cho input form model mi. Thm m hnh class form ny c 3 thuc tnh :
$username,$role,$proect .Cng thm cc quy tc ph hop d chc chn rng c
username v role l doc yu cu input field v ngi s dung s doc xc nhn l
khch hng hop l verify() class.
Verify() method s thuc hin :
Kch hoat tao mi ser AR class da vic tm kim user ni vi input username.
Nu kch hoat thnh cng n s tip tuc lin kt user vi proect s dung method mi
l :associateserToProect($user) . Nu khng c user doc tm thy n s tr v
thng bo li .
Thm views/proect/adduser.php trng by form cho vic thm user ti proect.Form
ny ch cn 2 trng l :username v role vi thuc tnh l dropdown danh sch.
THm mi controller action method goi l actionAdduser() t ProectController class
v chnh sa accessRules() method d xc thuc thnh vin (member). Action mi ny
x l cho biu din view mi doc hin thj t form v diu khin post quay lai khi form
doc submit.
THt( HBWN:
iu chnh lai Proect Model Class
/
Returns an array of available roles in which a user can be placed when being added to a proect
/
public static function getserRoleOptions()

return CHtml::listData(Yii::app()->authManager->getRoles(), 'name', 'name');

/
Makes an association between a user and a the proect
/
public function associateserToProect($user)

$sql = "NSERT NTO tbl_proect_user_assignment (proect_id, user_id) VALES (:proectd, :userd)";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":proectd", $this->id, PDO::PARAM_NT);
$command->bindValue(":userd", $user->id, PDO::PARAM_NT);
return $command->execute();

/
Determines whether or not a user is already part of a proect
/
public function issernProect($user)

$sql = "SELECT user_id FROM tbl_proect_user_assignment WHERE proect_id=:proectd AND
user_id=:userd";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":proectd", $this->id, PDO::PARAM_NT);
$command->bindValue(":userd", $user->id, PDO::PARAM_NT);
return $command->execute()==1 ? true : false;

Th=! !1& 7#r! !#del 4la55 Pr#ee4tU5er#r!


Ch doc dng ging nh form dng nhp chng ta dang tao mt form model class mi nh l mt
trung tm lu tr form input cc tham s v tp trung lai cc user hop l. y l mt class dn gin
k tha t Yii class Cform Model v c thuc tnh ging form input Chng ta cn ng cnh du n c
th thm user t proect :

<?php
/
ProectserForm class.
ProectserForm is the data structure for keeping
the form data related to adding an existing user to a proect. t is used by the 'Adduser' action of
'ProectController'.
/
class ProectserForm extends CFormModel

/
@var string username of the user being added to the proect
/
public $username;
/
@var string the role to which the user will be associated within the proect
/
public $role;
/
@var obect an instance of the Proect AR model class
/
public $proect;
/
Declares the validation rules.
The rules state that username and password are required,
and password needs to be authenticated using the verify() method
/
public function rules()

return array(
// username and password are required
array('username, role', 'required'),
// password needs to be authenticated
//array('username', 'verify'),
array('username', 'exist', 'className'=>'ser'),
array('username', 'verify'),
);

/
Authenticates the existence of the user in the system.
f valid, it will also make the association between the user, role and proect
This is the 'verify' validator as declared in rules().
/
public function verify($attribute,$params)

if(!$this->hasErrors()) // we only want to authenticate when no other input errors are present

$user = ser::model()->findByAttributes(array('username'=>$this->username));
if($this->proect->issernProect($user))

$this->addError('username','This user has already been added to the proect.');

else

$this->proect->associateserToProect($user);
$this->proect->associateserToRole($this->role, $user->id);
$auth = Yii::app()->authManager;
$bizRule='return isset($params["proect"]) && $params["proect"]->issernRole("'.$this->role.'");';
$auth->assign($this->role,$user->id, $bizRule);

Th=! !1& a4t&#n !eth#d tw pr#ee4t 4#ntr#ller


Chng ta cn mt controller action diu khin qu trnh ti cc yu cu d hin thj form thm user ti
mt proect .Thm actionAdduser() vo Proect Controller:
public function actionAdduser()

$form=new ProectserForm;
$proect = $this->loadModel();
// collect user input data
if(isset($_POST['ProectserForm']))

$form->attributes=$_POST['ProectserForm'];
$form->proect = $proect;
// validate user input and set a sucessfull flassh message if valid
if($form->validate())

%&&::appgm<6u5er<65etla5hg?5u44e55?,7#r!<6u5erna!e . ha5 *een added t# the pr#ee4t. m
$form=new ProectserForm;


// display the add user form
$users = ser::model()->findAll();
$usernames=array();
foreach($users as $user)

$usernames[]=$user->username;

$form->proect = $proect;
$this->render('adduser',array('model'=>$form, 'usernames'=>$usernames));

Mt thay di na ta phi lm vi ProectController class, d l thm action method mi d truy cp cc


quy tc c bn d user doc php truy cp vo action ny :
public function accessRules()

return array(
array('allow', // allow all users to perform 'index' and 'view' actions
?a4t&#n5?6arra9g?&nde3?,?8&e"?, ?addu5er?m,
'users'=>array('@'),
),

Th=! 7&le !1& tr#n/ 8&e" h&^n th+ #r!


Tao : protected/views/proect/adduser.php
<?php
$this->pageTitle=Yii::app()->name . ' - Add ser To Proect';
$this->breadcrumbs=array(
$model->proect->name=>array('view','id'=>$model->proect->id),
'Add ser',
);
$this->menu=array(
array('label'=>'Back To Proect', 'url'=>array('view','id'=>$model->proect->id)),
);
?>
<h1>Add ser To <?php echo $model->proect->name; ?></h1>
<?php if(Yii::app()->user->hasFlash('success')):?>
<div class="successMessage">
<?php echo Yii::app()->user->getFlash('success'); ?>
</div>
<?php endif; ?>
<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('CAutoComplete', array(
'model'=>$model,
'attribute'=>'username',
'data'=>$usernames,
'multiple'=>false,
'htmlOptions'=>array('size'=>2),
)); ?>
<?php echo $form->error($model,'username'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'role'); ?>
<?php echo $form->dropDownList($model,'role', Proect::getserRoleOptions()); ?>
<?php echo $form->error($model,'role'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Add ser'); ?>
</div>
<?php $this->endWidget(); ?>
</div>
KBP TRA P( n % rU%N
iu cui cng chng ta cn phi lm l kim tra thm u quyn cho cc chc nng khc nhau
.Trc d trong chng ny, chng ta d phc tho v sau d thuc hin h thng phn cp y quyn
RBAC cho cc vai tr khc nhau chng ta c. Tt c moi th doc dt ra d cho php hoc t chi
truy cp dn cc chc nng dua trn cc diu khon d doc cp cho ngi s dung trong cc du
n, vi mt ngoai l. Chng ti cha thuc hin kim tra truy cp cn thit khi c gng d yu cu chc
nng. Cc ng dung vn cn s dung b loc truy cp dn gin doc djnh ngha trn mi du n, pht
hnh v ngi s dung b diu khin ca chng ti. Chng ti s lm diu ny cho mt trong cc diu
khon ca chng ti v sau d d thuc hin cn lai nh mt bi tp cho ngi doc.
Tai Protected/views/proect/view.php thm vo sau danh sch menu ta c :
&7(Yii::app()->user->checkAccess('admin',arra9('proect'=>$model)))

$this->menu[] = arra9('label'=>'Add ser To Proect', 'url'=>arra9('adduser', 'id'=>$model->id));

Lu quyn truy cp admin ly t authitem table .Tt c cc member doc admin cp php du c th vo doc.
Tip theo d ngn chn vic user vo bng navigate ta thm hm kim tra vo actionAdduser() :
public function actionAdduser()

$proect = $this->loadModel();
&7g%&&::appgm<6u5er<64he4$A44e55g?4reateU5er?, arra9g?pr#ee4t?6pr#ee4tmmm

thr#" ne" (HttpE34ept&#ngRQ,?%#u are n#t auth#r&ed t# per<7#r! th&5 a4t&#n.?m

$form=new ProectserForm;
// collect user input data

(HTNO Th=! U5er (#!!ent gL& nhn u5erm.


Vic du tin ca cc tnh nng m chng ti s gii quyt l
kh nng cho ngi dng d lai kin v cc vn d ca du n.
Kh nng cho ngi dng tham gia vo mt cuc di thoai v cc vn d ca du n l mt phn quan
trong ca bt ky cng cu theo di vn d cung cp. Mt cch d dat doc diu ny l cho php ngi
dng d lai kin truc tip v cc vn d. Cc kin s hnh thnh mt cuc tr chuyn v vn d
ny v cung cp mt ngay lp tc, cng nh bi cnh ljch s d gip theo di tui tho ca bt ky vn
d no. Chng ti cng s s dung d chng minh s dung Yii vt dung v thit lp mt m hnh
portlet cung cp ni dung cho ngi s dung (d bit thm thng tin v Portlet, hy truy cp
http://en.wikipedia.org/wiki/Portlet).
KC H#-4h:
Khi mt ngi dng dang xem cc chi tit ca bt ky vn d du n, ho s c th doc tt c cc kin
trc dy d doc thm vo nh l cng nh tao ra mt nhn xt mi v vn d ny. Chng ti cng
mun
thm mt mnh nh ca ni dung, portlet, trang du n nim yt c hin thj
mt danh sch cc kin gn dy cn lai trn tt c cc vn d. y s l mt cch tt dep d cung
cp
mt ca s vo hoat dng ngi dng gn dy v cho php d dng truy cp dn cc vn d mi
nht c cuc tr chuyn hoat dng.
Sau dy l mt danh sch cc task (nhim vu ) m chng ta s cn phi hon thnh d dat doc
nhng muc tiu:
Thit k v tao ra mt bng c s d liu mi d h tro kin
Tao class AR Yii lin quan vi bng tho lun mi ca chng ti
Thm mt form truc tip dn trang chi tit sn phm d cho php ngi s dung
gi kin
Hin thj mt danh sch ca tt c cc kin lin kt vi mt sn phm truc tip trn cc trang chi
tit cc vn d.
Tn dung loi th ca widget Yii d hin thj mt danh sch cc kin gn dy nht trn trang danh
sch cc du n (proect).
T-# !N hnh
Tao table vo database :
CREATE TABLE tbl_comment
(
`id` NTEGER NOT NLL PRMARY KEY ATO_NCREMENT,
`content` TEXT NOT NLL,
`issue_id` NTEGER,
`create_time` DATETME,
`create_user_id` NTEGER,
`update_time` DATETME,
`update_user_id` NTEGER
)
Nhng li comment doc xc djnh trong tng trang cu th ta xc djnh tai trang sn phm vi
issue_id v n doc vit bi mt ngi s dung cu th nn tao create_user_id v xc djnh cc quan
h kha chnh kha ngoai.
ALTER TABLE `tbl_comment` ADD CONSTRANT `FK_comment_issue` FOREGN KEY
(`issue_id`) REFERENCES `tbl_issue` (`id`);
ALTER TABLE `tbl_comment` ADD CONSTRANT `FK_comment_author` FOREGN KEY
(`create_user_id`) REFERENCES `tbl_user` (`id`);
Xy dung m hnh trong Gii / Model Generator v goi class comment.->click preview->generate.
khi chng ta d tao ra model class cho comment , chng ta s cn thm mt cch r rng mi quan
h t class model ssue (sn phm) cho comment. Chng ta cng s thm mt mi quan h nh l
mt truy vn thng k d d dng ly s long cc kin lin kt
vi mt vn d doc da ra (ging nh chng ta d lm trong class Proect cho ssue.).
iu chnh ssue::relation() (quan h):
public function relations()

return array(
'requester' => array(self::BELONGS_TO, 'ser', 'requester_id'),
'owner' => array(self::BELONGS_TO, 'ser', 'owner_id'),
'proect' => array(self::BELONGS_TO, 'Proect', 'proect_id'),
?4#!!ent5? 6 arra9g5el7::HASfPAN%, ?(#!!ent?, ?&55uef&d?m,
?4#!!ent(#unt? 6 arra9g5el7::STAT, ?(#!!ent?, ?&55uef&d?m,
);

Ngoi ra, chng ta cn phi thay di class Comment AR doc m rng ty chnh t
TrackStarActiveRecord class base , d thun loi chng ta dt trong beforeValidate () method . n
gin ch cn thay di du ca djnh ngha lp nh vy:
<?php
/
This is the model class for table "tbl_comment".
/
4la55 (#!!ent e3tend5 Tra4$StarA4t&8eRe4#rd g4n/ 4] th^ lE (he4$U5erA4t&8eRe4#rdm .

Chng ta s thay di nh d cc djnh ngha trong Comment::relation() method. Cc thuc tnh


quan h doc dt tn cho chng ta khi class model doc tao ra. Chng ta hy thay di mt trong
nhng tn createser l author , v diu ny lin quan dn ngi s dung khng dai din cho tc gi
ca bnh lun. y ch l mt su thay di ng ngha, nhng s gip d
d lm cho m ca chng ti d dng hn d doc v hiu. Thay di method trong Comment::relation:
/
@return array relational rules.
/
public function relations()

// NOTE: you may need to adust the relation name and the related
// class name for the relations automatically generated below.
return array(
?auth#r? 6 arra9g5el7::[ELONOSfTO, ?U5er?, ?4reatefu5erf&d?m,
'issue' => array(self::BELONGS_TO, 'ssue', 'issue_id'),
);

(reat&n/ the (#!!ent (RUD


Vo gii thuc hin vi comment v click preview->generate.
Sau khi chng ta dng nhp , chng ta s c th xem cc li comment trnh autogenerated thng qua
RL sau:
http://l#4alh#5t/tra4$5tar/&nde3.php@r4#!!ent/4reate
Nh chng ta d thy nhiu ln trc dy, chng ta thng phi thuc hin diu chnh m
autogenerated scaffolding d dp ng cc yu cu cu th ca ng dung. i vi mt, hnh thc
autogenerated ca chng ti d tao ra mt nhn xt mi c mt trng du vo cho mi ct duy nht
doc xc djnh trong bng c s d liu tbl_comment.
Chng ta khng thuc su mun tt c cc trng DL hin ra trong biu mu. Trong thuc t, chng ta
cn lm dn gin ha form ny ch c mt lnh vuc du vo duy nht cho ni dung bnh lun (content
comment) . Hn na, chng ta khng mun ngi dng truy cp cc hnh thc thng qua cc RL
trn, nhng thay v ch cn truy cp vo trang chi tit sn phm . Ngi dng s thm kin trn
cng mt trang m ho dang xem thng tin chi tit v sn phm ny. Chng ta cn xy dung hng
ti mt ci g d tng tu nh nhng g doc m t trong cc nh chup mn hnh sau dy:
thuc hin doc diu ny, ta s diu chnh ssue controller class d x l cc comment cng
nh thay di chi tit sn phm hin thj cc li comment hin c v tao comment mi t
form.Ngoi ra li comment s ch doc tao trong vn cnh ca sn phm chng ta s thm
mi mt method vo class model ssue d tao mi commment.
Th=! !xt l& 4#!!ent
Thm method trong ssue AR (model)
/
Adds a comment to this issue
/
public function addComment($comment)

$comment->issue_id=$this->id;
return $comment->save();

Phng php ny dm bo cc thit lp ph hop ca cc D vn d bnh lun trc khi lu cc bnh


lun mi. Khi dng th nghim mt ln na d dm bo n ngay by gi di.
Chng ta mun tao comment form d hin thj v gi d liu tr lai ssueController::actionView()
method , chng ta s cn diu chnh method. Chng ta cng thm mi method protected diu khin
form POST request. u tin, chnh lai actionView() method :
public function actionView()

&55ueth&5<6l#adP#delgm
4#!!entth&5<64reate(#!!entg&55uem
$this->render('view',array(
'model'=>$issue,
'comment?=>$comment,
));

Tao function createComment:


protected function createComment($issue)

$comment=new Comment;
if(isset($_POST['Comment']))

$comment->attributes=$_POST['Comment'];
if($issue->addComment($comment))

Yii::app()->user->setFlash('commentSubmitted',"Your comment has been added." );
$this->refresh();


return $comment;

createComment () chju trch nhim x l cc yu cu POST d tao ra mt bnh lun mi dua trn du
vo ngi s dung. Nu comment tao ra thnh cng, trang s doc lm mi hin thj cc nhn xt
mi doc tao ra. Cc thay di doc thuc hin d ssueController:: ActionView () chju trch nhim cho
cuc goi phng php mi ny v cng c th cho n cc trng hop nhn xt mi d xem.
H&^n th+ #r!
By gi ta cn chnh lai view. Ta phi tao file view mi render hin thj nhng li comment v
comment input form.Tao file _comments.php vo protected/view/issue/ :
<?php foreach($comments as $comment): ?>
<div class="comment">
<div class="author">
<?php echo $comment->author->username; ?>:
</div>
<div class="time">
on <?php echo date('F , 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; ?>
M protected/view/issue/view.php thm vo cui 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; ?>
<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>
M protected/views/comment/_form.php v chnh sa :
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'comment-form',
'enableAaxValidation'=>false,
)); ?>
<p class="note">Fields with <span class="required"></span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'content'); ?>
<?php echo $form->textArea($model,'content',array('rows'=>, 'cols'=>0)); ?>
<?php echo $form->error($model,'content'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>
<?php $this->endWidget(); ?>
</div>
T-# !xt 4#!!ent5 "&d/et /n Fc9.
By gi chng ta c kh nng d lai kin trong sn phm, chng ta s tp trung vo muc tiu th 2.
Chng ta mun d hin thj cho ngi dng mt danh sch ca tt c cc kin gn dy d doc
dng trong cc trang sn phm khc nhau trn tt c cc du n. iu ny s cung cp lin kt tt
cc hoat dng truyn thng ngi dng trong ng dung. Chng ti cng mun xy dung khi nh ca
ni dung ny trong mt cch m s cho php ti s dung tai cc dja dim khc nhau trong trang web.
iu ny l rt nhiu trong phong cch ca cc ng dung cng thng tin web nh din dn tin tc,
cc ng dung bo co thi tit v cc trang web nh Yahoo v iGoogle. Nhng doan nh ca ni
dung thng doc goi l portlet, v dy l l do tai sao chng ti goi xy dung mt kin trc portlet
du lp di lp lai ny. Mt ln na, ban c th tham kho
http://en.wikipedia.org/wiki/Portlet cho bit thm thng tin v ch d ny
O&1& th&ju (>&d/et
Chng ti s s dung mt widget Yii d xy dung mt kin gn dy ca portlet v hin thj n trn
trang chnh ca du n chi tit d chng ta c th thy hoat dng ca bnh lun trn tt c cc vn d
lin quan dn du n. chng minh su d dng ti s dung, chng ti s mang n mt bc xa hn
v cng c th hin thj mt danh sch cc du n cu th kin v trang chi tit du n.
Tao hm :Tm comment gn dy: Trong Comment::findRecentComment.
public static function findRecentComments($limit=10, $proectd=null)

if($proectd != null)

return self::model()->with(array(
'issue'=>array('condition'=>'proect_id='.$proectd)))->findAll(array(
'order'=>'t.create_time DESC',
'limit'=>$limit,
));

else

//get all comments across all proects
return self::model()->with('issue')->findAll(array(
'order'=>'t.create_time DESC',
'limit'=>$limit,
));

Method tr n c 2 tham s $limit d han ch s long, $proectd xc djnh id du n m cc comment nm


trong d. Tham s th 2 s gip cho widget s dung hin thj tt c comment trong 1 du n. V vy, nu id
du vo du n d doc ch djnh, n han ch cc kt qu tr v ch nhng kin lin kt vi du n,
nu khng, tt c cc kin trn tt c cc cc du n doc tr lai.
Th=! 4h& t&Ct 8 4J4 tru9 8ln AR vuan hj tr#n/ %&&
Hai truy vn trn quan h AR mt cht mi cho chng ti. Chng ti d khng doc s dung
rt nhiu cc ty chon ny trong cc truy vn trc d ca chng ti. Trc dy, chng ti d doc s
dung phng php dn gin nht d thuc hin cc truy vn quan h:
1. Ti instance AR.
2. Truy cp thuc tnh quan h doc djnh ngha trong method relation ().
V du, nu chng ta mun truy vn cho tt c cc sn phm (ssue) lin quan ti du n(Proect) c id
1, chng ti s thuc hin hai dng m sau dy:
// retr&e8e the pr#ee4t "h#5e BD &5 '
pr#ee4tPr#ee4t::!#delgm<67&nd[9P$g'm
// retr&e8e the pr#ee4t?5 &55ue5: a relat&#nal vuer9 &5 a4tuall9 *e&n/ per7#r!ed *eh&nd the 54ene5 here
&55ue5pr#ee4t<6&55ue5
y l mt phng thc hi chm tai v n cn ch c m id hop l mi thuc hin.Nu nh c qu nhiu du n
cn ti tng ng vi qu nhiu id cn nap diu ny s gy ra vic chm tr. V th chng ta cn phi dng gii
php tt hn.
Eager Loading l mt gii php truy xut vo quan h ca AR ci dt cng mt time nh trong trng hop AR
chnh doc yu cu. iu ny doc dng vi with() method kt hop c find() hoc findAll() method cho AR
query. Ta thuc hin nh sau :
//retrieve all proect AR instances along with their associated issue AR instances
$proects = Proect::model()->with('issues')->findAll();
Trong Comment::findRecentComments() ta c :
return 5el7::model()->with('issue')->findAll(arra9('order'=>'t.create_time DESC','limit'=>$limit,));
chng ta ch djnh t.create_time cho bit ta mun s dung ct ca bng chnh. Nu chng ta mun thay
v d cc ct create_time issue , chng ti s thay di, truy vn th hai v du, nh sau:
return Comment::model()->with('issue')->findAll(array(
'order?=>?issue.create_time DESC?,
'limit'=>$limit,
));
hon thnh nhng g ta dang thuc hin ta m ssueController::loadModel() method :
public function loadModel($withComments=false)

if($this->_model===null)

if(isset($_GET['id']))

if($withComments)

$this->_model=ssue::model()->with(array( 'comments'=>array('with'=>'author')))
->findbyPk($_GET['id']);

else

$this->_model=ssue::model()->findbyPk($_GET['id']);


if($this->_model===null)
throw new CHttpException(404,'The requested page does not exist.');

return $this->_model;

Thay di ssueController::actionView(), as such:


public function actionView()

$issue=$this->loadModel(true)
Thd4 h&jn t-# >&d/et
By gi chng ta d sn sng d tao ra cc widget mi ca chng ti s dung phng php
mi ca chng ti d hin thj comment recent ca chng ti.
Nh chng ta d d cp mt widget trong Yii l mt class extend t CWidget framework . Chng ta
s thm widget mi ca chng ti d doc protected / component / , nh cc ni dung ca th muc
ny d doc quy djnh trong cc file cu hnh chnh d tu dng ti v ng dung. Bng cch ny, chng
ti s khng phi nhp khu mt cch r rng lp mi ln chng ti mun s dung n. Chng ta s
dt tn RecentComments widget ca chng ti, v vy chng ti cn thm mt tp tin php cng tn th
muc. Thm djnh ngha class RecentComment.php dn tp tin mi doc tao ra nh sau:
protected / component / RecentComments.php
<?php
/
RecentComments is a Yii widget used to display a list of recent comments
/
class RecentComments extends CWidget

private $_comments;
public $displayLimit = ;
public $proectd = null;
public function init()

$this->_comments = Comment::model() ->findRecentComments($this->displayLimit, $this->proectd);

public function getRecentComments()

return $this->_comments;

public function run()

// this method is called by CController::endWidget()
$this->render('recentComments');

Cng vic chnh khi tao ra mt widget mi l d ghi d ln init () v run () lp c s. (method ) init khi
tao cc widget v doc goi l thuc tnh ca n d doc khi tao. Phng thc run () thuc hin cc
widget. Trong trng hop ny, chng ti ch cn khi tao cc widget bng cch yu cu kin gn
dy dua trn $ displayLimit v proectd thuc tnh. Thuc hin ca widget ch dn gin l lm cho tp
tin xem c lin quan dn viewfile , m chng ta vn cha tao ra. cc tp tin xem, theo quy c, doc
dt trong view / directly trong cng mt th muc widget c tr, v c tn tng tu nh widget, nhng
bt du vi mt l th ch thng. Tao tp tin trong protecd/component / views /
recentComments.php.
<ul>
<?php foreach($this->getRecentComments() as $comment): ?>
<div class="author">
<?php echo $comment->author->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>
M protected/views/proect/index.php. Thm vo cui trang
<?php $this->widget('RecentComments'); ?>
O&1& th&ju (p#rtlet:
CPortlet l mt phn ca zii, m rng lp th vin chnh thc dng gi di km vi Yii. N cung cp
mt lp c s tt dep cho tt c cc vt dung theo phong cch portlet. N s cho php chng ta lm
cho mt tiu d tt dep cng nh ph hop HTML dnh du, v vy tt c cc portlet trn cc ng dung
c th d dng theo kiu mt cch tng tu. Mt khi chng ta c mt tin ch lm cho ni dung (nh
phu tng RecentComments ca chng ti), chng ti ch dn gin l c th s dung ni dung tr lai
ca cc phu tng ca chng ti nh ni dung cho CPortlet, m bn thn n l mt tin ch, nh n
cng m rng t CWidget. Chng ta c th lm diu ny bng cch dt cuc goi ca chng ti d cc
widget RecentComments gia mt beginWidget () v mt endWiget () goi cho CPortlet, nh vy:Thay
th vo protected/proect/index
@php th&5<6*e/&n>&d/etg?&&."&d/et5.(P#rtlet?, arra9g
?t&tle?6?Re4ent (#!!ent5?,
mm
th&5<6"&d/etg?Re4ent(#!!ent5?m
th&5<6end>&d/etgm @6
Thm widget vo trang khc :
Add the following to the bottom of the protected/views/proect/view.php file:
<?php $this->beginWidget('zii.widgets.CPortlet', array(
'title'=>'Recent Proect Comments',
));
$this->widget('RecentComments', array('proectd'=>$model->id));
$this->endWidget(); ?>
(HTNO ': Th=! !xt RSS "e* eed
Ci Zend_Framework down: http://framework.zend.com/download/latest. Ta ch cn s dung gi nh
(minimal).
Gii nn v ly Zend t library : library/zend/feed.
Chp vo Yii FM vi dng dn ; protected/vendors/Zend/Feed.php
S dung Zend_Feed
Open up CommentController.php and add the following public method:
public function actionFeed()

if(isset($_GET['pid'])) $proectd = intval($_GET['pid']);
else $proectd = null;
$comments = Comment::model()->findRecentComments(20, $proectd);
//convert from an array of comment AR class instances to an name=>value array for Zend
$entries=array();
foreach($comments as $comment)

$entries[]=array(
'title'=>$comment->issue->name,
'link'=>CHtml::encode($this->createAbsoluterl('issue/view',array('id'=>$comment->issue->id))),
'description'=> $comment->author->username . ' says:<br>' . $comment->content,
'lastpdate'=>strtotime($comment->create_time),
'author'=>$comment->author->username,
);

//now use the Zend Feed class to generate the Feed
// generate and render RSS feed
$feed=Zend_Feed::importArray(array(
'title' => 'Trackstar Proect Comments Feed',
'link' => $this->createrl(''),
'charset' => 'TF-',
'entries' => $entries,
), 'rss');
$feed->send();

Ban c th nh rng phng php ny tr v mt mng cc trng hop Bnh lun lp AR. Chng ti
lp qua mng ny quay tr lai v chuyn di d liu vo djnh dang du kin bi cc thnh phn
Zend_Feed. Zend_Feed du kin s mt mng dn gin c cha cc yu t l mng c cha cc d
liu cho mi muc nhn xt. Mi nhp c nhn l mt mng kt hop dn gin ca tn => cp gi trj.
thuc hin theo quy djnh vi cc djnh dang RSS cu th, mi muc c nhn ca chng ti ti thiu phi
c tiu d, lin kt, v m t. Chng ti cng d b sung thm hai lnh vuc ty chon, mt goi l
lastpdate, Zend_Feed djch lnh vuc RSS pubDate, v mt d xc djnh tc gi.
C thm mt vi phng php gip d chng ti tn dung loi th d c doc cc d liu
trong djnh dang dng. i vi mt, chng ti s dung createAbsoluterl ca cc b diu khin ()
phng php, ch khng phi ch createrl () d tao ra mt RL dy d.
Tao /vendors/Zend/Feed.php
T_O URL Thcn th&jn 81& n/}& dXn/.
S dung rlManager:
oc xy dung trong qun l RL trong Yii l mt thnh phn ng dung c th doc cu hnh trong
tp tin doc bo v / config / main.php. Hy m tp tin d v thm mt tuyn b thnh phn RL mi
qun l mng cc thnh phn:
'urlManager' => array (
'urlFormat' => 'dng dn',
),
Min l chng ta gn b vi urlManager n mc djnh v tn, chng ti khng cn phi xc djnh lp
ca cc thnh phn bi v n l trc khi k khai d doc CrlManager.php trong lp khun kh
CWebApplication.php.
RL ca chng ta dang tm kim tt hn, nhng chng ta vn c kjch bn nhp cnh, index.php, quy
djnh v chng ta khng c th ni thm hu t. Xml vo cui RL cp d liu ca chng ti. V vy,
chng ta s n index.php nh l mt phn ca RL, v cng c th thit lp cc yu cu djnh tuyn
d hiu rng mt yu cu cho commentfeed.xml thuc su c ngha l mt yu cu cho actionFeed ()
trong lp CommentController.php. Chng ta hy thuc su gii quyt vn d th hai du tin.
(lu Hnh 4J4 vu9 t4 F+nh tu9Cn gr#utem.
Qun l RL Yii cho php chng ta xc djnh quy tc d xc djnh RL doc phn tch c php v tao
ra. Mt nguyn tc bao gm xc djnh mt tuyn dng v mt m hnh. M hnh ny doc s dung
d ph hop vi trn mt phn thng tin dng dn RL d xc djnh quy tc doc s dung d phn
tch hoc tao ra cc RL. Cc m hnh c th cha cc thng s doc dt tn bng cch s dung cc
ParamName c php: RegExp. Khi phn tch mt RL, mt quy tc ph hop s trch xut cc thng
s ny doc dt tn t cc thng tin dng dn v dt chng vo bin $ _GET. Khi mt RL doc
tao ra bi cc ng dung, mt quy tc ph hop s trch xut cc thng s doc dt tn t $ _GET v
dt chng vo phn thng tin dng dn RL doc tao ra. Nu mt m hnh kt thc vi'/', n c
ngha l cc tham s thm GET c th doc ni thm vo phn thng tin dng dn ca RL.
Ta djnh tuyn vo rlManager nh sau:
'urlManager'=>arra9(
'urlFormat'=>'path',
'rules'=>arra9(
'<controller:\w>/<id:\d>'=>'<controller>/view',
'<controller:\w>/<action:\w>/<id:\d>'=>'<controller>/<action>',
'<controller:\w>/<action:\w>'=>'<controller>/<action>',
),
),
L#-& * 4J4 54r&pt tw URL
[c9 /& 4h{n/ ta 4h 4n l#-& * &nde3.php tw 4J4 URL. n&u nE9 F}I4 thd4 h&jn the# ha&
*}14:
'. Tha9 F& 4lu hnh !J9 4h "e* F^ F+nh tu9Cn l-& tlt 4\ 4J4 9=u 4u $hNn/ t}Zn/ .n/ 81&
tp t&n h#G4 th} !04 h&jn 4] F^ &nde3.php.
,. Th&Ct lp thux4 tMnh 5h#"S4r&ptNa!e 4a UrlPana/er 7al5e.
Tao htdocs/webroot/.htaccess :
Options FollowSymLinks
ndexgnore /
RewriteEngine on
if a directory or a file exists, use it directly
RewriteCond %REQEST_FLENAME !-f
RewriteCond %REQEST_FLENAME !-d
otherwise forward it to index.php
RewriteRule . index.php
(HTNO '' :LE! th&Ct $Cgde5&/nm, trnh *E9gla9#utm,/&a#
d&jngthe!e5m tLt hZn
Tao mt ch d mi cho cc ng dung ca chng ti bng cch tao ra b tr mi, CSS v cc tp tin
ti sn khc d cung cp cc ng dung vi mt thit k pha trc kt thc mi
S dung cc tnh nng quc t v ni dja ho ca Yii djch
mt phn ca ng dung ca chng ti dn mt ngn ng mi
Load CSS:
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baserl; ?>/css/main.css"
/>
Tiu d trang : <title><?php echo CHtml::encode($this->pageTitle); ?></title>
(reat&n/ a *read4ru!* na8&/at&#n
Ta c th xem v du ny:
<?php
$this->breadcrumbs=array(
'Proects'=>array('index'),
$model->name=>array('view','id'=>$model->id),
'pdate',
);
(hu9^n d+4h "e* 5an/ !xt n/Nn n/i $hJ4
N] 4un/ 4lp di l&ju !&n F+a ph}Zn/ 4h# /n nh} !y& n/Nn n/i 8E $hu 8d4
N] 4un/ 4lp 4J4 d+4h 80 hH trI tr#n/ *\n d+4h 4a t&n nhn 8n *\n 8E tp t&n
N] 4un/ 4lp 4h# !&n F+a ph}Zn/ ph0 thux4 8E# n/E9 8E th& /&an F+nh d-n/
N] 4un/ 4lp 4h# !&n F+a ph}Zn/ ph0 thux4 8E# F+nh d-n/ 5L
n+nh n/h-a 8Xn/ !&ngl#4atem 8E n/Nn n/iglan/ua/em.
Min dja phng dng d ch mt tp hop cc thng s d xc djnh ngn ng ca ngi s dung,
quc gia, v s thch giao din ngi s dung no khc c th c lin quan dn vj tr ca ngi dng.
N thng doc xc djnh bi mt D tng hop bao gm mt djnh danh ngn ng v nhn dang mt
khu vuc. V du, mt D min dja phng ca vi l vit tt ca ngn ng ting Anh v khu vuc ca Hoa
Ky. thng nht, tt c cc D min dja phng trong Yii doc chun ha vi djnh dang hoc
LanguageD hoc LanguageD_RegionD trong trng hop thp hn (v du, en hoc en_us).
Yii, min dja phng d liu doc biu din nh l mt th hin ca lp CLocale, mt lp con ca
chng. N cung cp thng tin min dja phng cu th bao gm c biu tong tin t v s tin t, s,
ngy, v cc djnh dang thi gian, tn lin quan dn ngy thng nh thng, ngy trong tun, v nh
vy. Vi mt D min dja phng, ngi ta c th c doc th hin tng ng CLocal bng cch s
dung cc CLocal phng php tnh:: getnstance ($ localeD) hoc s dung ng dung. Cc m v du
sau dy tao ra mt th hin mi dua trn djnh danh dja phng en_us bng cch s dung cc thnh
phn ng dung:
Yii::app()->getLocale('vi_vn');
Yii di km vi d liu min dja phng cho gn nh moi ngn ng v khu vuc. D liu dn t cc
Repository Locale d liu chung (CLDR) (http://cldr.unicode.org/) v doc lu tr trong cc tp tin
doc dt tn theo id min dja phng ca mnh trong Yii framework framework/i1n/data /. V vy,
trong v du trn tao ra mt th hin mi CLocale, d liu doc s dung d da vo cc thuc tnh t
framework/i1n/data/en_us.php tp tin. Nu ban nhn di th muc ny, ban s thy cc tp tin d
liu cho cc ngn ng khc v khu vuc.
THt( HBWN Do(H NON NOV
Thuc hin djch mt thng dip :
t(string $category, string $message, array $params=array ( ), string $source=NLL, string
$language=NLL)
CPhpMessageSource: y l ngun thng dip mc djnh. Cc bn djch tin nhn doc lu tr nh
cc cp gi trj quan trong trong mt mng PHP. Cc thng bo ban du l cha kha v tin nhn djch
l gi trj. Mi mng dai din cho cc bn djch cho mt th loai dc bit ca tin nhn v
lu tr trong mt tp tin kjch bn ring bit ca PHP c tn l tn loai.
Cc file PHP djch cho cng mt ngn ng doc lu tr theo
cng mt th muc c tn l D min dja phng. Tt c cc th muc ny du nm trong
th muc theo quy djnh ca basePath.
CGettextMessageSource: Cc bn djch tin nhn doc lu tr nh cc tp tin gettext GN.
CDbMessageSource: Cc bn djch tin nhn doc lu tr trong cc bng c s d liu.
Mt ngun message doc nap nh mt thnh phn ng dung. Yii trc khi nhn dang mt thnh
phn ng dung c tn message d lu tr cc tin nhn doc s dung trong mt ng dung s dung.
Theo mc djnh, cc loai ngun tin nhn ny l CPhpMessageSource v con dng c s d lu tr
cc tp tin bn djch PHP l :protected/messages
.
Say dy l mt v du s di mt chng dng di d gip mang lai tt c nhng diu ny vi nhau.
Hy djch nhn trng biu mu dng nhp ca chng ti vo mt ngn ng gi tng chng ta s goi
VietNam. VietNam doc vit bng cch ly mt t hoc cum t ting Anh v vit n theo chiu ngoc
lai. V vy, dy l bn djch field nhn VietNam
.
En/l&5h V&etNa!
sername TenDangNhap
Password MatKhau
Remember me next time Ghi nho tai khoan
Chng ti s s dung vic thuc hin CPhpMessageSource mc djnh d nh djch tin nhn ca chng
ti. V vy, diu du tin chng ta cn lm l tao ra mt tp tin PHP c cha cc bn djch ca chng
ti. Chng ta s tao D local l 'vi' v chng ta s goi l "mc djnh" danh muc cho by gi. V vy,
chng ta cn tao mt file mi trong th muc base message theo djnh dang / localeD
CategoryName.php /. V vy, di vi v du ny, chng ta cn d tao ra mt tp tin mi doc dt vo /
protected / languages / vi / default.php, v sau d thm cc mng djch thut sau dy:
<?php
return array(
'sername' => 'Emanresu',
'Password' => 'Drowssap',
'Remember me next time' => 'Emit txen em rebmemer',
);
iu tip theo chng ta cn lm d thit lp chuyn ngn ng sang ting Vit Nam.Ta c th lm diu
ny trong file cu hnh,do d n s tc dng ti ton b trang web.Tuy nhin chng ta ch c bn djch
mu ca chng ta,ta ch cn thit lp n trong SiteController::actionLogin() method,do d n ch p
dung khi render cho login().M tp tin v thit lp ngn ng bt du vi method:
public function actionLogin()

Yii::app()->language = 'vi';
By gi, diu cui cng chng ta cn lm l thuc hin goi ti Yii:: t () d nhng trng (field) label
doc gi thng qua bn djch. Nhng field label vuc doc quy djnh tai cc LoginForm::
attributeLabels () phng php. Thay th phng php ton b nh sau:
/
Declares attribute labels.
/
public function attributeLabels()

return array(
'rememberMe'=>Yii::t('default','Remember me next time'),
'username'=>Yii::t('default', 'sername'),
'password'=>Yii::t('default', 'Password'),
);

Thd4 h&jn d+4h tp t&n:


Yii cng cung cp kh nng s dung cc tp tin khc nhau dua trn Local D. Djch tp tin doc thuc
hin bng cch goi method CApplication:: findLocalizedFile (). Phng php ny c trong dng dn
vo mt tp tin v phng php ny s tm kim mt tp tin c cng tn, nhng di mt th muc
cng tn vi D min dja phng muc tiu quy djnh hoc nh l du vo cho php phng php,
hoc nhng g doc quy djnh cu th trong ng dung cu hnh.
Tt c chng ta thuc su cn phi lm l tao ra cc tp tin bn djch thch hop. Chng ti s gn b vi
djch di hnh thc dng nhp. V vy, tao ra mt tp tin views mi / protected / views / site / vi /
login.php v thm cc ni dung sau d doc djch sang Ting vit:
<?php
$this->pageTitle='Nigol';
$this->breadcrumbs=array(
'Dang nhap',
);
?>
<h1>Dang nhap</h1>
<p>Vui long dien day du thong tin:</p>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'login-form', 'enableAaxValidation'=>true,
)); ?>
<p class="note">Vui long dien day du thong tin voi dau <span class="required"></span> yeu cau.</p>
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
<?php echo $form->error($model,'username'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password'); ?>
<?php echo $form->error($model,'password'); ?>
<p class="hint">
<tt>nimda\nimda</tt> ro <tt>omed\omed</tt> htiw nigol yam uoy :tnih
</p>
</div>
<div class="row rememberMe">
<?php echo $form->checkBox($model,'rememberMe'); ?>
<?php echo $form->label($model,'rememberMe'); ?>
<?php echo $form->error($model,'rememberMe'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Nigol'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
Th=! t&n nhn ! rxn/ tw hj th]n/
T-# *\n/ data*a5e
Ban tao mt bng mi nh sau ch a thng tin tin nhn t h thng:
(REATE TA[LE t*lf595f!e55a/e
g
&d BNTEOER NOT NULL PRBPAR% KE% AUTOfBN(REPENT,
!e55a/e TEDT NOT NULL,
4reateft&!e DATETBPE,
4reatefu5erf&d BNTEOER,
updateft&!e DATETBPE,
updatefu5erf&d BNTEOER
m
T-# !#dle (RUD 54a77#ld&n/
Sau khi d c bng database ban thm vo sql d tao bng v thuc hin bi , the Gii code generator. Chng ta bt
du s dung P#del Oenerat#r option d tao cc class model v sau d (rud Oenerat#r tao c bn scaffolding
nhanh chng vi model. Go ahead and navigate to the Gii tool form for creating a new model. This time, as we are
doing this within the context of a module, we need to explicitly specify the model path. Fill out the form with the values
depicted as shown in the following screenshot (though, of course, your (#de Te!plate path value should be specific
to your local setup):
Tao CRD scaffolding in the same way. Again, the only real difference between what we have done previously and
what we are doing now is our specification that the location of the model class is in the admin module. After choosing
the (rud Oenerat#r option from the Gii tool, fill out the P#del (la55 and (#ntr#ller BD form fields as shown in the
following screenshot: (Nhn hnh v dng lo v my t ting anh, k nh hng dn vic hoc du, li ko mun djch
=.=, dng CRD chn roi cn ko lm dc th b tay =.=)
This alerts the tool to the fact that our model class is under the admin module and that our controller class, as well as
all other files related to this code generation should be placed within the admin module as well.
Hon thnh ban click vo Pre8&e" button, v sau d l Oenerate. The following is a list of all of the files that are
created by this action:
TH=! l&n$ 8E# hE! !1&
M file cha main menu chnh t, /protected/modules/admin/views/layouts/main.php, v thm doan
array sau vo menu widget:
array('label'=>'System Messages', 'url'=>array('/admin/sysMessage/index')),
1. copy 2 bng layout t ngoi main application ti module: l: copy
/protected/views/layouts/column2.php ti /protected/modules/admin/views/layouts/column2.php.
2. Xa /layouts/main l input t beginContent() method goi trc dng ban va copied l
column2.php file.
3. iu chnh SysMessage model class doc extend (k tha) TrackstarActiveRecord (Nu n goi
lai, thm code doc tu dng update ngoi create_time/user v update_time/user properties. iu
chnh SysMessageController controller class d s dung column column2.php layout file t khng ch
1 module folder t main application. The autogenerated code has specified
$layout='application.views.layouts.column2', but we need this to be simply $layout='column2'.
4. Chng ta doc k tha t TrackstarActiveRecord, chng ta c th xa nhng field khng cn thit
khi proect tu sinh ra autogenerated sys messages creation form v xa rules lin quan dn chng
(associated rules) from the model class. Xa 2 rules sau t SysMessage::rules() method:
array('create_user, update_user', 'numerical', 'integerOnly'=>true), and array('create_time,
update_time', 'safe').
One last change we should make is to update our simple access rules to reflect the requirement that only users in the
admin role can access our action methods. This is mostly for illustrative purposes as we already took care of the
access using our RBAC model approach in the AdminModule::beforeControlerAction method itself. We could actually
ust remove the accessRules entirely. However, let's ust update them to reflect the requirement so you can see how
that would work using the access rule approach. n the SysMessageController::accessRules() method, change the entire
contents to the following:
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(''),
),
);

M trnh duyt g: http://localhost/demo/admin/sysMessage/create, we are presented with something


similar to the following screenshot:
in vo form message Hell# U5er5 Th&5 &5 9#ur ad!&n 5pea$&n/... v click Su*!&t. The application will redirect
you to the details listing page for this newly created message as shown in the following screenshot:
D&5pla9&n/ the !e55a/e t# u5er5
B!p#rt&n/ the ne" !#del 4la55 7#r appl&4at&#n<"&de a44e55
n order to access the newly created model from anywhere in our application, we need to import it as a part of the
application configuration. Alter protected/config/main.php to include the new admin module models folder:
// autoloading model and component classes
'import'=>array(
'application.models.',
'application.components.',
?appl&4at&#n.!#dule5.ad!&n.!#del5.?,
),
Sele4t&n/ the !#5t re4entl9 updated !e55a/e
We'll restrict the display to ust one message, and we'll choose the most recently updated message, based on the
update_time column in the table. As we want to add this to the main proects listing page, we need to alter the
ProectController::actionndex() method. Alter that method by adding the following highlighted code:
public function actionndex()

$dataProvider=new CActiveDataProvider('Proect');
Yii::app()->clientScript->registerLinkTag(
'alternate',
'application/rssxml',
$this->createrl('comment/feed'));
///et the late5t 595te! !e55a/e t# d&5pla9 *a5ed #n the updateft&!e 4#lu!n
595Pe55a/e S95Pe55a/e::!#delgm<67&ndgarra9g
?#rder?6?t.updateft&!e DES(?,
mm
&7g595Pe55a/e nullm
!e55a/e 595Pe55a/e<6!e55a/e
el5e
!e55a/e null
$this->render('index',array(
'dataProvider'=>$dataProvider,
?595Pe55a/e?6!e55a/e,
));

Now we need to alter our view file to display this new bit of content. Add the following to views/proect/index.php, ust
above the <h1>Proects</h1> header text:
<?php if($sysMessage != null):?>
<div class="sys-message">
<?php echo $sysMessage; ?>
</div>
<?php endif; ?>
Now when we visit our proects listing page (that is, our application's home page) we can see it display as shown in
the following screenshot:
[ONUS
(h FI& *\n d+4h t&Cp the# 81& e*##$:
Yii 1.1 Application
Development Cookbook
( Pht trin ng dung Yii 1.1 )
http://""".5e#drupal.8n

You might also like