You are on page 1of 148

[YII 1.

1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

Yii 1.1 Application Development Cookbook Public: packpub Year : 2011


http://www.seodrupal.vn Translate by : longt8x email : phamducbact1k10@gmail.com

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

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012


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

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

Ok, hon tt cu hnh tin hnh coder.


153

CHNG 1 -

Gii thiu v Yii framework

1 S dng getter and setter ( Hm nhn v hm thit lp).

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 PHP cng ging nh cc cng ngh khc nh Java, C# , u c cu trc lp trnh hng i tng v xy dng cng ngh theo cc class(lp), yii framework c xy dng trn nn php cng khng ngoi l, tuy nhin iu khc bit l n k tha t Ccomponent (class o cho bt k class no trong Yii). Cch thc hin: Chng ta theo di nh ngha lp trong php vi hm thit lp (setter) v hm nhn li (getter)
class MyClass { private $property; // ham nhan lay gi tr public function getProperty() { return $this->property; } // ham khi to gi tr public function setProperty($value) { $this->property = $value; } } // to mi i tng $object = new MyClass(); // thit lp i tng $object->setProperty('value'); // tr v gi tr echo $object->getProperty(); Trong Yii chng ta thc hin nh k tha t Ccomponent nh sau :
// extending CComponent is necessary class MyClass extends CComponent { private $property; public function getProperty() { return $this->property; } public function setProperty($value) { $this->property = $value; } } $object = new MyClass(); $object->property = 'value'; // cng nh php : $object-> setProperty('value'); echo $object->property; // cng nh $object->getProperty();

153

Ngoi ra Yii cn h tr cc hm sau thc hin vic thit lp v nhn gi tr : __get, __set, __isset, v __unset

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012


Cch dng nh sau : vd public function __get($name) { $getter='get'.$name; if(method_exists($this,$getter)) return $this->$getter(); }

2 S dng Yii Event ( Cc s kin trong Yii)


Hu ht cc class u c k tha t Yii Component (Ccomponent) v th nn chng ta c th s l tt cc s kin t ng dng. Mt s kin tng ng l mt li nhn, mt thng ip ti ng dng yu cu thc hin cng vic no , chng ta c th ng k nhiu s kin x l thc hin ty theo loi s kin, mt hm x l c th nhn c cc tham s t cc s kin vi cc tham s c nh ngha, S dng cc s kin cho php t c s linh hot trong ng
dng.

Cch thc hin th no ? nh ngha mt s kin trong lp con ca Ccomponent, bn s thm phng thc (method) vi tn bt u bng t on, v d nu bn thm onRegister method , bn s nhn c tng ng mt s kin bn khai bo. Cc loi s kin c s dng ging nh : - nh ngha mt s kin c thm tung ng mt phng thc, - Kch hot mt hay nhiu s kin x l. - Thnh phn nng cao (raise) ca mt s kin c s dng bi Ccomponent ::raiseEvent method - Tt c cc th hin x l c gi t ng. Hy nhn vo cch chng ta c th kch hot mt s kin x l t mt s kin. Chng ta s dng Ccomponent::attachEventHandler method.N chp nhn cc tham s sau y: $name : Tn s kin. $handler: X l s kin,yu cu ca bn trc mi s kin thng l mt hm tiu chun gi li (standard function callback) php s dng. Bn c th thc hin hm gi li nh sau : S dng hm cc b (global function) v ch nhn tn ging nh cc chui v d my_function. S dng cc phng thc tnh t lp (static class method).Bn s ch tr v gi tr array(Tn lp (Name class),Tn phng thc tnh(static method Name)). S dng object method : array($object,object method) To v nhn hm nh danh s dng create_function nh sau: Trc tin nh ngha component
http://www.seodrupal.vn | Learn Drupal Online

153

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 public function init() { parent::init(); $component = Yii::app()->{$this->component}; } $component>attachEventHandler(onClick,create_function($event,echo click!)); Vi phin bn PHP 5.3 tr ln bn ch cn vit: $component->attachEventHandler(onclick,function($event){echo click;}); code ngn hn bn ch cn vit nh sau : $component>onClick=$handler; hoc $component->onClick->add($handler); qun l vic x l s kin bn s dng hm get handler list (Clist) trong Ccomponent::getEventHandlers v lm vic vi n. V d : $component->getEventHandlers(onClick)->add($handler); thm mt x l vo u danh sch cc x l ta vit: $component->getEventHandlers(onClick)->insertAt(0,$handler); xa mt x l bn s dng Ccomponent::detachEventHandler: $component->detachEventHandler(onClick,$handler);

Yii application c 2 s kin c s l trong cc trng hp sau ; Capplication::onBeginRequest v Capplication::onEndRequest hy s dng chng . t cu hnh thit lp nh sau vo file index.php trc khi chy ng dng: require_once($yii); $app = Yii::createWebApplication($config); // Kch hot s l trc khi bt u ng dng Yii::app()->onBeginRequest = function($event) { // starting output buffering with gzip handler return ob_start("ob_gzhandler"); }; // Kch hot s l sau khi kt thc ng dng Yii::app()->onEndRequest = function($event) { // releasing output buffer return ob_end_flush(); };
http://www.seodrupal.vn | Learn Drupal Online

153

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $app->run(); Comment l mt tiu chun ca AR model generate vi Gii, Post l mt phng thc ngoi l trong Gii-generated model. Chng ta s custom s kin NewCommentEvent thc hin c post v comment model v s l class Notifier lm vic: Bt u vo protected/components/ to NewCommentEvent.php

class NewCommentEvent extends CModelEvent { public $comment; public $post; } Rt n gin ch bao gm 2 thuc tnh. By gi bn di chuyn ti protected/models/Post.php. Tt c tiu chun AR method c xy dng nh sau:

class Post extends CActiveRecord { function addComment(Comment $comment){ $comment->post_id = $this->id; // to mi s kin t class trc $event = new NewCommentEvent($this); $event->post = $this; $event->comment = $comment; // kch hot s kin mi
153

$this->onNewComment($event); return $event->isValid; } // nh ngha s kin onNewComment


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 public function onNewComment($event) { $this->raiseEvent('onNewComment', $event); } } Tip theo to trong protected/components/ file Notifier.php

class Notifier { function comment($event){ $text = "C mt comment mi t {$event->comment->author} trong post {$event->post->title}"; mail('admin@example.com', 'New comment', $text); } } Tip theo vo trong protected/controllers/ to file PostController.php Class PostController extends Ccontroller { // to action thm comment function actionAddComment() { $post = Post::model()->findByPk(10); $notifier = new Notifier(); // kch hot s l s kin $post->onNewComment = array($notifier, 'comment');
153

// d liu tht c di dng request $_POST $comment = new Comment(); $comment->author = 'Sam Dark';
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $comment->text = 'Yii events are amazing!'; // thm comment $post->addComment($comment); }

} Nh vy l bn bit cch kch hot v s l mt s kin , tuy nhin nhiu trng hp khng nht thit phi kch hot s l s kin m chng ta cng c th kch hot s l s kin t cc component tn ti v chng ta ch cn overriding cc class c bn . V d chng ta c form model UserForm s dng thu thp thng tin ca ngi dng v chng ta cn hin th y h tn ca user. Tht may, Cmodel class c bn trong Yii model c th m rng form models. Cmodel::afterValidate c gi sau khi form c submit thnh cng. Ta vo protected/models/ to file UserForm.php class UserForm extends CFormModel { public $firstName; //tn public $lastName; //h public $fullName; //tn y public function rules() { return array( //tp hp quy tc : firstname,lastname c yu cu (k rng) array('firstName, lastName', 'required'),
153

); } // $event y c thit lp t CEvent


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 // to ra v thit lp mt s kin( event) khi method c gi . // CModel::afterValidate(). function afterValidate() { //Nu phng thc c gi th s kin s t ng np d liu sau: $this->fullName = $this->firstName.' '.$this->lastName; // iu quan trng l n phi c gi li t lp cha (parent class) // l iu gip cc s l s kin khc c gi li. return parent::afterValidate(); } }

Chng ta cn gi li t lp cha (parent class) ca afterValidate() v hm nh ngha onAfterValidate() thc cht l raiseEvent: Protected function afterValidate() { $this->onAfterValidate(new CEvent($this)); } 2. S dng import v autoloading Khi lp trnh vi php hu ht cc class v hm to u c load bi hai phng thc l : include v require. Tuy nhin bn cng c th s dng loader nh SPL class, yii s dng cng ngh ny vo Yii Base v vic xy dng cc lp tiu chun trong yii CdbCriteria. Mc nh autoloader (YiiBase::autoload) s c s dng.
153

Hu ht tt c cc lp c load khi cn including hoc importing . Yii hon tt bi YiiBase::$_coreClasses map, v th m vic load trong Yii rt nhanh.Zii class cng nh Cmenu, extension class hoc class ca bn nh ngha cng c t ng load. 3. Cu hnh Component(Thnh phn)
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Yii l mt framework custom, hu nh mi th u c th custom mt cch d dng l u im ca yii, trc tin chng ta tm hiu file config ca Yii trong protected/con fig /main.php c th s dng database kt ni mysql ta ch cn b 2 dng /* ---- */ array di y c kch hot. return array( 'components'=>array( 'db'=>array( 'class'=>'system.db.CDbConnection', 'connectionString'=>'mysql:host=localhost;dbname=database_ name', 'username'=>'root', 'password'=>'', 'charset'=>'utf8', ), ), );

Khi c th kt ni ti database ri bn ch cn khai bo Yii::app()->db; l ta c th lm vic trc tip vi CSDL. Mt s component trong Yii bn nn bit :
153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

4: Lm vic vi Request
Vi yii bn c th tr v d liu di dng request m php a ra nh $_SERVER, $_GET,$_POST, nhng tt hn bn nn lm theo vic s dng ca Yii l :ChttpRequest class , lp ny gii quyt nhng ngoi l t server, qun l cookies,cung cp thm vn bo mt,v c bit l hng i tng . Bn c th truy nhp request component trong yii bng vic s dng : Yii::app()>getRequest(). V th nn xem mt s hm hu ch , cc method tr v khc bit t URL :

chc chn cc request c truyn ng ta c thm cc hm kim tra : IsPostRequest (Kim tra hm post), getIsAjaxRequest (kim tra ajax loader), getRequestType (kim tra request thuc loi get hay post hay ajax). V d chng ta mun kim tra xem aJax c load hay cha ta xem v d sau :
class TestController extends CController { public function actionIndex() { if(Yii::app()->request->isAjaxRequest)s $this->renderPartial('test'); else $this->render('test'); } } 153 Ngoi ra b cng c th dng cc hm thi l thng d c PHP ki tra nh n t p ng a m isset, ispost . class TestController extends CController { http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012


public function actionIndex() { $request = Yii::app()->request; $param = $request->getParam('id', 1); // equals to $param = isset($_REQUEST['id']) ? $_REQUEST['id'] : 1; $param = $request->getQuery('id'); // equals to $param = isset($_GET['id']) ? $_GET['id'] : null; $param = $request->getPost('id', 1); // equals to $param = isset($_POST['id']) ? $_POST['id'] : 1; } } i cu cng chng ti mu b bi thm trong ch 1 ny chnh l hm u i n n t ng getCookies, n tr v t CcookieCollection class cho php chng ta lm vi v cookie, V c i CcookieCollection k th t Cmap nn chng ta c th s d method sau: c a ng class TestController extends CController { public function actionIndex() { $request = Yii::app()->request; // nh gi tr cookie n c a $cookie = $request->cookies['test']; 153 if($cookie) // in gi tr cookie echo $cookie->value; else { http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012


// to mi cookie $cookie=new CHttpCookie('test','I am a cookie!'); $request->cookies['test'] = $cookie; } } N b lm vi v nhi gi tr cookie , b mu code c mnh ng g hy u n c i u c a n n a n n s dng class sau: class Cookie { public static function get($name) { $cookie=Yii::app()->request->cookies[$name]; if(!$cookie) return null; return $cookie->value; } public static function set($name, $value, $expiration=0) { $cookie=new CHttpCookie($name,$value); $cookie->expire = $expiration; Yii::app()->request->cookies[$name]=$cookie; } } B thay code trong TestController nh sau: n i 153 class TestController extends CController { public function actionIndex() { http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012


$cookie = Cookie::get('test'); if($cookie) echo $cookie; else Cookie::set('test','I am a cookie!!'); } }

L , ch m v cc b m h s khng th lm th v khng c database u ng t i n i c c th, xin vui lng down source code bn English test app ca h.

CHNG 2 : ROUTER (nh tuyn), Controller (iu khin), and views (khung nhn)
Trong chng ny bn s c hc:

Cu hnh quy tc url, Generating Url by path S dng biu thc quy tc (regular expression) trong URL rules To url rules cho cc trang tnh. Cung cp url rules mi thi im. S dng controller c bn S dng action c bn Hin th trang ng vi CViewAction S dng flash messages ( C thng ip) S dng controller context trong view S dng clips


153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 S dng decorator nh ngha nhiu layout (giao din) Paginating and sorting data (Phn trang v sp xp d liu)

1. Cu hnh quy tc URL


Trc tin bn vo protected/config/main.php Tm dng sau: // application components 'components'=>array( // uncomment the following to enable URLs in path-format /* 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( '<controller:\w+>/<id:\d+>'=>'<controller>/view', '<controller:\w+>/<action:\w+>/<id:\ d+>'=>'<controller>/<action>', '<controller:\w+>/<action:\w+>'=>'<controller>/<action>', ), ), B hai du /* v */ sau xa mi th trong rules ta bt u thc hnh. 'urlManager'=>array( 'urlFormat'=>'path',
153

'rules'=>array( ), ),
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 'db'=>array('connectionString'=>'sqlite:'.dirname(__FILE__).'/../data/testdrive.db',), Vo protected/controllers to websiteController.php vi dng code sau: class WebsiteController extends CController { public function actionIndex() { echo "index"; } public function actionPage($alias) { echo "Page is $alias."; } }

