public function setAccountRole($accountId, $baseRoleId, $name, $color, $resources, $accountRoleId = null)
{
$id = $this->db->getOne('SELECT account_role_id FROM `acl_account_roles` WHERE name = ? AND account_id = ? LIMIT 1', [$name, $accountId]);
if ($id && $accountRoleId != $id) {
throw new \Exception('Account role with such name already exists');
}
if (empty($accountRoleId)) {
//Creates new account role
$accountRoleId = self::generateAccountRoleId();
$new = true;
}
$this->db->Execute("\n INSERT `acl_account_roles`\n SET `account_role_id` = ?,\n `account_id` = ?,\n `role_id` = ?,\n `name` = ?,\n `color` = ?,\n `is_automatic` = 0\n ON DUPLICATE KEY UPDATE\n `role_id` = ?,\n `name` = ?,\n `color` = ?\n ", array($accountRoleId, $accountId, $baseRoleId, $name, $color, $baseRoleId, $name, $color));
$accountRole = $this->getAccountRole($accountRoleId);
if ($accountRole === null) {
throw new Exception\AclException($new ? 'Database error' : 'Cannot find requested ACL role!');
}
$baseRole = $accountRole->getBaseRole();
foreach ($accountRole->getIteratorResources() as $resourceDefinition) {
/* @var $resourceDefinition \Scalr\Acl\Resource\ResourceObject */
$resourceId = $resourceDefinition->getResourceId();
$accountResource = $accountRole->getResource($resourceId);
$toUpdate = null;
$toUpdatePerm = [];
foreach ($resourceDefinition->getPermissions() as $permissionId => $permissionName) {
$granted = isset($resources[$resourceId]['permissions'][$permissionId]) ? $resources[$resourceId]['permissions'][$permissionId] == 1 : false;
if ($granted != $baseRole->isAllowed($resourceId, $permissionId)) {
//Unique permission is overridden on account level and needs to be created
$toUpdatePerm[$permissionId] = [$accountRoleId, $resourceId, $permissionId, $granted ? 1 : 0, $granted ? 1 : 0];
} else {
if ($accountResource !== null) {
//Unique permission needs to be removed
$this->db->Execute("\n DELETE FROM `acl_account_role_resource_permissions`\n WHERE `account_role_id` = ?\n AND `resource_id` = ?\n AND `perm_id` = ?\n ", array($accountRoleId, $resourceId, $permissionId));
}
}
}
$granted = isset($resources[$resourceId]['granted']) ? $resources[$resourceId]['granted'] == 1 : false;
if ($granted != $baseRole->isAllowed($resourceId)) {
//Resource record is overridden on account level and needs to be created
$toUpdate = array($accountRoleId, $resourceId, $granted ? 1 : 0, $granted ? 1 : 0);
} elseif ($resourceDefinition->getMode() !== null || !empty($toUpdatePerm) && $granted) {
//Referenced resource must be created as foreign key requires.
$toUpdate = array($accountRoleId, $resourceId, $granted ? 1 : null, $granted ? 1 : null);
} else {
//Resource record the same as in the base role and needs to be removed
$this->db->Execute("\n DELETE FROM `acl_account_role_resources`\n WHERE `account_role_id` = ?\n AND `resource_id` = ?\n ", array($accountRoleId, $resourceId));
}
if ($toUpdate) {
$this->db->Execute("\n INSERT `acl_account_role_resources`\n SET `account_role_id` = ?,\n `resource_id` = ?,\n `granted` = ?\n ON DUPLICATE KEY UPDATE\n `granted` = ?\n ", $toUpdate);
}
if ($resourceDefinition->getMode() !== null) {
//Saves ACL Resource Mode only if it's defined in the Resouce Definition
$modeValue = !empty($resources[$resourceId]['mode']) && in_array(intval($resources[$resourceId]['mode']), array_keys($resourceDefinition->getMode()->getMapping())) ? intval($resources[$resourceId]['mode']) : $resourceDefinition->getMode()->getDefault();
$this->db->Execute("\n INSERT `acl_account_role_resource_modes`\n SET `account_role_id` = ?,\n `resource_id` = ?,\n `mode` = ?\n ON DUPLICATE KEY UPDATE\n `mode` = ?\n ", [$accountRoleId, $resourceId, $modeValue, $modeValue]);
}
if ($toUpdatePerm) {
foreach ($toUpdatePerm as $opt) {
$this->db->Execute("\n INSERT `acl_account_role_resource_permissions`\n SET `account_role_id` = ?,\n `resource_id` = ?,\n `perm_id` = ?,\n `granted` = ?\n ON DUPLICATE KEY UPDATE\n `granted` = ?\n ", $opt);
}
}
}
return $accountRoleId;
}