Exemplo n.º 1
0
 /**
  * Show update permissions page
  *
  * @param void
  * @return null
  */
 function update_permissions()
 {
     $user = Contacts::findById(get_id());
     if (!($user instanceof Contact && $user->isUser()) || $user->getDisabled()) {
         flash_error(lang('user dnx'));
         ajx_current("empty");
         return;
     }
     // if
     if (!$user->canUpdatePermissions(logged_user())) {
         flash_error(lang('no access permissions'));
         ajx_current("empty");
         return;
     }
     // if
     $redirect_to = array_var($_GET, 'redirect_to');
     if (trim($redirect_to) == '' || !is_valid_url($redirect_to)) {
         $redirect_to = $user->getCardUserUrl();
     }
     // if
     $sys_permissions_data = array_var($_POST, 'sys_perm');
     if (!is_array($sys_permissions_data)) {
         $pg_id = $user->getPermissionGroupId();
         $parameters = permission_form_parameters($pg_id);
         // Module Permissions
         $module_permissions = TabPanelPermissions::findAll(array("conditions" => "`permission_group_id` = {$pg_id}"));
         $module_permissions_info = array();
         foreach ($module_permissions as $mp) {
             $module_permissions_info[$mp->getTabPanelId()] = 1;
         }
         $all_modules = TabPanels::findAll(array("conditions" => "`enabled` = 1", "order" => "ordering"));
         $all_modules_info = array();
         foreach ($all_modules as $module) {
             $all_modules_info[] = array('id' => $module->getId(), 'name' => lang($module->getTitle()), 'ot' => $module->getObjectTypeId());
         }
         // System Permissions
         $system_permissions = SystemPermissions::findById($pg_id);
         tpl_assign('module_permissions_info', $module_permissions_info);
         tpl_assign('all_modules_info', $all_modules_info);
         tpl_assign('system_permissions', $system_permissions);
         tpl_assign('permission_parameters', $parameters);
         $more_permissions = array();
         Hook::fire('add_user_permissions', $pg_id, $more_permissions);
         tpl_assign('more_permissions', $more_permissions);
         // Permission Groups
         $groups = PermissionGroups::getNonPersonalSameLevelPermissionsGroups('`parent_id`,`id` ASC');
         tpl_assign('groups', $groups);
         $roles = SystemPermissions::getAllRolesPermissions();
         tpl_assign('roles', $roles);
         $tabs = TabPanelPermissions::getAllRolesModules();
         tpl_assign('tabs_allowed', $tabs);
         tpl_assign('guest_groups', PermissionGroups::instance()->getGuestPermissionGroups());
     }
     tpl_assign('user', $user);
     tpl_assign('redirect_to', $redirect_to);
     if (array_var($_POST, 'submitted') == 'submitted') {
         $user_data = array_var($_POST, 'user');
         if (!is_array($user_data)) {
             $user_data = array();
         }
         try {
             DB::beginWork();
             $pg_id = $user->getPermissionGroupId();
             $user->setUserType(array_var($user_data, 'type'));
             $user->save();
             save_permissions($pg_id, $user->isGuest());
             DB::commit();
             flash_success(lang('success user permissions updated'));
             ajx_current("back");
         } catch (Exception $e) {
             DB::rollback();
             flash_error($e->getMessage());
             ajx_current("empty");
         }
     }
     // if
 }