Thay i file .htaccess trong protected nh sau : Options +FollowSymLinks IndexIgnore */* RewriteEngine on # if a directory or a file exists, use it directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # otherwise forward it to index.php RewriteRule . index.php Thm on sau vo main.php nh sau:
153

'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( 'home' => 'website/index',


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 '<alias:about>' => 'website/page', 'page/<alias>' => 'website/page', ), ), Ln lt g vo trnh duyt cc ng dn sau: http://localhost/skybook/index.php/page/test http://localhost/skybook/index.php/home http://localhost/skybook/index.php/about http://localhost/skybook/index.php/page/about

Bn s thy bin alias trong action page s thay i ty theo ng dn th 2 sau page bn in vo, y chnh l url nh danh (url alias). Thc t iu g xy ra: Vi quy tc : home=>website/index , trong Yii mi controller v action u c mt quy tc chung mc nh l moduleId (tn module)/controllerID(tn controller)/actionID(tn action). V d trong trng hp home l module : default, controller website, v action l index. page/<alias>=>website/page,
153

y , chng ta nh ngha mt alias parameter ( tham s nh danh) c bit trong Url sau /page/. N c th nhn v cc tham s o t tham s $alias trong action Page ca website controller. y bn nh ngha tr v tham s cho n bng vic thit lp quy tc:

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 <alias:about>=>website/page, ng ngha vi vic tham s $alias s ch nhn c tham s o l about.

2. Generating Url By Path


Khi chng ta cn generate Url ca index v page action trong website controller.Quyt nh ni chng ta cn n,c nhng cch lm khc nhau nhng c bn hy nhn mt s phng thc generate url sau: CHtml::link(), v mt s phng thc CHtml nh form,refresh v ajaxLink tt c chp nhn url v thuc tnh s dng trong views. nh dng chung cho vic tr v d liu nh sau: Url string: Tr v ng dn url dng k t. Array(quy tc cc b,tham s=>gi tr, tham s => gi tr). Mt s trng hp url s c generated.

nh dng ca quy tc vn theo th t : modulesID/controllerID/actionId. Tham s l bin $_GET s nhn mt action vi nh tuyn c bit, cho v d nu chng ta mun to mt url t websitecontroller ::actionIndex v nhn tham s $_GET[name] ta ch cn lm nh sau: echo CHtml::link('Click me!', array('website/index', 'name' => 't c bn tu kha lm ra Yii (Quiang Xue)')); URl rt hu ch khi s dng controller . Trong controller bn c th s dng createUrl to mi url v createAbsoluteUrl hin th thong tin v url: class WebsiteController extends CController { public function actionTest() { echo $this->createUrl('website/page', 'alias' => 'about'); echo $this->createAbsoluteUrl('website/page',
153

'alias' => 'test'); } // the rest of the methods


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } Khi bn khng mun hin khi to ca controller , khi bn thc thi ng dng bn c th s dng method sau: echo Yii::app()->createUrl('website/page', 'alias' => 'about'); echo Yii::app()->createAbsoluteUrl('website/page', 'alias' => 'test');

3.S dng biu thc quy tc trong Url rules


Nga quen ng c v g li thm ru nn ta xa d liu trong rules array(). Tip theo vo protected/controllers to file PostController.php mi vi dng sau: class PostController extends CController { public function actionView($alias) { echo "Showing post with alias $alias."; } public function actionIndex($order = 'DESC') { echo "Showing posts ordered $order."; } public function actionHello($name) { echo "Hello, $name!"; } }
153

Cu hnh li .htaccess trong protected nh sau: Options +FollowSymLinks IndexIgnore */*


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 RewriteEngine on # if a directory or a file exists, use it directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # otherwise forward it to index.php RewriteRule . index.php Tip theo thay i li trong main.php phn rules nh sau: 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( 'post/<alias:[-a-z]+>' => 'post/view', '(posts|archive)' => 'post/index', '(posts|archive)/<order:(DESC|ASC)>' => 'post/index', 'sayhello/<name>' => 'post/hello', ), ), Sau vo trnh duyt t sng: http://localhost/skybook/index.php/post/test-post thnh cng http://localhost/skybook/index.php/post/test-9 hi sinh (v hm ngoi l yu cu dng k t k phi dng s) http://localhost/skybook/index.php/achive hi sinh v index thuc dng s khng thuc k t http://localhost/skybook/index.php/posts/ASC thnh cng
153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

4. To Url rules cho trang tnh


Mt website cha cc thuc tnh tnh thng l :/about,/contact,/tos, lnh s l n trang ch n gin l controller action. Ta s tm mt cch to ra Url rules cho cc thuc tnh ca trang. Li vo main.php phn rules ht phn ch (xa ton b mi th trong array ca rules). Thay i li nh sau: '<alias:about>' => 'website/page', '<alias:contact>' => 'website/page', '<alias:tos>' => 'website/page', '<alias:(about|contact|tos)>' => 'website/page', 'tos' => array('website/page', 'defaultParams' => array('alias' => 'terms_of_service')),

6. S dng controller c bn
u tin ta vo protected/components to SecureController.php <?php
153

class SecureController extends Controller { public function filters() {


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 return array( 'accessControl', ); } public function accessRules() { return array( array('allow', 'users'=>array('@'), ), array('deny', 'users'=>array('*'), ), ); } } Vo protected/config/ main.php tm on /* 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'Enter Your Password Here', // If removed, Gii defaults to localhost only. Edit carefully to taste.
153

'ipFilters'=>array('127.0.0.1','::1'), ), */
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 B 2 dng check v in password cho gii (generated database) 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'1111', 'ipFilters'=>array('127.0.0.1','::1'), ), Tip theo vo http://localhost/skybook/index.php/gii/default/login in mt khu l 1111 Tip theo chn Controller Generator g SecureController

153

Nh generate t controller v action index n o m my nh l g nhanh qu word bo : please slow character @@ t n,

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012


Generate xong ng ngha vi vic bn to xong controller SecureController , bn c thvo protected/controllers tm thy file ny v trong views. Th nhanh chng ng khng ? ta khng c ph m cng t tuy nhin @@ khng t n i t o khuy khch v cc d l i h kh nng custom cao v th nn ch n n i generate models cho chng xong, cn controller th tt nht t to file . C trc c YII v tun th MVC, (model/views/controller) . u a n

7. S dng c bn Action
Vo protected/config/main.php tm on sau: 'db'=>array( 'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/testdrive.db', ), // uncomment the following to use a MySQL database

'db'=>array( 'connectionString' => 'mysql:host=localhost;dbname=testdrive', 'emulatePrepare' => true, 'username' => 'root', 'password' => '', 'charset' => 'utf8', ), Thay th b skybook ho b nguyn, vo localhost/phpmyadmin t table testdrive ng c n o nu bn nguyn, hoc nu thay th= skybook th to bng skybook. Vo phpmyadmin vi table mi to vi query: CREATE TABLE `post` ( 153 `id` int(10) unsigned NOT NULL auto_increment, `created_on` int(11) unsigned NOT NULL, `title` varchar(255) NOT NULL, `content` text NOT NULL, http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012


PRIMARY KEY (`id`) ); CREATE TABLE `user` ( `id` int(10) unsigned NOT NULL auto_increment, `username` varchar(200) NOT NULL, `password` char(40) NOT NULL, PRIMARY KEY (`id`) );

153 Nhn go query thc hin. c Tip theo vo GII generated 2 bng mi to bng cch chn model generated

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

G ln lt Post v User trong table Name ri generated Nu n bo override th vn generated kim tra vo protected/models s tm thy 2 file mi to. Tip theo vo PostController vit li nh sau: class PostController extends CController { function actionIndex() { $posts = Post::model()->findAll(); $this->render('index', array( 'posts' => $posts, ));
153

} function actionDelete($id) {
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $post = Post::model()->findByPk($id); if(!$post) throw new CHttpException(404); if($post->delete()) $this->redirect('post/index'); throw new CHttpException(500); } } Tip theo vo protected/components to file DeleteAction.php class DeleteAction extends CAction { function run() { if(empty($_GET['id'])) throw new CHttpException(404); $post = Post::model()->findByPk($_GET['id']); if(!$post) throw new CHttpException(404); if($post->delete()) $this->redirect('post/index'); throw new CHttpException(500); }
153

} Hy s dng component mi ny trong PostController actionDelete

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

class PostController extends CController { function actions() { return array( 'delete' => 'DeleteAction', ); } } OK.chng ta s dng delete action trong component cho post controller nhng vn cn user controller, ta custom li delete action: class DeleteAction extends CAction { public $pk = 'id'; public $redirectTo = 'index'; public $modelClass; function run() { if(empty($_GET[$this->pk])) throw new CHttpException(404); $model = CActiveRecord::model($this->modelClass)
153

->findByPk($_GET[$this->pk]); if(!$model) throw new CHttpException(404);


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 if($model->delete()) $this->redirect($this->redirectTo); throw new CHttpException(500); } } By gi chng ta c th s dng action cho c 2 controller .Vi post controller ta lm nh sau: class PostController extends CController { function actions() { return array( 'delete' => array( 'class' => 'DeleteAction', 'modelClass' => 'Post', ); ); } } Vi user controller ta cng khai bo action mi trong component class UserController extends CController {
153

function actions() { return array(


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 'delete' => array( 'class' => 'DeleteAction', 'modelClass' => 'User', ); ); } } Vi cch ny ta c th tit kim thi gian xy dng hm vi nhng hm c cu trc ging nhau.

8. S dng Flash Messages


Khi bn chnh sa model vi form,hay xa item trong models hoc lm vi nhng thao tc user, bn lun lun phi a ra li thong bo ti user cng vic thc hin xong cha hay hon thnh,Flash messages s gip hin th nhng li thong bo v d :xa thnh cng, cp nht thnh cng, Tr li protected/controllers/websitecontroller vit li nh sau: class WebsiteController extends CController { function actionOk() { Yii::app()->user->setFlash('success', 'Everything went fine!'); $this->redirect('index'); }
153

function actionBad() { Yii::app()->user->setFlash('error', 'Everything went wrong!');


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $this->redirect('index'); } function actionIndex() { $this->render('index'); } } Vo protected/views/website to index.php <?php if(Yii::app()->user->hasFlash('success')):?> <div class="flash-notice"> <?php echo Yii::app()->user->getFlash('success')?> </div> <?php endif?> <?php if(Yii::app()->user->hasFlash('error')):?> <div class="flash-error"> <?php echo Yii::app()->user->getFlash('error')?> </div> <?php endif?>

Vo trnh duyt http://localhost/skybook/index.php/website/ok http://localhost/skybook/index.php/website/bad

153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

9. S dng controller context trong views


