Sử dụng Acl trong cakephp – Phần 2
Chúng ta tiếp tục phần 2 của bài viết “Sử dụng Acl trong cakephp”
6. Kiếm tra xem group và user đã được liên kết với Acl chưa
- Các bạn mở trình duyệt và chạy url: http://localhost/cake_acl/groups/add
- Lần lượt thêm vào các group: Administrators, Managers và Users
- Chạy tiếp url: http://localhost/cake_acl/users/add
- Thêm vào các user: admin (thuộc group Administrators), manager (thuộc group Managers), user (thuộc group Users). Nhớ password đã đặt cho từng user
(Đường link của các bạn có thể khác của mình)
- Sau khi đã thêm các group và user như trên, bạn mở bảng aros ra và xem dữ liệu:

- Nếu dữ liệu ra đúng như trên thì AclBehavior đã hoạt động đúng
7. Tạo aco
- Bước tiếp theo, chúng ta sẽ đưa tất cả các controller (bao gồm cả đối tượng cotrollers), các action của từng controller vào bảng acos
- Để công việc này thuận tiện hơn, chúng ta sẽ sử dụng đoạn code đã được xây dựng sẵn. Bạn đưa đoạn code dưới vào controller nào cũng được, mình đưa vào groups_controller.php
function build_acl() { if (!Configure::read('debug')) { return $this->_stop(); } $log = array(); $aco =& $this->Acl->Aco; $root = $aco->node('controllers'); if (!$root) { $aco->create(array('parent_id' => null, 'model' => null, 'alias' => 'controllers')); $root = $aco->save(); $root['Aco']['id'] = $aco->id; $log[] = 'Created Aco node for controllers'; } else { $root = $root[0]; } App::import('Core', 'File'); $Controllers = Configure::listObjects('controller'); $appIndex = array_search('App', $Controllers); if ($appIndex !== false ) { unset($Controllers[$appIndex]); } $baseMethods = get_class_methods('Controller'); $baseMethods[] = 'buildAcl'; $Plugins = $this->_getPluginControllerNames(); $Controllers = array_merge($Controllers, $Plugins); // look at each controller in app/controllers foreach ($Controllers as $ctrlName) { $methods = $this->_getClassMethods($this->_getPluginControllerPath($ctrlName)); // Do all Plugins First if ($this->_isPlugin($ctrlName)){ $pluginNode = $aco->node('controllers/'.$this->_getPluginName($ctrlName)); if (!$pluginNode) { $aco->create(array('parent_id' => $root['Aco']['id'], 'model' => null, 'alias' => $this->_getPluginName($ctrlName))); $pluginNode = $aco->save(); $pluginNode['Aco']['id'] = $aco->id; $log[] = 'Created Aco node for ' . $this->_getPluginName($ctrlName) . ' Plugin'; } } // find / make controller node $controllerNode = $aco->node('controllers/'.$ctrlName); if (!$controllerNode) { if ($this->_isPlugin($ctrlName)){ $pluginNode = $aco->node('controllers/' . $this->_getPluginName($ctrlName)); $aco->create(array('parent_id' => $pluginNode['0']['Aco']['id'], 'model' => null, 'alias' => $this->_getPluginControllerName($ctrlName))); $controllerNode = $aco->save(); $controllerNode['Aco']['id'] = $aco->id; $log[] = 'Created Aco node for ' . $this->_getPluginControllerName($ctrlName) . ' ' . $this->_getPluginName($ctrlName) . ' Plugin Controller'; } else { $aco->create(array('parent_id' => $root['Aco']['id'], 'model' => null, 'alias' => $ctrlName)); $controllerNode = $aco->save(); $controllerNode['Aco']['id'] = $aco->id; $log[] = 'Created Aco node for ' . $ctrlName; } } else { $controllerNode = $controllerNode[0]; } //clean the methods. to remove those in Controller and private actions. foreach ($methods as $k => $method) { if (strpos($method, '_', 0) === 0) { unset($methods[$k]); continue; } if (in_array($method, $baseMethods)) { unset($methods[$k]); continue; } $methodNode = $aco->node('controllers/'.$ctrlName.'/'.$method); if (!$methodNode) { $aco->create(array('parent_id' => $controllerNode['Aco']['id'], 'model' => null, 'alias' => $method)); $methodNode = $aco->save(); $log[] = 'Created Aco node for '. $method; } } } if(count($log)>0) { debug($log); } } function _getClassMethods($ctrlName = null) { App::import('Controller', $ctrlName); if (strlen(strstr($ctrlName, '.')) > 0) { // plugin's controller $num = strpos($ctrlName, '.'); $ctrlName = substr($ctrlName, $num+1); } $ctrlclass = $ctrlName . 'Controller'; $methods = get_class_methods($ctrlclass); // Add scaffold defaults if scaffolds are being used $properties = get_class_vars($ctrlclass); if (array_key_exists('scaffold',$properties)) { if($properties['scaffold'] == 'admin') { $methods = array_merge($methods, array('admin_add', 'admin_edit', 'admin_index', 'admin_view', 'admin_delete')); } else { $methods = array_merge($methods, array('add', 'edit', 'index', 'view', 'delete')); } } return $methods; } function _isPlugin($ctrlName = null) { $arr = String::tokenize($ctrlName, '/'); if (count($arr) > 1) { return true; } else { return false; } } function _getPluginControllerPath($ctrlName = null) { $arr = String::tokenize($ctrlName, '/'); if (count($arr) == 2) { return $arr[0] . '.' . $arr[1]; } else { return $arr[0]; } } function _getPluginName($ctrlName = null) { $arr = String::tokenize($ctrlName, '/'); if (count($arr) == 2) { return $arr[0]; } else { return false; } } function _getPluginControllerName($ctrlName = null) { $arr = String::tokenize($ctrlName, '/'); if (count($arr) == 2) { return $arr[1]; } else { return false; } } /** * Get the names of the plugin controllers ... * * This function will get an array of the plugin controller names, and * also makes sure the controllers are available for us to get the * method names by doing an App::import for each plugin controller. * * @return array of plugin names. * */ function _getPluginControllerNames() { App::import('Core', 'File', 'Folder'); $paths = Configure::getInstance(); $folder =& new Folder(); $folder->cd(APP . 'plugins'); // Get the list of plugins $Plugins = $folder->read(); $Plugins = $Plugins[0]; $arr = array(); // Loop through the plugins foreach($Plugins as $pluginName) { // Change directory to the plugin $didCD = $folder->cd(APP . 'plugins'. DS . $pluginName . DS . 'controllers'); // Get a list of the files that have a file name that ends // with controller.php $files = $folder->findRecursive('.*_controller\.php'); // Loop through the controllers we found in the plugins directory foreach($files as $fileName) { // Get the base file name $file = basename($fileName); // Get the controller name $file = Inflector::camelize(substr($file, 0, strlen($file)-strlen('_controller.php'))); if (!preg_match('/^'. Inflector::humanize($pluginName). 'App/', $file)) { if (!App::import('Controller', $pluginName.'.'.$file)) { debug('Error importing '.$file.' for plugin '.$pluginName); } else { /// Now prepend the Plugin name ... // This is required to allow us to fetch the method names. $arr[] = Inflector::humanize($pluginName) . "/" . $file; } } } } return $arr; } |
- Mở trình duyệt lên và chạy: http://localhost/cake_acl/groups/build_acl
- Mở bảng acos để xem dữ liệu:

- Chèn code sau vào trong hàm beforeFilter của app_controller.php
$this->Auth->actionPath = 'controllers/'; |
8. Phân quyền
- Cú pháp chung:
$this->Acl->allow($aroAlias, $acoAlias); |
- Phân quyền demo: đưa hàm bên dưới vào users_controller.php
function initDB() { $group =& $this->User->Group; //cho phép administrators truy cập mọi thứ $group->id = 1; $this->Acl->allow($group, 'controllers'); //cho phép managers quản lý post, cấm truy xuất khu vực và action khác $group->id = 2; $this->Acl->deny($group, 'controllers'); $this->Acl->allow($group, 'controllers/Posts'); //cho phép users chỉ được add và edit post, cấm truy xuất các khu vực và action khác $group->id = 3; $this->Acl->deny($group, 'controllers'); $this->Acl->allow($group, 'controllers/Posts/add'); $this->Acl->allow($group, 'controllers/Posts/edit'); $this->Acl->allow($group, 'controllers/Widgets/add'); $this->Acl->allow($group, 'controllers/Widgets/edit'); echo "all done"; exit; } |
- Mở trình duyệt lên và chạy: http://localhost/cake_acl/users/initDB
- Mở bảng aros_acos xem dữ liệu:

- Như vậy là phân quyền thành công
9. Kiểm thử
- Bỏ hàm beforeFilter() trong groups_controller.php và users_controller.php đi
- Mở trình duyệt chạy link: http://localhost/cake_acl/users/, bạn sẽ bị đẩy ra trang login. Tại đây bạn tiến hành đăng nhập lần lượt bằng các user: admin, manager và user, sau đó thao tác với các action trong group, user và post.
- Nếu vào action nào không được phép, bạn sẽ bị redirect về trang đã đứng trước đó!
10. Chúc các bạn thực hiện thành công
- Các bạn có thể tải các file liên quan tới bài viết tại đây: hướng dẫn dùng Acl và Auth trong cakephp
Chú ý: khi đưa ứng dụng lên hosting các bạn phải remove 2 function build_acl và initDB đi nhé!
1 Comment to “Sử dụng Acl trong cakephp – Phần 2”
Post comment
Bài viết mới
- CakePHP version 1.3.12
- Tạo chuỗi ngẫu nhiên với 1 dòng code
- Kỹ thuật “bit field” trong phân quyền
- Làm việc với File và Folder
- CakePHP 1.3.8
- CakePHP 1.3.7 Released
- Ajax trong CakePHP
- Tạo và load file config trong CakePHP
- Làm site đa ngôn ngữ với CakePHP (Phần 1)
- CakePHP 1.3.6 and 1.2.9 released
- CakePHP 1.3.5 released
- Type hinting trong PHP
- CakePHP ra phiên bản mới 1.3.4
- Tích hợp Zend framework vào CakePHP
- Tạo virtual host trên local
- Sử dụng Acl trong cakephp – Phần 2
- Sử dụng Acl trong cakephp – Phần 1
- Sinh code tự động với cake console
- Tự động xóa record ở bảng con khi reocord ở bảng cha bị xóa
- Xác thực người dùng với component Auth
Thảo luận mới
- admin on Cách viết plugin cho CakePHP
- vinh on Xác thực người dùng với component Auth
- vinh on Sử dụng Acl trong cakephp – Phần 1
- hoaipt on Cách viết plugin cho CakePHP
- tuyền on Kỹ thuật “bit field” trong phân quyền
- admin on Tạo danh mục đa cấp với behavior Tree
- admin on Làm việc với File và Folder
- admin on Sinh code tự động với cake console
- admin on Kỹ thuật “bit field” trong phân quyền
- phùng ngọc lan on Tạo danh mục đa cấp với behavior Tree
TAG
Calendar
Lưu trữ
- September 2011 (3)
- July 2011 (1)
- March 2011 (1)
- February 2011 (1)
- November 2010 (4)
- October 2010 (1)
- September 2010 (2)
- August 2010 (9)
- July 2010 (9)
- June 2010 (22)
Blogroll
- Bakery
- Biển đảo Việt Nam
- CakePHP
- CakePHP Google Group
- CakePHP Manual
- CakePHP Questions
- Diễn đàn CakePHP VN

admin

Notice (8): Undefined property: UsersController::$Acl [APP\controllers\users_controller.php, line 27]
Fatal error: Call to a member function allow() on a non-object in C:\xampp\htdocs\loginacl\app\controllers\users_controller.php on line 27
Mình copy source của bạn chạy thử nhưng mà khi chạy đến bước xuất dữ liệu cho table aco thì bị lỗi như vậy.