Exemplo n.º 2
0
 /**
  * Edit group
  *
  * @param void
  * @return null
  */
 function edit()
 {
     $this->setTemplate('add');
     if (!can_manage_security(logged_user())) {
         flash_error(lang('no access permissions'));
         ajx_current("empty");
         return;
     }
     // if
     $group = PermissionGroups::findById(get_id());
     if (!$group instanceof PermissionGroup) {
         flash_error(lang('group dnx'));
         $this->redirectTo('administration', 'groups');
     }
     // if
     $group_data = array_var($_POST, 'group');
     if (!is_array($group_data)) {
         $pg_id = $group->getId();
         $parameters = permission_form_parameters($pg_id);
         // Module Permissions
         $module_permissions = TabPanelPermissions::findAll(array("conditions" => "`permission_group_id` = {$pg_id}"));
         $module_permissions_info = array();
         foreach ($module_permissions as $mp) {
             $module_permissions_info[$mp->getTabPanelId()] = 1;
         }
         $all_modules = TabPanels::findAll(array("conditions" => "`enabled` = 1", "order" => "ordering"));
         $all_modules_info = array();
         foreach ($all_modules as $module) {
             $all_modules_info[] = array('id' => $module->getId(), 'name' => lang($module->getTitle()), 'ot' => $module->getObjectTypeId());
         }
         // System Permissions
         $system_permissions = SystemPermissions::findById($pg_id);
         tpl_assign('module_permissions_info', $module_permissions_info);
         tpl_assign('all_modules_info', $all_modules_info);
         tpl_assign('system_permissions', $system_permissions);
         tpl_assign('permission_parameters', $parameters);
         // users
         $group_users = array();
         $cpgs = ContactPermissionGroups::findAll(array("conditions" => "`permission_group_id` = {$pg_id}"));
         foreach ($cpgs as $cpg) {
             $group_users[] = $cpg->getContactId();
         }
         tpl_assign('groupUserIds', $group_users);
         tpl_assign('users', Contacts::getAllUsers());
         tpl_assign('pg_id', $group->getId());
         tpl_assign('group', $group);
         tpl_assign('group_data', array('name' => $group->getName()));
         add_page_action(lang('delete'), "javascript:if(confirm(lang('confirm delete group'))) og.openLink('" . $group->getDeleteUrl() . "');", 'ico-trash', null, null, true);
     } else {
         try {
             $group->setFromAttributes($group_data);
             DB::beginWork();
             $group->save();
             // set permissions
             $pg_id = $group->getId();
             //save_permissions($pg_id);
             $gr_users = $group->getUsers();
             $gr_users_ids = array();
             if ($post_users = array_var($_POST, 'user')) {
                 foreach ($post_users as $user_id => $val) {
                     if ($val == '1' && is_numeric($user_id)) {
                         $gr_users_ids[] = $user_id;
                     }
                 }
             }
             foreach ($gr_users as $us) {
                 if (!in_array($us->getId(), $gr_users_ids)) {
                     $gr_users_ids[] = $us->getId();
                 }
             }
             // save users
             ContactPermissionGroups::delete("`permission_group_id` = {$pg_id}");
             if ($users = array_var($_POST, 'user')) {
                 foreach ($users as $user_id => $val) {
                     if ($val == '1' && is_numeric($user_id) && Contacts::findById($user_id) instanceof Contact) {
                         $cpg = new ContactPermissionGroup();
                         $cpg->setPermissionGroupId($pg_id);
                         $cpg->setContactId($user_id);
                         $cpg->save();
                     }
                 }
             }
             //ApplicationLogs::createLog($group, ApplicationLogs::ACTION_EDIT);
             DB::commit();
             flash_success(lang('success edit group', $group->getName()));
             ajx_current("back");
         } catch (Exception $e) {
             DB::rollback();
             tpl_assign('error', $e);
             return;
         }
         try {
             save_user_permissions_background(logged_user(), $pg_id, false, $gr_users_ids);
         } catch (Exception $e) {
             tpl_assign('error', $e);
         }
     }
 }