To controller sau: class WebsiteController extends CController { function actionIndex() { $this->pageTitle = 'Controller context test'; $this->render('index'); } function hello() { if(!empty($_GET['name'])) echo 'Hello, '.$_GET['name'].'!';
153

} }

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 To views : <h1><?php echo $this->pageTitle?></h1> <p>Hello call. <?php $this->hello()?></p> <?php $this->widget('zii.widgets.CMenu',array( 'items'=>array( array('label'=>'Home', 'url'=>array('index')), array('label'=>'Yiiframework home', 'url'=>'http://yiiframework.ru/', ), ))?

10. S dng li views vi partial


class WebsiteController extends CController { function actionIndex() { $this->render('index'); } }

To protected/views/common/youtube.php <object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/S6u7ylr0zIg?fs=1 "></


153

param><param name="allowFullScreen" value="true"></ param><param name="allowscriptaccess" value="always"></ param><embed src="http://www.youtube.com/v/S6u7ylr0zIg?fs=1" type="application/x-shockwave-flash" allowscriptaccess="always"
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 allowfullscreen="true" width="480" height="385"></embed></object>

Chnh sa li : <object width="<?php echo!empty($width) ? $width : 480?>" height="<?php echo!empty($height) ? $height: 385?>"><param name="movie" value="http://www.youtube.com/v/<?php echo $id?>?fs=1 "></param><param name="allowFullScreen" value="true"></ param><param name="allowscriptaccess" value="always"></ param><embed src="http://www.youtube.com/v/<?php echo $id?>?fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="<?php echo !empty($width) ? $width : 480?>" height="<?php echo !empty($height) ? $height: 385?>"></ embed></object>

To protected/website/index.php <?php $this->renderPartial('////common/youtube', array( 'id' => '8Rp-CaIKvQs', // you can get this id by simply looking at video URL 'width' => 320, 'height' => 256, ))?> Gi ta s th gi email ,them mi action trong website controller
153

class WebsiteController extends CController { function actionSendmails() {


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $users = User::model->findAll(); foreach($users as $user) { $this->sendEmail('welcome', $user->email, 'Welcome to the website!', array('user' => $user)); } echo 'Emails were sent.'; } function sendEmail($template, $to, $subject, $data) { mail($to, $subject, $this->renderPartial ('//email/'.$template, $data, true)); } } Tip theo to protected/views/email/welcome.php: Hello <?php echo $user->name?>, Welcome to the website! You can go check our new videos section. There are funny raccoons. Yours, Website team.

11 . S dng clip
Khi chng ta cn nh ngha 2 v tr trong layout : trc content v footer, m protected/views/layouts/main.php them on sau trc output (<?php echo $content;?>) <?php if(!empty($this->clips['beforeContent'])) echo $this->clips['beforeContent']?> V them on sau trc footer
http://www.seodrupal.vn | Learn Drupal Online

153

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 <?php if(!empty($this->clips['footer'])) Echo $this->clips['footer']; ?> By gi chng ta cn in vo v tr ca chng, m controller action cho beforeContent region. M protected/controllers/SiteController.php v them on sau vo actionIndex: $this->beginClip('beforeContent'); echo 'Your IP is '.Yii::app()->request->userHostAddress; $this->endClip(); Tip theo m protected/views/site/index.php v them on sau: <?php $this->beginClip('footer')?> ng dng c xy dng bi Tu kha. <?php $this->endClip()?> Hon tt bn c th m index bn s thy a ch IP v ng dng gn footer.

12 . nh ngha nhiu Layout.


Hu ht ng dng s dng mt layout duy nht cho tt c khung nhn,tuy nhin nhiu d n i hi cu hnh v thm m khc nhau dn ti c nhiu layout khc nhau v th nn yii cho php to dng nhiu layout mt cch chuyn bit v hiu qu. Ta to 2 layout trong protected/views/layouts: blog v articles. Blog cha ng ni dung sau: <?php $this->beginContent('//layouts/main')?> <div> <?php echo $content?> </div>
153

<div class="sidebar tags"> <ul> <li><a href="#php">PHP</a></li> <li><a href="#yii">Yii</a></li>


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 </ul> </div> <div class="sidebar links"> <ul> <li><a href="http://yiiframework.com/">Yiiframework</a></li> <li><a href="http://php.net/">PHP</a></li> </ul> </div> <?php $this->endContent()?>

Article cha ni dung sau: <?php $this->beginContent('//layouts/main')?> <div> <?php echo $content?> </div> <div class="sidebar toc"> <ul> <li><a href="#intro">1. Introduction</a></li> <li><a href="#quick-start">2. Quick start</a></li> </ul> </div> <?php $this->endContent()?>
153

To 3 controller l BlogController,ArticleController v PorfolioController vi indexAction class BlogController extends Controller {


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 function actionIndex() { $this->layout = 'blog'; $this->render('//site/index'); } } class ArticleController extends Controller { function actionIndex() { $this->layout = 'articles'; $this->render('//site/index'); } } class PortfolioController extends Controller { function actionIndex() { $this->render('//site/index'); } } Gi hy th vo http://localhost/skybook/index.php/blog, http://localhost/skybook/index.php/article and
153

http://localhost/skybook/index.php/portfolio. Chng ta va nh ngha 2 layout cho blog v articles. Nu chng ta khng mun copy-pase mt phn ca layout chnh,chng ta th them layout c nh ngha
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 bng cch s dng $this->beginContent v this->endContent; th hin hnh di y:

13. Phn trang v sp xp d liu


Trc khi kt thc chng 2 ta s i vo tm hiu ActiveRecord vi c ch phn trang , sp xp d liu theo tiu chun. Vo protected/controllers/PostController.php class PostController extends Controller { function actionIndex() { $criteria = new CDbCriteria(); $count=Post::model()->count($criteria); $pages=new CPagination($count); // elements per page
153

$pages->pageSize=5; $pages->applyLimit($criteria); // sorting


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $sort = new CSort('Post'); $sort->attributes = array( 'id', 'title', ); $sort->applyOrder($criteria); $models = Post::model()->findAll($criteria); $this->render('index', array( 'models' => $models, 'pages' => $pages, 'sort' => $sort, )); } } Tip theo xy dng views: protected/views/post/index.php <p><?php echo $sort->link('id')?></p> <p><?php echo $sort->link('title')?></p> <ol> <?php foreach($models as $model):?> <li> <h2><?php echo $model->id?> - <?php echo $model->title?></h2> </li>
153

<?php endforeach?> </ol> <?php $this->widget('CLinkPager', array( 'pages' => $pages,


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 ))?> thc hin kim tra bn vo phpmyadmin v thm vo bng post khong 20 item, sau vo trnh duyt xem kt qu: http://localhost/skybook/post

CHNG 3

153

AJAX V jQuery

Trong chng ny bn s khm ph: Ti mt block vi AJAX Qun l asserts Including resources vi page Lm vic vi JSON Nhn thit lp t PHP v Javascript X l bin s ca input

1. Ti mt Block vi AJAX To mt controller mi trong protected/controllers tn QuoteController


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 : <?php class QuoteController extends Controller { private $quotes = array( array('Walking on water and developing software from a specification are easy if both are frozen.', 'Edward V Berard'), array('It always takes longer than you expect, even when you take into account Hofstadter&rsquo;s Law.', 'Hofstadter&rsquo;s Law'), array('Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.', 'Rick Osborne'), array('I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone.', 'Bjarne Stroustrup'), array('Java is to JavaScript what Car is to Carpet.', 'Chris Heilmann'), ); private function getRandomQuote() { return $this->quotes[array_rand($this->quotes, 1)]; }
153

function actionIndex() { $this->render('index', array( 'quote' => $this->getRandomQuote()


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 )); } //ajax callback function actionGetQuote() { $this->renderPartial('_quote', array( 'quote' => $this->getRandomQuote(), )); } }

Tip theo to views : protected/views/quote/index.php <h2>Quote of the day</h2> <div id="quote-of-the-day"> <?php $this->renderPartial('_quote', array( 'quote' => $quote, ))?> </div> <?php echo CHtml::ajaxLink('Next quote', array('getQuote'), array('update' => '#quote-of-the-day'))?>
153

To views th 2 l protected/views/quote/_quote.php &ldquo;<?php echo $quote[0]?>&rdquo;, <?php echo $quote[1]?>

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

Vo trnh duyt g : http://localhost/skybook/index.php/quote/index c th xem cu hnh ajax to ra bn dng firebug tr vo vng next quote s hin th javascript to ra ajax t Chtml::ajaxLink. 2. Qun l Assert Mt trong nhng kh nng tuyt vi ca Yii l c th bo v ti sn (m ngun) mt cch hiu qu Khi thc thi mt extension c kch hot javascript,css,images th folder gc khng th truy nhp c t trnh duyt. Khi bn cn truy nhp li ti sn (css,js,image) ca bn ch cn combine javascript Khi bn s dng assert nhiu ln trong phn trang v trnh trng lp Hy bt u k hoch trc, bn c th thay i widgets ti bt k th mc no, n nm trong protected/components. N chp nhn c mt hoc 2 class trong , nhng khi s lng class tng ln, n s to ra vn ,To mt assert trong widget vi protected/extensions/facebook_events.v t trong ajax-loader.gif bn vui lng download ti http://ajaxload.info . Tip theo to facebook_event.css v facebook_event.js To EFacebookEvents.php trong folder facebook_events <?php class EFacebookEvents extends CWidget
153

{ public $keyword; private $loadingImageUrl; protected $url = "https://graph.facebook.com/search?q=%s&type=


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 event&callback=?"; protected function getUrl() { return sprintf($this->url, urlencode($this->keyword)); } public function init() { // khoi tao duong dan file assets $assetsDir = dirname(__FILE__).'/assets'; $cs = Yii::app()->getClientScript(); $cs->registerCoreScript("jquery");

// thiet lap duong dan toi file js $cs->registerScriptFile( Yii::app()->assetManager->publish( $assetsDir.'/facebook_events.js' ), CClientScript::POS_END ); //thiet lap duong dan toi file css $cs->registerCssFile( Yii::app()->assetManager->publish( $assetsDir.'/facebook_events.css'
153

) ); // thiet lap duong dan toi file images // asset can be accessed with
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $this->loadingImageUrl = Yii::app()->assetManager->publish( $assetsDir.'/ajax-loader.gif' ); } public function run() { $this->render("body", array( 'url' => $this->getUrl(), 'loadingImageUrl' => $this->loadingImageUrl,, 'keyword' => $this->keyword, )); } }

Tip theo vo protected/extensions/facebook_events/ to views/body.php <div class="facebook-events" data-url="<?php echo $url?>"> <h2><?php echo $keyword?> events</h2> <div class="data"> <?php echo CHtml::image($loadingImageUrl)?> </div> </div> Tip theo vo file facebook_events.js :
153

jQuery(function($){ $(".facebook-events").each(function(){ var url = $(this).data("url"); var container = $(".data", this);


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $.getJSON(url,function(json){ var html = "<ul>"; $.each(json.data,function(){ html += "<li>"+ "<p><strong>" + this.name + "</strong> </p><p>"+this.location "</p></li>"; }); html += "</ul>"; container.html(html); }); }); });

Vo file facebook_events.css: .facebook-events { padding: 10px; width: 400px; float: left; } .facebook-events ul { padding: 0;
153

} .facebook-events li { list-style: none; border: 1px solid #ccc;


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 padding: 10px; margin: 2px; } Vo protected/views/site/index.php <?php $this->widget("ext.facebook_events.EFacebookEvents", array( 'keyword' => 'php', ))?>

<?php $this->widget("ext.facebook_events.EFacebookEvents", array( 'keyword' => 'jquery', ))?> Gi vo trang ch xem kt qu:

153

Cch thc hot ng:


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Khi chng ta s dng $this->widget trong site/index view, 2 phng thc trong EFacebookEvents u chy init ci m public assert v kt ni chng ti trang, sau chy render html. Nhng g c trong th mc :Assert Nu bn kim tra s thy nhng dng sau:

Th mc nh 1a6630a0 c s dng ngn chn va chm ca cc tp tin vi nhng ci tn tng t t cc th mc khc nhau. Tn ca th mc l mt hm bm m ha path assert directory.Trc assert t mi th mc c copy ti cng mt ni,iu ny ngha l th mc image,css,js public ca bn c th tham chiu ti images,css,js t cc ng dn lien quan.

3.Including resource ti trang


Yii c tn class c bit l CClientScript gip cho vic include script css. Cch thc nh : Yii::app()->clientScript->registerScriptFile("http://example.com/js/main.js"); i vi core jquery: Yii::app()->clientScript->registerCoreScript('jquery'); i vi CSS; Yii::app()->clientScript->registerCssFile('http://example.com/css/main.css'); Yii::app()->registerCss('myCSS', 'body {margin: 0; padding: 0}','all'); ng k linker resources:
153

Yii::app()->clientScript->registerLinkTag( 'alternate', 'application/rss+xml',


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $this->createUrl('rss/articles') );

ng k metaTag: Yii::app()->clientScript->registerMetaTag(' text/html;charset=utf-8', null, 'Content-Type');

4. Lm vic vi JSON
JSON rt n gin,d s dng, l s dng nh dng AJAX application data.YII cng c lm vic vi n. u tin ta vo phpmyadmin v to mi table : Tin tc: CREATE TABLE `news` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `created_on` int(11) unsigned NOT NULL, `title` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) Tip theo bn vo GII ri gererated Model, bn g news v nhn generated. Sau khi thnh cng kim tra ti protected/models xem c file new cha ? Vo protected/controllers to NewsController.php <?php class NewsController extends Controller {
153

//tao bo loc. public function filters() {


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 return array( 'ajaxOnly + data',

); } public function actionIndex() { $this->render('index'); } public function actionData() { $criteria = new CDbCriteria(); $criteria->order = 'created_on DESC'; $criteria->limit = 10; $news = News::model()->findAll($criteria); echo CJSON::encode($news); } public function actionAddRandomNews() { $news = new News(); $news->title = "Item #".rand(1, 10000); $news->created_on = time();
153

$news->save(); echo "OK"; } }


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Tip theo bn to views: protected/views/news/index.php

<div class="news-list"> Loading </div> <?php Yii::app()->clientScript->registerCoreScript("jquery")?> <script type="text/javascript"> jQuery(function($) { var newsList = $('.news-list'); function updateNews(){ newsList.html("Loading"); $.ajax({ url: "<?php echo $this->createUrl('data')?>", dataType: 'json', cache: false, success: function(data) { var out = "<ol>"; $(data).each(function(){ out+="<li>"+this.title+"</li>"; }); out += "</ol>"; newsList.html(out);
153

} }); } updateNews();
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 setInterval(function(){ updateNews() }, 2000); }); </script> Sau thc hin xong vo trnh duyt g: http://localhost/skybook/index.php/news/index

5: X l bin s ca input
i khi ng dng yu cu nhp form cha bin s ca input,mt chc nng qun l ng dng c th cung cp hnh nh,ni bn c th them mt hoc nhiu chc nng trong danh sch task,bn c th xem v d di y:

153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

