153 [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 : [email protected]Everything you want supported please send request to email or yahoo : [email protected], thank you! Bạn vào trang chủ : http://www.yiiframework.com/download/ Download phiên bản mới nhất về sau đó giải nén (extract here), sau đó rename lại là cookbook, copy folder cookbook mới giải nén vào C:\xampp\htdocs\, bạn phải down xampp về rồi cài đặt setup thành công thì chạy xampp center thiết lập apache và mysql running. http://localhost/cookbook/requirements/index.php Phần mềm chạy local: Xampp, Wamp, ko nên dùng appserv vì bị lỗi( nguyên nhân mình ko biết, tốt nhất nên tránh). Hoặc xài luôn host thật nếu nhà có điều kiện. 1. Chuẩn bị Trước tiên bạn phải cấu hình windows để sử dụng được php với cmd -Giả sử bạn cài apache mặc định trên WinXP (C:\xampp\htdocs). -Bạn thiết lập lại biến môi trường (Environment Variables) bằng cách vào: Start -> My Computer (right click!) -> Advanced Tab -> Environment Variables -> Click Path in System variables (windows 7 là Path) -> Edit. http://www.seodrupal.vn | Learn Drupal Online
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Everything you want supported please send request to email or yahoo : [email protected], thank you!
Bạn vào trang chủ : http://www.yiiframework.com/download/
Download phiên bản mới nhất về sau đó giải nén (extract here), sau đó rename lại là cookbook, copy folder cookbook mới giải nén vào C:\xampp\htdocs\, bạn phải down xampp về rồi cài đặt setup thành công thì chạy xampp center thiết lập apache và mysql running.
http://localhost/cookbook/requirements/index.php
Phần mềm chạy local: Xampp, Wamp, ko nên dùng appserv vì bị lỗi( nguyên nhân mình ko biết, tốt nhất nên tránh).
Hoặc xài luôn host thật nếu nhà có điều kiện.
1. Chuẩn bịTrước tiên bạn phải cấu hình windows để sử dụng được php với cmd
-Giả sử bạn cài apache mặc định trên WinXP (C:\xampp\htdocs).
-Bạn thiết lập lại biến môi trường (Environment Variables) bằng cách vào: Start -> My Computer (right click!) -> Advanced Tab -> Environment Variables -> Click Path in System variables (windows 7 là Path) -> Edit.
-Click vào biến PATH và chọn Edit. Lưu ý là đừng có xoá bỏ các đường dẫn đã tồn tại trong textbox mà ngăn cách chúng với nhau bằng dấu ";".
-Tiếp đó bạn thêm vào những đường dẫn sau: "C:\xampp\php" và " C:\xampp\htdocs\
cookbook\framework". Lưu ý sửa đường dẫn cho phù hợp với máy bạn nha .-Khởi động máy tính lại.
2.Tạo ứng dụng Yii mới-YiiRoot là thư mục nơi bạn đã cài đặt Yii
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Ok, hoàn tất cấu hình để tiến hành coder.
CHƯƠNG 1 - Giới thiệu về Yii framework
1 – Sử dụng getter and setter ( Hàm nhận và hàm thiết lập).
PHP cũng giống như các công nghệ khác như Java, C# , đều có cấu trúc lập trình hướng đối tượng và xây dựng công nghệ theo các class(lớp), yii framework được xây dựng trên nền php cũng không ngoại lệ, tuy nhiên điều khác biệt là nó kế thừa từ Ccomponent (class ảo cho bất kỳ class nào trong Yii).
Cách thực hiện:
Chúng ta theo dõi định nghĩa lớp trong php với hàm thiết lập (setter) và hàm nhận lại (getter)
class MyClass{private $property;
// ham nhan lay giá trịpublic function getProperty(){return $this->property;}// ham khởi tạo giá trịpublic function setProperty($value){$this->property = $value;}}// tạo mới đối tượng$object = new MyClass();// thiết lập đối tượng$object->setProperty('value');// trả về giá trịecho $object->getProperty();
Trong Yii chúng ta thực hiện nhờ kế thừa từ Ccomponent như sau :
// extending CComponent is necessaryclass MyClass extends CComponent{
private $property;public function getProperty(){return $this->property;}
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
public function setProperty($value){$this->property = $value;}}$object = new MyClass();$object->property = 'value'; // cũng như php : $object->setProperty('value');echo $object->property; // cũng như $object->getProperty();Ngoài ra Yii còn hỗ trợ các hàm sau thực hiện việc thiết lập và nhận giá trị : __get, __set, __isset, và __unset
Cách dùng như sau : vdpublic function __get($name){$getter='get'.$name;if(method_exists($this,$getter))return $this->$getter();
}
2 – Sử dụng Yii Event ( Các sự kiện trong Yii)
Hầu hết các class đều được kế thừa từ Yii Component (Ccomponent) vì thế nên chúng ta có thể sử lý tốt các sự kiện từ ứng dụng. Một sự kiện tương ứng là một lời nhắn, một thông điệp tới ứng dụng để yêu cầu thực hiện công việc nào đó, chúng ta có thể đăng ký nhiều sự kiện xử lí để thực hiện tùy theo loại sự kiện, một hàm xử lý có thể nhận được các tham số từ các sự kiện với các tham số được định nghĩa, Sử dụng các sự kiện cho phép đạt được sự linh hoạt trong ứng dụng.
Cách thực hiện thế nào ?Để định nghĩa một sự kiện trong lớp con của Ccomponent, bạn sẽ thêm phương thức (method) với tên bắt đầu bằng từ “on”, ví dụ nếu bạn thêm onRegister method , bạn sẽ nhận được tương ứng một sự kiện bạn đã khai báo.
Các loại sự kiện được sử dụng giống như :- Định nghĩa một sự kiện được thêm tuơng ứng một phương thức,- Kích hoạt một hay nhiều sự kiện xử lý.- Thành phần nâng cao (raise) của một sự kiện được sử dụng bởi
Ccomponent ::raiseEvent method - Tất cả các thể hiện xử lý được gọi tự động.Hãy nhìn vào cách chúng ta có thể kích hoạt một sự kiện xử lý từ một sự kiện.Chúng ta sử dụng Ccomponent::attachEventHandler method.Nó chấp nhận các tham số sau đây:$name : Tên sự kiện.
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
$handler: Xử lý sự kiện,yêu cầu của bạn trước mỗi sự kiện thường là một hàm tiêu chuẩn gọi lại (standard function callback) php để sử dụng.Bạn có thể thực hiện hàm gọi lại như sau : Sử dụng hàm cục bộ (global function) và chỉ nhận tên giống như các chuỗi ví dụ “ my_function”.Sử dụng các phương thức tĩnh từ lớp (static class method).Bạn sẽ chỉ trả về giá trị array(‘Tên lớp (Name class)’,’Tên phương thức tĩnh(static method Name)’).Sử dụng object method : array($object,’object method’)Tạo và nhận hàm định danh sử dụng create_function như sau:Trước tiên định nghĩa componentpublic function init() { parent::init(); $component = Yii::app()->{$this->component}; }$component->attachEventHandler(‘onClick’,create_function(‘$event’,’echo “click!”));
Với phiên bản PHP 5.3 trở lên bạn chỉ cần viết:$component->attachEventHandler(‘onclick’,function($event){echo ‘click’;});
Để code ngắn hơn bạn chỉ cần viết như sau : $component->onClick=$handler; hoặc$component->onClick->add($handler);
Để quản lý việc xử lý sự kiện bạn sử dụng hàm get handler list (Clist) trong Ccomponent::getEventHandlers và làm việc với nó.Ví dụ : $component->getEventHandlers(‘onClick’)->add($handler);
Để thêm một xử lý vào đầu danh sách các xử lý ta viết:$component->getEventHandlers(‘onClick’)->insertAt(0,$handler);
Để xóa một xử lý bạn sử dụng Ccomponent::detachEventHandler:$component->detachEventHandler(‘onClick’,$handler);
Yii application có 2 sự kiện được sử lý trong các trường hợp sau ;Capplication::onBeginRequest và Capplication::onEndRequest hãy sử dụng chúng .Đặt cấu hình thiết lập như sau vào file index.php trước khi chạy ứng dụng:
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
require_once($yii);$app = Yii::createWebApplication($config);// Kích hoạt sử lý trước khi bắt đầu ứng dụngYii::app()->onBeginRequest = function($event){// starting output buffering with gzip handlerreturn ob_start("ob_gzhandler");};// Kích hoạt sử lý sau khi kết thúc ứng dụngYii::app()->onEndRequest = function($event){// releasing output bufferreturn ob_end_flush();};$app->run();
Comment là một tiêu chuẩn của AR model generate với Gii, Post là một phương thức ngoại lệ trong Gii-generated model. Chúng ta sẽ custom sự kiện NewCommentEvent để thực hiện cả post và comment model và sử lý class Notifier làm việc:
Bắt đầu vào protected/components/ tạo NewCommentEvent.php
class NewCommentEvent extends CModelEvent {
public $comment;
public $post;
}
Rất đơn giản chỉ bao gồm 2 thuộc tính.
Bây giờ bạn di chuyển tới protected/models/Post.php. Tất cả tiêu chuẩn AR method được xây dựng như sau:
class Post extends CActiveRecord {
function addComment(Comment $comment){
$comment->post_id = $this->id;
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
// tạo mới sự kiện từ class trước
$event = new NewCommentEvent($this);
$event->post = $this;
$event->comment = $comment;
// kích hoạt sự kiện mới
$this->onNewComment($event);
return $event->isValid;
}
// định nghĩa sự kiện onNewComment
public function onNewComment($event) {
$this->raiseEvent('onNewComment', $event);
}
}
Tiếp theo tạo trong protected/components/ file Notifier.php
class Notifier {
function comment($event){
$text = "Có một comment mới từ {$event->comment->author} trong post {$event->post->title}";
Như vậy là bạn đã biết cách kích hoạt và sử lý một sự kiện , tuy nhiên nhiều trường hợp không nhất thiết phải kích hoạt sử lý sự kiện mà chúng ta cũng có thể kích hoạt sử lý sự kiện từ các component đã tồn tại và chúng ta chỉ cần overriding các class cơ bản đó . Ví dụ chúng ta có form model UserForm sử dụng để thu thập thông tin của người dùng và chúng ta cần hiển thị đầy đủ họ tên của user.
Thật may, Cmodel class cơ bản trong Yii model có thể mở rộng form models.
Cmodel::afterValidate được gọi sau khi form được submit thành công.
Ta vào protected/models/ tạo file UserForm.php
class UserForm extends CFormModel
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
{
public $firstName; //tên
public $lastName; //họ
public $fullName; //tên đầy đủ
public function rules()
{
return array(
//tập hợp quy tắc : firstname,lastname được yêu cầu (k rỗng)
array('firstName, lastName', 'required'),
);
}
// $event ở đây được thiết lập từ CEvent
// tạo ra và thiết lập một sự kiện( event) khi method được gọi .
// CModel::afterValidate().
function afterValidate()
{
//Nếu phương thức được gọi thì sự kiện sẽ tự động nạp dữ liệu sau:
// điều quan trọng là nó phải được gọi lại từ lớp cha (parent class)
// đó là điều giúp các sử lý sự kiện khác được gọi lại.
return parent::afterValidate();
}
}
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Chúng ta cần gọi lại từ lớp cha (parent class) của afterValidate() vì hàm định nghĩa onAfterValidate() thực chất là raiseEvent:
Protected function afterValidate()
{
$this->onAfterValidate(new CEvent($this));
}
2. Sử dụng import và autoloadingKhi lập trình với php hầu hết các class và hàm tạo đều được load bởi hai phương thức là : “include” và “require”. Tuy nhiên bạn cũng có thể sử dụng loader nhờ SPL class, yii sử dụng công nghệ này vào Yii Base và việc xây dựng các lớp tiêu chuẩn trong yii CdbCriteria. Mặc định autoloader (YiiBase::autoload) sẽ được sử dụng.Hầu hết tất cả các lớp được load khi cần including hoặc importing . Yii hoàn tất bởi YiiBase::$_coreClasses map, vì thế mà việc load trong Yii rất nhanh.Zii class cũng như Cmenu, extension class hoặc class của bạn định nghĩa cũng được tự động load.
3. Cấu hình Component(Thành phần)Yii là một framework custom, hầu như mọi thứ đều có thể custom một cách dễ dàng đó là ưu điểm của yii, trước tiên chúng ta tìm hiểu file config của Yii trong protected/con fig /main.phpĐể có thể sử dụng database kết nối mysql ta chỉ cần bỏ 2 dòng /* ---- */ để array dưới đây được kích hoạt.return array(…'components'=>array('db'=>array('class'=>'system.db.CDbConnection','connectionString'=>'mysql:host=localhost;dbname=database_name','username'=>'root','password'=>'','charset'=>'utf8',),…),…);
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Khi đã có thể kết nối tới database rồi bạn chỉ cần khai báo Yii::app()->db; là ta đã có thể làm việc trực tiếp với CSDL.
Một số component trong Yii bạn nên biết :
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
4: Làm việc với Request
Với yii bạn có thể trả về dữ liệu dưới dạng request mà php đưa ra như $_SERVER,$_GET,$_POST, nhưng tốt hơn bạn nên làm theo việc sử dụng của Yii là :ChttpRequest class , lớp này giải quyết những ngoại lệ từ server, quản lý cookies,cung cấp thêm vấn đề bảo mật,và đặc biệt là hướng đối tượng .
Bạn có thể truy nhập request component trong yii bằng việc sử dụng : Yii::app()->getRequest(). Vì thế nên xem một số hàm hữu ích , các method trả về khác biệt từ URL :
Để chắc chắn các request được truyền đúng ta có thêm các hàm kiểm tra : IsPostRequest (Kiểm tra hàm post), getIsAjaxRequest (kiểm tra ajax loader), getRequestType (kiểm tra request thuộc loại get hay post hay ajax).
Ví dụ chúng ta muốn kiểm tra xem aJax đã được load hay chưa ta xem ví dụ sau :
class TestController extends CController
{
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
public function actionIndex()
{
if(Yii::app()->request->isAjaxRequest)s
$this->renderPartial('test');
else
$this->render('test');
}
}
Ngoài ra bạn cũng có thể dùng các hàm thiết lập thông dụng của PHP để kiểm tra như isset, ispost ….
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Điều cuối cùng chúng tôi muốn bạn biết thêm trong chương 1 này chính là hàm getCookies, nó trả về từ CcookieCollection class cho phép chúng ta làm việc với cookie, Vì CcookieCollection được kế thừa từ Cmap nên chúng ta có thể sử dụng method sau:
class TestController extends CController
{
public function actionIndex()
{
$request = Yii::app()->request;
// nhận giá trị của cookie
$cookie = $request->cookies['test'];
if($cookie)
// in giá trị cookie
echo $cookie->value;
else {
// tạo mới cookie
$cookie=new CHttpCookie('test','I am a cookie!');
$request->cookies['test'] = $cookie;
}
}
Nếu bạn làm việc với nhiều giá trị của cookie , bạn muốn code của mình ngắn gọn hãy sử dụng class sau:
class Cookie
{
public static function get($name)
{
$cookie=Yii::app()->request->cookies[$name];
if(!$cookie)
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
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ạn thay đổi code trong TestController như sau:
class TestController extends CController
{
public function actionIndex()
{
$cookie = Cookie::get('test');
if($cookie)
echo $cookie;
else
Cookie::set('test','I am a cookie!!');
}
}
Lưu ý, chương một với các bạn mới học sẽ không thể làm thử được vì không có database để thử, xin vui lòng down source code bản English để test app của họ.
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
http://localhost/skybook/index.php/about
http://localhost/skybook/index.php/page/about
Bạn sẽ thấy biến alias trong action page sẽ thay đổi tùy theo đường dẫn thứ 2 sau page bạn điền vào, đây chính là url định danh (url alias).
Thực tế điều gì đã xảy ra:
Với quy tắc : ‘home’=>’website/index’ , trong Yii mỗi controller và action đều có một quy tắc chung mặc định là moduleId (tên module)/controllerID(tên controller)/actionID(tên action). Ví dụ trong trường hợp home đó là module : default, controller website, và action là index.
‘page/<alias>’=>’website/page’,
Ở đây , chúng ta định nghĩa một alias parameter ( tham số định danh) đặc biệt trong Url sau /page/. Nó có thể nhận về các tham số ảo từ tham số $alias trong action Page của website controller.
Ở đây bạn định nghĩa trả về tham số cho nó bằng việc thiết lập quy tắc:
‘<alias:about>’=>’website/page’, đồng nghĩa với việc tham số $alias sẽ chỉ nhận được tham số ảo là about.
2. Generating Url By Path
Khi chúng ta cần generate Url của index và page action trong website controller.Quyết định nơi chúng ta cần nó,có những cách làm khác nhau nhưng cơ bản hãy nhìn một số phương thức generate url sau:
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
CHtml::link(), và một số phương thức CHtml như form,refresh và ajaxLink tất cả chấp nhận url và thuộc tính sử dụng trong views. Định dạng chung cho việc trả về dữ liệu như sau:
Url string: Trả về đường dẫn url dạng kí tự.
Array(quy tắc cục bộ,tham số=>giá trị, tham số => giá trị…). Một số trường hợp url sẽ được generated.
Định dạng của quy tắc vẫn theo thứ tự : modulesID/controllerID/actionId.
Tham số là biến $_GET sẽ nhận một action với định tuyến đặc biệt, cho ví dụ nếu chúng ta muốn tạo một url từ websitecontroller ::actionIndex và nhận tham số $_GET[‘name’] ta chỉ cần làm như sau:
'name' => 'Đệt cụ bọn tàu khựa đã làm ra Yii (Quiang Xue)'));
URl rất hữu ích khi sử dụng controller . Trong controller bạn có thể sử dụng createUrl để tạo mới url và createAbsoluteUrl để hiển thị thong tin về url:
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
4.Tạo Url rules cho trang tĩnh
Một website chứa các thuộc tính tĩnh thường là :/about,/contact,/tos, lệnh sử lý đến trang đó chỉ đơn giản là controller action. Ta sẽ tìm một cách để tạo ra Url rules cho các thuộc tính của trang.
Lại vào main.php phần rules để hót phân chó (xóa toàn bộ mọi thứ trong array của rules).
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Nhấn generate để tạo controller và action index
Địt mẹ máy như lồn, gõ nhanh quá word báo : please slow character @@
Generate xong đồng nghĩa với việc bạn đã tạo xong controller SecureController , bạn có thể vào protected/controllers để tìm thấy file này và trong views.
Thật nhanh chóng đúng không ? ta không cần phải mất công tạo tuy nhiên @@ không khuyến khích vì các dự lớn đòi hỏi khả năng custom cao vì thế nên chỉ generate models cho chóng xong, còn controller thì tốt nhất tự tạo file .
Cấu trúc của YII vẫn tuân thủ MVC, (model/views/controller) .
Thay thế bằng skybook hoặc bạn để nguyên, vào localhost/phpmyadmin tạo table testdrive nếu bạn để nguyên, hoặc nếu thay thế = skybook thì tạo bảng skybook.
Vào phpmyadmin với table mới tạo với query:
CREATE TABLE `post` (
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
`id` int(10) unsigned NOT NULL auto_increment,
`created_on` int(11) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`content` text NOT NULL,
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`)
);
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Nhấn go để query được thực hiện.
Tiếp theo vào GII generated 2 bảng mới tạo bằng cách chọn model generated
Gõ lần lượt Post và User trong table Name rồi generated
Nếu nó báo override thì vẫn generated
Để kiểm tra vào protected/models sẽ tìm thấy 2 file mới tạo.
Tiếp theo vào PostController viết lại như sau:
class PostController extends CController
{
function actionIndex()
{
$posts = Post::model()->findAll();
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
$this->render('index', array(
'posts' => $posts,
));
}
function actionDelete($id)
{
$post = Post::model()->findByPk($id);
if(!$post)
throw new CHttpException(404);
if($post->delete())
$this->redirect('post/index');
throw new CHttpException(500);
}
}
Tiếp theo vào protected/components tạo 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())
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
$this->redirect('post/index');
throw new CHttpException(500);
}
}
Hãy sử dụng component mới này trong PostController ở actionDelete
class PostController extends CController
{
function actions()
{
return array(
'delete' => 'DeleteAction',
);
}
…
}
OK.chúng ta sử dụng delete action trong component cho post controller nhưng vẫn còn user controller, ta custom lại delete action:
class DeleteAction extends CAction
{
public $pk = 'id';
public $redirectTo = 'index';
public $modelClass;
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
function run()
{
if(empty($_GET[$this->pk]))
throw new CHttpException(404);
$model = CActiveRecord::model($this->modelClass)
->findByPk($_GET[$this->pk]);
if(!$model)
throw new CHttpException(404);
if($model->delete())
$this->redirect($this->redirectTo);
throw new CHttpException(500);
}
}
Bây giờ chúng ta có thể sử dụng action cho cả 2 controller .Với post controller ta làm như sau:
class PostController extends CController
{
function actions()
{
return array(
'delete' => array(
'class' => 'DeleteAction',
'modelClass' => 'Post',
);
);
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
}
…
}
Với user controller ta cũng khai báo action mới trong component
class UserController extends CController
{
function actions()
{
return array(
'delete' => array(
'class' => 'DeleteAction',
'modelClass' => 'User',
);
);
}
…
}
Với cách này ta có thể tiết kiệm thời gian xây dựng hàm với những hàm có cấu trúc giống nhau.
8. Sử dụng Flash Messages
Khi bạn chỉnh sửa model với form,hay xóa item trong models hoặc làm với những thao tác user, bạn luôn luôn phải đưa ra lời thong báo tới user công việc đó đã thực hiện xong chưa hay đã hoàn thành,…Flash messages sẽ giúp hiển thị những lời thong báo ví dụ :”xóa thành công, cập nhật thành công,…”
Trở lại protected/controllers/websitecontroller viết lại như sau:
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
class WebsiteController extends CController
{
function actionOk()
{
Yii::app()->user->setFlash('success', 'Everything went
fine!');
$this->redirect('index');
}
function actionBad()
{
Yii::app()->user->setFlash('error', 'Everything went wrong!');
'id' => '8Rp-CaIKvQs', // you can get this id by simply looking
at video URL
'width' => 320,
'height' => 256,
))?>
Giờ ta sẽ thử gửi email ,them mới action trong website controller
class WebsiteController extends CController
{
function actionSendmails()
{
$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));
}
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
}
Tiếp theo tạo 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ử dụng clip
Khi chúng ta cần định nghĩa 2 vị trí trong layout : trước content và footer, mở protected/views/layouts/main.php them đoạn sau trước output (<?php echo $content;?>)
Bây giờ chúng ta cần điền vào vị trí của chúng, mở controller action cho beforeContent region. Mở protected/controllers/SiteController.php và them đoạn sau vào actionIndex:
$this->beginClip('beforeContent');
echo 'Your IP is '.Yii::app()->request->userHostAddress;
$this->endClip();
Tiếp theo mở protected/views/site/index.php và them đoạn sau:
<?php $this->beginClip('footer')?>
Ứng dụng được xây dựng bởi Tàu khựa.
<?php $this->endClip()?>
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Hoàn tất bạn có thể mở index bạn sẽ thấy địa chỉ IP và “ứng dụng…” ở gần footer.
12 . Định nghĩa nhiều Layout.
Hầu hết ứng dụng sử dụng một layout duy nhất cho tất cả khung nhìn,tuy nhiên nhiều dự án đòi hỏi cấu hình và thẩm mỹ khác nhau dẫn tới có nhiều layout khác nhau vì thế nên yii cho phép tạo dựng nhiều layout một cách chuyên biệt và hiệu quả.
Ta tạo 2 layout trong protected/views/layouts: blog và articles. Blog chứa đựng nội dung sau:
Tạo 3 controller là BlogController,ArticleController và PorfolioController với indexAction
class BlogController extends Controller
{
function actionIndex()
{
$this->layout = 'blog';
$this->render('//site/index');
}
}
class ArticleController extends Controller
{
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
function actionIndex()
{
$this->layout = 'articles';
$this->render('//site/index');
}
}
class PortfolioController extends Controller
{
function actionIndex()
{
$this->render('//site/index');
}
}
Giờ hãy thử vào http://localhost/skybook/index.php/blog, http://localhost/skybook/index.php/article and
http://localhost/skybook/index.php/portfolio.
Chúng ta vừa định nghĩa 2 layout cho blog và articles. Nếu chúng ta không muốn copy-pase một phần của layout chính,chúng ta thử them layout được định nghĩa bằng cách sử dụng $this->beginContent và this->endContent; thể hiện ở hình dưới đây:
Vào trình duyệt gõ : http://localhost/skybook/index.php/quote/index
Để có thể xem cấu hình ajax tạo ra bạn dùng firebug trỏ vào vùng next quote sẽ hiển thị javascript tạo ra ajax từ Chtml::ajaxLink.
2. Quản lý Assert
Một trong những khả năng tuyệt vời của Yii là có thể bảo vệ tài sản (mã nguồn) một cách hiệu quả
Khi thực thi một extension được kích hoạt javascript,css,images thì folder gốc không thể truy nhập được từ trình duyệt.
Khi bạn cần truy nhập lại tài sản (css,js,image) của bạn chỉ cần combine javascript
Khi bạn sử dụng assert nhiều lần trong phân trang và tránh trùng lặp
Hãy bắt đầu kế hoạch trước, bạn có thể thay đổi widgets tới bất kì thư mục nào, nó nằm trong protected/components. Nó chấp nhận có một hoặc 2 class trong đó, nhưng khi số lượng class tăng lên, nó sẽ tạo ra vấn đề,Tạo một assert trong widget với protected/extensions/facebook_events.và đặt trong đó ajax-loader.gif bạn vui lòng download tại http://ajaxload.info . Tiếp theo tạo facebook_event.css và facebook_event.js
Tạo EFacebookEvents.php trong folder facebook_events
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Cách thức hoạt động:
Khi chúng ta sử dụng $this->widget trong site/index view, 2 phương thức trong EFacebookEvents đều chạy init cái mà public assert và kết nối chúng tới trang, sau đó chạy render html.
Những gì có trong thư mục :Assert
Nếu bạn kiểm tra sẽ thấy những dòng sau:
Thư mục như 1a6630a0 được sử dụng để ngăn chặn va chạm của các tập tin với những cái tên tương tự từ các thư mục khác nhau. Tên của thư mục
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
là một hàm băm mã hóa path assert directory.Trước đó assert từ mỗi thư mục được copy tới cùng một nơi,điều này nghĩa là thư mục image,css,js public của bạn có thể tham chiếu tới images,css,js từ các đường dẫn lien quan.
3.Including resource tới trang
Yii có tên class đặc biệt là CClientScript để giúp cho việc include script css.
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
</script>
Sau thực hiện xong vào trình duyệt gõ: http://localhost/skybook/index.php/news/index
5: Xử lí biến số của input
Đôi khi ứng dụng yêu cầu nhập form chứa biến số của input,một chức năng quản lý ứng dụng có thể cung cấp hình ảnh,nơi bạn có thể them một hoặc nhiều chức năng trong danh sách task,bạn có thể xem ví dụ dưới đây:
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
CHƯƠNG 5 Database ,ActiveRecord,và Model Tricks
Trong chương này bạn sẽ khám phá:
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Nhận dữ liệu từ database
Sử dụng scopes để hiển thị model với các ngôn ngữ khác nhau
Truy cập models field với AR
Applying Markdown và HTML
Hightlight code với Yii
Tự động timestamp
Thiết lập author tự động
Thực thi các bảng kế thừa đơn
Sử dụng CDbCriteria
1. Nhận dữ liệu từ database
Hầu hết ứng dụng ngày nay đều sử dụng database,dù là một website nhỏ cho tới mạng xã hội , ít nhất một phần được bảo vệ bởi database,Yii giới thiệu 3 cách làm việc trên database:
Active Record
Query Builder
SQL và DAO
Để thực hiện bạn vào : http://dev.mysql.com/doc/sakila/en/sakila.html để tải gói database về sau đó vào phpmyadmin import vào csdlTiếp theo vào Gii tạo model actor và field tables
Ta vào protected /controller tạo DbController.php
<?phpclass DbController extends Controller{protected function afterAction($action){$time = sprintf('%0.5f', Yii::getLogger()
Sauk hi thực hiện xong bạn chạy trên trình duyệt và vào databse để kiểm tra dữ liệu mới tạo.
2. Sử dụng Scopes để hiển thị models cho những ngôn ngữ khác nhau
Đa ngôn ngữ trong website của bạn là việc điều khiển không hề dễ dàng,bạn cần phải thay đổi giao diện,thay đổi tin nhắn,định dạng ngày tháng,và rất nhiều thứ khác. Yii giúp bạn làm việc hiệu quả hơn với CLDR (Unicode Common Locate Data Repository) dữ liệu và cung cấp công cụ thay đổi ngôn ngữ. Khi tới ứng dụng với nhiều ngôn ngữ, bạn có thể sẽ tìm ra cách của riêng bạn.
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Để bắt đầu tạo mới databse: vào phpmyadmin và chọn mục 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 hoàn tất vào GII chọn model generated gõ Post vào modelname và generated
Sauk hi generated bạn vào models/Post.php và viết lại method giống như sau:
class Post extends CActiveRecord
{
public function defaultScope()
{
return array(
'condition' => "lang=:lang",
'params' => array(
':lang' => Yii::app()->language,
),
);
}
public function lang($lang){
$this->getDbCriteria()->mergeWith(array(
'condition' => "lang=:lang",
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
'params' => array(
':lang' => $lang,
),
));
return $this;
}
}
Tiếp theo vào protected/controllers/DbtestController.php
<?php
class DbtestController extends CController
{
public function actionIndex()
{
// Hiển thị ngôn ngữ mặc định
$posts = Post::model()->findAll();
echo '<h1>Default language</h1>';
foreach($posts as $post)
{
echo '<h2>'.$post->title.'</h2>';
echo $post->text;
}
// Hiển thị ngôn ngữ của Đức
$posts = Post::model()->lang('de')->findAll();
echo '<h1>German</h1>';
foreach($posts as $post)
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
{
echo '<h2>'.$post->title.'</h2>';
echo $post->text;
}
}
}
Sauk hi hoàn thành vào trình duyệt gõ : http://localhost/skybook/dbtest/index
3. Truy cập model field với Active-Record event-like method
Vào phpmyadmin chọn mục SQL và thực hiện query sau:
DROP TABLE IF EXISTS `post`;
CREATE TABLE IF NOT EXISTS `post` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NOT NULL,
`text` TEXT NOT NULL,
PRIMARY KEY (`id`)
);
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
beforeSave (trước khi lưu) được định nghĩa trong CActiveRecord class và chỉ thực hiện hàm trước khi lưu models.Bởi sử dụng biểu thức quy tắc, chúng thay thế mọi thứ giống một url với một link được sử dụng và gọi lại để hàm thực thi cha,sự kiện thực tế là raised propery , trong hàm saving bạn có thể trả về giá trị false.
Một số method bạn nên biết:
AfterConstruct : Hàm được gọi sau khi một model được khởi tạo bởi mã nguồn
beforeDelete/afterDelete : Hàm được gọi trước/sau khi bản ghi bị xóa
beforeSave/afterSave: Hàm được khởi tạo trước khi/sau khi lưu bản ghi thành công.
beforeValidate/afterValidate: Hàm được gọi khi khởi tạo trước/sau khi validation form kết thúc.
4. Highlight code với Yii
Nếu bạn post code,công ty của bạn lien quan đến nghề báo và wiki blog,sẽ luôn luôn tốt hơn khi hệ thống có highlight (hiệu ứng nháy), và một người đọc code cũng cảm thấy thoải mái.
Để thực hiện ta vào phpmyadmin chọn mục SQL và thực hiện query sau:
CREATE TABLE `snippet` (
`id` int(11) unsigned NOT NULL auto_increment,
`title` varchar(255) NOT NULL,
`code` text NOT NULL,
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
`html` text NOT NULL,
`language` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
);
Tiếp theo vào Giii generated model Snippet
Sauk hi generate thành công bạn thay đổi hàm rules trong Snippet.php ở protected/models/Snippet.php
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
5. Thực thi kế thừa bảng
Dữ liệu quan hệ thường không hỗ trợ kế thừa . Nếu bạn muốn thực hiện kế thừa database, bạn cũng có thể được hỗ trợ từ Yii
Cấu trúc kế thừa đơn giản như:
Xe
|-> Xe thể thao
|->Xe du lịch
|->Xe gia đình.
Để bắt đầu ta vào phpmyadmin chọn sql và chạy 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'),
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
('Porsche Boxster', 'sport'),
('Ferrari 550', 'sport');
Ta generated model Car trong Gii
Trong Protected/models/Car.php ta sửa lại như sau:
<?php
class Car extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'car';
}
protected function instantiate($attributes)
{
switch($attributes['type'])
{
case 'sport':
$class='SportCar';
break;
case 'family':
$class='FamilyCar';
break;
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
default:
$class=get_class($this);
}
$model=new $class(null);
return $model;
}
}
Sau đó ta kế thừa cho protected/models/SportCar.php
<?php
class SportCar extends Car
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function defaultScope()
{
return array(
'condition'=>"type='sport'",
);
}
}
Tiếp theo ta cũng kế thừa cho protected/models/FamilyCar.php
<?php
class FamilyCar extends Car
http://www.seodrupal.vn | Learn Drupal Online
153
[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='family'",
);
}
}
Trong protected/controller tạo TestController.php
<?php
class TestController extends CController
{
public function actionIndex()
{
echo "<h1>All cars</h1>";
$cars = Car::model()->findAll();
foreach($cars as $car)
{
// Mỗi chiếc xe có thể là của class car, sportcar, hoặc familycar
echo get_class($car).' '.$car->name."<br />";
}
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
echo "<h1>Sport cars only</h1>";
$sportCars = SportCar::model()->findAll();
foreach($sportCars as $car)
{
echo get_class($car).' '.$car->name."<br />";
}
}
}
Xong xuôi vào trình duyệt gõ : http://localhost/skybook/test/index
6. Sử dụng CdbCriteria
Khi sử dụng Active Record method như findAll, hoặc find, chúng ta có thể nhận tiêu chuẩn giống như tham số,nó có thể trả về mảng hay một khởi tạo của CdbCriteria class.Class này hiển thị query tiêu chuẩn, giống như điều kiện,ordering by,limit/offset, vv…
Bản thân class Criteria không xây dựng query, nhưng chỉ hiển thị dữ liệu hoặc cho phép điều chỉnh chúng, Hàm làm việc thực tế nằm trong Active Record method nơi các tiêu chuẩn của class này sử dụng.
Dịch code có thể đọc như sau:
Hiển thị 10 dòng post với comment từ approved post với id trong khoảng 4,8,15,16,24 hoặc 42 order by id.
Select * from post p (định danh post) JOIN (nối) comment c(định danh comment) ON (điều kiện nối) 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.
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
CHƯƠNG 6 KẾ THỪA Yii
Trong chương này, bạn sẽ khám phá:
Sử dụng data provides
Sử dụng grids (lưới)
Sử dụng lists (danh sách)
Tạo custom grid column( Cột lưới)
Yii có thư viện hữu ích gọi là Zii, nó đồng hành cùng với framework và một số class khác giúp cho việc phát triển trở lên dễ dàng hơn bao giờ hết,hầu hết thành phần chủ yếu là grid và list cái cho phép bạn xây dựng dữ liệu trong Admin và user website rất nhanh và đẹp. Trong chương này bạn sẽ học cách điều chỉnh component và những thứ bạn cần,bạn sẽ học về data provides,chúng là một phần trong core framework.
1 Sử dụng data provides (nhà cung cấp dữ liệu)
Data provides được sử dụng để triệu tập dữ liệu model giống như sắp xếp, phân trang, và querying.Chúng được sử dụng với grids và lists. Bởi vì cả 2 widget và provider là một tiêu chuẩn (chuẩn mực),bạn có thể hiển thị giống như dữ liệu sử dụng khác widget và bạn có thể hiện dữ liệu cho một widget từ various provider (tài sản được cung cấp).
Để thực hiện coder bạn vào http://dev.mysql.com/doc/sakila/en/sakila.html download database sau đó import vào csdl thong qua phpmyadmin.
Sử dụng Gii để tạo model film.
Vào protected/views/ tạo grid/index.php
<?php $this->widget('zii.widgets.grid.CGridView',
array('dataProvider' => $dataProvider,
))?>
Sau đó,tạo protected/controllers/GridController.php
<?php
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
class GridController extends Controller
{
public function actionAR()
{
$dataProvider = new CActiveDataProvider('Film', array(
'pagination'=>array(
'pageSize'=>10,
),
'sort'=>array(
'defaultOrder'=> array('title'=>false),
)
));
$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',
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
'duty'=>'founder and project lead',
'active'=>true,
),
array(
'name'=>'Wei Zhuo',
'id'=>'3',
'forumName'=>'wei',
'memberSince'=>'Jan 2008',
'location'=>'Sydney, Australia',
'duty'=>'project site maintenance and development',
'active'=>true,
),
array(
'name'=>'Sebastián Thierer',
'id'=>'54',
'forumName'=>'sebas',
'memberSince'=>'Sep 2009',
'location'=>'Argentina',
'duty'=>'component development',
'active'=>true,
),
array(
'name'=>'Alexander Makarov',
'id'=>'415',
'forumName'=>'samdark',
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
'memberSince'=>'Mar 2010',
'location'=>'Russia',
'duty'=>'core framework development',
'active'=>true,
),
array(
'name'=>'Maurizio Domba',
'id'=>'2650',
'forumName'=>'mdomba',
'memberSince'=>'Aug 2010',
'location'=>'Croatia',
'duty'=>'core framework development',
'active'=>true,
),
array(
'name'=>'Y!!',
'id'=>'1644',
'forumName'=>'Y!!',
'memberSince'=>'Aug 2010',
'location'=>'Germany',
'duty'=>'core framework development',
'active'=>true,
),
array(
'name'=>'Jeffrey Winesett',
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
'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',
'memberSince'=>'Sep 2009 - Aug 2010',
'location'=>'California, US',
'duty'=>'component development',
'active'=>false,
),
array(
'name'=>'István Beregszászi',
'id'=>'1286',
'forumName'=>'pestaa',
'memberSince'=>'Sep 2009 - Mar 2010',
'location'=>'Hungary',
'duty'=>'core framework development',
'active'=>false,
),
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
'defaultOrder'=>array('title' => false),
),
'pagination'=>array(
'pageSize'=>10,
),
));
$this->render('index', array(
'dataProvider' => $dataProvider,
));
}
}
Vào localhost /skybook/grid/aR , grid/array và grid/sql để xem kết quả:
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
2. Sử dụng Zii Grid
Zii grid rất hữu ích và nhanh chóng trong việc tạo khung lưới cho các trang quản trị admin hoặc bất kỳ trang nào yêu cầu về số liệu.
Để bắt đầu bạn vào website : http://dev.mysql.com/doc/sakila/en/
sakila.html. down load database sau do giải nén vào phpmyadmin, chọn table của bạn và import db.
Sử dụng Gii tạo model generated cho customer, address,city.
Tiếp theo vào Gii chọn controller generated : Customer
Chạy customer controller và tới quản trị Manage Customer link trong gii bạn sẽ có kết quả như sau:
3. Sử dụng lists
Zii list là công cụ khá tốt cho việc trình bày dữ liệu ở bất kỳ data provider để kết thúc user khi xử lí phân trang và sắp xếp tự động.CListView là rất dễ dàng trong việc custom vì nó cho phép xây dựng bất kỳ thuộc tính nào trong list page.
Vào website : http://dev.mysql.com/doc/sakila/en/
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
sakila.html download cơ sở dữ liệu rồi vào phpmyadmin import vào database
Vào gii model generated tạo : customer,store,address,city
Tiếp theo mở gii,chọn CRug generator và nhấn Customer tới model class field, nhấn preview và generated
Gii sẽ generated controller trong protected/controllers
Chạy index action của customer controller ta có kết quả sau :
http://localhost/skybook/customer/index
Thêm tiêu chuẩn sắp xếp:
bạn vào protected/views/customer/index.php và thay thế bằng nội dung sau :
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
4. Tạo customer Grid column
Hầu hết thời gian bạn không cần tạo khung lưới cho các thuộc tính của bạn khi mà Yii đã cung cấp đầy đủ công cụ thực hiện vì thế nên bạn chỉ cần tạo custom cho riêng mình.
Ta bắt đầu tạo custom grid column cho phép toggling Y/N giá trị và thay đổi giá trị trong models nhờ AJAX
Bạn vào : http://dev.mysql.com/doc/sakila/en/
sakila.html tải database về sau đó vào phpmyadmin import và db của bạn.
Vào GII model generated tạo : customer
Mở Gii chọn CRUD generated chọn : Customer và generated
Cách thực hiện : Trong table chúng ta có một field active (kích hoạt) , chúng ta muốn toggle với flag column . Column sẽ hiển thị 2 trường Y và N quyết định giá trị trả về được cliking hay ko.
Vào protected/components/ tạo FlagColumn.php
<?php
class FlagColumn extends CGridColumn
{
public $name;
public $sortable=true;
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
CHƯƠNG 7 KẾ THỪA Yii
Trong chương này bạn sẽ khám phá:
Tạo component
Tạo controller action
Tạo reusable controller
Tạo một widget
Tạo CLI commands
Tạo filter
Tạo modules
Tạo một customer view renderer
Làm mở rộng distribution-ready
1. Tạo component
Nếu bạn có một vài đoạn code có thể tái sử dụng được nhưng bạn không biết cách thức,widget,behavior hãy sử dụng component. Component kế thừa từ CComponent hoặc CApplicationComponent.Sau đó một component có thể kích hoạt tới ứng dụng và cấu hình sử dụng trong protected/config/main.php.
Để ví dụ chúng ta định nghĩa: EImageManage ứng dụng thành phần sẽ dùng để resize ảnh sử dụng thư viện GD, kích hoạt nó tới ứng dụng và sử dụng nó.
Hầu hết thời gian chúng ta cần tạo ứng dụng thành phần của riêng ta, tuy nhiên việc tải code đã tồn tại giúp ta giảm thời gian lập trình và tiết kiệm công sức.
Ví dụ để hiện user role từ databse sử dụng Yii::app()->user->role có thể kế thừa từ CwebUser component giống như sau:
Tiếp theo vào kích hoạt controller : protected/controllers/ tạo DeleteController.php:
<?php
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
class DeleteController extends CController
{
public function actions()
{
return array(
'deletePost' => array(
'class' => 'ext.actions.EDeleteAction',
'modelName' => 'Post',
'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.";
}
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
}
Bây giờ bạn có thể vào trình duyệt gõ: http://localhost/skybook/delete/deletePost/pk, http://localhost/skybook/delete/deleteComment/pk
3. Tạo reusable Controller
Trong Yii bạn có thể tái sử dụng controller , nếu bạn tạo nhiều ứng dụng với controller có thuộc tính giống nhau, di chuyển tất cả các lệnh code tới controller tái sử dụng sẽ tiết kiệm nhiều thời gian cho bạn.
Trong bài này,chúng ta sẽ tạo đơn giản api controller sẽ được thi hành với JSON,CRUD API cho một model, nó sẽ đưa input data từ POST hoặc GET và sẽ sử lý bằng JSON data tiếp theo là HTTP code
Vào Gii,tạo 1 model generated là Post
Tiếp theo vào protected/extensions/ tạo json_api tạo JsonApiController.php:
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
protected function respond($httpCode, $status, $data = array())
{
$response['status'] = $status;
$response['data'] = $data;
echo CJSON::encode($response);
Yii::app()->end($httpCode, true);
}
}
Tiếp theo bạn cần kết nối t ới ứng dụng với protected/conFig/main.php
Nó có thể hoàn thành việc thêm con troller,cấu hình tới controllerMap property của CwebApplication và tat hay thế cấu hình sau trong main.php
…
'controllerMap' => array(
'api' => array(
'class' => 'ext.json_api.JsonApiController',
'modelName' => 'Post',
),
),
…
Chúng ta cần kết nối tới controller và đặc biệt nó sẽ làm việc với post model.
Bạn sẽ cần form tới post data nhưng nếu bạn có một số dữ liệu tồn tại bạn có thể sử dụng phương thức nhận bằng cách http://localhost/skybook/api/get/pk/1
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
{"status":"OK","data":{"id":"1","text":"post1",
"title":"post1","is_deleted":"0"}}
4. Tạo một widget
Một widget là một phần tái sử dụng của khung nhìn views nó không chỉ render một số dữ liệu mà còn đọc một số logic. Nó có thể là một sự kiện nhận dữ liệu từ models và sử dụng nó trong bản thân views.
Hãy tạo một widget và vẽ một chart biểu đồ nghệ thuật sử dụng google API.
Trong protected/extensions/ tạo folder chart, tạo EChartWidget.php:
Tiếp theo vào protected/controllers/ tạo ChartController.php
<?php
class ChartController extends CController
{
public function actionIndex()
{
$value = rand(10, 90);
$this->widget('ext.chart.EChartWidget', array(
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
'title' => 'Do you like it?',
'data' => array(
$value, 100-$value
),
'labels' => array(
'No',
'Yes',
),
));
}
}
Vào trình duyệt gõ : http://localhost/skybook/chart/index lưu ý nhà phải kết nối với internet mới truy nhập vào được google thì mới thấy cái biểu đồ này.
5. Tạo filters (bộ lọc)
Một filters là một class có thể chạy trước/sau một action đang thực hiện. Nó có thể sử dụng và thay đổi nội dung thực hiện hoặc thay đổi output, trong ví dụ này bạn sẽ thực thi một output đơn giản được filter với compress HTML output và xóa tất cả mọi định dạng.
Vào protected/extensions/ tạo compress_html folder, tạo ECompressHtmlFilter.php
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Xong xuôi vào http://localhost/skybook/wiki/index và localhost/skybook/wiki/edit
Tiếp theo vào 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'
),
),
Mỗi modules được tạo chứa một main modules class giống wikimodule nơi chúng ta có thể định nghĩa cấu hình thuộc tính,định nghĩa import, thay đổi đường dẫn, kích hoạt controller, và nhiều hơn..
Mặc định mỗi moduels generated với Gii chạy index action của default controller:
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
$this->actionView('index');
}
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,
));
Nếu modules này giữ một ID chúng ta sẽ hiển thị nó và sử dụng trong views.
Nếu không có trang nào giữ ID, chúng ta xử lý bởi action khác:
$model = Wiki::model()->findByPk($id);
if(!$model)
{
$model = new Wiki();
$model->id = $id;
}
if(!empty($_POST['Wiki']))
{
if(!empty($_POST['Wiki']['text']))
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
{
$model->text = $_POST['Wiki']['text'];
if($model->save())
$this->redirect(array('view', 'id' => $id));
}
else
{
Wiki::model()->deleteByPk($id);
}
}
$this->render('edit', array(
'model' => $model
));
NẾU KHÔNG CÓ modules nào sử dụng ID mới tạo,nếu có một models chúng ta edit nó,edit form data từ POST và kiểm tra nó rỗng hay không chúng ta delete models,nếu có ký tự chúng ta lưu lại.
6. Tạo một custom view renderer
Có nhiều PHP templates được yii nhận là native PHP và Prado templates. Nếu bạn muốn sử dụng nó trong Yii bạn có thể định nghĩa chúng.
Bây giờ chúng ta sẽ nhúng Smarty 3.0 vào Yii.
Bạn vào trang chủ : http://www.smarty.net/. Tải phiên bản mới nhất về.
Giải nén (extract here ) rồi vào folder đó copy folder libs của smarty tới protected/vendors/smarty .
Cách thực hiện như sau:
Vào protected/extensions/smarty tạo ESmartyViewRenderer.php:
"$sourceFile" does not exist.', array('{file}'=>$sourceFile)));
$this->smarty->assign($data);
if($return)
return $this->smarty->fetch($sourceFile);
else
$this->smarty->display($sourceFile);
}
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
}
Tiếp theo bạn cần kết nối views renderer với ứng dụng. Trong protected/config/main.php chúng ta cần tải viewRenderer component:
…
// application components
'components'=>array(
…
'viewRenderer'=>array(
'class'=>'ext.smarty.ESmartyViewRenderer',
),
),
…
Lưu ý, trong component có dữ liệu thì bạn để nguyên chỉ việc thêm vào :
'viewRenderer'=>array(
'class'=>'ext.smarty.ESmartyViewRenderer',
),
Bây giờ kiểm tra nó, Tạo protected/controllers/ Tạo SmartyController.php
<?php
class SmartyController extends Controller
{
function actionNative()
{
$this->render('native', array(
'username' => 'Alexander',
));
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
}
function actionSmarty()
{
$this->render('smarty', array(
'username' => 'Alexander',
));
}
}
Tiếp theo t ạo views: protected/views/smarty/native.php:
Hello, <?php echo $username?>!
protected/views/smarty/smarty.tpl:
Hello, {$username}!
Bây giờ vào trình duyệt gõ : http://localhost/skybook/smarty/native
Bạn sẽ thấy dòng : Hello,Alexander!
7. Làm extensions distribution-ready
Trong chương này bạn đã được học rất nhiều các tạo thuộc tính từ Yii extensions. Bây giờ chúng ta nói về cách chia sẻ thành quả của bạn với mọi người và tại sao nó lại quan trong.
Hãy check trong form sau những điều bạn suy nghĩ là đúng nhất về extensions
Nội dung trong sang, dễ đọc và sử dụng trong API
Tài liệu tốt
Mọi người đều có thể tìm thấy nó
Extensions áp dụng được hầu hết trong ứng dụng user
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Sẽ là thành phần chính
Tốt cho việc test code, tạo nền tảng cho ý tưởng với bài test
Bạn cần được cung cấp hỗ trợ cho nó
Tất nhiên tất cả yếu tố trên đều được yêu cầu thực sự cần thiết để tạo ra một sản phẩm tốt.
CHƯƠNG 8 BẢO MẬT
Bạn sẽ khám phá điều gì trong chương cuối này ?
Sử dụng controller filter
Sử dụng CHtml và CHtmlPurifier tới sự kiện XSS
Khám phá SQL injection
Khám phá CSRF
Sử dụng RBAC
1. Sử dụng controller filter
Trong nhiều trường hợp,chúng ta cần lọc ra dữ liệu hoặc thực hiện một số action cơ bản trong data,ví dụ với custom filter, chúng ta có thể lọc ra lượt truy cập bởi IP,sức mạnh của user với việc sử dụng HTTPS,hoặc redirect user từ một phần quan trọng trong cấu hình trang để sử dụng trong ứng dụng. Yii có xây dựng hai bộ lọc ,đầu tiên là CInlineFilter nó cho phép sử dụng controller method như một bộ lọc, và cái thứ hai là (là một thứ chúng
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
ta sẽ focus nó) CAccessControlFilter nó cho phép điều khiển truy cập tới dữ liệu của controller action.
Trong bài học này ta sẽ thực hiện những việc sau:
Giới hạn truy cập tới controller action với chỉ các user định danh
Giới hạn truy cập tới controller action từ IPs đặc biệt
Giới hạn truy cập tới người dùng đặc biệt
Giới hạn truy cập cho user của một trình duyệt đặc biệt, trong trường hợp chúng ta cũng có thể hiển thị custom messager
Trước tiên vào protected/controllers tạo AccessController.php
<?php
class AccessController extends CController
{
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!";
}
}
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
'message' => "You're using the wrong browser, sorry.",
),
array(
'allow',
'actions' => array('authOnly'),
'users' => array('@'),
),
array(
'allow',
'actions' => array('ip'),
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
'ips' => array('127.0.0.1'),
),
array(
'allow',
'actions' => array('user'),
'users' => array('admin'),
),
array('deny'),
);
}
http://localhost/skybook/access/authonly , thay autheronly bằng ip, user để test
Bây giờ chúng ta sẽ thử controller trên trình duyệt sử dụng cả 2 tài khoản admin và demo sẽ đều có kết quả sau
2. Sử dụng CHtml và CHtmlPurifier tới sự kiện XSS
XSS là viết tắt của cross-site scripting và là một loại lỗ hổng mà cho phép tríchmột kịch bản phía máy khách (thông thường, JavaScript) trong trang được xem bởi người dùng khác. Xem xét sức mạnh của kịch bản phía máy khách này có thể dẫn đến hậu quả rất nghiêm trọng như bỏ qua kiểm tra an ninh, nhận được một thông tin người dùng, hoặc rò rỉ dữ liệu.
Để test ta vào protected/controllers tạo XssController.php
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
<?php
class XssController extends CController
{
public function actionSimple()
{
echo 'Hello, '.$_GET['username'].'!';
}
}
Bây giờ vào trình duyệt gõ : http://localhost/skybook/xss/simple?username=Longt8x, tuy nhiên tài sản chính không xuất hiện lên output , ta gõ tiếp ; http://localhost/skybook/xss/simple?username=<script>alert(‘XSS’);</script>
Đương nhiên trong ví dụ này khách chỉ sử dụng một hàm alert thong số, nhưng trong form data của bạn chứa nhiều dữ liệu mật thì điều thất thoát là khó tránh, Yii đưa ra giải pháp sau:
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
3. Sự kiện SQL injection
SQL injection là một loại injection code được sử dụng để làm tổn thương ở cấp cơ sở dữ liệu và cho phép thực hiện bất kỳ SQL cho phép người sử dụng độc hại để thực hiện hành động chẳng hạn như xóa dữ liệu hoặc nâng cao đặc quyền của họ.
Trước tiên vào phpmyadmin chọn sql và thêm query sau:
CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(100) NOT NULL,
`password` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `user`(`id`,`username`,`password`) VALUES ( '1','Alex'
,'202cb962ac59075b964b07152d234b70');
INSERT INTO `user`(`id`,`username`,`password`) VALUES ( '2','Qiang
','202cb962ac59075b964b07152d234b70');
Tiếp theo generated model : User sử dụng Gii
Vào protected/controllers/ tạo SqlController.php
<?php
class SqlController extends CController
{
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
public function actionSimple()
{
$userName = $_GET['username'];
$password = md5($_GET['password']);
$sql = "SELECT * FROM user WHERE username = '$userName'
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
'1'='1'; --' AND password = '008c5926ca861023c1d2a36653fd88e2'
LIMIT 1;
Để fix vấn đề này bạn thêm vào controller action mới:
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();
if($user)
{
echo "Success";
}
else
{
echo "Failure";
}
}
Bây giờ vào http://localhost/skybook/sql/preparedSẽ hiện ra chữ failure, như vậy thong tin đã được bảo toàn.
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
4. Sự kiện CSRF
CSRF hay XSRF viết tắt cross-site là một request giả ,một vài thủ thuật sử dụng độc hại của trình duyệt user để âm thầm thực hiện một yêu cầu HTTP đến với trang web khi người dùng đăng nhập. Một ví dụ về cuộc tấn công này là chèn một thẻ hình ảnh vô hình với src trỏ đếnhttp://example.com/site/logout. Thậm chí nếu các thẻ hình ảnh được chèn vào trong một trang web khác,ngay lập tức bạn sẽ được đăng nhập từ example.com. Hậu quả của CSRF có thể sẽ rất nghiêm trọng: phá hủy dữ liệu trang web, ngăn chặn tất cả các người sử dụng trang web đăng nhập vào, phơi bày tin dữ liệu, và hơn thế nữa…
Một số thực trạng của CSRF:
Như CSRF nên được thực hiện bởi người sử dụng trình duyệt của nạn nhân, kẻ tấn công có thể không thường thay đổi tiêu đề HTTP được gửi.
Yii include một token generation và token checking. Thêm nữa có thể tự động insert một token trong HTML form:
Vào protected/config/main.php thêm đoạn sau:
'components'=>array(
…
'request'=>array(
'enableCsrfValidation'=>true,
),
…
),
Sauk hi cấu hình ứng dụng bạn sử dụng C:Html::beginForm và CHtml::endForm khởi tạo của HTML form.
public function actionCreate()
{
echo CHtml::beginForm();
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Nếu bạn lưu form html và thử submit,bạn sẽ nhận được một lời thong báo giống như sau:
Bảo mật mức cao:
Nếu ứng dụng của bạn yêu cầu độ bảo mật cao hơn nữa, bạn hãy vào protected/config/main.php
'components' => array(
...
'user'=>array(
// enable cookie-based authentication
'allowAutoLogin'=>false,
),
...
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
),
Sau đó cho session timeout hoạt động
'components' => array(
...
'session' => array(
'timeout' => 200,
),
...
),
Sử dụng thuộc tính GET và POST
HTTP khẳng định không sử dụng GET cho các hoạt động thay đổi dữ liệu hoặc trạng thái. Gắn bó với nguyên tắc này là một cách tốt. Nó không ngăn cản tất cả các loại CSRF, nhưng ít nhất sẽ làm cho một số mũi trích như <img src = trở lên vô nghĩa....
5 . Sử dụng RBAC
RBAC là phương pháp kiểm soát truy cập mạnh mẽ nhất có sẵn trong Yii. Nó được mô tả trong tài liệu hướng dẫn,nhưng kể từ khi nó là khá phức tạp và mạnh mẽ, nó không phải là dễ dàng như vậy để hiểu làm thế nào nó thực sựhoạt động mà không nhận được hood .Trong bài này, chúng ta sẽ làm rõ vai trò của hệ thống phân cấp từ tiêu chuẩn hướng dẫn, import nó, và giải thích những gì đang xảy ra trong nội bộ.
Vào protected/config/main.php sửa lại thong số giống như sau:
return array(
'components'=>array(
…
'authManager'=>array(
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
'class'=>'CDbAuthManager',
'connectionID'=>'db',
),
),
…
);
Thêm vào protected/components/UserIdentity.php đoạn sau:
$users=array(
// username => password
'demo'=>'demo',
'admin'=>'admin',
'readerA'=>'123',
'authorB'=>'123',
'editorC'=>'123',
'adminD'=>'123',
);
Tạo protected/controllers/RbacController.php
<?php
class RbacController extends CController
{
public function filters()
{
return array(
'accessControl',
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
);
}
public function accessRules()
{
return array(
array(
'allow',
'actions' => array('deletePost'),
'roles' => array('deletePost'),
),
array(
'allow',
'actions' => array('init', 'test'),
),
array('deny'),
);
}
public function actionInit()
{
$auth=Yii::app()->authManager;
$auth->createOperation('createPost','create a post');
$auth->createOperation('readPost','read a post');
$auth->createOperation('updatePost','update a post');
$auth->createOperation('deletePost','delete a post');
$bizRule='return Yii::app()->user->id==$params
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
["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');
$auth->assign('admin','adminD');
echo "Done.";
}
public function actionDeletePost()
{
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Bây giờ vào localhost/skybook/rbac/init để xem kết quả
http://www.seodrupal.vn | Learn Drupal Online
153
[YII 1.1 APP DEVELOPMENT COOKBOOK ] August 28, 2012
Đặt tên các nút RBAC Một hệ thống cấp bậc phức tạp trở nên khó hiểu mà không cần sử dụng một số loại đặt tên một hội nghị. Một quy ước giúp không làm cho chúng ta nhầm lẫn như sau: [Group_] [own_] entity_action Trường hợp riêng được sử dụng khi quy tắc xác định khả năng sửa đổi một phần tử chỉ khi người sử dụng hiện nay là chủ sở hữu của các yếu tố và nhóm chỉ là một không gian tên. Thực thể là một tên của thực thể, chúng tôi đang làm việc và hành động là hành động mà chúng tôi đang thực hiện. Ví dụ, nếu chúng ta cần phải tạo ra một quy tắc để xác định nếu người dùng có thể xóa một bài đăng blog, chúng tôi sẽ đặt tên nó như là blog_post_delete. Nếu quy tắc xác định nếu một người dùng có thể chỉnh sửa các blog của riêng bình luận, tên sẽ được blog_own_comment_edit. Một cách để giữ cho hệ thống phân cấp đơn giản và hiệu quả Theo những đề nghị khi có thể để tối đa hóa hiệu suất và giảm hệ thống phân cấp phức tạp: ff Tránh gắn nhiều vai trò một người dùng duy nhất. ff Không kết nối các nút cùng loại. Vì vậy, ví dụ, tránh kết nối một trong những nhiệm vụ một số khác. Để giữ cho hệ thống phân cấp còn đơn giản, chúng ta có thể tránh việc tạo ra và sử dụng các nút thêm trong một số trường hợp bằng cách thay thế chúng bằng các điều kiện bổ sung. Một ví dụ là các sửa đổi của Post. Chúng ta có thể tạo ra một nút blog_own_post_edit với bizRule như sau: return Yii::app()->user->id==$params["post"]->author_id;Ngoài ra, chúng ta có thể thêm cùng một logic thường xuyên lựa chọn bài như sau: $post = Post::model()->findByAttributes(array(
'id' => $id,
'author_id' => Yii::app()->user->id,
));
If(!$post)
throw new CHttpException(404);
Bằng cách sử dụng cách thứ hai, chúng ta sẽ tránh nhận được một nút hệ thống phân cấp RBAC do lưu kho.