function healPermissionGroup(SharingTableFlag $flag)
 {
     if ($flag->getObjectId() > 0) {
         try {
             $obj = Objects::findObject($flag->getObjectId());
             if (!$obj instanceof ContentDataObject) {
                 $flag->delete();
                 // if object does not exists then delete the flag
                 return;
             }
             DB::beginWork();
             // update sharing table
             $obj->addToSharingTable();
             DB::commit();
         } catch (Exception $e) {
             DB::rollback();
             Logger::log("Failed to heal object permissions for object " . $flag->getObjectId() . " (flag_id = " . $flag->getId() . ")");
             return false;
         }
         // delete flag
         $flag->delete();
         return true;
     } else {
         // heal
         $controller = new SharingTableController();
         $permissions_string = $flag->getPermissionString();
         $permission_group_id = $flag->getPermissionGroupId();
         $permissions = json_decode($permissions_string);
         if ($flag->getMemberId() > 0) {
             foreach ($permissions as $p) {
                 if (!isset($p->m)) {
                     $p->m = $flag->getMemberId();
                 }
             }
         }
         try {
             DB::beginWork();
             // update sharing table
             $controller->afterPermissionChanged($permission_group_id, $permissions);
             DB::commit();
         } catch (Exception $e) {
             DB::rollback();
             Logger::log("Failed to heal permission group {$permission_group_id} (flag_id = " . $flag->getId() . ")\n" . $e->getTraceAsString());
             return false;
         }
         // delete flag
         $flag->delete();
         return true;
     }
 }
 /**
  * Enter description here ...
  * @param Contact $contact
  * @param array of ObjectType $types
  * @param array of int  $members
  */
 function grantAllPermissions(Contact $contact, $members)
 {
     if ($contact->getUserType() > 0 && count($members)) {
         $userType = $contact->getUserTypeName();
         $permissions = array();
         // TO fill sharing table
         $gid = $contact->getPermissionGroupId();
         foreach ($members as $member_id) {
             //new
             $member = Members::findById($member_id);
             $dimension = $member->getDimension();
             $types = array();
             $member_types = DimensionObjectTypeContents::getContentObjectTypeIds($dimension->getId(), $member->getObjectTypeId());
             if (count($member_types)) {
                 switch ($userType) {
                     case 'Super Administrator':
                     case 'Administrator':
                     case 'Manager':
                     case 'Executive':
                         $types = $member_types;
                         break;
                     case 'Collaborator Customer':
                     case 'Non-Exec Director':
                         foreach (ObjectTypes::findAll(array("conditions" => " name NOT IN ('mail') ")) as $type) {
                             //TODO This sucks
                             $types[] = $type->getId();
                         }
                         break;
                     case 'Internal Collaborator':
                     case 'External Collaborator':
                         foreach (ObjectTypes::findAll(array("conditions" => " name NOT IN ('mail','contact', 'report') ")) as $type) {
                             //TODO This sucks
                             $types[] = $type->getId();
                         }
                         break;
                     case 'Guest Customer':
                         foreach (ObjectTypes::findAll(array("conditions" => " name IN ('message', 'weblink', 'event', 'file') ")) as $type) {
                             //TODO This sucks
                             $types[] = $type->getId();
                         }
                         break;
                     case 'Guest':
                         foreach (ObjectTypes::findAll(array("conditions" => " name IN ('message', 'weblink', 'event') ")) as $type) {
                             //TODO This sucks
                             $types[] = $type->getId();
                         }
                         break;
                 }
             }
             foreach ($types as $type_id) {
                 if (!ContactMemberPermissions::instance()->findOne(array("conditions" => "permission_group_id = {$gid}\tAND \n\t\t\t\t\t\t\tmember_id = {$member_id} AND \n\t\t\t\t\t\t\tobject_type_id = {$type_id}"))) {
                     $cmp = new ContactMemberPermission();
                     $cmp->setPermissionGroupId($gid);
                     $cmp->setMemberId($member_id);
                     $cmp->setObjectTypeId($type_id);
                     if ($userType != "Guest" && $userType != "Guest Customer") {
                         $cmp->setCanWrite(1);
                         $cmp->setCanDelete(1);
                     } else {
                         $cmp->setCanWrite(0);
                         $cmp->setCanDelete(0);
                     }
                     $cmp->save();
                     $perm = new stdClass();
                     $perm->m = $member_id;
                     $perm->r = 1;
                     $perm->w = 1;
                     $perm->d = 1;
                     $perm->o = $type_id;
                     $permissions[] = $perm;
                 }
             }
         }
         if (count($permissions)) {
             $stCtrl = new SharingTableController();
             $stCtrl->afterPermissionChanged($contact->getPermissionGroupId(), $permissions);
         }
     }
 }
 private function cut_max_user_permissions(Contact $user)
 {
     $admin_pg = PermissionGroups::findOne(array('conditions' => "`name`='Super Administrator'"));
     $all_roles_max_permissions = RoleObjectTypePermissions::getAllRoleObjectTypePermissionsInfo();
     $admin_perms = $all_roles_max_permissions[$admin_pg->getId()];
     $all_object_types = array();
     foreach ($admin_perms as &$aperm) {
         $all_object_types[] = $aperm['object_type_id'];
     }
     $max_permissions = array_var($all_roles_max_permissions, $user->getUserType());
     $pg_id = $user->getPermissionGroupId();
     foreach ($all_object_types as $ot) {
         if (!$ot) {
             continue;
         }
         $max = array_var($max_permissions, $ot);
         if (!$max) {
             // cannot read -> delete in contact_member_permissions
             $sql = "DELETE FROM " . TABLE_PREFIX . "contact_member_permissions WHERE permission_group_id={$pg_id} AND object_type_id={$ot}";
             DB::execute($sql);
         } else {
             // cut can_delete and can_write using max permissions
             $can_d = $max['can_delete'] ? "1" : "0";
             $can_w = $max['can_write'] ? "1" : "0";
             $sql = "UPDATE " . TABLE_PREFIX . "contact_member_permissions\r\n\t\t\t\tSET can_delete=(can_delete AND {$can_d}), can_write=(can_write AND {$can_w})\r\n\t\t\t\tWHERE permission_group_id={$pg_id} AND object_type_id={$ot}";
             DB::execute($sql);
         }
     }
     // rebuild sharing table for permission group $pg_id
     $cmp_rows = DB::executeAll("SELECT * FROM " . TABLE_PREFIX . "contact_member_permissions WHERE permission_group_id={$pg_id}");
     $permissions_array = array();
     foreach ($cmp_rows as $row) {
         $p = new stdClass();
         $p->m = array_var($row, 'member_id');
         $p->o = array_var($row, 'object_type_id');
         $p->d = array_var($row, 'can_delete');
         $p->w = array_var($row, 'can_write');
         $p->r = 1;
         $permissions[] = $p;
     }
     $sharing_table_controller = new SharingTableController();
     $sharing_table_controller->after_permission_changed($pg_id, $permissions_array);
 }