Bi mc nh, trang s hin th mt vi chc nng v hai button: Add task s them thuc tnh v save l lu li thong tin ca form. Ta s to protected/models file Task.php: <?php class Task extends CFormModel { public $title; public $text; public function rules() //thiet lap quy tac { return array( array('title', 'required'), // tieu de khong rong array('text', 'safe'), //text duoc bao ve
153

); } }
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Tip theo vo protected/controllers/TaskController.php <?php class TaskController extends Controller { public function filters() { return array( 'ajaxOnly + field' ); } public function actionIndex() { $models = array(); if(!empty($_POST['Task'])) //kiem tra co request post hay k { foreach($_POST['Task'] as $taskData) { $model = new Task(); $model->setAttributes($taskData); if($model->validate()) $models[] = $model; }
153

} if(!empty($models)){ // Neu ban muon luu lai du lieu co the luu tai day }
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 else $models[] = new Task(); $this->render('index', array( 'models' => $models, )); } public function actionField($index) { $model = new Task(); $this->renderPartial('_task', array( 'model' => $model, 'index' => $index, )); } }

Ta to view: protected/views/task/index.php <div class="form"> <?php echo CHtml::beginForm()?> <ul class="tasks"> <?php for($i=0; $i<count($models); $i++):?> <?php $this->renderPartial('_task', array(
153

'model' => $models[$i], 'index' => $i, ))?> <?php endfor ?>
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 </ul> <div class="row buttons"> <?php echo CHtml::button('Add task', array('class' => 'tasks-add'))?> <?php Yii::app()->clientScript->registerCoreScript ("jquery")?> <script> $(".tasks-add").click(function(){ $.ajax({ success: function(html){ $(".tasks").append(html); }, type: 'get', url: '<?php echo $this->createUrl('field')?>', data: { index: $(".tasks li").size() }, cache: false, dataType: 'html' }); }); </script>
153

<?php echo CHtml::submitButton('Save')?> </div> <?php echo CHtml::endForm()?> </div>


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Cui cng to views cho partial: protected/views/task/_task.php <li> <div class="row"> <?php echo CHtml::activeLabel($model, "[$index]title")?> <?php echo CHtml::activeTextField($model, "[$index]title")?> </div> <div class="row"> <?php echo CHtml::activeLabel($model, "[$index]text")?> <?php echo CHtml::activeTextArea($model, "[$index]text")?> </div> </li> Vo trnh duyt g http://localhost/skybook/task/index xem kt qu.

CHNG 4
Chng ny bn s khm ph:
153

LM VIC VI FORM

Uploading files Thm Captcha Custom Captcha

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 To mt custom widget vi Cwidget