Exemplo n.º 3
0
     $parameters['root_permissions'] = $root_permissions;
     $parameters['member_permissions'] = $member_permissions;
 }
 // Module Permissions
 $module_permissions = TabPanelPermissions::findAll(array("conditions" => "`permission_group_id` = {$pg_id}"));
 $module_permissions_info = array();
 foreach ($module_permissions as $mp) {
     $module_permissions_info[$mp->getTabPanelId()] = 1;
 }
 $all_modules = TabPanels::findAll(array("conditions" => "`enabled` = 1", "order" => "ordering"));
 $all_modules_info = array();
 foreach ($all_modules as $module) {
     $all_modules_info[] = array('id' => $module->getId(), 'name' => lang($module->getTitle()), 'ot' => $module->getObjectTypeId());
 }
 // System Permissions
 $system_permissions = SystemPermissions::findById($pg_id);
 tpl_assign('module_permissions_info', $module_permissions_info);
 tpl_assign('all_modules_info', $all_modules_info);
 if (!$system_permissions instanceof SystemPermission) {
     $system_permissions = new SystemPermission();
 }
 tpl_assign('system_permissions', $system_permissions);
 tpl_assign('permission_parameters', $parameters);
 $more_permissions = array();
 Hook::fire('add_user_permissions', $pg_id, $more_permissions);
 tpl_assign('more_permissions', $more_permissions);
 tpl_assign('pg_id', $pg_id);
 // Permission Groups
 $groups = PermissionGroups::getNonPersonalSameLevelPermissionsGroups('`parent_id`,`id` ASC');
 tpl_assign('groups', $groups);
 foreach ($groups as $group) {
Exemplo n.º 4
0
function save_permissions($pg_id, $is_guest = false)
{
    $sys_permissions_data = array_var($_POST, 'sys_perm');
    $changed_members = array();
    //module permissions
    $mod_permissions_data = array_var($_POST, 'mod_perm');
    TabPanelPermissions::clearByPermissionGroup($pg_id);
    if (!is_null($mod_permissions_data) && is_array($mod_permissions_data)) {
        foreach ($mod_permissions_data as $tab_id => $val) {
            $tpp = new TabPanelPermission();
            $tpp->setPermissionGroupId($pg_id);
            $tpp->setTabPanelId($tab_id);
            $tpp->save();
        }
    }
    //system permissions
    $system_permissions = SystemPermissions::findById($pg_id);
    if (!$system_permissions instanceof SystemPermission) {
        $system_permissions = new SystemPermission();
        $system_permissions->setPermissionGroupId($pg_id);
    }
    $system_permissions->setAllPermissions(false);
    $other_permissions = array();
    Hook::fire('add_user_permissions', $pg_id, $other_permissions);
    foreach ($other_permissions as $k => $v) {
        $system_permissions->setColumnValue($k, false);
    }
    $sys_permissions_data['can_task_assignee'] = !$is_guest;
    $system_permissions->setFromAttributes($sys_permissions_data);
    $system_permissions->save();
    //member permissions
    $permissionsString = array_var($_POST, 'permissions');
    if ($permissionsString && $permissionsString != '') {
        $permissions = json_decode($permissionsString);
    }
    if (isset($permissions) && !is_null($permissions) && is_array($permissions)) {
        $allowed_members_ids = array();
        foreach ($permissions as $perm) {
            if (!isset($all_perm_deleted[$perm->m])) {
                $all_perm_deleted[$perm->m] = true;
            }
            $allowed_members_ids[$perm->m] = array();
            $allowed_members_ids[$perm->m]['pg'] = $pg_id;
            $cmp = ContactMemberPermissions::findById(array('permission_group_id' => $pg_id, 'member_id' => $perm->m, 'object_type_id' => $perm->o));
            if (!$cmp instanceof ContactMemberPermission) {
                $cmp = new ContactMemberPermission();
                $cmp->setPermissionGroupId($pg_id);
                $cmp->setMemberId($perm->m);
                $cmp->setObjectTypeId($perm->o);
            }
            $cmp->setCanWrite($is_guest ? false : $perm->w);
            $cmp->setCanDelete($is_guest ? false : $perm->d);
            if ($perm->r) {
                if (isset($allowed_members_ids[$perm->m]['w'])) {
                    if ($allowed_members_ids[$perm->m]['w'] != 1) {
                        $allowed_members_ids[$perm->m]['w'] = $is_guest ? false : $perm->w;
                    }
                } else {
                    $allowed_members_ids[$perm->m]['w'] = $is_guest ? false : $perm->w;
                }
                if (isset($allowed_members_ids[$perm->m]['d'])) {
                    if ($allowed_members_ids[$perm->m]['d'] != 1) {
                        $allowed_members_ids[$perm->m]['d'] = $is_guest ? false : $perm->d;
                    }
                } else {
                    $allowed_members_ids[$perm->m]['d'] = $is_guest ? false : $perm->d;
                }
                $cmp->save();
                $all_perm_deleted[$perm->m] = false;
            } else {
                $cmp->delete();
            }
            $changed_members[] = $perm->m;
        }
        $sharingTablecontroller = new SharingTableController();
        $sharingTablecontroller->afterPermissionChanged($pg_id, $permissions);
        foreach ($allowed_members_ids as $key => $mids) {
            $mbm = Members::findById($key);
            $root_cmp = ContactMemberPermissions::findById(array('permission_group_id' => $mids['pg'], 'member_id' => $key, 'object_type_id' => $mbm->getObjectTypeId()));
            if (!$root_cmp instanceof ContactMemberPermission) {
                $root_cmp = new ContactMemberPermission();
                $root_cmp->setPermissionGroupId($mids['pg']);
                $root_cmp->setMemberId($key);
                $root_cmp->setObjectTypeId($mbm->getObjectTypeId());
            }
            $root_cmp->setCanWrite($mids['w']);
            $root_cmp->setCanDelete($mids['d']);
            $root_cmp->save();
        }
        foreach ($all_perm_deleted as $mid => $pd) {
            if ($pd) {
                ContactMemberPermissions::instance()->delete("`permission_group_id` = {$pg_id} AND `member_id` = {$mid}");
            }
        }
    }
    // set all permissiions to read_only
    if ($is_guest) {
        $all_saved_permissions = ContactMemberPermissions::findAll(array("conditions" => "`permission_group_id` = {$pg_id}"));
        foreach ($all_saved_permissions as $sp) {
            /* @var $sp ContactMemberPermission */
            if ($sp->getCanDelete() || $sp->getCanWrite()) {
                $sp->setCanDelete(false);
                $sp->setCanWrite(false);
                $sp->save();
            }
        }
        $cdps = ContactDimensionPermissions::findAll(array("conditions" => "`permission_type` = 'allow all'"));
        foreach ($cdps as $cdp) {
            $cdp->setPermissionType('check');
            $cdp->save();
        }
    }
    // check the status of the changed dimensions to set 'allow_all', 'deny_all' or 'check'
    $dimensions = Dimensions::findAll(array("conditions" => array("`id` IN (SELECT DISTINCT `dimension_id` FROM " . Members::instance()->getTableName(true) . " WHERE `id` IN (?))", $changed_members)));
    foreach ($dimensions as $dimension) {
        $mem_ids = $dimension->getAllMembers(true);
        if (count($mem_ids) == 0) {
            $mem_ids[] = 0;
        }
        $count = ContactMemberPermissions::count(array('conditions' => "`permission_group_id`={$pg_id} AND `member_id` IN (" . implode(",", $mem_ids) . ") AND `can_delete` = 0"));
        if ($count > 0) {
            $dimension->setContactDimensionPermission($pg_id, 'check');
        } else {
            $count = ContactMemberPermissions::count(array('conditions' => "`permission_group_id`={$pg_id} AND `member_id` IN (" . implode(",", $mem_ids) . ")"));
            if ($count == 0) {
                $dimension->setContactDimensionPermission($pg_id, 'deny all');
            } else {
                $allow_all = true;
                $dim_obj_types = $dimension->getAllowedObjectTypeContents();
                $members = Members::findAll("`id` IN (" . implode(",", $mem_ids) . ")");
                foreach ($dim_obj_types as $dim_obj_type) {
                    $mem_ids_for_ot = array();
                    foreach ($members as $member) {
                        if ($dim_obj_type->getDimensionObjectTypeId() == $member->getObjectTypeId()) {
                            $mem_ids_for_ot[] = $member->getId();
                        }
                    }
                    if (count($mem_ids_for_ot) == 0) {
                        $mem_ids_for_ot[] = 0;
                    }
                    $count = ContactMemberPermissions::count(array('conditions' => "`permission_group_id`={$pg_id} AND \n\t\t\t\t\t\t`object_type_id` = " . $dim_obj_type->getContentObjectTypeId() . " AND `can_delete` = 1 AND `member_id` IN (" . implode(",", $mem_ids_for_ot) . ")"));
                    if ($count != count($mem_ids_for_ot)) {
                        $allow_all = false;
                        break;
                    }
                }
                if ($allow_all) {
                    $dimension->setContactDimensionPermission($pg_id, 'allow all');
                } else {
                    $dimension->setContactDimensionPermission($pg_id, 'check');
                }
            }
        }
    }
}
Exemplo n.º 5
0
function save_permissions($pg_id, $is_guest = false, $permissions_data = null, $save_cmps = true, $update_sharing_table = true, $fire_hook = true, $update_contact_member_cache = true, $users_ids_to_check = array(), $only_member_permissions = false)
{
    if (is_null($permissions_data)) {
        // system permissions
        $sys_permissions_data = array_var($_POST, 'sys_perm');
        // module permissions
        $mod_permissions_data = array_var($_POST, 'mod_perm');
        // root permissions
        if ($rp_genid = array_var($_POST, 'root_perm_genid')) {
            $rp_permissions_data = array();
            foreach ($_POST as $name => $value) {
                if (str_starts_with($name, $rp_genid . 'rg_root_')) {
                    $rp_permissions_data[$name] = $value;
                }
            }
        }
        // member permissions
        $permissionsString = array_var($_POST, 'permissions');
    } else {
        // system permissions
        $sys_permissions_data = array_var($permissions_data, 'sys_perm');
        // module permissions
        $mod_permissions_data = array_var($permissions_data, 'mod_perm');
        // root permissions
        $rp_genid = array_var($permissions_data, 'root_perm_genid');
        $rp_permissions_data = array_var($permissions_data, 'root_perm');
        // member permissions
        $permissionsString = array_var($permissions_data, 'permissions');
    }
    try {
        DB::beginWork();
        $changed_members = array();
        // save module permissions
        if (!$only_member_permissions) {
            try {
                TabPanelPermissions::clearByPermissionGroup($pg_id, true);
                if (!is_null($mod_permissions_data) && is_array($mod_permissions_data)) {
                    foreach ($mod_permissions_data as $tab_id => $val) {
                        DB::execute("INSERT INTO " . TABLE_PREFIX . "tab_panel_permissions (permission_group_id,tab_panel_id) VALUES ('{$pg_id}','{$tab_id}') ON DUPLICATE KEY UPDATE permission_group_id=permission_group_id");
                    }
                }
            } catch (Exception $e) {
                Logger::log("Error saving module permissions for permission group {$pg_id}: " . $e->getMessage() . "\n" . $e->getTraceAsString());
                throw $e;
            }
        }
        $root_permissions_sharing_table_delete = array();
        $root_permissions_sharing_table_add = array();
        if (logged_user() instanceof Contact && can_manage_security(logged_user())) {
            try {
                if (!$only_member_permissions) {
                    // save system permissions
                    $system_permissions = SystemPermissions::findById($pg_id);
                    if (!$system_permissions instanceof SystemPermission) {
                        $system_permissions = new SystemPermission();
                        $system_permissions->setPermissionGroupId($pg_id);
                    }
                    $system_permissions->setAllPermissions(false);
                    $other_permissions = array();
                    Hook::fire('add_user_permissions', $pg_id, $other_permissions);
                    foreach ($other_permissions as $k => $v) {
                        $system_permissions->setColumnValue($k, false);
                    }
                    // check max permissions for role, in case of modifying user's permissions
                    $role_id = "-1";
                    $tmp_contact = Contacts::findOne(array('conditions' => 'permission_group_id = ' . $pg_id));
                    if ($tmp_contact instanceof Contact) {
                        $role_id = $tmp_contact->getUserType();
                    }
                    $max_role_system_permissions = MaxSystemPermissions::findOne(array('conditions' => 'permission_group_id = ' . $role_id));
                    if ($max_role_system_permissions instanceof MaxSystemPermission) {
                        foreach ($sys_permissions_data as $col => &$val) {
                            $max_val = $max_role_system_permissions->getColumnValue($col);
                            if (!$max_val) {
                                unset($sys_permissions_data[$col]);
                            }
                        }
                    }
                    // don't allow to write emails for collaborators and guests
                    if ($tmp_contact instanceof Contact) {
                        $user_type_name = $tmp_contact->getUserTypeName();
                        if (!in_array($user_type_name, array('Super Administrator', 'Administrator', 'Manager', 'Executive'))) {
                            $mail_ot = ObjectTypes::findByName('mail');
                            if ($mail_ot instanceof ObjectType) {
                                DB::executeAll("UPDATE " . TABLE_PREFIX . "contact_member_permissions SET can_write=0, can_delete=0 WHERE object_type_id=" . $mail_ot->getId() . " AND permission_group_id={$pg_id}");
                            }
                        }
                    }
                    $sys_permissions_data['can_task_assignee'] = !$is_guest;
                    $system_permissions->setFromAttributes($sys_permissions_data);
                    $system_permissions->setUseOnDuplicateKeyWhenInsert(true);
                    $system_permissions->save();
                    //object type root permissions
                    $can_have_root_permissions = config_option('let_users_create_objects_in_root') && in_array($user_type_name, array('Super Administrator', 'Administrator', 'Manager', 'Executive'));
                    if ($rp_genid && $can_have_root_permissions) {
                        ContactMemberPermissions::delete("permission_group_id = {$pg_id} AND member_id = 0");
                        foreach ($rp_permissions_data as $name => $value) {
                            if (str_starts_with($name, $rp_genid . 'rg_root_')) {
                                $rp_ot = substr($name, strrpos($name, '_') + 1);
                                if (is_numeric($rp_ot) && $rp_ot > 0 && $value == 0) {
                                    $root_permissions_sharing_table_delete[] = $rp_ot;
                                }
                                if (!is_numeric($rp_ot) || $rp_ot <= 0 || $value < 1) {
                                    continue;
                                }
                                $root_permissions_sharing_table_add[] = $rp_ot;
                                // save with member_id = 0
                                $root_perm_cmp = new ContactMemberPermission();
                                $root_perm_cmp->setPermissionGroupId($pg_id);
                                $root_perm_cmp->setMemberId('0');
                                $root_perm_cmp->setObjectTypeId($rp_ot);
                                $root_perm_cmp->setCanWrite($value >= 2);
                                $root_perm_cmp->setCanDelete($value >= 3);
                                $root_perm_cmp->save();
                            }
                        }
                    }
                    if (!$can_have_root_permissions) {
                        ContactMemberPermissions::delete("permission_group_id = {$pg_id} AND member_id = 0");
                        $sh_controller = new SharingTableController();
                        $all_object_type_ids = ObjectTypes::findAll(array('id' => true));
                        $sh_controller->adjust_root_permissions($pg_id, array('root_permissions_sharing_table_delete' => $all_object_type_ids));
                    }
                }
            } catch (Exception $e) {
                Logger::log("Error saving system and root permissions for permission group {$pg_id}: " . $e->getMessage() . "\n" . $e->getTraceAsString());
                throw $e;
            }
        }
        // set all permissions to read_only if user is guest
        if ($is_guest) {
            try {
                $all_saved_permissions = ContactMemberPermissions::findAll(array("conditions" => "`permission_group_id` = {$pg_id}"));
                foreach ($all_saved_permissions as $sp) {
                    /* @var $sp ContactMemberPermission */
                    if ($sp->getCanDelete() || $sp->getCanWrite()) {
                        $sp->setCanDelete(false);
                        $sp->setCanWrite(false);
                        $sp->save();
                    }
                }
                $cdps = ContactDimensionPermissions::findAll(array("conditions" => "`permission_type` = 'allow all'"));
                foreach ($cdps as $cdp) {
                    $cdp->setPermissionType('check');
                    $cdp->save();
                }
            } catch (Exception $e) {
                Logger::log("Error setting guest user permissions to read_only for permission group {$pg_id}: " . $e->getMessage() . "\n" . $e->getTraceAsString());
                throw $e;
            }
        }
        // check the status of the changed dimensions to set 'allow_all', 'deny_all' or 'check'
        try {
            $dimensions = Dimensions::findAll(array("conditions" => array("`id` IN (SELECT DISTINCT `dimension_id` FROM " . Members::instance()->getTableName(true) . " WHERE `id` IN (?))", $changed_members)));
            foreach ($dimensions as $dimension) {
                $dimension->setContactDimensionPermission($pg_id, 'check');
            }
        } catch (Exception $e) {
            Logger::log("Error setting dimension permissions for permission group {$pg_id}: " . $e->getMessage() . "\n" . $e->getTraceAsString());
            throw $e;
        }
        //member permissions
        if ($permissionsString && $permissionsString != '') {
            $permissions = json_decode($permissionsString);
        }
        if (isset($permissions) && !is_null($permissions) && is_array($permissions)) {
            try {
                $tmp_contact = Contacts::findOne(array('conditions' => 'permission_group_id = ' . $pg_id));
                if ($tmp_contact instanceof Contact) {
                    $user_type_name = $tmp_contact->getUserTypeName();
                    $role_id = $tmp_contact->getUserType();
                    $max_role_ot_perms = MaxRoleObjectTypePermissions::instance()->findAll(array('conditions' => "role_id = '{$role_id}'"));
                }
                $mail_ot = ObjectTypes::findByName('mail');
                $sql_insert_values = "";
                $member_object_types_to_delete = array();
                $allowed_members_ids = array();
                foreach ($permissions as &$perm) {
                    if (!isset($all_perm_deleted[$perm->m])) {
                        $all_perm_deleted[$perm->m] = true;
                    }
                    $allowed_members_ids[$perm->m] = array();
                    $allowed_members_ids[$perm->m]['pg'] = $pg_id;
                    if ($perm->r) {
                        if (isset($allowed_members_ids[$perm->m]['w'])) {
                            if ($allowed_members_ids[$perm->m]['w'] != 1) {
                                $allowed_members_ids[$perm->m]['w'] = $is_guest ? false : $perm->w;
                            }
                        } else {
                            $allowed_members_ids[$perm->m]['w'] = $is_guest ? false : $perm->w;
                        }
                        if (isset($allowed_members_ids[$perm->m]['d'])) {
                            if ($allowed_members_ids[$perm->m]['d'] != 1) {
                                $allowed_members_ids[$perm->m]['d'] = $is_guest ? false : $perm->d;
                            }
                        } else {
                            $allowed_members_ids[$perm->m]['d'] = $is_guest ? false : $perm->d;
                        }
                        // check max permissions for user type
                        if ($tmp_contact instanceof Contact) {
                            $max_perm = null;
                            foreach ($max_role_ot_perms as $max_role_ot_perm) {
                                if ($max_role_ot_perm->getObjectTypeId() == $perm->o) {
                                    $max_perm = $max_role_ot_perm;
                                }
                            }
                            if ($max_perm) {
                                if (!$max_perm->getCanDelete()) {
                                    $perm->d = 0;
                                }
                                if (!$max_perm->getCanWrite()) {
                                    $perm->w = 0;
                                }
                            } else {
                                $perm->d = 0;
                                $perm->w = 0;
                                $perm->r = 0;
                            }
                        }
                        if ($save_cmps) {
                            // don't allow to write emails for collaborators and guests
                            if ($tmp_contact instanceof Contact && !in_array($user_type_name, array('Super Administrator', 'Administrator', 'Manager', 'Executive'))) {
                                if ($mail_ot instanceof ObjectType && $perm->o == $mail_ot->getId()) {
                                    $perm->d = 0;
                                    $perm->w = 0;
                                }
                            }
                            $sql_insert_values .= ($sql_insert_values == "" ? "" : ",") . "('" . $pg_id . "','" . $perm->m . "','" . $perm->o . "','" . $perm->d . "','" . $perm->w . "')";
                            if (!isset($member_object_types_to_delete[$perm->m])) {
                                $member_object_types_to_delete[$perm->m] = array();
                            }
                            $member_object_types_to_delete[$perm->m][] = $perm->o;
                        }
                        $all_perm_deleted[$perm->m] = false;
                    } else {
                        if (is_numeric($perm->m) && is_numeric($perm->o)) {
                            DB::execute("DELETE FROM " . TABLE_PREFIX . "contact_member_permissions WHERE member_id='" . $perm->m . "' AND object_type_id='" . $perm->o . "' AND permission_group_id={$pg_id}");
                        }
                    }
                    $changed_members[] = $perm->m;
                }
                if ($save_cmps) {
                    if (count($all_perm_deleted) > 0) {
                        $member_ids_to_delete = array();
                        foreach ($all_perm_deleted as $mid => $del) {
                            // also check in contact_member_permissions
                            $cmps = ContactMemberPermissions::findAll(array('conditions' => 'permission_group_id=' . $pg_id . " AND member_id={$mid}"));
                            if ($del && (!is_array($cmps) || count($cmps) == 0)) {
                                $member_ids_to_delete[] = $mid;
                            }
                        }
                        if (count($member_ids_to_delete) > 0) {
                            DB::execute("DELETE FROM " . TABLE_PREFIX . "contact_member_permissions WHERE member_id IN (" . implode(',', $member_ids_to_delete) . ") AND permission_group_id={$pg_id}");
                        }
                    }
                    foreach ($member_object_types_to_delete as $mid => $obj_type_ids) {
                        if (count($obj_type_ids) > 0) {
                            DB::execute("DELETE FROM " . TABLE_PREFIX . "contact_member_permissions WHERE member_id={$mid} AND object_type_id IN (" . implode(',', $obj_type_ids) . ") AND permission_group_id={$pg_id}");
                        }
                    }
                    if ($sql_insert_values != "") {
                        DB::execute("INSERT INTO " . TABLE_PREFIX . "contact_member_permissions (permission_group_id, member_id, object_type_id, can_delete, can_write) VALUES {$sql_insert_values} ON DUPLICATE KEY UPDATE member_id=member_id");
                    }
                }
            } catch (Exception $e) {
                Logger::log("Error saving member permissions for permission group {$pg_id}: " . $e->getMessage() . "\n" . $e->getTraceAsString());
                throw $e;
            }
        }
        DB::commit();
    } catch (Exception $e) {
        Logger::log("Error saving permissions for permission group {$pg_id}: " . $e->getMessage() . "\n" . $e->getTraceAsString());
        DB::rollback();
    }
    try {
        if (isset($permissions) && !is_null($permissions) && is_array($permissions)) {
            if ($update_sharing_table) {
                try {
                    $sharingTablecontroller = new SharingTableController();
                    $rp_info = array('root_permissions_sharing_table_delete' => $root_permissions_sharing_table_delete, 'root_permissions_sharing_table_add' => $root_permissions_sharing_table_add);
                    $sharingTablecontroller->afterPermissionChanged($pg_id, $permissions, $rp_info);
                } catch (Exception $e) {
                    Logger::log("Error saving permissions to sharing table for permission group {$pg_id}: " . $e->getMessage() . "\n" . $e->getTraceAsString());
                    throw $e;
                }
            }
            if ($update_contact_member_cache) {
                try {
                    $contactMemberCacheController = new ContactMemberCacheController();
                    $group = PermissionGroups::findById($pg_id);
                    $real_group = null;
                    if ($group->getType() == 'user_groups') {
                        $real_group = $group;
                    }
                    $users = $group->getUsers();
                    $users_ids_checked = array();
                    foreach ($users as $us) {
                        $users_ids_checked[] = $us->getId();
                        $contactMemberCacheController->afterUserPermissionChanged($us, $permissions, $real_group);
                    }
                    //check all users related to the group
                    foreach ($users_ids_to_check as $us_id) {
                        if (!in_array($us_id, $users_ids_checked)) {
                            $users_ids_checked[] = $us_id;
                            $us = Contacts::findById($us_id);
                            if ($us instanceof Contact) {
                                $contactMemberCacheController->afterUserPermissionChanged($us, $permissions, $real_group);
                            }
                        }
                    }
                } catch (Exception $e) {
                    Logger::log("Error saving permissions to contact member cache for permission group {$pg_id}: " . $e->getMessage() . "\n" . $e->getTraceAsString());
                    throw $e;
                }
            }
        }
    } catch (Exception $e) {
        Logger::log("Error saving module permissions for permission group {$pg_id}: " . $e->getMessage() . "\n" . $e->getTraceAsString());
    }
    if ($fire_hook) {
        Hook::fire('after_save_contact_permissions', $pg_id, $pg_id);
    }
    // remove contact object from members where permissions were deleted
    $user = Contacts::findOne(array('conditions' => 'permission_group_id=' . $pg_id));
    if ($user instanceof Contact) {
        $to_remove = array();
        if (isset($all_perm_deleted) && is_array($all_perm_deleted)) {
            foreach ($all_perm_deleted as $m_id => $must_remove) {
                if ($must_remove) {
                    $to_remove[] = $m_id;
                }
            }
            ObjectMembers::removeObjectFromMembers($user, logged_user(), null, $to_remove);
        }
    }
}