function addParameterPermissionItem($itemCfg)
{
    // verify obligatory fields
    if (!$itemCfg->object) {
        throw new Exception('Permission item object must be set');
    }
    if (!$itemCfg->parameter) {
        throw new Exception('Permission item object parameter must be set');
    }
    if (!$itemCfg->action) {
        throw new Exception('Permission item action id must be set');
    }
    if (is_null($itemCfg->partnerId) || $itemCfg->partnerId === '') {
        throw new Exception('Permission item partner id must be set');
    }
    if (!in_array($itemCfg->action, array(ApiParameterPermissionItemAction::INSERT, ApiParameterPermissionItemAction::READ, ApiParameterPermissionItemAction::UPDATE, ApiParameterPermissionItemAction::USAGE))) {
        throw new Exception("Action type [{$itemCfg->action}] unknown");
    }
    // check if item already exists in db
    $c = new Criteria();
    $c->addAnd(kApiParameterPermissionItem::OBJECT_COLUMN_NAME, $itemCfg->object, Criteria::EQUAL);
    $c->addAnd(kApiParameterPermissionItem::PARAMETER_COLUMN_NAME, $itemCfg->parameter, Criteria::EQUAL);
    $c->addAnd(kApiParameterPermissionItem::ACTION_COLUMN_NAME, $itemCfg->action, Criteria::EQUAL);
    $c->addAnd(PermissionItemPeer::PARTNER_ID, array(PartnerPeer::GLOBAL_PARTNER, $itemCfg->partnerId), Criteria::IN);
    $c->addAnd(PermissionItemPeer::TYPE, PermissionItemType::API_PARAMETER_ITEM, Criteria::EQUAL);
    $existingItem = PermissionItemPeer::doSelectOne($c);
    $item = null;
    if ($existingItem) {
        $item = $existingItem;
        KalturaLog::log('Permission item for [' . $item->getAction() . '->' . $item->getObject() . '->' . $item->getParameter() . '] partner id [' . $item->getPartnerId() . '] already exists with id [' . $item->getId() . ']');
    } else {
        // save new permission item object
        $item = new kApiParameterPermissionItem();
        foreach ($itemCfg as $key => $value) {
            if ($key === 'permissions') {
                continue;
                // permissions are set later
            }
            $setterCallback = array($item, "set{$key}");
            if (method_exists($item, 'set' . $key)) {
                call_user_func_array($setterCallback, array($value));
            } else {
                KalturaLog::err("Skipping call to set{$key}() since there is no such method.");
            }
        }
        $item->save();
        KalturaLog::log('New permission item id [' . $item->getId() . '] added for [' . $item->getAction() . '->' . $item->getObject() . '->' . $item->getParameter() . '] partner id [' . $item->getPartnerId() . ']');
    }
    // add item to each defined permission
    $permissionNames = array_map('trim', str_getcsv($itemCfg->permissions));
    addItemToPermissions($item, $permissionNames, $itemCfg->partnerId);
}
     echo $msg . PHP_EOL;
     continue;
 }
 // skip action if set with ticket type N (blocked)
 if (in_array(BLOCKED_TICKET_TYPE, $ticketTypes)) {
     $msg = '***** NOTICE - Action [' . $serviceActionName . '] is set with ticket type N (blocked) -> skipping!';
     KalturaLog::notice($msg);
     echo $msg . PHP_EOL;
     continue;
 }
 foreach ($partners as $partner) {
     $c = new Criteria();
     $c->addAnd(kApiActionPermissionItem::SERVICE_COLUMN_NAME, $serviceId, Criteria::EQUAL);
     $c->addAnd(kApiActionPermissionItem::ACTION_COLUMN_NAME, $actionName, Criteria::EQUAL);
     $c->addAnd(PermissionItemPeer::PARTNER_ID, array(PartnerPeer::GLOBAL_PARTNER, $partner->getId()), Criteria::IN);
     $permissionItem = PermissionItemPeer::doSelectOne($c);
     if (!$permissionItem) {
         $msg = '***** ERROR - Permission item for service [' . $serviceId . '] action [' . $actionName . '] not found in DB!';
         KalturaLog::alert($msg);
         echo $msg . PHP_EOL;
         continue;
     }
     // check if a special ticket type was set for the action which is different from the basic system ticket types
     if (in_array(USER_KS_TICKET_TYPE, $ticketTypes) && !in_array($permissionItem->getId(), $userSessionPermissionItemIds)) {
         // ticket type 1 set - add a special user KS permission to all relevant partners and add current permission item to it
         $userKsRole = getOrCreateUserSessionRole($partner->getId());
         $userKsPermission = getOrCreateSessionPermission($partner->getId(), 'user');
         $userKsPermission->addPermissionItem($permissionItem->getId(), true);
         $userKsRole->setPermissionNames(PermissionName::USER_SESSION_PERMISSION . ',' . $userKsPermission->getName());
         $partner->setUserSessionRoleId($userKsRole->getId());
         $partner->save();
function removeParameterPermissionItem($itemCfg)
{
    // verify obligatory fields
    if (!$itemCfg->object) {
        throw new Exception('Permission item object must be set');
    }
    if (!$itemCfg->parameter) {
        throw new Exception('Permission item object parameter must be set');
    }
    if (!$itemCfg->action) {
        throw new Exception('Permission item action id must be set');
    }
    if (is_null($itemCfg->partnerId) || $itemCfg->partnerId === '') {
        throw new Exception('Permission item partner id must be set');
    }
    if (!in_array($itemCfg->action, array(ApiParameterPermissionItemAction::INSERT, ApiParameterPermissionItemAction::READ, ApiParameterPermissionItemAction::UPDATE))) {
        throw new Exception("Action type [{$itemCfg->action}] unknown");
    }
    if (is_null($itemCfg->permissions) || $itemCfg->permissions === '') {
        throw new Exception('Permission item permissions must be set');
    }
    // check if item already exists in db
    $c = new Criteria();
    $c->addAnd(kApiParameterPermissionItem::OBJECT_COLUMN_NAME, $itemCfg->object);
    $c->addAnd(kApiParameterPermissionItem::PARAMETER_COLUMN_NAME, $itemCfg->parameter);
    $c->addAnd(kApiParameterPermissionItem::ACTION_COLUMN_NAME, $itemCfg->action);
    $c->addAnd(PermissionItemPeer::PARTNER_ID, array(PartnerPeer::GLOBAL_PARTNER, $itemCfg->partnerId), Criteria::IN);
    $c->addAnd(PermissionItemPeer::TYPE, PermissionItemType::API_PARAMETER_ITEM);
    $permissionItem = PermissionItemPeer::doSelectOne($c);
    if (!$permissionItem) {
        return;
    }
    // add item to each defined permission
    $permissionNames = array_map('trim', explode(',', $itemCfg->permissions));
    removeItemFromPermissions($permissionItem, $permissionNames);
}
function setPermissions($serviceConfig, $setBaseSystemPermissions, $userSessionPermission, $noKsPermission, $partnerId)
{
    // get list of services defined in the services.ct files
    $servicesTable = $serviceConfig->getAllServicesByCt();
    // for each defined service.action
    foreach ($servicesTable as $ctPath => $services) {
        foreach ($services as $serviceActionName) {
            $serviceConfig->setServiceName($serviceActionName);
            $serviceSplit = explode('.', $serviceActionName);
            $serviceName = $serviceSplit[0];
            $actionName = $serviceSplit[1];
            $ticketTypes = explode(',', $serviceConfig->getTicketType());
            $serviceId = $serviceName;
            $pluginName = getPluginNameFromServicesCtPath($ctPath);
            if ($pluginName) {
                $serviceId = strtolower($pluginName) . '_' . $serviceId;
            }
            $serviceClass = KalturaServicesMap::getService($serviceId);
            if (!$serviceClass) {
                $tmpServiceIds = KalturaServicesMap::getServiceIdsFromName($serviceName);
                if ($tmpServiceIds && count($tmpServiceIds) == 1) {
                    $serviceId = reset($tmpServiceIds);
                    $serviceClass = KalturaServicesMap::getService($serviceId);
                }
            }
            if (!$serviceClass) {
                $msg = '***** ERROR - service id [' . $serviceId . '] not found in services map!';
                KalturaLog::alert($msg);
                echo $msg . PHP_EOL;
                continue;
            }
            // skip action if set with ticket type N (blocked)
            if (in_array(BLOCKED_TICKET_TYPE, $ticketTypes)) {
                $msg = '***** NOTICE - Action [' . $serviceActionName . '] is set with ticket type N (blocked) -> skipping!';
                KalturaLog::notice($msg);
                echo $msg . PHP_EOL;
                continue;
            }
            // check if a permission item for the current action already exists
            $c = new Criteria();
            $c->addAnd(kApiActionPermissionItem::SERVICE_COLUMN_NAME, $serviceId, Criteria::EQUAL);
            $c->addAnd(kApiActionPermissionItem::ACTION_COLUMN_NAME, $actionName, Criteria::EQUAL);
            $c->addAnd(PermissionItemPeer::PARTNER_ID, array(PartnerPeer::GLOBAL_PARTNER, $partnerId), Criteria::IN);
            $permissionItem = PermissionItemPeer::doSelectOne($c);
            if ($permissionItem) {
                $msg = '***** NOTICE - Permission item for [' . $serviceActionName . '] already exists with id [' . $permissionItem->getId() . ']';
                KalturaLog::alert($msg);
                echo $msg . PHP_EOL;
            } else {
                // create a new api action permission item and save it
                $permissionItem = new kApiActionPermissionItem();
                $permissionItem->setService($serviceId);
                $permissionItem->setAction($actionName);
                $permissionItem->setPartnerId($partnerId);
                $permissionItem->save();
            }
            // get the defined permission names from the tags section of the services.ct file
            $permissionNames = $serviceConfig->getTags();
            $permissionNames = explode(',', $permissionNames);
            $anyPermissionSet = false;
            // was any permission set to include the current permission item or not
            foreach ($permissionNames as $permissionName) {
                if (!$permissionName) {
                    continue;
                }
                // add the permission item to all its defined permission objects
                $c = new Criteria();
                $c->addAnd(PermissionPeer::NAME, $permissionName, Criteria::EQUAL);
                $c->addAnd(PermissionPeer::TYPE, PermissionType::NORMAL, Criteria::EQUAL);
                //$c->addAnd(PermissionPeer::PARTNER_ID, array(PartnerPeer::GLOBAL_PARTNER, $partnerId), Criteria::IN);
                $permission = PermissionPeer::doSelectOne($c);
                if (!$permission) {
                    $msg = '***** ERROR - Permission [' . $permissionName . '] not found in DB although set for [' . $serviceActionName . ']';
                    KalturaLog::alert($msg);
                    echo $msg . PHP_EOL;
                    continue;
                }
                $permission->addPermissionItem($permissionItem->getId(), true);
                $anyPermissionSet = true;
            }
            // add permission item to the basic NO_KS and USER_KS permissions according to its ticket type
            // (partner admin role already contains all other permissions)
            if ($setBaseSystemPermissions) {
                if (in_array(NO_KS_TICKET_TYPE, $ticketTypes)) {
                    $noKsPermission->addPermissionItem($permissionItem->getId(), true);
                    $userSessionPermission->addPermissionItem($permissionItem->getId(), true);
                    $anyPermissionSet = true;
                } else {
                    if (in_array(USER_KS_TICKET_TYPE, $ticketTypes)) {
                        $userSessionPermission->addPermissionItem($permissionItem->getId(), true);
                        $anyPermissionSet = true;
                    }
                }
            }
            if (!$anyPermissionSet) {
                $msg = '***** ERROR - No permission was set for [' . $serviceActionName . ']';
                KalturaLog::alert($msg);
                echo $msg . PHP_EOL;
            }
        }
    }
}