1. Uploading files
Trong folder protected bn to mt th mc mi c tn: uploads Chng ta s bt u vi model, v vy s to protected/models/Upload.php <?php class Upload extends CFormModel { public $file; public function rules() { return array(//yeu cau thuoc tinh file c th them cc thuc tnh khc cch nhau du //phy array('file', 'file', 'types'=>'zip'), ); } } Trong protected/controllers to UploadController.php <?php class UploadController extends Controller {

function actionIndex() {
153

$dir = Yii::getPathOfAlias('application.uploads'); //hien thi duong dan upload $uploaded = false; $model=new Upload(); //goi model
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 if(isset($_POST['Upload'])) { $model->attributes=$_POST['Upload']; $file=CUploadedFile::getInstance($model,'file'); if($model->validate()){ //validate form thanh cong thi luu file do vao thu muc $uploaded = $file->saveAs($dir.'/'.$file->getName()); } } $this->render('index', array( //hien thi thong tin ten file, duong dan 'model' => $model, 'uploaded' => $uploaded, 'dir' => $dir, )); } } Tip theo ta to views: protected/views/upload/index.php <?php if($uploaded):?> <p>File was uploaded. Check <?php echo $dir?>.</p> <?php endif ?> <?php echo CHtml::beginForm('','post',array ('enctype'=>'multipart/form-data'))?> <?php echo CHtml::error($model, 'file')?>
153

<?php echo CHtml::activeFileField($model, 'file')?> <?php echo CHtml::submitButton('Upload')?> <?php echo CHtml::endForm()?> Vo trnh duyt g: http://localhost/skybook/index.php/upload/index
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

2. Thm Captcha
To protected/models/EmailForm.php <?phpclass EmailForm extends CFormModel { public $email; function rules(){ return array( array('email', 'email'), ); } } To protected/controller/EmailController.php
153

<?php class EmailController extends Controller { public function actionIndex()


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 { $success = false; $model = new EmailForm(); if(!empty($_POST['EmailForm'])) { $model->setAttributes($_POST['EmailForm']); if($model->validate()) { $success = true; // handle form here } } $this->render('index', array( 'model' => $model, 'success' => $success, )); } } To views: protected/email/index.php <?php if($success):?> <p>Success!</p> <?php endif?>
153

<?php echo CHtml::beginForm()?> <p> <?php echo CHtml::activeLabel($model, 'email')?> <?php echo CHtml::activeTextField($model, 'email')?>
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 <?php echo CHtml::error($model, 'email')?> </p> <p> <?php echo CHtml::submitButton()?> </p> <?php echo CHtml::endForm()?> Vo http://localhost/skybook/index.php/email/index test

3.Custom Captcha
Ta c th custom captcha mt cch d dng nh CCaptchaAction Trong protected/components to MathCaptchaAction.php <?php class MathCaptchaAction extends CCaptchaAction {
153

protected function generateVerifyCode() { return mt_rand((int)$this->minLength, (int)$this->maxLength);


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } public function renderImage($code) { parent::renderImage($this->getText($code)); } protected function getText($code) { $code = (int)$code; $rand = mt_rand(1, $code-1); $op = mt_rand(0, 1); if($op) return $code-$rand.+.$rand; else return $code+$rand.-.$rand; } } Trong controller trc them action sau: public function actions() { return array( 'captcha'=>array( 'class'=>'MathCaptchaAction',
153

'minLength' => 1, 'maxLength' => 10, ), );


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } Ta c kt qu:

4. To mt custom input widget vi CInputWidget


Trong protected/components to RangeInputField.php <?php class RangeInputField extends CInputWidget { public $attributeFrom; public $attributeTo; public $nameFrom; public $nameTo;
153

public $valueFrom; public $valueTo; function run()


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 { if($this->hasModel()) { echo CHtml::activeTextField ($this->model, $this->attributeFrom); echo ' &rarr; '; echo CHtml::activeTextField ($this->model, $this->attributeTo); } else { echo CHtml::textField($this->nameFrom, $this->valueFrom); echo ' &rarr; '; echo CHtml::textField($this->nameTo, $this->valueTo); } } } Tip theo vo protected/models RangeForm.php <?php class RangeForm extends CFormModel { public $from; public $to;
153

function rules() { return array( array('from, to', 'numerical', 'integerOnly' => true),
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 array('from', 'compare', 'compareAttribute' => 'to', 'operator' => '<=', 'skipOnError' => true), ); } } Tip theo vo protected/controllers to RangeController.php <?php class RangeController extends Controller { function actionIndex() { $success = false; $model = new RangeForm(); if(!empty($_POST['RangeForm'])) { $model->setAttributes($_POST['RangeForm']); if($model->validate()) $success = true; } $this->render('index', array( 'model' => $model, 'success' => $success,
153

)); } } Tip theo vo protected/views/ to range/index.php


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 <?php if($success):?> <p>Success!</p> <?php endif?> <?php echo CHtml::errorSummary($model)?> <?php echo CHtml::beginForm()?> <?php $this->widget('RangeInputField', array( 'model' => $model, 'attributeFrom' => 'from', 'attributeTo' => 'to', ))?> <?php echo CHtml::submitButton('Submit')?> <?php echo CHtml::endForm()?>

Vo trnh duyt g: http://localhost/skybook/index.php/range/index

153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

CHNG 5

Database ,ActiveRecord,v Model Tricks

Trong chng ny bn s khm ph: Nhn d liu t database S dng scopes hin th model vi cc ngn ng khc nhau Truy cp models field vi AR Applying Markdown v HTML Hightlight code vi Yii T ng timestamp Thit lp author t ng Thc thi cc bng k tha n S dng CDbCriteria

1. Nhn d liu t database


153

Hu ht ng dng ngy nay u s dng database,d l mt website nh cho ti mng x hi , t nht mt phn c bo v bi database,Yii gii thiu 3 cch lm vic trn database: Active Record
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Query Builder SQL v DAO thc hin bn vo : http://dev.mysql.com/doc/sakila/en/sakila.html ti gi database v sau vo phpmyadmin import vo csdl Tip theo vo Gii to model actor v field tables Ta vo protected /controller to DbController.php

153

<?php class DbController extends Controller { protected function afterAction($action) { $time = sprintf('%0.5f', Yii::getLogger() ->getExecutionTime()); $memory = round(memory_get_peak_usage()/(1024*1024),2)."MB"; echo "Time: $time, memory: $memory"; parent::afterAction($action); } public function actionAr() { $actors = Actor::model()->findAll(array('with' => 'films', 'order' => 't.first_name, t.last_name, films.title')); echo '<ol>'; foreach($actors as $actor) { echo '<li>'; echo $actor->first_name.' '.$actor->last_name; echo '<ol>'; foreach($actor->films as $film) { echo '<li>'; echo $film->title; echo '</li>'; } echo '</ol>'; echo '</li>'; } echo '</ol>'; } public function actionQueryBuilder() {
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $rows = Yii::app()->db->createCommand() ->from('actor') ->join('film_actor', 'actor.actor_id=film_actor.actor_id') ->leftJoin('film', 'film.film_id=film_actor.film_id') ->order('actor.first_name, actor.last_name, film.title') ->queryAll(); $this->renderRows($rows); } public function actionSql() { $sql = "SELECT *

153

FROM actor a JOIN film_actor fa ON fa.actor_id = a.actor_id JOIN film f ON fa.film_id = f.film_id ORDER BY a.first_name, a.last_name, f.title"; $rows = Yii::app()->db->createCommand($sql)->queryAll(); $this->renderRows($rows); } public function renderRows($rows) { $lastActorName = null; echo '<ol>'; foreach($rows as $row) { $actorName = $row['first_name'].' '.$row['last_name']; if($actorName!=$lastActorName){ if($lastActorName!==null){ echo '</ol>'; echo '</li>'; } $lastActorName = $actorName; echo '<li>'; echo $actorName; echo '<ol>'; } echo '<li>'; echo $row['title']; echo '</li>'; } echo '</ol>'; } } Sauk hi thc hin xong bn chy trn trnh duyt v vo databse kim tra d liu mi to.
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

2. S dng Scopes hin th models cho nhng ngn ng khc nhau


a ngn ng trong website ca bn l vic iu khin khng h d dng,bn cn phi thay i giao din,thay i tin nhn,nh dng ngy thng,v rt nhiu th khc. Yii gip bn lm vic hiu qu hn vi CLDR (Unicode Common Locate Data Repository) d liu v cung cp cng c thay i ngn ng. Khi ti ng dng vi nhiu ngn ng, bn c th s tm ra cch ca ring bn.

bt u to mi databse: vo phpmyadmin v chn mc SQL : DROP TABLE IF EXISTS `post`; CREATE TABLE IF NOT EXISTS `post` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `lang` VARCHAR(5) NOT NULL DEFAULT 'en', `title` VARCHAR(255) NOT NULL, `text` TEXT NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO `post`(`id`,`lang`,`title`,`text`) VALUES (1,'en_us','Yii news','Text in English'), (2,'de','Yii Nachrichten','Text in Deutsch'); Sau khi hon tt vo GII chn model generated g Post vo modelname v generated Sauk hi generated bn vo models/Post.php v vit li method ging nh sau: class Post extends CActiveRecord { public function defaultScope() {
153

return array( 'condition' => "lang=:lang", 'params' => array(


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 ':lang' => Yii::app()->language, ), ); } public function lang($lang){ $this->getDbCriteria()->mergeWith(array( 'condition' => "lang=:lang", 'params' => array( ':lang' => $lang, ), )); return $this; } } Tip theo vo protected/controllers/DbtestController.php <?php class DbtestController extends CController { public function actionIndex() { // Hin th ngn ng mc nh $posts = Post::model()->findAll();
153

echo '<h1>Default language</h1>'; foreach($posts as $post) { echo '<h2>'.$post->title.'</h2>';


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 echo $post->text; } // Hin th ngn ng ca c $posts = Post::model()->lang('de')->findAll(); echo '<h1>German</h1>'; foreach($posts as $post) { echo '<h2>'.$post->title.'</h2>'; echo $post->text; } } } Sauk hi hon thnh vo trnh duyt g : http://localhost/skybook/dbtest/index

3. Truy cp model field vi Active-Record event-like method


Vo phpmyadmin chn mc SQL v thc hin query sau: DROP TABLE IF EXISTS `post`;
153

CREATE TABLE IF NOT EXISTS `post` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `title` VARCHAR(255) NOT NULL,
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 `text` TEXT NOT NULL, PRIMARY KEY (`id`) );

Tip theo vo Gii generated model Post Sau bn vo models/Post.php v thm hm sau: protected function beforeSave() { $this->text = preg_replace('~((?:https?|ftps?)://.*?)( |$)~iu', '<a href="\1">\1</a>\2', $this->text); return parent::beforeSave(); } Tip theo vo protected/controllers to TestController.php <?php class TestController extends CController { function actionIndex() { $post=new Post(); $post->title='links test'; $post->text='test http://www.p cht m tu kha.vn/ test';
153

$post->save(); print_r($post->text); } }
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Vo tnh duyt g http://localhost/skybook/test/index xem kt qu. Cch lm vic nh sau: beforeSave (trc khi lu) c nh ngha trong CActiveRecord class v ch thc hin hm trc khi lu models.Bi s dng biu thc quy tc, chng thay th mi th ging mt url vi mt link c s dng v gi li hm thc thi cha,s kin thc t l raised propery , trong hm saving bn c th tr v gi tr false. Mt s method bn nn bit:

AfterConstruct : Hm c gi sau khi mt model c khi to bi m ngun beforeDelete/afterDelete : Hm c gi trc/sau khi bn ghi b xa beforeSave/afterSave: Hm c khi to trc khi/sau khi lu bn ghi thnh cng. beforeValidate/afterValidate: Hm c gi khi khi to trc/sau khi validation form kt thc.

4. Highlight code vi Yii


Nu bn post code,cng ty ca bn lien quan n ngh bo v wiki blog,s lun lun tt hn khi h thng c highlight (hiu ng nhy), v mt ngi c code cng cm thy thoi mi. thc hin ta vo phpmyadmin chn mc SQL v thc hin query sau: CREATE TABLE `snippet` (
153

`id` int(11) unsigned NOT NULL auto_increment, `title` varchar(255) NOT NULL, `code` text NOT NULL, `html` text NOT NULL,
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 `language` varchar(20) NOT NULL, PRIMARY KEY (`id`) ); Tip theo vo Giii generated model Snippet Sauk hi generate thnh cng bn thay i hm rules trong Snippet.php protected/models/Snippet.php public function rules() { return array( array('title, code, language', 'required'), array('title', 'length', 'max'=>255), array('language', 'length', 'max' => 20), ); } Thm method sau khi validate: protected function afterValidate() { $highlighter = new CTextHighlighter(); $highlighter->language = $this->language; $this->html = $highlighter->highlight($this->code); return parent::afterValidate(); }

153

public function getSupportedLanguages() { return array(


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 'php' => 'PHP', 'css' => 'CSS', 'html' => 'HTML', 'javascript' => 'JavaScript', ); } Tip theo vo protected/controller to SnippetController.php <?php class SnippetController extends CController { public function actionIndex() { $criteria = new CDbCriteria(); $criteria->order = 'id DESC'; $models = Snippet::model()->findAll(); $this->render('index', array( 'models' => $models, )); } public function actionView($id) { $model = Snippet::model()->findByPk($id);
153

if(!$model) throw new CException(404); $this->render('view', array( 'model' => $model,


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 )); } public function actionAdd() { $model = new Snippet(); $data = Yii::app()->request->getPost('Snippet'); if($data) { $model->setAttributes($data); if($model->save()) $this->redirect(array('view', 'id' => $model->id)); } $this->render('add', array( 'model' => $model, )); } public function actionEdit($id){ $model = Snippet::model()->findByPk($id); if(!$model) throw new CHttpException(404); $data = Yii::app()->request->getPost('Snippet'); if($data)
153

{ $model->setAttributes($data); if($model->save()) $this->redirect(array('view', 'id' => $model->id));


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } $this->render('edit', array( 'model' => $model, )); } }

Tip theo ta to view trong protected/views/snippet/index.php <h2>Snippets</h2> <?php echo CHtml::link('Add snippet', array('add'))?> <ol> <?php foreach($models as $model):?> <li> <?php echo CHtml::link( CHtml::encode($model->title), array('view', 'id' => $model->id) )?> </li> <?php endforeach?> </ol> To tip view th 2 : protected/views/snippet/view.php <h2><?php echo CHtml::link('Snippets', array('index'))?> <?php
153

echo CHtml::encode($model->title)?> </h2> <?php echo CHtml::link('Edit', array ('edit', 'id' => $model->id))?>
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 <div> <?php echo $model->html?> </div> To view add : protected/views/snippet/add.php <h2><?php echo CHtml::link('Snippets', array('index'))?> Add snippet </h2> <?php $this->renderPartial('_form', array('model' => $model))?> To view edit: protected/views/snippet/edit.php <h2><?php echo CHtml::link('Snippets', array('index'))?> Edit snippet </h2> <?php $this->renderPartial('_form', array('model' => $model))?> To view _form : protected/views/snippet/_form.php <?php echo CHtml::beginForm()?> <ul> <li> <?php echo CHtml::activeLabel($model, 'title')?> <?php echo CHtml::activeTextField($model, 'title')?> </li> <li> <?php echo CHtml::activeLabel($model, 'code')?>
153

<?php echo CHtml::activeTextArea($model, 'code')?> </li> <li> <?php echo CHtml::activeLabel($model, 'language')?>
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 <?php echo CHtml::activeDropDownList($model, 'language', $model->getSupportedLanguages())?> </li> <li> <?php echo CHtml::submitButton('Save')?> </li> </ul> <?php echo CHtml::endForm()?> Sauk hi hon thnh vo trnh duyt g : http://localhost/skybook/snippet/index T t tn hng hiu ng:

153

5. Thc thi k tha bng


D liu quan h thng khng h tr k tha . Nu bn mun thc hin k tha database, bn cng c th c h tr t Yii
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Cu trc k tha n gin nh: Xe |-> Xe th thao |->Xe du lch |->Xe gia nh. bt u ta vo phpmyadmin chn sql v chy query sau: CREATE TABLE `car` ( `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `type` varchar(100) NOT NULL, PRIMARY KEY (`id`) ); INSERT INTO `car` (`name`, `type`) VALUES ('Ford Focus', 'family'), ('Opel Astra', 'family'), ('Kia Ceed', 'family'), ('Porsche Boxster', 'sport'), ('Ferrari 550', 'sport'); Ta generated model Car trong Gii Trong Protected/models/Car.php ta sa li nh sau: <?php class Car extends CActiveRecord
153

{ public static function model($className=__CLASS__) { return parent::model($className);


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } public function tableName() { return 'car'; } protected function instantiate($attributes) { switch($attributes['type']) { case 'sport': $class='SportCar'; break; case 'family': $class='FamilyCar'; break; default: $class=get_class($this); } $model=new $class(null); return $model; } }
153

Sau ta k tha cho protected/models/SportCar.php <?php class SportCar extends Car {


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 public static function model($className=__CLASS__) { return parent::model($className); } public function defaultScope() { return array( 'condition'=>"type='sport'", ); } } Tip theo ta cng k tha cho protected/models/FamilyCar.php <?php class FamilyCar extends Car { public static function model($className=__CLASS__) { return parent::model($className); } public function defaultScope() { return array(
153

'condition'=>"type='family'", ); } }
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Trong protected/controller to TestController.php <?php class TestController extends CController { public function actionIndex() { echo "<h1>All cars</h1>"; $cars = Car::model()->findAll(); foreach($cars as $car) { // Mi chic xe c th l ca class car, sportcar, hoc familycar echo get_class($car).' '.$car->name."<br />"; } echo "<h1>Sport cars only</h1>"; $sportCars = SportCar::model()->findAll(); foreach($sportCars as $car) { echo get_class($car).' '.$car->name."<br />"; } } } Xong xui vo trnh duyt g : http://localhost/skybook/test/index
153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

6. S dng CdbCriteria
Khi s dng Active Record method nh findAll, hoc find, chng ta c th nhn tiu chun ging nh tham s,n c th tr v mng hay mt khi to ca CdbCriteria class.Class ny hin th query tiu chun, ging nh iu kin,ordering by,limit/offset, vv Thng thng n hay c s dng nh di y: $criteria = new CDbCriteria(); $criteria->limit = 10; $criteria->order= 'id DESC'; $criteria->with = array('comments'); $criteria->compare('approved', 1); $criteria->addInCondition('id', array(4, 8, 15, 16, 23, 42)); $posts = Post::model()->findAll($criteria); Cch lm vic: Bn thn class Criteria khng xy dng query, nhng ch hin th d liu hoc cho php iu chnh chng, Hm lm vic thc t nm trong Active Record method ni cc tiu chun ca class ny s dng.
153

Dch code c th c nh sau: Hin th 10 dng post vi comment t approved post vi id trong khong 4,8,15,16,24 hoc 42 order by id.

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Select * from post p (nh danh post) JOIN (ni) comment c(nh danh comment) ON (iu kin ni) p.id=c.post_id where p.approval=1 and p.id in (4,8,16,15,24,42) order by p.id DESC LIMIT 10.

CHNG 6

153

K THA Yii

Trong chng ny, bn s khm ph: S dng data provides S dng grids (li) S dng lists (danh sch) To custom grid column( Ct li)

Yii c th vin hu ch gi l Zii, n ng hnh cng vi framework v mt s class khc gip cho vic pht trin tr ln d dng hn bao gi ht,hu ht thnh phn ch yu l grid v list ci cho php bn xy dng d liu trong Admin v user website rt nhanh v p. Trong chng ny bn s hc cch iu chnh component v nhng th bn cn,bn s hc v data provides,chng l mt phn trong core framework.
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

1 S dng data provides (nh cung cp d liu)


Data provides c s dng triu tp d liu model ging nh sp xp, phn trang, v querying.Chng c s dng vi grids v lists. Bi v c 2 widget v provider l mt tiu chun (chun mc),bn c th hin th ging nh d liu s dng khc widget v bn c th hin d liu cho mt widget t various provider (ti sn c cung cp). thc hin coder bn vo http://dev.mysql.com/doc/sakila/en/sakila.html download database sau import vo csdl thong qua phpmyadmin. S dng Gii to model film. Vo protected/views/ to grid/index.php <?php $this->widget('zii.widgets.grid.CGridView', array('dataProvider' => $dataProvider, ))?> Sau ,to protected/controllers/GridController.php <?php class GridController extends Controller { public function actionAR() { $dataProvider = new CActiveDataProvider('Film', array( 'pagination'=>array( 'pageSize'=>10, ), 'sort'=>array(
153

'defaultOrder'=> array('title'=>false), ) ));


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $this->render('index', array( 'dataProvider' => $dataProvider, )); } public function actionArray() { $yiiDevelopers = array( array( 'name'=>'Qiang Xue', 'id'=>'2', 'forumName'=>'qiang', 'memberSince'=>'Jan 2008', 'location'=>'Washington DC, USA', 'duty'=>'founder and project lead', 'active'=>true, ), array( 'name'=>'Wei Zhuo', 'id'=>'3', 'forumName'=>'wei', 'memberSince'=>'Jan 2008', 'location'=>'Sydney, Australia',
153

'duty'=>'project site maintenance and development', 'active'=>true, ), array(


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 'name'=>'Sebastin Thierer', 'id'=>'54', 'forumName'=>'sebas', 'memberSince'=>'Sep 2009', 'location'=>'Argentina', 'duty'=>'component development', 'active'=>true, ), array( 'name'=>'Alexander Makarov', 'id'=>'415', 'forumName'=>'samdark', 'memberSince'=>'Mar 2010', 'location'=>'Russia', 'duty'=>'core framework development', 'active'=>true, ), array( 'name'=>'Maurizio Domba', 'id'=>'2650', 'forumName'=>'mdomba', 'memberSince'=>'Aug 2010',
153

'location'=>'Croatia', 'duty'=>'core framework development', 'active'=>true, ),


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 array( 'name'=>'Y!!', 'id'=>'1644', 'forumName'=>'Y!!', 'memberSince'=>'Aug 2010', 'location'=>'Germany', 'duty'=>'core framework development', 'active'=>true, ), array( 'name'=>'Jeffrey Winesett', 'id'=>'15', 'forumName'=>'jefftulsa', 'memberSince'=>'Sep 2010', 'location'=>'Austin, TX, USA', 'duty'=>'documentation and marketing', 'active'=>true, ), array( 'name'=>'Jonah Turnquist', 'id'=>'127', 'forumName'=>'jonah',
153

'memberSince'=>'Sep 2009 - Aug 2010', 'location'=>'California, US', 'duty'=>'component development', 'active'=>false,


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 ), array( 'name'=>'Istvn Beregszszi', 'id'=>'1286', 'forumName'=>'pestaa', 'memberSince'=>'Sep 2009 - Mar 2010', 'location'=>'Hungary', 'duty'=>'core framework development', 'active'=>false, ), ); $dataProvider = new CArrayDataProvider( $yiiDevelopers, array( 'sort'=>array( 'attributes'=>array('name', 'id', 'active'), 'defaultOrder'=>array('active' => true, 'name' => false), ), 'pagination'=>array( 'pageSize'=>10, ), )); $this->render('index', array(
153

'dataProvider' => $dataProvider, )); } public function actionSQL()


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 { $count=Yii::app()->db->createCommand('SELECT COUNT(*) FROM film')->queryScalar(); $sql='SELECT * FROM film'; $dataProvider=new CSqlDataProvider($sql, array( 'keyField'=>'film_id', 'totalItemCount'=>$count, 'sort'=>array( 'attributes'=>array('title'), 'defaultOrder'=>array('title' => false), ), 'pagination'=>array( 'pageSize'=>10, ), )); $this->render('index', array( 'dataProvider' => $dataProvider, )); } } Vo localhost /skybook/grid/aR , grid/array v grid/sql xem kt qu:

153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

2. S dng Zii Grid


Zii grid rt hu ch v nhanh chng trong vic to khung li cho cc trang qun tr admin hoc bt k trang no yu cu v s liu. bt u bn vo website : http://dev.mysql.com/doc/sakila/en/ sakila.html. down load database sau do gii nn vo phpmyadmin, chn table ca bn v import db. S dng Gii to model generated cho customer, address,city. Tip theo vo Gii chn controller generated : Customer Chy customer controller v ti qun tr Manage Customer link trong gii bn s c kt qu nh sau:
153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

3. S dng lists
Zii list l cng c kh tt cho vic trnh by d liu bt k data provider kt thc user khi x l phn trang v sp xp t ng.CListView l rt d dng trong vic custom v n cho php xy dng bt k thuc tnh no trong list page. Vo website : http://dev.mysql.com/doc/sakila/en/ sakila.html download c s d liu ri vo phpmyadmin import vo database Vo gii model generated to : customer,store,address,city Tip theo m gii,chn CRug generator v nhn Customer ti model class field, nhn preview v generated Gii s generated controller trong protected/controllers Chy index action ca customer controller ta c kt qu sau : http://localhost/skybook/customer/index

153

Thm tiu chu n s p x p:


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 bn vo protected/views/customer/index.php v thay th bng ni dung sau : <?php $this->widget('zii.widgets.CListView', array( 'dataProvider'=>$dataProvider, 'itemView'=>'_view', 'sortableAttributes'=>array( 'last_name', 'email', ), )); ?> Customer templates: Thay th views vi ni dung sau: <?php $this->widget('zii.widgets.CListView', array( 'dataProvider'=>$dataProvider, 'itemView'=>'_view', 'sortableAttributes'=>array( 'last_name', 'email', ), 'template' => '{sorter} {pager} {items} {sorter} {pager}', )); ?> Customer markup data display <?php $this->widget('zii.widgets.CListView', array(
153

'dataProvider'=>$dataProvider, 'itemView'=>'_view', 'itemsTagName' => 'ol', 'itemsCssClass' => 'customers',


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 'sortableAttributes'=>array( 'last_name', 'email', ), 'template' => '{sorter} {pager} {items} {sorter} {pager}', )); ?> Tip theo vo protected/views/customer to _views.php <li> <h2> <?php $title = CHtml::encode($data->first_name.' '.$data->last_name); echo CHtml::link($title, array('view', 'id'=> $data->customer_id)); ?> </h2> <ul> <li> <strong><?php echo CHtml::encode($data-> getAttributeLabel('store_id')); ?>:</strong> <?php echo CHtml::encode($data->store-> address->address.', '.$data->store->address->city->city.', '.$data->store->address->district); ?>
153

</li> <li> <strong><?php echo CHtml::encode($data-> getAttributeLabel('email')); ?>:</strong>


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 <?php echo CHtml::encode($data->email); ?> </li> <li> <strong><?php echo CHtml::encode($data-> getAttributeLabel('address_id')); ?>:</strong> <?php echo CHtml::encode($data->address->address.', '.$data->address->city->city.', '.$data->address->district); ?> </li> <li> <strong><?php echo CHtml::encode($data-> getAttributeLabel('active')); ?>:</strong> <?php echo $data->active ? 'Yes' : 'No'; ?> </li> </ul> </li> Vo protected/assets to customer.css ol.customers { list-style: none; margin: 1em 0; } ol.customers>li {
153

margin: 1em; padding:1em; background: #fcfcfc; border: 1px solid #9aafe5;


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } Quay li file _views trong protected/views/customer v thm on sau vo di cng <?php Yii::app()->clientScript->registerCssFile( Yii::app()->assetManager->publish(Yii::getPathOfAlias('application. assets').'/customers.css'))?> Th li trn trnh duyt bng vic F5:

4. To customer Grid column


Hu ht thi gian bn khng cn to khung li cho cc thuc tnh ca bn khi m Yii cung cp y cng c thc hin v th nn bn ch cn to custom cho ring mnh. Ta bt u to custom grid column cho php toggling Y/N gi tr v thay i gi tr trong models nh AJAX Bn vo : http://dev.mysql.com/doc/sakila/en/ sakila.html ti database v sau vo phpmyadmin import v db ca bn. Vo GII model generated to : customer M Gii chn CRUD generated chn : Customer v generated
153

Cch thc hin : Trong table chng ta c mt field active (kch hot) , chng ta mun toggle vi flag column . Column s hin th 2 trng Y v N quyt nh gi tr tr v c cliking hay ko. Vo protected/components/ to FlagColumn.php
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 <?php class FlagColumn extends CGridColumn { public $name; public $sortable=true; public $callbackUrl = array('flag'); private $_flagClass = "flag_link"; public function init() { parent::init(); $cs=Yii::app()->getClientScript(); $gridId = $this->grid->getId(); $script = <<<SCRIPT jQuery(".{$this->_flagClass}").live("click", function(e){ e.preventDefault(); var link = this; $.ajax({ dataType: "json", cache: false, url: link.href, success: function(data){ $('#$gridId').yiiGridView.update('$gridId'); }
153

}); }); SCRIPT; $cs->registerScript(__CLASS__.$gridId.'#flag_link', $script);


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } protected function renderDataCellContent($row, $data) { $value=CHtml::value($data,$this->name); $this->callbackUrl['pk'] = $data->primaryKey; $this->callbackUrl['name'] = urlencode($this->name); $this->callbackUrl['value'] = (int)empty($value); $link = CHtml::normalizeUrl($this->callbackUrl); echo CHtml::link(!empty($value) ? 'Y' : 'N', $link, array( 'class' => $this->_flagClass, )); } protected function renderHeaderCellContent() { if($this->grid->enableSorting && $this->sortable && $this->name!==null) echo $this->grid->dataProvider->getSort()->link( $this->name,$this->header); else if($this->name!==null && $this->header===null) { if($this->grid->dataProvider instanceof CActiveDataProvider) echo CHtml::encode($this->grid->dataProvider-> model->getAttributeLabel($this->name));
153

else echo CHtml::encode($this->name); } else


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 parent::renderHeaderCellContent(); } }

Tip theo vo protected/controllers/CustomerController.php v thay i action Flag public function actionFlag($pk, $name, $value){ $model = $this->loadModel($pk); $model->{$name} = $value; $model->save(false); if(!Yii::app()->request->isAjaxRequest){ $this->redirect('admin'); } } Cui cng vo protected/views/customer/admin.php Thay i dng widget: <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'customer-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( 'customer_id', 'store_id',
153

'first_name', 'last_name', 'email', 'address_id',


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 array( 'class' => 'FlagColumn', 'name' => 'active', ), /* 'create_date', 'last_update', */ array( 'class'=>'CButtonColumn', ), ), )); ?> Sau k hi thnh cng vo Http://localhost/skybook/customer/admin

153

Bn c th thy mt lot cng c kch hot, CRUD hin ln, customer tht d dng ng ko , t m tu kha.

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

CHNG 7
Trong chng ny bn s khm ph: To component To controller action To reusable controller To mt widget To CLI commands To filter To modules To mt customer view renderer Lm m rng distribution-ready

K THA Yii

1. To component
Nu bn c mt vi on code c th ti s dng c nhng bn khng bit cch thc,widget,behavior hy s dng component. Component k tha t CComponent hoc CApplicationComponent.Sau mt component c th kch hot ti ng dng v cu hnh s dng trong protected/config/main.php. v d chng ta nh ngha: EImageManage ng dng thnh phn s dng resize nh s dng th vin GD, kch hot n ti ng dng v s dng n. Vo protected/components to EImageManage.php <?php class EImageManager extends CApplicationComponent
153

{ protected $image; protected $width; protected $height;


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 protected $newWidth; protected $newHeight; public function resize($width = false, $height = false){ if($width!==false) $this->newWidth = $width; if($height!==false) $this->newHeight = $height; return $this; } public function load($filePath) { list($this->width, $this->height, $type) = getimagesize($filePath); switch ($type) { case IMAGETYPE_GIF: $this->image = imagecreatefromgif($filePath); break; case IMAGETYPE_JPEG: $this->image = imagecreatefromjpeg($filePath); break; case IMAGETYPE_PNG: $this->image = imagecreatefrompng($filePath); break;
153

default: throw new CException('Unsupported image type ' . $type); } return $this;
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } public function save($filePath) { $ext = pathinfo($filePath, PATHINFO_EXTENSION); $newImage = imagecreatetruecolor($this->newWidth, $this->newHeight); imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $this->newWidth, $this->newHeight, $this->width, $this->height); switch($ext) { case 'jpg': case 'jpeg': imagejpeg($newImage, $filePath); break; case 'png': imagepng($newImage, $filePath); break; case 'gif': imagegif($newImage, $filePath); break; default:
153

throw new CException("Unsupported image type ", $ext); }

imagedestroy($newImage);
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 if(!is_file($filePath)) throw new CException("Failed to write image."); } function __destruct() { imagedestroy($this->image); } } Tip theo vo main.php trong protected/config kch hot: Tm v thm vo on sau : // application components 'components'=>array( 'image' => array( 'class' => 'EImageManager', ), Tip theo chng ta s s dng on component mi nh sau: Yii::app()->image ->load(Yii::getPathOfAlias('webroot').'/src.png') ->resize(100,100) ->save(Yii::getPathOfAlias('webroot').'/dst.png');
153

T i application component t n t i

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Hu ht thi gian chng ta cn to ng dng thnh phn ca ring ta, tuy nhin vic ti code tn ti gip ta gim thi gian lp trnh v tit kim cng sc. V d hin user role t databse s dng Yii::app()->user->role c th k tha t CwebUser component ging nh sau: <?php class WebUser extends CWebUser { private $_model = null; function getRole() { if($user = $this->getModel()){ return $user->role; } else return 'guest'; } private function getModel(){ if($this->_model === null){ if($this->id === null) return null; $this->_model = User::model()->findByPk($this->id); } return $this->_model; } } V trong main.php ta phi cu hnh li nh sau:
153

// application components 'components'=>array(


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 'user'=>array( 'class' => 'WebUser', // other properties ),

2. To controller action
Trc tin bn vo phpmyadmin chn sql v thc hin query sau: CREATE TABLE `post` ( `id` int(11) NOT NULL auto_increment, `text` text, `title` varchar(255) default NULL, PRIMARY KEY (`id`) ); CREATE TABLE `comment` ( `id` int(11) NOT NULL auto_increment, `text` text, PRIMARY KEY (`id`) ); Generated model vi : post v comment trong Gii. Vo protected/extensions/actions to EDeleteAction.php <?php class EDeleteAction extends CAction
153

{ public $modelName; public $redirectTo = array('index'); /**


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 * Runs the action. * This method is invoked by the controller owning this action. */ public function run($pk) { CActiveRecord::model($this->modelName)->deleteByPk($pk); if(Yii::app()->getRequest()->getIsAjaxRequest()) { Yii::app()->end(200, true); } else { $this->getController()->redirect($this->redirectTo); } } } Tip theo vo kch hot controller : protected/controllers/ to DeleteController.php: <?php class DeleteController extends CController { public function actions() {
153

return array( 'deletePost' => array( 'class' => 'ext.actions.EDeleteAction', 'modelName' => 'Post',
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 'redirectTo' => array('indexPosts'), ), 'deleteComment' => array( 'class' => 'ext.actions.EDeleteAction', 'modelName' => 'Comment', 'redirectTo' => array('indexComments'), ), ); } public function actionIndexPosts() { echo "I'm index action for Posts."; } public function actionIndexComments() { echo "I'm index action for Comments."; } }

By gi bn c th vo trnh duyt g: http://localhost/skybook/delete/deletePost/pk, http://localhost/skybook/delete/deleteComment/pk


153

3. To reusable Controller
Trong Yii bn c th ti s dng controller , nu bn to nhiu ng dng vi controller c thuc tnh ging nhau, di chuyn tt c cc lnh code ti controller ti s dng s tit kim nhiu thi gian cho bn.
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Trong bi ny,chng ta s to n gin api controller s c thi hnh vi JSON,CRUD API cho mt model, n s a input data t POST hoc GET v s s l bng JSON data tip theo l HTTP code Vo Gii,to 1 model generated l Post Tip theo vo protected/extensions/ to json_api to JsonApiController.php: <?php class JsonApiController extends CController { const RESPONSE_OK = 'OK'; const RESPONSE_NO_DATA = 'No data'; const RESPONSE_NOT_FOUND = 'Not found'; const RESPONSE_VALIDATION_ERRORS = 'Validation errors'; public $modelName; public function init() { parent::init(); if(empty($this->modelName)) throw new CException("You should set modelName before using JsonApiController."); } public function actionCreate() { if(empty($_POST))
153

$this->respond(400, self::RESPONSE_NO_DATA); $model = new $this->modelName; $model->setAttributes($_POST);


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 if($model->save()) $this->respond(200, self::RESPONSE_OK); else $this->respond(400, self::RESPONSE_VALIDATION_ERRORS, $model->getErrors()); } public function actionGet($pk) { $model = CActiveRecord::model ($this->modelName)->findByPk($pk); if(!$model) $this->respond(404, self::RESPONSE_NOT_FOUND); $this->respond(200, self::RESPONSE_OK, $model->getAttributes()); } public function actionUpdate($pk) { if(empty($_POST)) $this->respond(400, self::RESPONSE_NO_DATA); $model = CActiveRecord::model ($this->modelName)->findByPk($pk); if(!$model)
153

$this->respond(404, self::RESPONSE_NOT_FOUND); $model->setAttributes($_POST); if($model->save()) $this->respond(200, self::RESPONSE_OK);


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 else $this->respond(400, self::RESPONSE_VALIDATION_ERRORS, $model->getErrors()); } public function actionDelete($pk) { if(CActiveRecord::model($this->modelName)->deleteByPk($pk)) { $this->respond(200, self::RESPONSE_OK); } else { $this->respond(404, self::RESPONSE_NOT_FOUND); } } protected function respond($httpCode, $status, $data = array()) { $response['status'] = $status; $response['data'] = $data; echo CJSON::encode($response); Yii::app()->end($httpCode, true); } }
153

Tip theo bn cn kt ni t i ng dng vi protected/conFig/main.php N c th hon thnh vic thm con troller,cu hnh ti controllerMap property ca CwebApplication v tat hay th cu hnh sau trong main.php
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 'controllerMap' => array( 'api' => array( 'class' => 'ext.json_api.JsonApiController', 'modelName' => 'Post', ), ),

Chng ta cn kt ni ti controller v c bit n s lm vic vi post model. Bn s cn form ti post data nhng nu bn c mt s d liu tn ti bn c th s dng phng thc nhn bng cch http://localhost/skybook/api/get/pk/1 ng dng tr v cho bn nh sau: {"status":"OK","data":{"id":"1","text":"post1", "title":"post1","is_deleted":"0"}}

4. To mt widget
Mt widget l mt phn ti s dng ca khung nhn views n khng ch render mt s d liu m cn c mt s logic. N c th l mt s kin nhn d liu t models v s dng n trong bn thn views. Hy to mt widget v v mt chart biu ngh thut s dng google API. Trong protected/extensions/ to folder chart, to EChartWidget.php:
153

<?php class EChartWidget extends CWidget { public $title;


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 public $data=array(); public $labels=array(); public function run() { echo "<img src=\"http://chart.apis.google.com/chart?chtt=".urlencode ($this->title)."&cht=pc&chs=300x150&chd=". $this->encodeData($this->data)."&chl=".implode ('|', $this->labels)."\">"; } protected function encodeData($data) { $maxValue=max($data); $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx yz0123456789'; $chartData="s:"; for($i=0;$i<count($data);$i++) { $currentValue=$data[$i]; if($currentValue>-1) $chartData.=substr($chars,61*($currentValue/$maxValue),1); else
153

$chartData.='_'; } return $chartData."&chxt=y&chxl=0:|0|".$maxValue; }


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } Tip theo vo protected/controllers/ to ChartController.php <?php class ChartController extends CController { public function actionIndex() { $value = rand(10, 90); $this->widget('ext.chart.EChartWidget', array( 'title' => 'Do you like it?', 'data' => array( $value, 100-$value ), 'labels' => array( 'No', 'Yes', ), )); } } Vo trnh duyt g : http://localhost/skybook/chart/index lu nh phi kt ni vi internet mi truy nhp vo c google th mi thy ci biu ny.

153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

5. To filters (b lc)
Mt filters l mt class c th chy trc/sau mt action ang thc hin. N c th s dng v thay i ni dung thc hin hoc thay i output, trong v d ny bn s thc thi mt output n gin c filter vi compress HTML output v xa tt c mi nh dng. Vo protected/extensions/ to compress_html folder, to ECompressHtmlFilter.php <?php class ECompressHtmlFilter extends CFilter { protected function preFilter($filterChain) { ob_start(); return parent::preFilter($filterChain); } protected function postFilter($filterChain) { $out = ob_get_clean(); echo preg_replace("~>(\s+|\t+|\n+)<~", "><", $out);
153

parent::postFilter($filterChain); } }
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 Tip theo chng ta cn kt ni ti ng dng, chng ta vo protected/controllers/ SiteController v thm filter: public function filters() { return array( array( 'ext.compress_html.ECompressHtmlFilter' ), ); } Chy ng dng v kim tra source code ta s thy nh sau: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional. dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><meta http-equiv="Content-Type" content="text/ html; charset=utf-8" /><meta name="language" content="en" /><!-blueprint CSS framework -->

6. To mt modules
Nu bn mun to mt ng dng y v mun s dng n vi vic custom theo bn, hu ht iu bn mun l vic bn cn phi to mt modules. Trong bi ny,chng ta s nhn vic to modules wiki,chng ta s khng focus user v qun l phn quyn v mi ngi iu khin mi th.
153

Trc tin vo php myadmin chn SQL : to query sau : CREATE TABLE `wiki` ( `id` varchar(255) NOT NULL, `text` text NOT NULL,
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 PRIMARY KEY (`id`) ) Generated : wiki model vi Gii Generated : wiki module vi Gii Di chuyn protected/models/wiki.php ti protected/modules/wiki/models/wiki.php Thm wiki ti moduels section ca protected/config/main.php 'modules'=>array( // uncomment the following to enable the Gii tool 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>false, ), 'wiki' ),

Cch thc hin: u tin hy thm wiki link ti CMarkdownParser. To protected/modules/wiki/components/wikiMarkdownParser.php: <?php class WikiMarkdownParser extends CMarkdownParser { public function transform($text) { $text = preg_replace_callback('~\[\[(.*?)(?:\|(.*?))?\]\]~',
153

array($this, 'processWikiLinks'), $text); return parent::transform($text); }


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 protected function processWikiLinks($matches) { $page = $matches[1]; $title = isset($matches[2]) ? $matches[2] : $matches[1]; return CHtml::link(CHtml::encode($title), array( 'view', 'id' => $page, )); } }

Tip theo s dng getHtml method t protected/modules/wiki/models/wiki.php public function getHtml() { $parser = new WikiMarkdownParser(); return $parser->transform($this->text); } Chng ta to customer protected/modules/wiki/controller/DefaultController. Chng ta ch cn 2 action l views v edit. To protected/modules/wiki/controller/DefaultController.php class DefaultController extends Controller { public function actionIndex() {
153

$this->actionView('index'); } public function actionView($id)


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 { $model = Wiki::model()->findByPk($id); if(!$model) { $this->actionEdit($id); Yii::app()->end(); } $this->render('view', array( 'model' => $model, )); } public function actionEdit($id) { $model = Wiki::model()->findByPk($id); if(!$model) { $model = new Wiki(); $model->id = $id; } if(!empty($_POST['Wiki'])) { if(!empty($_POST['Wiki']['text']))
153

{ $model->text = $_POST['Wiki']['text']; if($model->save()) $this->redirect(array('view', 'id' => $id));


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } else { Wiki::model()->deleteByPk($id); } } $this->render('edit', array( 'model' => $model )); } }

Tip theo to views : protected/modules/wiki/views/default/view.php <h2> <?php echo CHtml::encode($model->id)?> [<?php echo CHtml::link('edit', array('edit', 'id' => $model->id))?>] </h2> <?php echo $model->html ?> To views edit: protected/modules/wiki/views/default/edit.php <h2>Editing <?php echo CHtml::encode($model->id)?></h2> <?php echo CHtml::beginForm()?>
153

<?php echo CHtml::activeTextArea($model, 'text', array('cols' => 100, 'rows' => 20))?> <br /><br /> <?php echo CHtml::submitButton('Done')?>
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 <?php echo CHtml::endForm()?> Xong xui vo http://localhost/skybook/wiki/index v localhost/skybook/wiki/edit

Tip theo vo main.php trong protected/config thay i : 'modules'=>array( // uncomment the following to enable the Gii tool 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>false, ), 'wiki'=>array( 'class' => 'ext.wiki.WikiModule' ), ),

Mi modules c to cha mt main modules class ging wikimodule ni chng ta c th nh ngha cu hnh thuc tnh,nh ngha import, thay i ng dn, kch hot controller, v nhiu hn.. Mc nh mi moduels generated vi Gii chy index action ca default controller:
153

public function actionIndex() { $this->actionView('index');


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 }

Trong wiki module indexaction tat hay i nh sau: $model = Wiki::model()->findByPk($id); if(!$model) { $this->actionEdit($id); Yii::app()->end(); } $this->render('view', array( 'model' => $model, )); Nu modules ny gi mt ID chng ta s hin th n v s dng trong views. Nu khng c trang no gi ID, chng ta x l bi action khc: $model = Wiki::model()->findByPk($id); if(!$model) { $model = new Wiki(); $model->id = $id; } if(!empty($_POST['Wiki'])) {
153

if(!empty($_POST['Wiki']['text'])) { $model->text = $_POST['Wiki']['text']; if($model->save())


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $this->redirect(array('view', 'id' => $id)); } else { Wiki::model()->deleteByPk($id); } } $this->render('edit', array( 'model' => $model )); NU KHNG C modules no s dng ID mi to,nu c mt models chng ta edit n,edit form data t POST v kim tra n rng hay khng chng ta delete models,nu c k t chng ta lu li.

6. To mt custom view renderer


C nhiu PHP templates c yii nhn l native PHP v Prado templates. Nu bn mun s dng n trong Yii bn c th nh ngha chng. By gi chng ta s nhng Smarty 3.0 vo Yii. Bn vo trang ch : http://www.smarty.net/. Ti phin bn mi nht v. Gii nn (extract here ) ri vo folder copy folder libs ca smarty ti protected/vendors/smarty . Cch thc hin nh sau: Vo protected/extensions/smarty to ESmartyViewRenderer.php: <?php
153

class ESmartyViewRenderer extends CApplicationComponent implements IViewRenderer {


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 public $fileExtension='.tpl'; public $filePermission=0755; private $smarty; function init() { Yii::import('application.vendors.smarty.*'); spl_autoload_unregister(array('YiiBase','autoload')); require_once('Smarty.class.php'); spl_autoload_register(array('YiiBase','autoload')); $this->smarty = new Smarty(); $this->smarty->template_dir = ''; $compileDir = Yii::app()->getRuntimePath ().'/smarty/compiled/'; if(!file_exists($compileDir)){ mkdir($compileDir, $this->filePermission, true); } $this->smarty->compile_dir = $compileDir; $this->smarty->assign('Yii', Yii::app()); } /** * Render mt file viws. * Phng thc c yu cu t {@link IViewRenderer}.
153

* @param CBaseController the controller or widget who is rendering the view file. * @param string the view file path * @param mixed the data to be passed to the view
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 * @param boolean whether the rendering result should be returned * @return mixed the rendering result, or null if the rendering result is not needed. */

public function renderFile($context,$sourceFile,$data,$return) { // current controller properties will be accessible as {this.property} $data['this'] = $context; if(!is_file($sourceFile) || ($file=realpath($sourceFile))= ==false) throw new CException(Yii::t('ext','View file "$sourceFile" does not exist.', array('{file}'=>$sourceFile))); $this->smarty->assign($data); if($return) return $this->smarty->fetch($sourceFile); else $this->smarty->display($sourceFile); } } Tip theo bn cn kt ni views renderer vi ng dng. Trong protected/config/main.php chng ta cn ti viewRenderer component:
153

// application components 'components'=>array(


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 'viewRenderer'=>array( 'class'=>'ext.smarty.ESmartyViewRenderer', ), ), Lu , trong component c d liu th bn nguyn ch vic thm vo : 'viewRenderer'=>array( 'class'=>'ext.smarty.ESmartyViewRenderer', ), By gi kim tra n, To protected/controllers/ To SmartyController.php <?php class SmartyController extends Controller { function actionNative() { $this->render('native', array( 'username' => 'Alexander', )); } function actionSmarty() {
153

$this->render('smarty', array( 'username' => 'Alexander', )); }


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 }

Tip theo t o views: protected/views/smarty/native.php: Hello, <?php echo $username?>! protected/views/smarty/smarty.tpl: Hello, {$username}! By gi vo trnh duyt g : http://localhost/skybook/smarty/native Bn s thy dng : Hello,Alexander!

7. Lm extensions distribution-ready
Trong chng ny bn c hc rt nhiu cc to thuc tnh t Yii extensions. By gi chng ta ni v cch chia s thnh qu ca bn vi mi ngi v ti sao n li quan trong. Hy check trong form sau nhng iu bn suy ngh l ng nht v extensions Ni dung trong sang, d c v s dng trong API Ti liu tt Mi ngi u c th tm thy n Extensions p dng c hu ht trong ng dng user S l thnh phn chnh Tt cho vic test code, to nn tng cho tng vi bi test Bn cn c cung cp h tr cho n Tt nhin tt c yu t trn u c yu cu thc s cn thit to ra mt sn phm tt.
153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

CHNG 8
S dng controller filter

BO MT

Bn s khm ph iu g trong chng cui ny ?

S dng CHtml v CHtmlPurifier ti s kin XSS Khm ph SQL injection Khm ph CSRF S dng RBAC

1. S dng controller filter


Trong nhiu trng hp,chng ta cn lc ra d liu hoc thc hin mt s action c bn trong data,v d vi custom filter, chng ta c th lc ra lt truy cp bi IP,sc mnh ca user vi vic s dng HTTPS,hoc redirect user t mt phn quan trng trong cu hnh trang s dng trong ng dng. Yii c xy dng hai b lc ,u tin l CInlineFilter n cho php s dng controller method nh mt b lc, v ci th hai l (l mt th chng ta s focus n) CAccessControlFilter n cho php iu khin truy cp ti d liu ca controller action. Trong bi hc ny ta s thc hin nhng vic sau: Gii hn truy cp ti controller action vi ch cc user nh danh Gii hn truy cp ti controller action t IPs c bit Gii hn truy cp ti ngi dng c bit Gii hn truy cp cho user ca mt trnh duyt c bit, trong trng hp chng ta cng c th hin th custom messager
153

Trc tin vo protected/controllers to AccessController.php <?php class AccessController extends CController {


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 public function actionAuthOnly() { echo "Looks like you are authorized to run me."; } public function actionIp() { echo "Your IP is in our list. Lucky you!"; } public function actionUser() { echo "You're the right man. Welcome!"; } } Tip theo ta thm b lc sau: public function filters() { return array( 'accessControl', ); }

Tip theo ta thm access Rules (quy tc truy cp)


153

{ return array( array( 'deny',


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 'expression' => 'strpos($_SERVER[\'HTTP_USER_AGENT\'], \'MSIE\') !== FALSE', 'message' => "You're using the wrong browser, sorry.", ), array( 'allow', 'actions' => array('authOnly'), 'users' => array('@'), ), array( 'allow', 'actions' => array('ip'), 'ips' => array('127.0.0.1'), ), array( 'allow', 'actions' => array('user'), 'users' => array('admin'), ), array('deny'), ); }
153

http://localhost/skybook/access/authonly , thay autheronly bng ip, user test By gi chng ta s th controller trn trnh duyt s dng c 2 ti khon admin v demo s u c kt qu sau

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

2. S dng CHtml v CHtmlPurifier ti s kin XSS


XSS l vit tt ca cross-site scripting v l mt loi l hng m cho php trch mt kch bn pha my khch (thng thng, JavaScript) trong trang c xem bi ngi dng khc. Xem xt sc mnh ca kch bn pha my khch ny c th dn n hu qu rt nghim trng nh b qua kim tra an ninh, nhn c mt thng tin ngi dng, hoc r r d liu. test ta vo protected/controllers to XssController.php <?php class XssController extends CController { public function actionSimple() { echo 'Hello, '.$_GET['username'].'!'; } } By gi vo trnh duyt g : http://localhost/skybook/xss/simple? username=Longt8x, tuy nhin ti sn chnh khng xut hin ln output , ta g tip ; http://localhost/skybook/xss/simple?username=<script>alert(XSS);</script>

153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012

ng nhin trong v d ny khch ch s dng mt hm alert thong s, nhng trong form data ca bn cha nhiu d liu mt th iu tht thot l kh trnh, Yii a ra gii php sau: class XssController extends CController { public function actionSimple() { echo 'Hello, '.CHtml::encode($_GET['username']).'!'; } }

i vi mt link bn ch cn s dng nh sau: echo CHtml::link(CHtml::encode($_GET['username']), array());


153

Tip theo s dng CHtmlPurifier gip loi b nhng thong tin tha do pha my khch t nhp vo

public function actionHtml()


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 { $this->beginWidget('CHtmlPurifier'); echo $_GET['html']; $this->endWidget(); } public function actionHtml() { $purifier=new CHtmlPurifier(); echo $purifier->purify($_GET['html']); } Ta vo trnh duyt g http://localhost/skybook/xss/html? html=Hello,<strong>username</strong>!<script>alert(XSS);</script> s c kt qu sau:

3. S kin SQL injection


SQL injection l mt loi injection code c s dng lm tn thng cp c s d liu v cho php thc hin bt k SQL cho php ngi s dng c hi thc hin hnh ng chng hn nh xa d liu hoc nng cao c quyn ca h . Trc tin vo phpmyadmin chn sql v thm query sau: CREATE TABLE `user` (
153

`id` int(11) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(100) NOT NULL, `password` varchar(32) NOT NULL,
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 PRIMARY KEY (`id`) ); INSERT INTO `user`(`id`,`username`,`password`) VALUES ( '1','Alex' ,'202cb962ac59075b964b07152d234b70'); INSERT INTO `user`(`id`,`username`,`password`) VALUES ( '2','Qiang ','202cb962ac59075b964b07152d234b70'); Tip theo generated model : User s dng Gii Vo protected/controllers/ to SqlController.php <?php class SqlController extends CController { public function actionSimple() { $userName = $_GET['username']; $password = md5($_GET['password']); $sql = "SELECT * FROM user WHERE username = '$userName' AND password = '$password' LIMIT 1;"; $user = Yii::app()->db->createCommand($sql)->queryRow(); if($user) { echo "Success"; }
153

else { echo "Failure"; }


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } } Vo trnh duyt g : http://localhost/skybook/sql/simple? username=test&password=test bn s thy trnh duyt in : Failure. By gi thay http://localhost/skybook/sql/simple?username=%27+or+ %271%27%3D%271%2 7%3B+--&password=whatever. S thy hoc 1 =1; -N tng ng vi query : SELECT * FROM user WHERE username = '' or '1'='1'; --' AND password = '008c5926ca861023c1d2a36653fd88e2' LIMIT 1; fix vn ny bn thm vo controller action mi: public function actionPrepared() { $userName = $_GET['username']; $password = md5($_GET['password']); $sql = "SELECT * FROM user WHERE username = :username AND password = :password LIMIT 1;"; $command = Yii::app()->db->createCommand($sql); $command->bindValue('username', $userName); $command->bindValue('password', $password); $user = $command->queryRow();
153

if($user) { echo "Success";


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 } else { echo "Failure"; } }

By gi vo http://localhost/skybook/sql/prepared S hin ra ch failure, nh vy thong tin c bo ton.

4. S kin CSRF
CSRF hay XSRF vit tt cross-site l mt request gi ,mt vi th thut s dng c hi ca trnh duyt user m thm thc hin mt yu cu HTTP n vi trang web khi ngi dng ng nhp. Mt v d v cuc tn cng ny l chn mt th hnh nh v hnh vi src tr n http://example.com/site/logout. Thm ch nu cc th hnh nh c chn vo trong mt trang web khc,ngay lp tc bn s c ng nhp t example.com. Hu qu ca CSRF c th s rt nghim trng: ph hy d liu trang web, ngn chn tt c cc ngi s dng trang web ng nhp vo, phi by tin d liu, v hn th na Mt s thc trng ca CSRF: Nh CSRF nn c thc hin bi ngi s dng trnh duyt ca nn nhn, k tn cng c th khng thng thay i tiu HTTP c gi. Yii include mt token generation v token checking. Thm na c th t ng insert mt token trong HTML form: Vo protected/config/main.php thm on sau: 'components'=>array(
153

'request'=>array( 'enableCsrfValidation'=>true, ),
http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 ),

Sauk hi cu hnh ng dng bn s dng C:Html::beginForm v CHtml::endForm khi to ca HTML form. public function actionCreate() { echo CHtml::beginForm(); echo CHtml::submitButton(); echo CHtml::endForm(); }

Yii s t ng thm mt token field n sau: <form action="/csrf/create" method="post"> <div style="display:none"><input type="hidden" value="e4d1021e79ac 269e8d6289043a7a8bc154d7115a" name="YII_CSRF_TOKEN" /> Nu bn lu form html v th submit,bn s nhn c mt li thong bo ging nh sau:

153

Bo mt mc cao: Nu ng dng ca bn yu cu bo mt cao hn na, bn hy vo protected/config/main.php 'components' => array(


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 ... 'user'=>array( // enable cookie-based authentication 'allowAutoLogin'=>false, ), ... ),

Sau cho session timeout hot ng 'components' => array( ... 'session' => array( 'timeout' => 200, ), ... ), S dng thuc tnh GET v POST HTTP khng nh khng s dng GET cho cc hot ng thay i d liu hoc trng thi. Gn b vi nguyn tc ny l mt cch tt. N khng ngn cn tt c cc loi CSRF, nhng t nht s lm cho mt s mi trch nh <img src = tr ln v ngha....

5 . S dng RBAC
RBAC l phng php kim sot truy cp mnh m nht c sn trong Yii. N c m t trong ti liu hng dn,nhng k t khi n l kh phc tp v mnh m, n khng phi l d dng nh vy hiu lm th no n thc shot ng m khng nhn c hood . Trong bi ny, chng ta s lm r vai tr ca h thng phn cp t tiu chun hng dn, import n, v gii thch nhng g ang xy ra trong ni b. Vo protected/config/main.php sa li thong s ging nh sau:
http://www.seodrupal.vn | Learn Drupal Online

153

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 return array( 'components'=>array( 'authManager'=>array( 'class'=>'CDbAuthManager', 'connectionID'=>'db', ), ), );

Thm vo protected/components/UserIdentity.php on sau: $users=array( // username => password 'demo'=>'demo', 'admin'=>'admin', 'readerA'=>'123', 'authorB'=>'123', 'editorC'=>'123', 'adminD'=>'123', ); To protected/controllers/RbacController.php
153

<?php class RbacController extends CController { public function filters()


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 { return array( 'accessControl', ); } public function accessRules() { return array( array( 'allow', 'actions' => array('deletePost'), 'roles' => array('deletePost'), ), array( 'allow', 'actions' => array('init', 'test'), ), array('deny'), ); } public function actionInit() {
153

$auth=Yii::app()->authManager; $auth->createOperation('createPost','create a post'); $auth->createOperation('readPost','read a post'); $auth->createOperation('updatePost','update a post');


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 $auth->createOperation('deletePost','delete a post'); $bizRule='return Yii::app()->user->id==$params ["post"]->authID;'; $task=$auth->createTask('updateOwnPost','update a post by author himself',$bizRule); $task->addChild('updatePost'); $role=$auth->createRole('reader'); $role->addChild('readPost'); $role=$auth->createRole('author'); $role->addChild('reader'); $role->addChild('createPost'); $role->addChild('updateOwnPost'); $role=$auth->createRole('editor'); $role->addChild('reader'); $role->addChild('updatePost'); $role=$auth->createRole('admin'); $role->addChild('editor'); $role->addChild('author'); $role->addChild('deletePost'); $auth->assign('reader','readerA'); $auth->assign('author','authorB'); $auth->assign('editor','editorC');
153

$auth->assign('admin','adminD'); echo "Done."; } public function actionDeletePost()


http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 { echo "Post deleted."; } public function actionTest() { $post = new stdClass(); $post->authID = 'authorB'; echo "Current permissions:<br />"; echo "<ul>"; echo "<li>Create post: ".Yii::app()->user->checkAccess ('createPost')."</li>"; echo "<li>Read post: ".Yii::app()->user->checkAccess ('readPost')."</li>"; echo "<li>Update post: ".Yii::app()->user->checkAccess ('updatePost', array('post' => $post))."</li>"; echo "<li>Delete post: ".Yii::app()->user->checkAccess ('deletePost')."</li>"; echo "</ul>"; } } By gi vo localhost/skybook/rbac/init xem kt qu

153

http://www.seodrupal.vn | Learn Drupal Online

[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012 t tn cc nt RBAC Mt h thng cp bc phc tp tr nn kh hiu m khng cn s dng mt s loi t tn mt hi ngh. Mt quy c gip khng lm cho chng ta nhm ln nh sau: [Group_] [own_] entity_action Trng hp ring c s dng khi quy tc xc nh kh nng sa i mt phn t ch khi ngi s dng hin nay l ch s hu ca cc yu t v nhm ch l mt khng gian tn. Thc th l mt tn ca thc th, chng ti ang lm vic v hnh ng l hnh ng m chng ti ang thc hin. V d, nu chng ta cn phi to ra mt quy tc xc nh nu ngi dng c th xa mt bi ng blog, chng ti s t tn n nh l blog_post_delete. Nu quy tc xc nh nu mt ngi dng c th chnh sa cc blog ca ring bnh lun, tn s c blog_own_comment_edit. Mt cch gi cho h thng phn cp n gin v hiu qu Theo nhng ngh khi c th ti a ha hiu sut v gim h thng phn cp phc tp: ff Trnh gn nhiu vai tr mt ngi dng duy nht. ff Khng kt ni cc nt cng loi. V vy, v d, trnh kt ni mt trong nhng nhim v mt s khc. gi cho h thng phn cp cn n gin, chng ta c th trnh vic to ra v s dng cc nt thm trong mt s trng hp bng cch thay th chng bng cc iu kin b sung. Mt v d l cc sa i ca Post. Chng ta c th to ra mt nt blog_own_post_edit vi bizRule nh sau: return Yii::app()->user->id==$params["post"]->author_id; Ngoi ra, chng ta c th thm cng mt logic thng xuyn la chn bi nh sau: $post = Post::model()->findByAttributes(array( 'id' => $id, 'author_id' => Yii::app()->user->id, )); If(!$post) throw new CHttpException(404); Bng cch s dng cch th hai, chng ta s trnh nhn c mt nt h thng phn cp RBAC do lu kho.

153

http://www.seodrupal.vn | Learn Drupal Online

You might also like