Index: trunk/core/units/general/helpers/permissions_helper.php =================================================================== diff -u -N -r4611 -r4689 --- trunk/core/units/general/helpers/permissions_helper.php (.../permissions_helper.php) (revision 4611) +++ trunk/core/units/general/helpers/permissions_helper.php (.../permissions_helper.php) (revision 4689) @@ -49,6 +49,157 @@ { 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 '.$top_prefix.' <- '.$event->Prefix.':'.$event->Name.'', 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]); + } + + /** + * Checks permissions of user + * + * @param kEvent $event + */ + function CheckPermission(&$event, $perm_mapping) + { + $section = $event->getSection(); + if (preg_match('/^CATEGORY:(.*)/', $section)) { + return $this->CheckCategoryPermission($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->Application->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) { + // for debugging purposes + $event->SetRedirectParam('section', $section); + $event->SetRedirectParam('main_prefix', $top_prefix); + $event->SetRedirectParam('event_name', $event->Name); + $event->status = erPERM_FAIL; + } + return $perm_status; + } + + /** + * Check permissions + * + * @param kEvent $event + */ + function CheckCategoryPermission(&$event, $event_perm_mapping) + { + // would be better to check this too, but we have no such ermission for now + /*if ($event->Name == 'OnRateProduct') { + return $this->Application->CheckPermission('PRODUCT.RATE', 0); + }*/ + + // 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'); + + 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->Application->CheckPermission($item_prefix.'.ADD', 0, $category_id); + } + else { + return $this->Application->CheckPermission($item_prefix.'.ADD', 0, $category_id) || $this->Application->CheckPermission($item_prefix.'.MODIFY', 0, $category_id); + } + } + + $perm_status = false; + $check_perms = $this->getPermissionByEvent($event, $event_perm_mapping); + + 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]; + echo 'event_name: '.$event->Name.'; permission: '.$perm_name.'
'; + $perm_status = $this->Application->CheckPermission($perm_name, 0, $category_id); + + if ($perm_status) { + return $perm_status; + } + } + + if (!$perm_status) { + // for debugging purposes + $event->SetRedirectParam('section', $event->getSection()); + $event->SetRedirectParam('main_prefix', $top_prefix); + $event->SetRedirectParam('event_name', $event->Name); + $event->status = erPERM_FAIL; + } + return $perm_status; + } } ?> \ No newline at end of file