Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Tue, Sep 30, 7:23 AM

in-portal

Index: trunk/kernel/units/general/helpers/permissions_helper.php
===================================================================
--- trunk/kernel/units/general/helpers/permissions_helper.php (revision 5182)
+++ trunk/kernel/units/general/helpers/permissions_helper.php (revision 5183)
@@ -1,369 +1,369 @@
<?php
class kPermissionsHelper extends kHelper {
/**
* Current set of permissions for group being edited
*
* @var Array
*/
var $Permissions = Array();
function LoadPermissions($prefix)
{
$object =& $this->Application->recallObject($prefix.'-perm', null, Array('skip_autoload' => true));
$foreign_key = $this->Application->getUnitOption($prefix.'-perm', 'ForeignKey');
$foreign_value = $this->Application->GetVar($prefix.'_id');
$sql = 'SELECT *
FROM '.$object->TableName.'
WHERE '.$foreign_key.' = '.$foreign_value;
$permissions = $this->Conn->Query($sql, 'Permission');
$this->Permissions = Array();
foreach ($permissions as $perm_name => $perm_options) {
$perm_record['value'] = $perm_options['PermissionValue'];
$perm_record['id'] = $perm_options['PermissionId'];
$this->Permissions[$perm_name] = $perm_record;
}
}
function getPermissionValue($perm_name)
{
return getArrayValue($this->Permissions, $perm_name) ? $this->Permissions[$perm_name]['value'] : 0;
}
function getPermissionID($perm_name)
{
return getArrayValue($this->Permissions, $perm_name) ? $this->Permissions[$perm_name]['id'] : 0;
}
/**
* This is old permission like ADMIN or LOGIN
*
* @param string $section_name
* @param string $perm_name
* @return bool
*/
function isOldPermission($section_name, $perm_name)
{
return $section_name == 'in-portal:root' && $perm_name != 'view';
}
/**
* Returns permission names to check based on event name and item prefix (main item or subitem)
*
* @param kEvent $event
* @return Array
*/
function getPermissionByEvent(&$event, $perm_mapping)
{
$top_prefix = $event->getEventParam('top_prefix');
$pefix_type = ($top_prefix == $event->Prefix) ? 'self' : 'subitem';
$perm_mapping = getArrayValue($perm_mapping, $event->Name);
if (!$perm_mapping[$pefix_type]) {
trigger_error('Permission mappings not defined for event <b>'.$top_prefix.' <- '.$event->Prefix.':'.$event->Name.'</b>', E_USER_ERROR);
}
if ($perm_mapping[$pefix_type] === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
return explode('|', $perm_mapping[$pefix_type]);
}
/**
* Common event permission checking method
*
* @param kEvent $event
*/
function CheckEventPermission(&$event, $perm_mapping)
{
$section = $event->getSection();
if (preg_match('/^CATEGORY:(.*)/', $section)) {
return $this->CheckEventCategoryPermission($event, $perm_mapping);
}
$top_prefix = $event->getEventParam('top_prefix');
$check_perms = $this->getPermissionByEvent($event, $perm_mapping);
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
$perm_status = false;
foreach ($check_perms as $perm_name) {
// check if at least one of required permissions is set
$perm_name = $section.'.'.$perm_name;
$perm_status = $this->CheckPermission($perm_name, 1);
if (($perm_name == $section.'.add') && $perm_status && ($top_prefix == $event->Prefix)) {
// main item, add permission allowed, but ID is > 0, then deny permission
// how to get id here
}
if ($perm_status) {
return $perm_status;
}
}
if (!$perm_status) {
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $section);
$event->SetRedirectParam('main_prefix', $top_prefix);
$event->SetRedirectParam('event_name', $event->Name);
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$event->status = erPERM_FAIL;
}
return $perm_status;
}
/**
* Checks non-system permission on event per category basis
*
* @param kEvent $event
*/
function CheckEventCategoryPermission(&$event, $event_perm_mapping)
{
// mapping between specific permissions and common permissions
$perm_mapping = Array('add' => 'ADD', 'edit' => 'MODIFY', 'delete' => 'DELETE', 'view' => 'VIEW');
$top_prefix = $event->getEventParam('top_prefix');
$event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
if ($event->Prefix != $top_prefix) {
$top_event = new kEvent($top_prefix.':'.$event->Name);
$id = $event_handler->getPassedID($top_event);
}
else {
$id = $event_handler->getPassedID($event);
}
$item_prefix = $this->Application->getUnitOption($top_prefix, 'PermItemPrefix');
// 1. get primary category of category item
$id_field = $this->Application->getUnitOption($top_prefix, 'IDField');
$table_name = $this->Application->getUnitOption($top_prefix, 'TableName');
- $ci_table = $this->Application->getUnitOption($top_prefix.'-ci', 'TableName');
+ $ci_table = $this->Application->getUnitOption('ci', 'TableName');
if (!$id) {
// item being created -> check by current (before editing started, saved in OnPreCreate event) category permissions
$category_id = $this->Application->RecallVar('m_cat_id');
}
else {
// item being edited -> check by it's primary category permissions
$sql = 'SELECT ci.CategoryId
FROM '.$table_name.' main_table
LEFT JOIN '.$ci_table.' ci ON ci.ItemResourceId = main_table.ResourceId
WHERE (main_table.'.$id_field.' = '.$id.') AND (ci.PrimaryCat = 1)';
$category_id = $this->Conn->GetOne($sql);
}
if ((substr($event->Name, 0, 9) == 'OnPreSave') || ($event->Name == 'OnSave')) {
if ($event_handler->isNewItemCreate($event)) {
return $this->CheckPermission($item_prefix.'.ADD', 0, $category_id);
}
else {
return $this->CheckPermission($item_prefix.'.ADD', 0, $category_id) || $this->CheckPermission($item_prefix.'.MODIFY', 0, $category_id);
}
}
$perm_status = false;
$check_perms = $this->getPermissionByEvent($event, $event_perm_mapping);
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
foreach ($check_perms as $perm_name) {
// check if at least one of required permissions is set
if (!isset($perm_mapping[$perm_name])) {
// not mapped permission (e.g. advanced:approve) -> skip
continue;
}
$perm_name = $item_prefix.'.'.$perm_mapping[$perm_name];
$this->showDebug('Event <b>'.$event->Name.'</b> permission(-s): <b>'.$perm_name.'</b>', Array());
$perm_status = $this->CheckPermission($perm_name, 0, $category_id);
if ($perm_status) {
return $perm_status;
}
}
if (!$perm_status) {
$event->SetRedirectParam('index_file', 'index.php'); // because called from browse.php
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $event->getSection());
$event->SetRedirectParam('main_prefix', $top_prefix);
$event->SetRedirectParam('event_name', $event->Name);
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$event->status = erPERM_FAIL;
}
return $perm_status;
}
function showDebug($text, $params)
{
$is_ajax = $this->Application->GetVar('ajax') == 'yes' || isset($params['ajax']) || isset($params['tab_init']);
if (!$this->Application->isDebugMode() || $is_ajax) return true;
echo $text.'<br />';
}
function TagPermissionCheck($params, $tag_name)
{
$perm_event = getArrayValue($params, 'perm_event');
$permission_groups = getArrayValue($params, 'permissions');
if ($permission_groups) {
$this->showDebug('Tag <b>'.$tag_name.'</b> permission(-s): <b>'.$permission_groups.'</b>', $params);
$permission_groups = explode('|', $permission_groups);
$group_has_permission = false;
foreach ($permission_groups as $permission_group) {
$permissions = explode(',', $permission_group);
$has_permission = true;
foreach ($permissions as $permission) {
$has_permission = $has_permission && $this->CheckPermission($permission, isset($params['system']) && $params['system'] ? 1 : 0);
}
$group_has_permission = $group_has_permission || $has_permission;
if ($group_has_permission) {
return true;
}
}
return false;
}
elseif ($perm_event) {
$this->showDebug('Tag <b>'.$tag_name.'</b> permission_event: <b>'.$perm_event.'</b>', $params);
list($prefix, $event) = explode(':', $perm_event);
$event_handler =& $this->Application->recallObject($prefix.'_EventHandler');
return $event_handler->CheckPermission( new kEvent($perm_event) );
}
return true;
}
/**
* Returns no permission template to redirect to
*
* @param Array $params
* @return Array
*/
function getPermissionTemplate($params)
{
$t = $this->Application->GetVar('t');
if ($next_t = getArrayValue($params, 'next_template')) {
$t = $next_t;
}
if (!$this->Application->LoggedIn()) {
$redirect_template = $params['login_template'];
$redirect_params = Array('next_template' => $t);
}
else {
if (isset($params['no_permissions_template'])) {
$redirect_template = $params['no_permissions_template'];
}
else {
$redirect_template = $this->Application->IsAdmin() ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
}
$redirect_params = $this->Application->isDebugMode() ? Array('from_template' => 1, 'perms' => $params[ isset($params['permissions']) ? 'permissions' : 'perm_event'], 'next_template' => $t) : Array();
}
return Array($redirect_template, $redirect_params);
}
/**
* Check current user permissions based on it's group permissions in specified category (for non-system permissions) or just checks if system permission is set
*
* @param string $name permission name
* @param int $cat_id category id, current used if not specified
* @param int $type permission type {1 - system, 0 - per category}
* @return int
*/
function CheckPermission($name, $type = 1, $cat_id = null)
{
if ($this->Application->GetVar('u_id') == -1) {
// "root" is allowed anywhere
return $name == 'SYSTEM_ACCESS.READONLY' ? 0 : 1;
}
if ($type == 1) {
// "system" permission are always checked per "Home" category (ID = 0)
$cat_id = 0;
}
if (!isset($cat_id)) {
$cat_id = $this->Application->GetVar('m_cat_id');
}
$cache_key = $name.'|'.$type.'|'.$cat_id;
$perm_value = $this->Application->getCache('permissions', $cache_key);
if ($perm_value !== false) {
return $perm_value;
}
// perm cache is build only based on records in db, that's why if permission is not explicitly denied, then
// that (perm cache creator) code thinks that it is allowed & adds corresponding record and code below will
// return incorrect results
/*if (preg_match('/(.*)\.VIEW$/', $name) && ($type == 0)) {
// cached view permission of category: begin
$sql = 'SELECT perm_cache.PermId
FROM '.TABLE_PREFIX.'PermCache perm_cache
LEFT JOIN '.TABLE_PREFIX.'PermissionConfig perm_config ON perm_cache.PermId = perm_config.PermissionConfigId
WHERE (perm_config.PermissionName = '.$this->Conn->qstr($name).' AND perm_cache.CategoryId = '.$cat_id.')';
$view_filters = Array();
$groups = explode(',', $this->Application->RecallVar('UserGroups'));
foreach ($groups as $group) {
$view_filters[] = 'FIND_IN_SET('.$group.', perm_cache.ACL) || ((NOT FIND_IN_SET('.$group.', perm_cache.DACL)) AND perm_cache.ACL = \'\')';
}
$sql .= ' AND ('.implode(' OR ', $view_filters).')';
$perm_value = $this->Conn->GetOne($sql) ? 1 : 0;
$this->Application->setCache('permissions', $cache_key, $perm_value);
return $perm_value;
// cached view permission of category: end
}*/
if ($cat_id == 0) {
$cat_hierarchy = Array(0);
}
else {
$sql = 'SELECT ParentPath
FROM '.$this->Application->getUnitOption('c', 'TableName').'
WHERE CategoryId = '.$cat_id;
$cat_hierarchy = $this->Conn->GetOne($sql);
$cat_hierarchy = explode('|', $cat_hierarchy);
array_shift($cat_hierarchy);
array_pop($cat_hierarchy);
$cat_hierarchy = array_reverse($cat_hierarchy);
array_push($cat_hierarchy, 0);
}
$perm_value = 0;
$groups = $this->Application->RecallVar('UserGroups');
foreach ($cat_hierarchy as $category_id) {
$sql = 'SELECT PermissionValue
FROM '.TABLE_PREFIX.'Permissions
WHERE Permission = "'.$name.'" AND CatId = '.$category_id.' AND GroupId IN ('.$groups.') AND Type = '.$type;
$res = $this->Conn->GetOne($sql);
if ($res !== false) {
$perm_value = $res;
break;
}
}
$this->Application->setCache('permissions', $cache_key, $perm_value);
return $perm_value;
}
}
?>
\ No newline at end of file
Property changes on: trunk/kernel/units/general/helpers/permissions_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.11
\ No newline at end of property
+1.12
\ No newline at end of property
Index: trunk/core/units/general/helpers/permissions_helper.php
===================================================================
--- trunk/core/units/general/helpers/permissions_helper.php (revision 5182)
+++ trunk/core/units/general/helpers/permissions_helper.php (revision 5183)
@@ -1,369 +1,369 @@
<?php
class kPermissionsHelper extends kHelper {
/**
* Current set of permissions for group being edited
*
* @var Array
*/
var $Permissions = Array();
function LoadPermissions($prefix)
{
$object =& $this->Application->recallObject($prefix.'-perm', null, Array('skip_autoload' => true));
$foreign_key = $this->Application->getUnitOption($prefix.'-perm', 'ForeignKey');
$foreign_value = $this->Application->GetVar($prefix.'_id');
$sql = 'SELECT *
FROM '.$object->TableName.'
WHERE '.$foreign_key.' = '.$foreign_value;
$permissions = $this->Conn->Query($sql, 'Permission');
$this->Permissions = Array();
foreach ($permissions as $perm_name => $perm_options) {
$perm_record['value'] = $perm_options['PermissionValue'];
$perm_record['id'] = $perm_options['PermissionId'];
$this->Permissions[$perm_name] = $perm_record;
}
}
function getPermissionValue($perm_name)
{
return getArrayValue($this->Permissions, $perm_name) ? $this->Permissions[$perm_name]['value'] : 0;
}
function getPermissionID($perm_name)
{
return getArrayValue($this->Permissions, $perm_name) ? $this->Permissions[$perm_name]['id'] : 0;
}
/**
* This is old permission like ADMIN or LOGIN
*
* @param string $section_name
* @param string $perm_name
* @return bool
*/
function isOldPermission($section_name, $perm_name)
{
return $section_name == 'in-portal:root' && $perm_name != 'view';
}
/**
* Returns permission names to check based on event name and item prefix (main item or subitem)
*
* @param kEvent $event
* @return Array
*/
function getPermissionByEvent(&$event, $perm_mapping)
{
$top_prefix = $event->getEventParam('top_prefix');
$pefix_type = ($top_prefix == $event->Prefix) ? 'self' : 'subitem';
$perm_mapping = getArrayValue($perm_mapping, $event->Name);
if (!$perm_mapping[$pefix_type]) {
trigger_error('Permission mappings not defined for event <b>'.$top_prefix.' <- '.$event->Prefix.':'.$event->Name.'</b>', E_USER_ERROR);
}
if ($perm_mapping[$pefix_type] === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
return explode('|', $perm_mapping[$pefix_type]);
}
/**
* Common event permission checking method
*
* @param kEvent $event
*/
function CheckEventPermission(&$event, $perm_mapping)
{
$section = $event->getSection();
if (preg_match('/^CATEGORY:(.*)/', $section)) {
return $this->CheckEventCategoryPermission($event, $perm_mapping);
}
$top_prefix = $event->getEventParam('top_prefix');
$check_perms = $this->getPermissionByEvent($event, $perm_mapping);
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
$perm_status = false;
foreach ($check_perms as $perm_name) {
// check if at least one of required permissions is set
$perm_name = $section.'.'.$perm_name;
$perm_status = $this->CheckPermission($perm_name, 1);
if (($perm_name == $section.'.add') && $perm_status && ($top_prefix == $event->Prefix)) {
// main item, add permission allowed, but ID is > 0, then deny permission
// how to get id here
}
if ($perm_status) {
return $perm_status;
}
}
if (!$perm_status) {
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $section);
$event->SetRedirectParam('main_prefix', $top_prefix);
$event->SetRedirectParam('event_name', $event->Name);
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$event->status = erPERM_FAIL;
}
return $perm_status;
}
/**
* Checks non-system permission on event per category basis
*
* @param kEvent $event
*/
function CheckEventCategoryPermission(&$event, $event_perm_mapping)
{
// mapping between specific permissions and common permissions
$perm_mapping = Array('add' => 'ADD', 'edit' => 'MODIFY', 'delete' => 'DELETE', 'view' => 'VIEW');
$top_prefix = $event->getEventParam('top_prefix');
$event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
if ($event->Prefix != $top_prefix) {
$top_event = new kEvent($top_prefix.':'.$event->Name);
$id = $event_handler->getPassedID($top_event);
}
else {
$id = $event_handler->getPassedID($event);
}
$item_prefix = $this->Application->getUnitOption($top_prefix, 'PermItemPrefix');
// 1. get primary category of category item
$id_field = $this->Application->getUnitOption($top_prefix, 'IDField');
$table_name = $this->Application->getUnitOption($top_prefix, 'TableName');
- $ci_table = $this->Application->getUnitOption($top_prefix.'-ci', 'TableName');
+ $ci_table = $this->Application->getUnitOption('ci', 'TableName');
if (!$id) {
// item being created -> check by current (before editing started, saved in OnPreCreate event) category permissions
$category_id = $this->Application->RecallVar('m_cat_id');
}
else {
// item being edited -> check by it's primary category permissions
$sql = 'SELECT ci.CategoryId
FROM '.$table_name.' main_table
LEFT JOIN '.$ci_table.' ci ON ci.ItemResourceId = main_table.ResourceId
WHERE (main_table.'.$id_field.' = '.$id.') AND (ci.PrimaryCat = 1)';
$category_id = $this->Conn->GetOne($sql);
}
if ((substr($event->Name, 0, 9) == 'OnPreSave') || ($event->Name == 'OnSave')) {
if ($event_handler->isNewItemCreate($event)) {
return $this->CheckPermission($item_prefix.'.ADD', 0, $category_id);
}
else {
return $this->CheckPermission($item_prefix.'.ADD', 0, $category_id) || $this->CheckPermission($item_prefix.'.MODIFY', 0, $category_id);
}
}
$perm_status = false;
$check_perms = $this->getPermissionByEvent($event, $event_perm_mapping);
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
foreach ($check_perms as $perm_name) {
// check if at least one of required permissions is set
if (!isset($perm_mapping[$perm_name])) {
// not mapped permission (e.g. advanced:approve) -> skip
continue;
}
$perm_name = $item_prefix.'.'.$perm_mapping[$perm_name];
$this->showDebug('Event <b>'.$event->Name.'</b> permission(-s): <b>'.$perm_name.'</b>', Array());
$perm_status = $this->CheckPermission($perm_name, 0, $category_id);
if ($perm_status) {
return $perm_status;
}
}
if (!$perm_status) {
$event->SetRedirectParam('index_file', 'index.php'); // because called from browse.php
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $event->getSection());
$event->SetRedirectParam('main_prefix', $top_prefix);
$event->SetRedirectParam('event_name', $event->Name);
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$event->status = erPERM_FAIL;
}
return $perm_status;
}
function showDebug($text, $params)
{
$is_ajax = $this->Application->GetVar('ajax') == 'yes' || isset($params['ajax']) || isset($params['tab_init']);
if (!$this->Application->isDebugMode() || $is_ajax) return true;
echo $text.'<br />';
}
function TagPermissionCheck($params, $tag_name)
{
$perm_event = getArrayValue($params, 'perm_event');
$permission_groups = getArrayValue($params, 'permissions');
if ($permission_groups) {
$this->showDebug('Tag <b>'.$tag_name.'</b> permission(-s): <b>'.$permission_groups.'</b>', $params);
$permission_groups = explode('|', $permission_groups);
$group_has_permission = false;
foreach ($permission_groups as $permission_group) {
$permissions = explode(',', $permission_group);
$has_permission = true;
foreach ($permissions as $permission) {
$has_permission = $has_permission && $this->CheckPermission($permission, isset($params['system']) && $params['system'] ? 1 : 0);
}
$group_has_permission = $group_has_permission || $has_permission;
if ($group_has_permission) {
return true;
}
}
return false;
}
elseif ($perm_event) {
$this->showDebug('Tag <b>'.$tag_name.'</b> permission_event: <b>'.$perm_event.'</b>', $params);
list($prefix, $event) = explode(':', $perm_event);
$event_handler =& $this->Application->recallObject($prefix.'_EventHandler');
return $event_handler->CheckPermission( new kEvent($perm_event) );
}
return true;
}
/**
* Returns no permission template to redirect to
*
* @param Array $params
* @return Array
*/
function getPermissionTemplate($params)
{
$t = $this->Application->GetVar('t');
if ($next_t = getArrayValue($params, 'next_template')) {
$t = $next_t;
}
if (!$this->Application->LoggedIn()) {
$redirect_template = $params['login_template'];
$redirect_params = Array('next_template' => $t);
}
else {
if (isset($params['no_permissions_template'])) {
$redirect_template = $params['no_permissions_template'];
}
else {
$redirect_template = $this->Application->IsAdmin() ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
}
$redirect_params = $this->Application->isDebugMode() ? Array('from_template' => 1, 'perms' => $params[ isset($params['permissions']) ? 'permissions' : 'perm_event'], 'next_template' => $t) : Array();
}
return Array($redirect_template, $redirect_params);
}
/**
* Check current user permissions based on it's group permissions in specified category (for non-system permissions) or just checks if system permission is set
*
* @param string $name permission name
* @param int $cat_id category id, current used if not specified
* @param int $type permission type {1 - system, 0 - per category}
* @return int
*/
function CheckPermission($name, $type = 1, $cat_id = null)
{
if ($this->Application->GetVar('u_id') == -1) {
// "root" is allowed anywhere
return $name == 'SYSTEM_ACCESS.READONLY' ? 0 : 1;
}
if ($type == 1) {
// "system" permission are always checked per "Home" category (ID = 0)
$cat_id = 0;
}
if (!isset($cat_id)) {
$cat_id = $this->Application->GetVar('m_cat_id');
}
$cache_key = $name.'|'.$type.'|'.$cat_id;
$perm_value = $this->Application->getCache('permissions', $cache_key);
if ($perm_value !== false) {
return $perm_value;
}
// perm cache is build only based on records in db, that's why if permission is not explicitly denied, then
// that (perm cache creator) code thinks that it is allowed & adds corresponding record and code below will
// return incorrect results
/*if (preg_match('/(.*)\.VIEW$/', $name) && ($type == 0)) {
// cached view permission of category: begin
$sql = 'SELECT perm_cache.PermId
FROM '.TABLE_PREFIX.'PermCache perm_cache
LEFT JOIN '.TABLE_PREFIX.'PermissionConfig perm_config ON perm_cache.PermId = perm_config.PermissionConfigId
WHERE (perm_config.PermissionName = '.$this->Conn->qstr($name).' AND perm_cache.CategoryId = '.$cat_id.')';
$view_filters = Array();
$groups = explode(',', $this->Application->RecallVar('UserGroups'));
foreach ($groups as $group) {
$view_filters[] = 'FIND_IN_SET('.$group.', perm_cache.ACL) || ((NOT FIND_IN_SET('.$group.', perm_cache.DACL)) AND perm_cache.ACL = \'\')';
}
$sql .= ' AND ('.implode(' OR ', $view_filters).')';
$perm_value = $this->Conn->GetOne($sql) ? 1 : 0;
$this->Application->setCache('permissions', $cache_key, $perm_value);
return $perm_value;
// cached view permission of category: end
}*/
if ($cat_id == 0) {
$cat_hierarchy = Array(0);
}
else {
$sql = 'SELECT ParentPath
FROM '.$this->Application->getUnitOption('c', 'TableName').'
WHERE CategoryId = '.$cat_id;
$cat_hierarchy = $this->Conn->GetOne($sql);
$cat_hierarchy = explode('|', $cat_hierarchy);
array_shift($cat_hierarchy);
array_pop($cat_hierarchy);
$cat_hierarchy = array_reverse($cat_hierarchy);
array_push($cat_hierarchy, 0);
}
$perm_value = 0;
$groups = $this->Application->RecallVar('UserGroups');
foreach ($cat_hierarchy as $category_id) {
$sql = 'SELECT PermissionValue
FROM '.TABLE_PREFIX.'Permissions
WHERE Permission = "'.$name.'" AND CatId = '.$category_id.' AND GroupId IN ('.$groups.') AND Type = '.$type;
$res = $this->Conn->GetOne($sql);
if ($res !== false) {
$perm_value = $res;
break;
}
}
$this->Application->setCache('permissions', $cache_key, $perm_value);
return $perm_value;
}
}
?>
\ No newline at end of file
Property changes on: trunk/core/units/general/helpers/permissions_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.11
\ No newline at end of property
+1.12
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.4.10/kernel/units/general/helpers/multilanguage.php
===================================================================
--- branches/unlabeled/unlabeled-1.4.10/kernel/units/general/helpers/multilanguage.php (revision 5182)
+++ branches/unlabeled/unlabeled-1.4.10/kernel/units/general/helpers/multilanguage.php (revision 5183)
@@ -1,210 +1,225 @@
<?php
/**
* Performs action on multilingual fields
*
*/
class kMultiLanguageHelper extends kHelper {
var $languageCount = 0;
/**
* Structure of table, that is currently processed
*
* @var Array
*/
var $curStructure = Array();
/**
* Field, to get structure information from
*
* @var string
*/
var $curSourceField = false;
/**
* Fields from config, that are currently used
*
* @var Array
*/
var $curFields = Array();
function kMultiLanguageHelper()
{
parent::kHelper();
$this->languageCount = $this->getLanguageCount();
}
/**
* Returns language count in system (always is divisible by 5)
*
*/
function getLanguageCount()
{
$table_name = $this->Application->getUnitOption('lang', 'TableName');
$languages_count = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$table_name);
if (!$languages_count) {
// during installation we have not languages, but we need to created custom field columns
$languages_count = 1;
}
return $languages_count + 5 - ( $languages_count % 5 ? ($languages_count % 5) : 5 );
}
function scanTable($mask)
{
$i = 0;
$fields_found = 0;
$fields = array_keys($this->curStructure);
foreach ($fields as $field_name) {
if (preg_match($mask, $field_name)) {
$fields_found++;
}
}
return $fields_found;
}
function readTableStructure($table_name)
{
static $structure_status = Array();
if (!getArrayValue($structure_status, $table_name)) {
$this->curStructure = $this->Conn->Query('DESCRIBE '.$table_name, 'Field');
$structure_status[$table_name] = true;
}
}
/**
* Creates missing multilanguage fields in table by specified prefix
*
* @param string $prefix
* @param bool $refresh Forces config field structure to be re-read from database
*/
function createFields($prefix, $refresh = false)
{
if ($refresh) {
$this->Application->HandleEvent( new kEvent($prefix.':OnCreateCustomFields') );
}
$table_name = $this->Application->getUnitOption($prefix, 'TableName');
$this->curFields = $this->Application->getUnitOption($prefix, 'Fields');
if (!($table_name && $this->curFields) ) {
// invalid config found or prefix not found
return true;
}
$sqls = Array();
foreach($this->curFields as $field_name => $field_options)
{
if (getArrayValue($field_options, 'formatter') == 'kMultiLanguage') {
$this->readTableStructure($table_name);
$created_count = $this->getCreatedCount($field_name);
$create_count = $this->languageCount - $created_count;
if ($create_count > 0) {
// `l77_Name` VARCHAR( 255 ) NULL DEFAULT '0';
$field_mask = Array();
$field_mask['name'] = 'l%s_'.$field_name;
$field_mask['null'] = getArrayValue($field_options, 'not_null') ? 'NOT NULL' : 'NULL';
if ($this->curSourceField) {
$default_value = $this->getFieldParam('Default') != 'NULL' ? $this->Conn->qstr($this->getFieldParam('Default')) : $this->getFieldParam('Default');
$field_mask['type'] = $this->getFieldParam('Type');
}
else {
$default_value = is_null($field_options['default']) ? 'NULL' : $this->Conn->qstr($field_options['default']);
$field_mask['type'] = $field_options['db_type'];
}
$field_mask['default'] = 'DEFAULT '.$default_value;
$field_mask = $field_mask['name'].' '.$field_mask['type'].' '.$field_mask['null'].' '.$field_mask['default'];
$sqls[] = 'ALTER TABLE '.$table_name.( $this->generateAlterSQL($field_mask, $created_count + 1, $create_count) );
}
}
}
foreach ($sqls as $sql_query) {
$this->Conn->Query($sql_query);
}
}
function deleteField($prefix, $custom_id)
{
$table_name = $this->Application->getUnitOption($prefix, 'TableName');
$sql = 'DESCRIBE '.$table_name.' "l%_cust_'.$custom_id.'"';
$fields = $this->Conn->GetCol($sql);
$sql = 'ALTER TABLE '.$table_name.' ';
$sql_template = 'DROP COLUMN %s, ';
foreach ($fields as $field_name) {
$sql .= sprintf($sql_template, $field_name);
}
$sql = preg_replace('/(.*), $/', '\\1', $sql);
$this->Conn->Query($sql);
}
/**
* Returns parameter requested of current source field
*
* @param string $param_name
* @return string
*/
function getFieldParam($param_name)
{
return $this->curStructure[$this->curSourceField][$param_name];
}
function getCreatedCount($field_name)
{
$ret = $this->scanTable('/^l[\d]+_'.preg_quote($field_name, '/').'/');
if (!$ret) {
// no multilingual fields at all (but we have such field without language prefix)
$original_found = $this->scanTable('/'.preg_quote($field_name, '/').'/');
$this->curSourceField = $original_found ? $field_name : false;
}
else {
$this->curSourceField = 'l1_'.$field_name;
}
return $ret;
}
/**
* Returns ALTER statement part for adding required fields to table
*
* @param string $field_mask sql mask for creating field with correct definition (type & size)
* @param int $start_index add new fields starting from this index
* @param int $create_count create this much new multilingual field translations
* @return string
*/
function generateAlterSQL($field_mask, $start_index, $create_count)
{
- $i_count = $start_index + $create_count;
+ static $single_lang = null;
+ if (!isset($single_lang)) {
+ // if single language mode, then create indexes only on primary columns
+ $table_name = $this->Application->getUnitOption('lang', 'TableName');
+ $sql = 'SELECT COUNT(*)
+ FROM '.$table_name.'
+ WHERE Enabled = 1';
+ // if language count = 0, then assume it's multi language mode
+ $single_lang = $this->Conn->GetOne($sql) == 1;
+ }
+
$ret = ' ';
+ $i_count = $start_index + $create_count;
while ($start_index < $i_count) {
list($prev_field,$type) = explode(' ', sprintf($field_mask, $start_index - 1) );
if (substr($prev_field, 0, 3) == 'l0_') {
$prev_field = substr($prev_field, 3, strlen($prev_field));
if (!$this->curSourceField) {
// get field name before this one
$fields = array_keys($this->curFields);
$prev_field = $fields[array_search($prev_field, $fields) - 1];
if (getArrayValue($this->curFields[$prev_field], 'formatter') == 'kMultiLanguage') {
$prev_field = 'l'.$this->languageCount.'_'.$prev_field;
}
}
}
$field_expression = sprintf($field_mask, $start_index);
$ret .= 'ADD COLUMN '.$field_expression.' AFTER `'.$prev_field.'`, ';
+ if ($start_index == $this->Application->GetDefaultLanguageId() || !$single_lang) {
+ // create index for primary language column + for all others (if multiple languages installed)
list($field_name, $field_params) = explode(' ', $field_expression, 2);
$ret .= 'ADD INDEX (`'.$field_name.'` (5) ), ';
+ }
+
$start_index++;
}
return preg_replace('/, $/',';',$ret);
}
}
?>
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.4.10/kernel/units/general/helpers/multilanguage.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.4
\ No newline at end of property
+1.4.10.1
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.4.10/core/units/general/helpers/multilanguage.php
===================================================================
--- branches/unlabeled/unlabeled-1.4.10/core/units/general/helpers/multilanguage.php (revision 5182)
+++ branches/unlabeled/unlabeled-1.4.10/core/units/general/helpers/multilanguage.php (revision 5183)
@@ -1,210 +1,225 @@
<?php
/**
* Performs action on multilingual fields
*
*/
class kMultiLanguageHelper extends kHelper {
var $languageCount = 0;
/**
* Structure of table, that is currently processed
*
* @var Array
*/
var $curStructure = Array();
/**
* Field, to get structure information from
*
* @var string
*/
var $curSourceField = false;
/**
* Fields from config, that are currently used
*
* @var Array
*/
var $curFields = Array();
function kMultiLanguageHelper()
{
parent::kHelper();
$this->languageCount = $this->getLanguageCount();
}
/**
* Returns language count in system (always is divisible by 5)
*
*/
function getLanguageCount()
{
$table_name = $this->Application->getUnitOption('lang', 'TableName');
$languages_count = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$table_name);
if (!$languages_count) {
// during installation we have not languages, but we need to created custom field columns
$languages_count = 1;
}
return $languages_count + 5 - ( $languages_count % 5 ? ($languages_count % 5) : 5 );
}
function scanTable($mask)
{
$i = 0;
$fields_found = 0;
$fields = array_keys($this->curStructure);
foreach ($fields as $field_name) {
if (preg_match($mask, $field_name)) {
$fields_found++;
}
}
return $fields_found;
}
function readTableStructure($table_name)
{
static $structure_status = Array();
if (!getArrayValue($structure_status, $table_name)) {
$this->curStructure = $this->Conn->Query('DESCRIBE '.$table_name, 'Field');
$structure_status[$table_name] = true;
}
}
/**
* Creates missing multilanguage fields in table by specified prefix
*
* @param string $prefix
* @param bool $refresh Forces config field structure to be re-read from database
*/
function createFields($prefix, $refresh = false)
{
if ($refresh) {
$this->Application->HandleEvent( new kEvent($prefix.':OnCreateCustomFields') );
}
$table_name = $this->Application->getUnitOption($prefix, 'TableName');
$this->curFields = $this->Application->getUnitOption($prefix, 'Fields');
if (!($table_name && $this->curFields) ) {
// invalid config found or prefix not found
return true;
}
$sqls = Array();
foreach($this->curFields as $field_name => $field_options)
{
if (getArrayValue($field_options, 'formatter') == 'kMultiLanguage') {
$this->readTableStructure($table_name);
$created_count = $this->getCreatedCount($field_name);
$create_count = $this->languageCount - $created_count;
if ($create_count > 0) {
// `l77_Name` VARCHAR( 255 ) NULL DEFAULT '0';
$field_mask = Array();
$field_mask['name'] = 'l%s_'.$field_name;
$field_mask['null'] = getArrayValue($field_options, 'not_null') ? 'NOT NULL' : 'NULL';
if ($this->curSourceField) {
$default_value = $this->getFieldParam('Default') != 'NULL' ? $this->Conn->qstr($this->getFieldParam('Default')) : $this->getFieldParam('Default');
$field_mask['type'] = $this->getFieldParam('Type');
}
else {
$default_value = is_null($field_options['default']) ? 'NULL' : $this->Conn->qstr($field_options['default']);
$field_mask['type'] = $field_options['db_type'];
}
$field_mask['default'] = 'DEFAULT '.$default_value;
$field_mask = $field_mask['name'].' '.$field_mask['type'].' '.$field_mask['null'].' '.$field_mask['default'];
$sqls[] = 'ALTER TABLE '.$table_name.( $this->generateAlterSQL($field_mask, $created_count + 1, $create_count) );
}
}
}
foreach ($sqls as $sql_query) {
$this->Conn->Query($sql_query);
}
}
function deleteField($prefix, $custom_id)
{
$table_name = $this->Application->getUnitOption($prefix, 'TableName');
$sql = 'DESCRIBE '.$table_name.' "l%_cust_'.$custom_id.'"';
$fields = $this->Conn->GetCol($sql);
$sql = 'ALTER TABLE '.$table_name.' ';
$sql_template = 'DROP COLUMN %s, ';
foreach ($fields as $field_name) {
$sql .= sprintf($sql_template, $field_name);
}
$sql = preg_replace('/(.*), $/', '\\1', $sql);
$this->Conn->Query($sql);
}
/**
* Returns parameter requested of current source field
*
* @param string $param_name
* @return string
*/
function getFieldParam($param_name)
{
return $this->curStructure[$this->curSourceField][$param_name];
}
function getCreatedCount($field_name)
{
$ret = $this->scanTable('/^l[\d]+_'.preg_quote($field_name, '/').'/');
if (!$ret) {
// no multilingual fields at all (but we have such field without language prefix)
$original_found = $this->scanTable('/'.preg_quote($field_name, '/').'/');
$this->curSourceField = $original_found ? $field_name : false;
}
else {
$this->curSourceField = 'l1_'.$field_name;
}
return $ret;
}
/**
* Returns ALTER statement part for adding required fields to table
*
* @param string $field_mask sql mask for creating field with correct definition (type & size)
* @param int $start_index add new fields starting from this index
* @param int $create_count create this much new multilingual field translations
* @return string
*/
function generateAlterSQL($field_mask, $start_index, $create_count)
{
- $i_count = $start_index + $create_count;
+ static $single_lang = null;
+ if (!isset($single_lang)) {
+ // if single language mode, then create indexes only on primary columns
+ $table_name = $this->Application->getUnitOption('lang', 'TableName');
+ $sql = 'SELECT COUNT(*)
+ FROM '.$table_name.'
+ WHERE Enabled = 1';
+ // if language count = 0, then assume it's multi language mode
+ $single_lang = $this->Conn->GetOne($sql) == 1;
+ }
+
$ret = ' ';
+ $i_count = $start_index + $create_count;
while ($start_index < $i_count) {
list($prev_field,$type) = explode(' ', sprintf($field_mask, $start_index - 1) );
if (substr($prev_field, 0, 3) == 'l0_') {
$prev_field = substr($prev_field, 3, strlen($prev_field));
if (!$this->curSourceField) {
// get field name before this one
$fields = array_keys($this->curFields);
$prev_field = $fields[array_search($prev_field, $fields) - 1];
if (getArrayValue($this->curFields[$prev_field], 'formatter') == 'kMultiLanguage') {
$prev_field = 'l'.$this->languageCount.'_'.$prev_field;
}
}
}
$field_expression = sprintf($field_mask, $start_index);
$ret .= 'ADD COLUMN '.$field_expression.' AFTER `'.$prev_field.'`, ';
+ if ($start_index == $this->Application->GetDefaultLanguageId() || !$single_lang) {
+ // create index for primary language column + for all others (if multiple languages installed)
list($field_name, $field_params) = explode(' ', $field_expression, 2);
$ret .= 'ADD INDEX (`'.$field_name.'` (5) ), ';
+ }
+
$start_index++;
}
return preg_replace('/, $/',';',$ret);
}
}
?>
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.4.10/core/units/general/helpers/multilanguage.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.4
\ No newline at end of property
+1.4.10.1
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.8.2/kernel/units/general/helpers/permissions_helper.php
===================================================================
--- branches/unlabeled/unlabeled-1.8.2/kernel/units/general/helpers/permissions_helper.php (revision 5182)
+++ branches/unlabeled/unlabeled-1.8.2/kernel/units/general/helpers/permissions_helper.php (revision 5183)
@@ -1,368 +1,368 @@
<?php
class kPermissionsHelper extends kHelper {
/**
* Current set of permissions for group being edited
*
* @var Array
*/
var $Permissions = Array();
function LoadPermissions($prefix)
{
$object =& $this->Application->recallObject($prefix.'-perm', null, Array('skip_autoload' => true));
$foreign_key = $this->Application->getUnitOption($prefix.'-perm', 'ForeignKey');
$foreign_value = $this->Application->GetVar($prefix.'_id');
$sql = 'SELECT *
FROM '.$object->TableName.'
WHERE '.$foreign_key.' = '.$foreign_value;
$permissions = $this->Conn->Query($sql, 'Permission');
$this->Permissions = Array();
foreach ($permissions as $perm_name => $perm_options) {
$perm_record['value'] = $perm_options['PermissionValue'];
$perm_record['id'] = $perm_options['PermissionId'];
$this->Permissions[$perm_name] = $perm_record;
}
}
function getPermissionValue($perm_name)
{
return getArrayValue($this->Permissions, $perm_name) ? $this->Permissions[$perm_name]['value'] : 0;
}
function getPermissionID($perm_name)
{
return getArrayValue($this->Permissions, $perm_name) ? $this->Permissions[$perm_name]['id'] : 0;
}
/**
* This is old permission like ADMIN or LOGIN
*
* @param string $section_name
* @param string $perm_name
* @return bool
*/
function isOldPermission($section_name, $perm_name)
{
return $section_name == 'in-portal:root' && $perm_name != 'view';
}
/**
* Returns permission names to check based on event name and item prefix (main item or subitem)
*
* @param kEvent $event
* @return Array
*/
function getPermissionByEvent(&$event, $perm_mapping)
{
$top_prefix = $event->getEventParam('top_prefix');
$pefix_type = ($top_prefix == $event->Prefix) ? 'self' : 'subitem';
$perm_mapping = getArrayValue($perm_mapping, $event->Name);
if (!$perm_mapping[$pefix_type]) {
trigger_error('Permission mappings not defined for event <b>'.$top_prefix.' <- '.$event->Prefix.':'.$event->Name.'</b>', E_USER_ERROR);
}
if ($perm_mapping[$pefix_type] === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
return explode('|', $perm_mapping[$pefix_type]);
}
/**
* Common event permission checking method
*
* @param kEvent $event
*/
function CheckEventPermission(&$event, $perm_mapping)
{
$section = $event->getSection();
if (preg_match('/^CATEGORY:(.*)/', $section)) {
return $this->CheckEventCategoryPermission($event, $perm_mapping);
}
$top_prefix = $event->getEventParam('top_prefix');
$check_perms = $this->getPermissionByEvent($event, $perm_mapping);
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
$perm_status = false;
foreach ($check_perms as $perm_name) {
// check if at least one of required permissions is set
$perm_name = $section.'.'.$perm_name;
$perm_status = $this->CheckPermission($perm_name, 1);
if (($perm_name == $section.'.add') && $perm_status && ($top_prefix == $event->Prefix)) {
// main item, add permission allowed, but ID is > 0, then deny permission
// how to get id here
}
if ($perm_status) {
return $perm_status;
}
}
if (!$perm_status) {
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $section);
$event->SetRedirectParam('main_prefix', $top_prefix);
$event->SetRedirectParam('event_name', $event->Name);
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$event->status = erPERM_FAIL;
}
return $perm_status;
}
/**
* Checks non-system permission on event per category basis
*
* @param kEvent $event
*/
function CheckEventCategoryPermission(&$event, $event_perm_mapping)
{
// mapping between specific permissions and common permissions
$perm_mapping = Array('add' => 'ADD', 'edit' => 'MODIFY', 'delete' => 'DELETE', 'view' => 'VIEW');
$top_prefix = $event->getEventParam('top_prefix');
$event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
if ($event->Prefix != $top_prefix) {
$top_event = new kEvent($top_prefix.':'.$event->Name);
$id = $event_handler->getPassedID($top_event);
}
else {
$id = $event_handler->getPassedID($event);
}
$item_prefix = $this->Application->getUnitOption($top_prefix, 'PermItemPrefix');
// 1. get primary category of category item
$id_field = $this->Application->getUnitOption($top_prefix, 'IDField');
$table_name = $this->Application->getUnitOption($top_prefix, 'TableName');
- $ci_table = $this->Application->getUnitOption($top_prefix.'-ci', 'TableName');
+ $ci_table = $this->Application->getUnitOption('ci', 'TableName');
if (!$id) {
// item being created -> check by current (before editing started, saved in OnPreCreate event) category permissions
$category_id = $this->Application->RecallVar('m_cat_id');
}
else {
// item being edited -> check by it's primary category permissions
$sql = 'SELECT ci.CategoryId
FROM '.$table_name.' main_table
LEFT JOIN '.$ci_table.' ci ON ci.ItemResourceId = main_table.ResourceId
WHERE (main_table.'.$id_field.' = '.$id.') AND (ci.PrimaryCat = 1)';
$category_id = $this->Conn->GetOne($sql);
}
if ((substr($event->Name, 0, 9) == 'OnPreSave') || ($event->Name == 'OnSave')) {
if ($event_handler->isNewItemCreate($event)) {
return $this->CheckPermission($item_prefix.'.ADD', 0, $category_id);
}
else {
return $this->CheckPermission($item_prefix.'.ADD', 0, $category_id) || $this->CheckPermission($item_prefix.'.MODIFY', 0, $category_id);
}
}
$perm_status = false;
$check_perms = $this->getPermissionByEvent($event, $event_perm_mapping);
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
foreach ($check_perms as $perm_name) {
// check if at least one of required permissions is set
if (!isset($perm_mapping[$perm_name])) {
// not mapped permission (e.g. advanced:approve) -> skip
continue;
}
$perm_name = $item_prefix.'.'.$perm_mapping[$perm_name];
$this->showDebug('Event <b>'.$event->Name.'</b> permission(-s): <b>'.$perm_name.'</b>');
$perm_status = $this->CheckPermission($perm_name, 0, $category_id);
if ($perm_status) {
return $perm_status;
}
}
if (!$perm_status) {
$event->SetRedirectParam('index_file', 'index.php'); // because called from browse.php
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $event->getSection());
$event->SetRedirectParam('main_prefix', $top_prefix);
$event->SetRedirectParam('event_name', $event->Name);
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$event->status = erPERM_FAIL;
}
return $perm_status;
}
function showDebug($text)
{
if (!$this->Application->isDebugMode()) return true;
echo $text.'<br />';
}
function TagPermissionCheck($params, $tag_name)
{
$perm_event = getArrayValue($params, 'perm_event');
$permission_groups = getArrayValue($params, 'permissions');
if ($permission_groups) {
$this->showDebug('Tag <b>'.$tag_name.'</b> permission(-s): <b>'.$permission_groups.'</b>');
$permission_groups = explode('|', $permission_groups);
$group_has_permission = false;
foreach ($permission_groups as $permission_group) {
$permissions = explode(',', $permission_group);
$has_permission = true;
foreach ($permissions as $permission) {
$has_permission = $has_permission && $this->CheckPermission($permission, isset($params['system']) && $params['system'] ? 1 : 0);
}
$group_has_permission = $group_has_permission || $has_permission;
if ($group_has_permission) {
return true;
}
}
return false;
}
elseif ($perm_event) {
$this->showDebug('Tag <b>'.$tag_name.'</b> permission_event: <b>'.$perm_event.'</b>');
list($prefix, $event) = explode(':', $perm_event);
$event_handler =& $this->Application->recallObject($prefix.'_EventHandler');
return $event_handler->CheckPermission( new kEvent($perm_event) );
}
return true;
}
/**
* Returns no permission template to redirect to
*
* @param Array $params
* @return Array
*/
function getPermissionTemplate($params)
{
$t = $this->Application->GetVar('t');
if ($next_t = getArrayValue($params, 'next_template')) {
$t = $next_t;
}
if (!$this->Application->LoggedIn()) {
$redirect_template = $params['login_template'];
$redirect_params = Array('next_template' => $t);
}
else {
if (isset($params['no_permissions_template'])) {
$redirect_template = $params['no_permissions_template'];
}
else {
$redirect_template = $this->Application->IsAdmin() ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
}
$redirect_params = $this->Application->isDebugMode() ? Array('from_template' => 1, 'perms' => $params[ isset($params['permissions']) ? 'permissions' : 'perm_event'], 'next_template' => $t) : Array();
}
return Array($redirect_template, $redirect_params);
}
/**
* Check current user permissions based on it's group permissions in specified category (for non-system permissions) or just checks if system permission is set
*
* @param string $name permission name
* @param int $cat_id category id, current used if not specified
* @param int $type permission type {1 - system, 0 - per category}
* @return int
*/
function CheckPermission($name, $type = 1, $cat_id = null)
{
if ($this->Application->GetVar('u_id') == -1) {
// "root" is allowed anywhere
return $name == 'SYSTEM_ACCESS.READONLY' ? 0 : 1;
}
if ($type == 1) {
// "system" permission are always checked per "Home" category (ID = 0)
$cat_id = 0;
}
if (!isset($cat_id)) {
$cat_id = $this->Application->GetVar('m_cat_id');
}
$cache_key = $name.'|'.$type.'|'.$cat_id;
$perm_value = $this->Application->getCache('permissions', $cache_key);
if ($perm_value !== false) {
return $perm_value;
}
// perm cache is build only based on records in db, that's why if permission is not explicitly denied, then
// that (perm cache creator) code thinks that it is allowed & adds corresponding record and code below will
// return incorrect results
/*if (preg_match('/(.*)\.VIEW$/', $name) && ($type == 0)) {
// cached view permission of category: begin
$sql = 'SELECT perm_cache.PermId
FROM '.TABLE_PREFIX.'PermCache perm_cache
LEFT JOIN '.TABLE_PREFIX.'PermissionConfig perm_config ON perm_cache.PermId = perm_config.PermissionConfigId
WHERE (perm_config.PermissionName = '.$this->Conn->qstr($name).' AND perm_cache.CategoryId = '.$cat_id.')';
$view_filters = Array();
$groups = explode(',', $this->Application->RecallVar('UserGroups'));
foreach ($groups as $group) {
$view_filters[] = 'FIND_IN_SET('.$group.', perm_cache.ACL) || ((NOT FIND_IN_SET('.$group.', perm_cache.DACL)) AND perm_cache.ACL = \'\')';
}
$sql .= ' AND ('.implode(' OR ', $view_filters).')';
$perm_value = $this->Conn->GetOne($sql) ? 1 : 0;
$this->Application->setCache('permissions', $cache_key, $perm_value);
return $perm_value;
// cached view permission of category: end
}*/
if ($cat_id == 0) {
$cat_hierarchy = Array(0);
}
else {
$sql = 'SELECT ParentPath
FROM '.$this->Application->getUnitOption('c', 'TableName').'
WHERE CategoryId = '.$cat_id;
$cat_hierarchy = $this->Conn->GetOne($sql);
$cat_hierarchy = explode('|', $cat_hierarchy);
array_shift($cat_hierarchy);
array_pop($cat_hierarchy);
$cat_hierarchy = array_reverse($cat_hierarchy);
array_push($cat_hierarchy, 0);
}
$perm_value = 0;
$groups = $this->Application->RecallVar('UserGroups');
foreach ($cat_hierarchy as $category_id) {
$sql = 'SELECT PermissionValue
FROM '.TABLE_PREFIX.'Permissions
WHERE Permission = "'.$name.'" AND CatId = '.$category_id.' AND GroupId IN ('.$groups.') AND Type = '.$type;
$res = $this->Conn->GetOne($sql);
if ($res !== false) {
$perm_value = $res;
break;
}
}
$this->Application->setCache('permissions', $cache_key, $perm_value);
return $perm_value;
}
}
?>
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.8.2/kernel/units/general/helpers/permissions_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.8
\ No newline at end of property
+1.8.2.1
\ No newline at end of property
Index: branches/unlabeled/unlabeled-1.8.2/core/units/general/helpers/permissions_helper.php
===================================================================
--- branches/unlabeled/unlabeled-1.8.2/core/units/general/helpers/permissions_helper.php (revision 5182)
+++ branches/unlabeled/unlabeled-1.8.2/core/units/general/helpers/permissions_helper.php (revision 5183)
@@ -1,368 +1,368 @@
<?php
class kPermissionsHelper extends kHelper {
/**
* Current set of permissions for group being edited
*
* @var Array
*/
var $Permissions = Array();
function LoadPermissions($prefix)
{
$object =& $this->Application->recallObject($prefix.'-perm', null, Array('skip_autoload' => true));
$foreign_key = $this->Application->getUnitOption($prefix.'-perm', 'ForeignKey');
$foreign_value = $this->Application->GetVar($prefix.'_id');
$sql = 'SELECT *
FROM '.$object->TableName.'
WHERE '.$foreign_key.' = '.$foreign_value;
$permissions = $this->Conn->Query($sql, 'Permission');
$this->Permissions = Array();
foreach ($permissions as $perm_name => $perm_options) {
$perm_record['value'] = $perm_options['PermissionValue'];
$perm_record['id'] = $perm_options['PermissionId'];
$this->Permissions[$perm_name] = $perm_record;
}
}
function getPermissionValue($perm_name)
{
return getArrayValue($this->Permissions, $perm_name) ? $this->Permissions[$perm_name]['value'] : 0;
}
function getPermissionID($perm_name)
{
return getArrayValue($this->Permissions, $perm_name) ? $this->Permissions[$perm_name]['id'] : 0;
}
/**
* This is old permission like ADMIN or LOGIN
*
* @param string $section_name
* @param string $perm_name
* @return bool
*/
function isOldPermission($section_name, $perm_name)
{
return $section_name == 'in-portal:root' && $perm_name != 'view';
}
/**
* Returns permission names to check based on event name and item prefix (main item or subitem)
*
* @param kEvent $event
* @return Array
*/
function getPermissionByEvent(&$event, $perm_mapping)
{
$top_prefix = $event->getEventParam('top_prefix');
$pefix_type = ($top_prefix == $event->Prefix) ? 'self' : 'subitem';
$perm_mapping = getArrayValue($perm_mapping, $event->Name);
if (!$perm_mapping[$pefix_type]) {
trigger_error('Permission mappings not defined for event <b>'.$top_prefix.' <- '.$event->Prefix.':'.$event->Name.'</b>', E_USER_ERROR);
}
if ($perm_mapping[$pefix_type] === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
return explode('|', $perm_mapping[$pefix_type]);
}
/**
* Common event permission checking method
*
* @param kEvent $event
*/
function CheckEventPermission(&$event, $perm_mapping)
{
$section = $event->getSection();
if (preg_match('/^CATEGORY:(.*)/', $section)) {
return $this->CheckEventCategoryPermission($event, $perm_mapping);
}
$top_prefix = $event->getEventParam('top_prefix');
$check_perms = $this->getPermissionByEvent($event, $perm_mapping);
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
$perm_status = false;
foreach ($check_perms as $perm_name) {
// check if at least one of required permissions is set
$perm_name = $section.'.'.$perm_name;
$perm_status = $this->CheckPermission($perm_name, 1);
if (($perm_name == $section.'.add') && $perm_status && ($top_prefix == $event->Prefix)) {
// main item, add permission allowed, but ID is > 0, then deny permission
// how to get id here
}
if ($perm_status) {
return $perm_status;
}
}
if (!$perm_status) {
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $section);
$event->SetRedirectParam('main_prefix', $top_prefix);
$event->SetRedirectParam('event_name', $event->Name);
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$event->status = erPERM_FAIL;
}
return $perm_status;
}
/**
* Checks non-system permission on event per category basis
*
* @param kEvent $event
*/
function CheckEventCategoryPermission(&$event, $event_perm_mapping)
{
// mapping between specific permissions and common permissions
$perm_mapping = Array('add' => 'ADD', 'edit' => 'MODIFY', 'delete' => 'DELETE', 'view' => 'VIEW');
$top_prefix = $event->getEventParam('top_prefix');
$event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
if ($event->Prefix != $top_prefix) {
$top_event = new kEvent($top_prefix.':'.$event->Name);
$id = $event_handler->getPassedID($top_event);
}
else {
$id = $event_handler->getPassedID($event);
}
$item_prefix = $this->Application->getUnitOption($top_prefix, 'PermItemPrefix');
// 1. get primary category of category item
$id_field = $this->Application->getUnitOption($top_prefix, 'IDField');
$table_name = $this->Application->getUnitOption($top_prefix, 'TableName');
- $ci_table = $this->Application->getUnitOption($top_prefix.'-ci', 'TableName');
+ $ci_table = $this->Application->getUnitOption('ci', 'TableName');
if (!$id) {
// item being created -> check by current (before editing started, saved in OnPreCreate event) category permissions
$category_id = $this->Application->RecallVar('m_cat_id');
}
else {
// item being edited -> check by it's primary category permissions
$sql = 'SELECT ci.CategoryId
FROM '.$table_name.' main_table
LEFT JOIN '.$ci_table.' ci ON ci.ItemResourceId = main_table.ResourceId
WHERE (main_table.'.$id_field.' = '.$id.') AND (ci.PrimaryCat = 1)';
$category_id = $this->Conn->GetOne($sql);
}
if ((substr($event->Name, 0, 9) == 'OnPreSave') || ($event->Name == 'OnSave')) {
if ($event_handler->isNewItemCreate($event)) {
return $this->CheckPermission($item_prefix.'.ADD', 0, $category_id);
}
else {
return $this->CheckPermission($item_prefix.'.ADD', 0, $category_id) || $this->CheckPermission($item_prefix.'.MODIFY', 0, $category_id);
}
}
$perm_status = false;
$check_perms = $this->getPermissionByEvent($event, $event_perm_mapping);
if ($check_perms === true) {
// event is defined in mapping but is not checked by permissions
return true;
}
foreach ($check_perms as $perm_name) {
// check if at least one of required permissions is set
if (!isset($perm_mapping[$perm_name])) {
// not mapped permission (e.g. advanced:approve) -> skip
continue;
}
$perm_name = $item_prefix.'.'.$perm_mapping[$perm_name];
$this->showDebug('Event <b>'.$event->Name.'</b> permission(-s): <b>'.$perm_name.'</b>');
$perm_status = $this->CheckPermission($perm_name, 0, $category_id);
if ($perm_status) {
return $perm_status;
}
}
if (!$perm_status) {
$event->SetRedirectParam('index_file', 'index.php'); // because called from browse.php
if ($this->Application->isDebugMode()) {
// for debugging purposes
$event->SetRedirectParam('section', $event->getSection());
$event->SetRedirectParam('main_prefix', $top_prefix);
$event->SetRedirectParam('event_name', $event->Name);
$event->SetRedirectParam('next_template', $this->Application->GetVar('t'));
}
$event->status = erPERM_FAIL;
}
return $perm_status;
}
function showDebug($text)
{
if (!$this->Application->isDebugMode()) return true;
echo $text.'<br />';
}
function TagPermissionCheck($params, $tag_name)
{
$perm_event = getArrayValue($params, 'perm_event');
$permission_groups = getArrayValue($params, 'permissions');
if ($permission_groups) {
$this->showDebug('Tag <b>'.$tag_name.'</b> permission(-s): <b>'.$permission_groups.'</b>');
$permission_groups = explode('|', $permission_groups);
$group_has_permission = false;
foreach ($permission_groups as $permission_group) {
$permissions = explode(',', $permission_group);
$has_permission = true;
foreach ($permissions as $permission) {
$has_permission = $has_permission && $this->CheckPermission($permission, isset($params['system']) && $params['system'] ? 1 : 0);
}
$group_has_permission = $group_has_permission || $has_permission;
if ($group_has_permission) {
return true;
}
}
return false;
}
elseif ($perm_event) {
$this->showDebug('Tag <b>'.$tag_name.'</b> permission_event: <b>'.$perm_event.'</b>');
list($prefix, $event) = explode(':', $perm_event);
$event_handler =& $this->Application->recallObject($prefix.'_EventHandler');
return $event_handler->CheckPermission( new kEvent($perm_event) );
}
return true;
}
/**
* Returns no permission template to redirect to
*
* @param Array $params
* @return Array
*/
function getPermissionTemplate($params)
{
$t = $this->Application->GetVar('t');
if ($next_t = getArrayValue($params, 'next_template')) {
$t = $next_t;
}
if (!$this->Application->LoggedIn()) {
$redirect_template = $params['login_template'];
$redirect_params = Array('next_template' => $t);
}
else {
if (isset($params['no_permissions_template'])) {
$redirect_template = $params['no_permissions_template'];
}
else {
$redirect_template = $this->Application->IsAdmin() ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
}
$redirect_params = $this->Application->isDebugMode() ? Array('from_template' => 1, 'perms' => $params[ isset($params['permissions']) ? 'permissions' : 'perm_event'], 'next_template' => $t) : Array();
}
return Array($redirect_template, $redirect_params);
}
/**
* Check current user permissions based on it's group permissions in specified category (for non-system permissions) or just checks if system permission is set
*
* @param string $name permission name
* @param int $cat_id category id, current used if not specified
* @param int $type permission type {1 - system, 0 - per category}
* @return int
*/
function CheckPermission($name, $type = 1, $cat_id = null)
{
if ($this->Application->GetVar('u_id') == -1) {
// "root" is allowed anywhere
return $name == 'SYSTEM_ACCESS.READONLY' ? 0 : 1;
}
if ($type == 1) {
// "system" permission are always checked per "Home" category (ID = 0)
$cat_id = 0;
}
if (!isset($cat_id)) {
$cat_id = $this->Application->GetVar('m_cat_id');
}
$cache_key = $name.'|'.$type.'|'.$cat_id;
$perm_value = $this->Application->getCache('permissions', $cache_key);
if ($perm_value !== false) {
return $perm_value;
}
// perm cache is build only based on records in db, that's why if permission is not explicitly denied, then
// that (perm cache creator) code thinks that it is allowed & adds corresponding record and code below will
// return incorrect results
/*if (preg_match('/(.*)\.VIEW$/', $name) && ($type == 0)) {
// cached view permission of category: begin
$sql = 'SELECT perm_cache.PermId
FROM '.TABLE_PREFIX.'PermCache perm_cache
LEFT JOIN '.TABLE_PREFIX.'PermissionConfig perm_config ON perm_cache.PermId = perm_config.PermissionConfigId
WHERE (perm_config.PermissionName = '.$this->Conn->qstr($name).' AND perm_cache.CategoryId = '.$cat_id.')';
$view_filters = Array();
$groups = explode(',', $this->Application->RecallVar('UserGroups'));
foreach ($groups as $group) {
$view_filters[] = 'FIND_IN_SET('.$group.', perm_cache.ACL) || ((NOT FIND_IN_SET('.$group.', perm_cache.DACL)) AND perm_cache.ACL = \'\')';
}
$sql .= ' AND ('.implode(' OR ', $view_filters).')';
$perm_value = $this->Conn->GetOne($sql) ? 1 : 0;
$this->Application->setCache('permissions', $cache_key, $perm_value);
return $perm_value;
// cached view permission of category: end
}*/
if ($cat_id == 0) {
$cat_hierarchy = Array(0);
}
else {
$sql = 'SELECT ParentPath
FROM '.$this->Application->getUnitOption('c', 'TableName').'
WHERE CategoryId = '.$cat_id;
$cat_hierarchy = $this->Conn->GetOne($sql);
$cat_hierarchy = explode('|', $cat_hierarchy);
array_shift($cat_hierarchy);
array_pop($cat_hierarchy);
$cat_hierarchy = array_reverse($cat_hierarchy);
array_push($cat_hierarchy, 0);
}
$perm_value = 0;
$groups = $this->Application->RecallVar('UserGroups');
foreach ($cat_hierarchy as $category_id) {
$sql = 'SELECT PermissionValue
FROM '.TABLE_PREFIX.'Permissions
WHERE Permission = "'.$name.'" AND CatId = '.$category_id.' AND GroupId IN ('.$groups.') AND Type = '.$type;
$res = $this->Conn->GetOne($sql);
if ($res !== false) {
$perm_value = $res;
break;
}
}
$this->Application->setCache('permissions', $cache_key, $perm_value);
return $perm_value;
}
}
?>
\ No newline at end of file
Property changes on: branches/unlabeled/unlabeled-1.8.2/core/units/general/helpers/permissions_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.8
\ No newline at end of property
+1.8.2.1
\ No newline at end of property

Event Timeline