@konrad1234:
I have used this structure http://www.yiiframework.com/wiki/374/yiiboilerplate-setup-a-professional-project-structure-in-seconds/ for my CMS based on Yii. I’ve implemented Rights module to support this like this:
My current folder structure
-apps
----web
----backend
----common
-core
----cms
----yii
Current Rights Module Permission Management
Here are my modifications
1/ Make sure application id is the same with the folder name. For example, config file of backend app should be:
return array(
// Project Name
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
// Project Id - should be the same with its folder container
'id'=> 'backend',
...
);
2/ Modify RightsFilter.php
/**
* Performs the pre-action filtering.
* @param CFilterChain $filterChain the filter chain that the filter is on.
* @return boolean whether the filtering process should continue and the action
* should be executed.
*/
protected function preFilter($filterChain)
{
// By default we assume that the user is allowed access
$allow = true;
$user = Yii::app()->getUser();
$controller = $filterChain->controller;
$action = $filterChain->action;
// Check if the action should be allowed
if( $this->_allowedActions!=='*' && in_array($action->id, $this->_allowedActions)===false )
{
// Initialize the authorization item as an empty string
$authItem = '';
// Tuan implements to add app ID to item name GXC-CMS
$authItem .= strtolower(app()->id).'.';
// Append the module id to the authorization item name
// in case the controller called belongs to a module
if( ($module = $controller->getModule())!==null )
$authItem .= ucfirst($module->id).'.';
// Append the controller id to the authorization item name
$authItem .= ucfirst($controller->id);
// Check if user has access to the controller
if( $user->checkAccess($authItem.'.*')!==true )
{
// Append the action id to the authorization item name
$authItem .= '.'.ucfirst($action->id);
// Check if the user has access to the controller action
if( $user->checkAccess($authItem)!==true )
$allow = false;
}
}
// User is not allowed access, deny access
if( $allow===false )
{
$controller->accessDenied();
return false;
}
// Authorization item did not exist or the user had access, allow access
return true;
}
3/ Modify permissions.php layout
<div id="permissions">
<?php
$app=isset($_GET['app'])? strtolower($_GET['app']) : strtolower(app()->id);
Yii::app()->controller->pageTitle = Rights::t('core', 'Permissions').' - '.ucfirst($app).' Application' ; ?>
<?php
$apps=getAllApps();
?>
<p>
<?php foreach($apps as $app):?>
<?php echo CHtml::link(Rights::t('core', 'Set permissions for').' '.ucfirst($app), array('authItem/permissions','app'=>$app), array(
'class'=>'generator-link',)); ?> |
<?php endforeach; ?>
</p>
<?php foreach($apps as $app): ?>
<?php echo CHtml::link(Rights::t('core', 'Generate Items for').' '.ucfirst($app), array('authItem/generate','app'=>$app), array(
'class'=>'generator-link',)); ?> |
<?php endforeach; ?>
</p>
...
</div>
I have a globals.php file where I define global functions. I put getAllApps() function there
Remember to define path alias to COMMON folder
/**
* Function to Get All Apps Available
**/
public function getAllApps(){
$cache_id='gxchelpers-apps';
$apps=Yii::app()->cache->get($cache_id);
if($apps===false){
$apps=array();
$folders_app = get_subfolders_name(Yii::getPathOfAlias('common').DIRECTORY_SEPARATOR.'..') ;
foreach($folders_app as $folder){
if(file_exists(Yii::getPathOfAlias('common').DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.'protected'
.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'environment.php'))
$apps[]=$folder;
}
Yii::app()->cache->set($cache_id,$apps,7200);
}
return $apps;
}
4/ Modify RGenerator.php file
/**
* Returns a list of all application controllers.
* @return array the controllers.
*/
protected function getAllControllers()
{
$items['controllers']=array();
$items['modules']=array();
//Get App Path
$app=isset($_GET['app'])? strtolower($_GET['app']) : false;
// Tuan Implement to look for module controllers in common and cms folder also
//If there is no $_GET['app'], we will use the current app
if(!$app)
$basePath = Yii::app()->basePath;
else
$basePath = Yii::app()->basePath.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.$app.DIRECTORY_SEPARATOR.'protected';
if(is_dir($basePath)){
//Look for controller in current app
$items['controllers'] = $this->getControllersInPath($basePath.DIRECTORY_SEPARATOR.'controllers');
//Look for module controller in current app
$items['modules'] = $this->getControllersInModules($basePath);
//Look for module controller in common folder
$items['modules'] = array_merge($items['modules'],$this->getControllersInModules(Yii::getPathOfAlias('common')));
}
return $items;
}
4/ Modify RPermissionDataProvider.php
/**
* Generates the data for the data provider.
*/
protected function generateData()
{
$data = array();
$permissions = $this->_permissions;
$parents = $this->_parents;
foreach( $this->_items as $itemName=>$item )
{
$row = array();
$row['description'] = $item->getNameLink();
foreach( $this->_roles as $roleName=>$role )
{
// Item is directly assigned to the role
if( $permissions[ $roleName ][ $itemName ]===Rights::PERM_DIRECT )
{
$permissionColumn = $item->getRevokePermissionLink($role);
}
// Item is inherited by the role from one of its children
else if( $permissions[ $roleName ][ $itemName ]===Rights::PERM_INHERITED && isset($parents[ $roleName ][ $itemName ])===true )
{
$permissionColumn = $item->getInheritedPermissionText($parents[ $roleName ][ $itemName ], $this->displayParentType);
}
// Item is not assigned to the role
else
{
$permissionColumn = $item->getAssignPermissionLink($role);
}
// Populate role column
$row[ strtolower($roleName) ] = isset($permissionColumn)===true ? $permissionColumn : '';
}
// Append the row to data
$data[] = $row;
}
//Tuan implement to show Item based on App only
//Get App Path
$app=isset($_GET['app'])? strtolower($_GET['app']) : strtolower(app()->id);
foreach($data as $key=>$item){
if(strpos($item['description'],$app)===false){
//Strip Item that is not based on current app
unset($data[$key]);
}
}
$this->setData($data);
}
That’s all - I hope this help.