Esempio n. 4
0
function create_user($user_data, $permissionsString) {
    
	// try to find contact by some properties 
	$contact_id = array_var($user_data, "contact_id") ;
	$contact =  Contacts::instance()->findById($contact_id) ; 
	
	if (!is_valid_email(array_var($user_data, 'email'))) {
		throw new Exception(lang("email value is required"));
	}

	if (!$contact instanceof Contact) {
		// Create a new user
		$contact = new Contact();
		$contact->setUsername(array_var($user_data, 'username'));
		$contact->setDisplayName(array_var($user_data, 'display_name'));
		$contact->setCompanyId(array_var($user_data, 'company_id'));
		$contact->setUserType(array_var($user_data, 'type'));
		$contact->setTimezone(array_var($user_data, 'timezone'));
		$contact->setFirstname($contact->getObjectName() != "" ? $contact->getObjectName() : $contact->getUsername());
		$contact->setObjectName();
	} else {
		// Create user from contact
		$contact->setUserType(array_var($user_data, 'type'));
		if (array_var($user_data, 'company_id')) {
			$contact->setCompanyId(array_var($user_data, 'company_id'));
		}	
		$contact->setUsername(array_var($user_data, 'username'));
		$contact->setTimezone(array_var($user_data, 'timezone'));
	}
	$contact->save();
	if (is_valid_email(array_var($user_data, 'email'))) {
		$contact->addEmail(array_var($user_data, 'email'), 'personal', true);
	}
	
	
	//permissions
	$permission_group = new PermissionGroup();
	$permission_group->setName('User '.$contact->getId().' Personal');
	$permission_group->setContactId($contact->getId());
	$permission_group->setIsContext(false);
	$permission_group->setType("permission_groups");
	$permission_group->save();
	$contact->setPermissionGroupId($permission_group->getId());
	
	$contact_pg = new ContactPermissionGroup();
	$contact_pg->setContactId($contact->getId());
	$contact_pg->setPermissionGroupId($permission_group->getId());
	$contact_pg->save();

	if ( can_manage_security(logged_user()) ) {
		
		$sp = new SystemPermission();
		$rol_permissions=SystemPermissions::getRolePermissions(array_var($user_data, 'type'));
		foreach($rol_permissions as $pr){
			$sp->setPermission($pr);
		}
		$sp->setPermissionGroupId($permission_group->getId());

		$sp->setCanManageSecurity(array_var($user_data, 'can_manage_security'));
		$sp->setCanManageConfiguration(array_var($user_data, 'can_manage_configuration'));
		$sp->setCanManageTemplates(array_var($user_data, 'can_manage_templates'));
		$sp->setCanManageTime(array_var($user_data, 'can_manage_time'));
		$sp->setCanAddMailAccounts(array_var($user_data, 'can_add_mail_accounts'));
		$sp->setCanManageDimensions(array_var($user_data, 'can_manage_dimensions'));
		$sp->setCanManageDimensionMembers(array_var($user_data, 'can_manage_dimension_members'));
		$sp->setCanManageTasks(array_var($user_data, 'can_manage_tasks'));
		$sp->setCanTasksAssignee(array_var($user_data, 'can_task_assignee'));
		$sp->setCanManageBilling(array_var($user_data, 'can_manage_billing'));
		$sp->setCanViewBilling(array_var($user_data, 'can_view_billing'));
		
		Hook::fire('add_user_permissions', $sp, $other_permissions);
		if (!is_null($other_permissions) && is_array($other_permissions)) {
			foreach ($other_permissions as $k => $v) {
				$sp->setColumnValue($k, array_var($user_data, $k));
			}
		}
		$sp->save();
		
		if ($contact->isAdminGroup()) {
			// allow all un all dimensions if new user is admin
			$dimensions = Dimensions::findAll();
			$permissions = array();
			foreach ($dimensions as $dimension) {
				if ($dimension->getDefinesPermissions()) {
					$cdp = ContactDimensionPermissions::findOne(array("conditions" => "`permission_group_id` = ".$contact->getPermissionGroupId()." AND `dimension_id` = ".$dimension->getId()));
					if (!$cdp instanceof ContactDimensionPermission) {
						$cdp = new ContactDimensionPermission();
						$cdp->setPermissionGroupId($contact->getPermissionGroupId());
						$cdp->setContactDimensionId($dimension->getId());
					}
					$cdp->setPermissionType('allow all');
					$cdp->save();
					
					// contact member permisssion entries
					$members = $dimension->getAllMembers();
					foreach ($members as $member) {
						
						$ots = DimensionObjectTypeContents::getContentObjectTypeIds($dimension->getId(), $member->getObjectTypeId());
						$ots[]=$member->getObjectId();
						foreach ($ots as $ot) {
							$cmp = ContactMemberPermissions::findOne(array("conditions" => "`permission_group_id` = ".$contact->getPermissionGroupId()." AND `member_id` = ".$member->getId()." AND `object_type_id` = $ot"));
							if (!$cmp instanceof ContactMemberPermission) {
								$cmp = new ContactMemberPermission();
								$cmp->setPermissionGroupId($contact->getPermissionGroupId());
								$cmp->setMemberId($member->getId());
								$cmp->setObjectTypeId($ot);
							}
							$cmp->setCanWrite(1);
							$cmp->setCanDelete(1);
							$cmp->save();
							
							// Add persmissions to sharing table
							$perm = new stdClass();
							$perm->m = $member->getId();
							$perm->r= 1;
							$perm->w= 1;
							$perm->d= 1;
							$perm->o= $ot;
							$permissions[] = $perm ;
						}
					}
				}
			}
			
			if(count($permissions)){
				$sharingTableController = new SharingTableController();
				$sharingTableController->afterPermissionChanged($contact->getPermissionGroupId(), $permissions);
			}
			
		}
		
	}
	if(!isset($_POST['sys_perm'])){
		$rol_permissions=SystemPermissions::getRolePermissions(array_var($user_data, 'type'));
		$_POST['sys_perm']=array();
		foreach($rol_permissions as $pr){
			$_POST['sys_perm'][$pr]=1;
		}
		
	}
	if(!isset($_POST['mod_perm'])){
		$tabs_permissions=TabPanelPermissions::getRoleModules(array_var($user_data, 'type'));
		$_POST['mod_perm']=array();
		foreach($tabs_permissions as $pr){
			$_POST['mod_perm'][$pr]=1;
		}
	}
        
    $password = '';
	if (array_var($user_data, 'password_generator') == 'specify') {
		$perform_password_validation = true;
		// Validate input
		$password = array_var($user_data, 'password');
		if (trim($password) == '') {
			throw new Error(lang('password value required'));
		} // if
		if ($password <> array_var($user_data, 'password_a')) {
			throw new Error(lang('passwords dont match'));
		} // if
	} else {
		$user_data['password_generator'] = 'link';
		$perform_password_validation = false;
	}

	$contact->setPassword($password);   
	$contact->save();

	$user_password = new ContactPassword();
	$user_password->setContactId($contact->getId());
	$user_password->setPasswordDate(DateTimeValueLib::now());
	$user_password->setPassword(cp_encrypt($password, $user_password->getPasswordDate()->getTimestamp()));
	$user_password->password_temp = $password;
	$user_password->perform_validation = $perform_password_validation;
	$user_password->save();
        
	if (array_var($user_data, 'autodetect_time_zone', 1) == 1) {
		set_user_config_option('autodetect_time_zone', 1, $contact->getId());
	}
	
	/* create contact for this user*/

	ApplicationLogs::createLog($contact, ApplicationLogs::ACTION_ADD);

	// Set role permissions for active members
	$active_context = active_context();
	$sel_members = array();
	foreach ($active_context as $selection) {
		if ($selection instanceof Member) {
			$sel_members[] = $selection;
			$has_project_permissions = ContactMemberPermissions::instance()->count("permission_group_id = '".$contact->getPermissionGroupId()."' AND member_id = ".$selection->getId()) > 0;
			if (!$has_project_permissions) {
				RoleObjectTypePermissions::createDefaultUserPermissions($contact, $selection);
			}
		}
	}
	save_permissions($contact->getPermissionGroupId(), $contact->isGuest());
	
	Hook::fire('after_user_add', $contact, $null);
	
	// add user content object to associated members
	if (count($sel_members) > 0) {
		ObjectMembers::addObjectToMembers($contact->getId(), $sel_members);
		$contact->addToSharingTable();
	}
	
	// Send notification
	try {
		if (array_var($user_data, 'send_email_notification') && $contact->getEmailAddress()) {
                    
			if (array_var($user_data, 'password_generator', 'link') == 'link') {
				// Generate link password
				$user = Contacts::getByEmail(array_var($user_data, 'email'));
				$token = sha1(gen_id() . (defined('SEED') ? SEED : ''));
				$timestamp = time() + 60*60*24;
				set_user_config_option('reset_password', $token . ";" . $timestamp, $user->getId());
				Notifier::newUserAccountLinkPassword($contact, $password, $token);

			} else {
				Notifier::newUserAccount($contact, $password);
			}
			
		}
	} catch(Exception $e) {
		Logger::log($e->getTraceAsString());
	} // try
	return $contact;
}
Esempio n. 5
0
function save_member_permissions($member)
{
    $permissionsString = array_var($_POST, 'permissions');
    if ($permissionsString && $permissionsString != '') {
        $permissions = json_decode($permissionsString);
    }
    $sharingTablecontroller = new SharingTableController();
    $changed_pgs = array();
    if (isset($permissions) && is_array($permissions)) {
        $allowed_pg_ids = array();
        foreach ($permissions as &$perm) {
            $cmp = ContactMemberPermissions::findById(array('permission_group_id' => $perm->pg, 'member_id' => $member->getId(), 'object_type_id' => $perm->o));
            if (!$cmp instanceof ContactMemberPermission) {
                $cmp = new ContactMemberPermission();
                $cmp->setPermissionGroupId($perm->pg);
                $cmp->setMemberId($member->getId());
                $cmp->setObjectTypeId($perm->o);
            }
            $cmp->setCanWrite($perm->w);
            $cmp->setCanDelete($perm->d);
            if ($perm->r) {
                $allowed_pg_ids[$perm->pg] = array();
                if (isset($allowed_pg_ids[$perm->pg]['w'])) {
                    if (!$allowed_pg_ids[$perm->pg]['w']) {
                        $allowed_pg_ids[$perm->pg]['w'] = $perm->w;
                    }
                } else {
                    $allowed_pg_ids[$perm->pg]['w'] = $perm->w;
                }
                if (isset($allowed_pg_ids[$perm->pg]['d'])) {
                    if (!$allowed_pg_ids[$perm->pg]['d']) {
                        $allowed_pg_ids[$perm->pg]['d'] = $perm->d;
                    }
                } else {
                    $allowed_pg_ids[$perm->pg]['d'] = $perm->d;
                }
                $cmp->save();
            } else {
                $cmp->delete();
            }
            $perm->m = $member->getId();
            $changed_pgs[] = $perm->pg;
        }
        foreach ($changed_pgs as $pg_id) {
            $sharingTablecontroller->afterPermissionChanged($pg_id, $permissions);
        }
        foreach ($allowed_pg_ids as $key => $mids) {
            $root_cmp = ContactMemberPermissions::findById(array('permission_group_id' => $key, 'member_id' => $member->getId(), 'object_type_id' => $member->getObjectTypeId()));
            if (!$root_cmp instanceof ContactMemberPermission) {
                $root_cmp = new ContactMemberPermission();
                $root_cmp->setPermissionGroupId($key);
                $root_cmp->setMemberId($member->getId());
                $root_cmp->setObjectTypeId($member->getObjectTypeId());
            }
            $root_cmp->setCanWrite($mids['w'] == true ? 1 : 0);
            $root_cmp->setCanDelete($mids['d'] == true ? 1 : 0);
            $root_cmp->save();
        }
    }
    // check the status of the dimension to set 'allow_all', 'deny_all' or 'check'
    $dimension = $member->getDimension();
    $mem_ids = $dimension->getAllMembers(true);
    if (count($mem_ids) == 0) {
        $mem_ids[] = 0;
    }
    foreach ($changed_pgs as $pg_id) {
        $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');
                }
            }
        }
    }
}
 static function createDefaultUserPermissionsAllDimension(Contact $user, $dimension_id, $remove_previous = true)
 {
     $role_id = $user->getUserType();
     $permission_group_id = $user->getPermissionGroupId();
     $dimension = Dimensions::getDimensionById($dimension_id);
     if (!$dimension instanceof Dimension || !$dimension->getDefinesPermissions()) {
         return;
     }
     try {
         $shtab_permissions = array();
         $new_permissions = array();
         $role_permissions = self::findAll(array('conditions' => "role_id = '{$role_id}'"));
         $members = Members::findAll(array('conditions' => 'dimension_id = ' . $dimension_id));
         foreach ($members as $member) {
             $member_id = $member->getId();
             if ($remove_previous) {
                 ContactMemberPermissions::delete("permission_group_id = {$permission_group_id} AND member_id = {$member_id}");
             }
             foreach ($role_permissions as $role_perm) {
                 if ($member->canContainObject($role_perm->getObjectTypeId())) {
                     $cmp = new ContactMemberPermission();
                     $cmp->setPermissionGroupId($permission_group_id);
                     $cmp->setMemberId($member_id);
                     $cmp->setObjectTypeId($role_perm->getObjectTypeId());
                     $cmp->setCanDelete($role_perm->getCanDelete());
                     $cmp->setCanWrite($role_perm->getCanWrite());
                     $cmp->save();
                     $new_permissions[] = $cmp;
                     $perm = new stdClass();
                     $perm->m = $member_id;
                     $perm->r = 1;
                     $perm->w = $role_perm->getCanWrite();
                     $perm->d = $role_perm->getCanDelete();
                     $perm->o = $role_perm->getObjectTypeId();
                     $shtab_permissions[] = $perm;
                 }
             }
         }
         if (count($shtab_permissions)) {
             $cdp = ContactDimensionPermissions::instance()->findOne(array('conditions' => "permission_group_id = '{$permission_group_id}' AND dimension_id = {$dimension_id}"));
             if (!$cdp instanceof ContactDimensionPermission) {
                 $cdp = new ContactDimensionPermission();
                 $cdp->setPermissionGroupId($permission_group_id);
                 $cdp->setContactDimensionId($dimension_id);
                 $cdp->setPermissionType('check');
                 $cdp->save();
             } else {
                 if ($cdp->getPermissionType() == 'deny all') {
                     $cdp->setPermissionType('check');
                     $cdp->save();
                 }
             }
             $stCtrl = new SharingTableController();
             $stCtrl->afterPermissionChanged($permission_group_id, $shtab_permissions);
         }
         return $new_permissions;
     } catch (Exception $e) {
         throw $e;
     }
 }
             $flag->setPermissionGroupId($pg_id);
             $flag->setMemberId($member->getId());
             $flag->setPermissionString($permissions);
             $flag->setExecutionDate(DateTimeValueLib::now());
             $flag->setCreatedById(logged_user()->getId());
             $flag->save();
             DB::commit();
         } catch (Exception $e) {
             DB::rollback();
             Logger::log("Error saving permissions (2): " . $e->getMessage() . "\n" . $e->getTraceAsString());
         }
     }
 }
 $flags_to_delete = array();
 // transactions to update_sharing table
 $sharingTablecontroller = new SharingTableController();
 if (is_array($changed_pgs)) {
     $perm_array = json_decode($permissions);
     foreach ($perm_array as $pa) {
         if (!isset($pa->m)) {
             $pa->m = $member->getId();
         }
     }
     foreach ($changed_pgs as $pg_id) {
         try {
             // update sharing table
             DB::beginWork();
             $sharingTablecontroller->afterPermissionChanged($pg_id, $perm_array);
             $flags_to_delete[] = $pg_id;
             DB::commit();
         } catch (Exception $e) {
Esempio n. 8
0
function save_member_permissions($member, $permissionsString = null, $save_cmps = true, $update_sharing_table = true, $fire_hook = true, $update_contact_member_cache = true)
{
    @set_time_limit(0);
    ini_set('memory_limit', '1024M');
    if (!$member instanceof Member) {
        return;
    }
    if (is_null($permissionsString)) {
        $permissionsString = array_var($_POST, 'permissions');
    }
    if ($permissionsString && $permissionsString != '') {
        $permissions = json_decode($permissionsString);
    }
    $sharingTablecontroller = new SharingTableController();
    $contactMemberCacheController = new ContactMemberCacheController();
    $changed_pgs = array();
    $sql_insert_values = "";
    if (isset($permissions) && is_array($permissions)) {
        $allowed_pg_ids = array();
        foreach ($permissions as $k => &$perm) {
            if ($perm->r) {
                $allowed_pg_ids[$perm->pg] = array();
                if (isset($allowed_pg_ids[$perm->pg]['w'])) {
                    if (!$allowed_pg_ids[$perm->pg]['w']) {
                        $allowed_pg_ids[$perm->pg]['w'] = $perm->w;
                    }
                } else {
                    $allowed_pg_ids[$perm->pg]['w'] = $perm->w;
                }
                if (isset($allowed_pg_ids[$perm->pg]['d'])) {
                    if (!$allowed_pg_ids[$perm->pg]['d']) {
                        $allowed_pg_ids[$perm->pg]['d'] = $perm->d;
                    }
                } else {
                    $allowed_pg_ids[$perm->pg]['d'] = $perm->d;
                }
                // check max permissions for user type
                $tmp_contact = Contacts::findOne(array('conditions' => 'permission_group_id = ' . $perm->pg));
                if ($tmp_contact instanceof Contact) {
                    $max_role_ot_perms = MaxRoleObjectTypePermissions::instance()->findAll(array('conditions' => "role_id = '" . $tmp_contact->getUserType() . "'"));
                    $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;
                        }
                    }
                    $perm->m = $member->getId();
                    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;
                        unset($permissions[$k]);
                        continue;
                    }
                }
                if ($save_cmps) {
                    $sql_insert_values .= ($sql_insert_values == "" ? "" : ",") . "('" . $perm->pg . "','" . $member->getId() . "','" . $perm->o . "','" . $perm->d . "','" . $perm->w . "')";
                }
            }
            $perm->m = $member->getId();
            $changed_pgs[$perm->pg] = $perm->pg;
        }
        if ($save_cmps) {
            if (count($changed_pgs) > 0) {
                DB::execute("DELETE FROM " . TABLE_PREFIX . "contact_member_permissions WHERE permission_group_id IN (" . implode(',', $changed_pgs) . ") AND member_id=" . $member->getId());
            }
            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");
            }
        }
        foreach ($permissions as $p) {
            if (!$p->m) {
                $p->m = $member->getId();
            }
        }
        if ($update_sharing_table) {
            foreach ($changed_pgs as $pg_id) {
                $sharingTablecontroller->afterPermissionChanged($pg_id, $permissions);
            }
        }
        if ($update_contact_member_cache) {
            $contactMemberCacheController->afterMemberPermissionChanged(array('changed_pgs' => $changed_pgs, 'member' => $member));
        }
        foreach ($allowed_pg_ids as $key => $mids) {
            $root_cmp = ContactMemberPermissions::findById(array('permission_group_id' => $key, 'member_id' => $member->getId(), 'object_type_id' => $member->getObjectTypeId()));
            if (!$root_cmp instanceof ContactMemberPermission) {
                $root_cmp = new ContactMemberPermission();
                $root_cmp->setPermissionGroupId($key);
                $root_cmp->setMemberId($member->getId());
                $root_cmp->setObjectTypeId($member->getObjectTypeId());
            }
            $root_cmp->setCanWrite($mids['w'] == true ? 1 : 0);
            $root_cmp->setCanDelete($mids['d'] == true ? 1 : 0);
            $root_cmp->save();
        }
    }
    // check the status of the dimension to set 'allow_all', 'deny_all' or 'check'
    $dimension = $member->getDimension();
    foreach ($changed_pgs as $pg_id) {
        $dimension->setContactDimensionPermission($pg_id, 'check');
    }
    if ($fire_hook) {
        Hook::fire('after_save_member_permissions', array('member' => $member, 'user_id' => logged_user()->getId()), $member);
    }
    return array('changed_pgs' => $changed_pgs, 'member' => $member);
}
    foreach ($root_permissions as $name => $value) {
        if (str_starts_with($name, $root_permissions_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;
        }
    }
    $rp_info = array('root_permissions_sharing_table_delete' => $root_permissions_sharing_table_delete, 'root_permissions_sharing_table_add' => $root_permissions_sharing_table_add);
    // update sharing table
    DB::beginWork();
    $sharingTablecontroller = new SharingTableController();
    $sharingTablecontroller->afterPermissionChanged($pg_id, json_decode($permissions), $rp_info);
    // delete flag
    $flag->delete();
    DB::commit();
} catch (Exception $e) {
    DB::rollback();
    Logger::log("Error saving permissions (2): " . $e->getMessage() . "\n" . $e->getTraceAsString());
}
// save tree
try {
    DB::beginWork();
    $contactMemberCacheController = new ContactMemberCacheController();
    $group = PermissionGroups::findById($pg_id);
    $real_group = null;
    if ($group->getType() == 'user_groups') {