mirror of https://github.com/acanas/swad-core.git
Version 16.247
This commit is contained in:
parent
500bd55ca7
commit
f639ebb425
|
@ -1002,7 +1002,7 @@ void Acc_CompletelyEliminateAccount (struct UsrData *UsrDat,
|
|||
Att_RemoveUsrFromAllAttEvents (UsrDat->UsrCod);
|
||||
|
||||
/***** Remove user from all the groups of all courses *****/
|
||||
Grp_RemUsrFromAllGrps (UsrDat);
|
||||
Grp_RemUsrFromAllGrps (UsrDat->UsrCod);
|
||||
|
||||
/***** Remove user's requests for inscription *****/
|
||||
sprintf (Query,"DELETE FROM crs_usr_requests WHERE UsrCod=%ld",
|
||||
|
|
|
@ -236,13 +236,15 @@
|
|||
/****************************** Public constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define Log_PLATFORM_VERSION "SWAD 16.246 (2017-06-20)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 16.247 (2017-06-20)"
|
||||
#define CSS_FILE "swad16.235.1.css"
|
||||
#define JS_FILE "swad16.206.3.js"
|
||||
|
||||
// Number of lines (includes comments but not blank lines) has been got with the following command:
|
||||
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*?.h sql/swad*.sql | tail -1
|
||||
/*
|
||||
Version 16.247: Jun 20, 2017 Fixed bug when removing a user from a course.
|
||||
Code refactoring related with caches. (222063 lines)
|
||||
Version 16.246: Jun 20, 2017 Fixed bugs and code refactoring in groups. (221975 lines)
|
||||
Version 16.245: Jun 12, 2017 Place editable in centre configuration. (221876 lines)
|
||||
Version 16.244.1: Jun 12, 2017 Fix bug in edition of centres. (221817 lines)
|
||||
|
|
|
@ -287,7 +287,7 @@ void Con_GetAndShowLastClicks (void)
|
|||
|
||||
/* Get institution code (row[5]) */
|
||||
Ins.InsCod = Str_ConvertStrCodToLongCod (row[5]);
|
||||
Ins_GetShortNameOfInstitutionByCod (&Ins);
|
||||
Ins_GetShortNameOfInstitution (&Ins);
|
||||
|
||||
/* Get centre code (row[6]) */
|
||||
Ctr.CtrCod = Str_ConvertStrCodToLongCod (row[6]);
|
||||
|
|
|
@ -1403,53 +1403,56 @@ bool Cty_GetDataOfCountryByCod (struct Country *Cty,Cty_GetExtraData_t GetExtraD
|
|||
/***************************** Get country name ******************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Cty_FlushCacheCountryName (void)
|
||||
{
|
||||
Gbl.Cache.CountryName.CtyCod = -1L;
|
||||
Gbl.Cache.CountryName.CtyName[0] = '\0';
|
||||
}
|
||||
|
||||
void Cty_GetCountryName (long CtyCod,char CtyName[Cty_MAX_BYTES_NAME + 1])
|
||||
{
|
||||
extern const char *Txt_STR_LANG_ID[1 + Txt_NUM_LANGUAGES];
|
||||
char Query[128];
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
static struct
|
||||
{
|
||||
long CtyCod;
|
||||
char CtyName[Cty_MAX_BYTES_NAME + 1];
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
{'\0'}
|
||||
};
|
||||
|
||||
/***** Check if country code is correct *****/
|
||||
/***** 1. Fast check: Trivial case *****/
|
||||
if (CtyCod <= 0)
|
||||
CtyName[0] = '\0'; // Empty name
|
||||
else
|
||||
{
|
||||
if (CtyCod != Cached.CtyCod) // If not cached...
|
||||
{
|
||||
Cached.CtyCod = CtyCod;
|
||||
CtyName[0] = '\0'; // Empty name
|
||||
return;
|
||||
}
|
||||
|
||||
/***** Get name of the country from database *****/
|
||||
sprintf (Query,"SELECT Name_%s FROM countries WHERE CtyCod='%03ld'",
|
||||
Txt_STR_LANG_ID[Gbl.Prefs.Language],CtyCod);
|
||||
if (DB_QuerySELECT (Query,&mysql_res,"can not get the name of a country")) // Country found...
|
||||
{
|
||||
/* Get row */
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (CtyCod == Gbl.Cache.CountryName.CtyCod)
|
||||
{
|
||||
Str_Copy (CtyName,Gbl.Cache.CountryName.CtyName,
|
||||
Cty_MAX_BYTES_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the name of the country */
|
||||
Str_Copy (Cached.CtyName,row[0],
|
||||
Cty_MAX_BYTES_NAME);
|
||||
}
|
||||
else
|
||||
Cached.CtyName[0] = '\0';
|
||||
/***** 3. Slow: get country name from database *****/
|
||||
Gbl.Cache.CountryName.CtyCod = CtyCod;
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
}
|
||||
sprintf (Query,"SELECT Name_%s FROM countries WHERE CtyCod='%03ld'",
|
||||
Txt_STR_LANG_ID[Gbl.Prefs.Language],CtyCod);
|
||||
if (DB_QuerySELECT (Query,&mysql_res,"can not get the name of a country")) // Country found...
|
||||
{
|
||||
/* Get row */
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
Str_Copy (CtyName,Cached.CtyName,
|
||||
/* Get the name of the country */
|
||||
Str_Copy (Gbl.Cache.CountryName.CtyName,row[0],
|
||||
Cty_MAX_BYTES_NAME);
|
||||
}
|
||||
else
|
||||
Gbl.Cache.CountryName.CtyName[0] = '\0';
|
||||
|
||||
/* Free structure that stores the query result */
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
Str_Copy (CtyName,Gbl.Cache.CountryName.CtyName,
|
||||
Cty_MAX_BYTES_NAME);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1703,6 +1706,9 @@ void Cty_RemoveCountry (void)
|
|||
Cty.CtyCod);
|
||||
DB_QueryDELETE (Query,"can not remove a country");
|
||||
|
||||
/***** Flush cache *****/
|
||||
Cty_FlushCacheCountryName ();
|
||||
|
||||
/***** Write message to show the change made *****/
|
||||
sprintf (Gbl.Alert.Txt,Txt_Country_X_removed,
|
||||
Cty.Name[Gbl.Prefs.Language]);
|
||||
|
@ -1846,6 +1852,9 @@ static void Cty_UpdateCtyNameDB (long CtyCod,const char *FieldName,const char *N
|
|||
sprintf (Query,"UPDATE countries SET %s='%s' WHERE CtyCod='%03ld'",
|
||||
FieldName,NewCtyName,CtyCod);
|
||||
DB_QueryUPDATE (Query,"can not update the name of a country");
|
||||
|
||||
/***** Flush cache *****/
|
||||
Cty_FlushCacheCountryName ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -99,6 +99,7 @@ void Cty_FreeListCountries (void);
|
|||
void Cty_WriteSelectorOfCountry (void);
|
||||
void Cty_WriteCountryName (long CtyCod,const char *ClassLink);
|
||||
bool Cty_GetDataOfCountryByCod (struct Country *Cty,Cty_GetExtraData_t GetExtraData);
|
||||
void Cty_FlushCacheCountryName (void);
|
||||
void Cty_GetCountryName (long CtyCod,char CtyName[Cty_MAX_BYTES_NAME + 1]);
|
||||
void Cty_PutParamCtyCod (long CtyCod);
|
||||
long Cty_GetAndCheckParamOtherCtyCod (long MinCodAllowed);
|
||||
|
|
|
@ -175,8 +175,8 @@ void Enr_PutButtonInlineToRegisterStds (long CrsCod)
|
|||
{
|
||||
extern const char *Txt_Register_students;
|
||||
|
||||
if (Rol_GetRoleInCrs (CrsCod,Gbl.Usrs.Me.UsrDat.UsrCod) == Rol_TCH) // I am a teacher in course
|
||||
if (!Usr_GetNumUsrsInCrs (Rol_STD,CrsCod)) // No students in course
|
||||
if (Rol_GetRoleUsrInCrs (Gbl.Usrs.Me.UsrDat.UsrCod,CrsCod) == Rol_TCH) // I am a teacher in course
|
||||
if (!Usr_GetNumUsrsInCrs (Rol_STD,CrsCod)) // No students in course
|
||||
{
|
||||
Act_FormStart (ActReqEnrSevStd);
|
||||
Crs_PutParamCrsCod (CrsCod);
|
||||
|
@ -231,7 +231,7 @@ void Enr_ModifyRoleInCurrentCrs (struct UsrData *UsrDat,Rol_Role_t NewRole)
|
|||
Enr_NotifyAfterEnrolment (UsrDat,NewRole);
|
||||
|
||||
UsrDat->Roles.InCurrentCrs.Role = NewRole;
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
|
||||
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get roles
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ void Enr_RegisterUsrInCurrentCrs (struct UsrData *UsrDat,Rol_Role_t NewRole,
|
|||
'N');
|
||||
DB_QueryINSERT (Query,"can not register user in course");
|
||||
UsrDat->Roles.InCurrentCrs.Role = NewRole;
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
|
||||
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get roles
|
||||
|
||||
|
@ -3024,7 +3024,7 @@ void Enr_PutLinkToAdminOneUsr (Act_Action_t NextAction)
|
|||
extern const char *Txt_Administer_me;
|
||||
extern const char *Txt_Administer_one_user;
|
||||
const char *TitleText = Enr_ICanAdminOtherUsrs[Gbl.Usrs.Me.Role.Logged] ? Txt_Administer_one_user :
|
||||
Txt_Administer_me;
|
||||
Txt_Administer_me;
|
||||
|
||||
Lay_PutContextualLink (NextAction,NULL,NULL,
|
||||
"config64x64.gif",
|
||||
|
@ -3922,7 +3922,7 @@ void Enr_ModifyUsr1 (void)
|
|||
if (ItsMe)
|
||||
{
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role;
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.UsrCod = Gbl.Usrs.Other.UsrDat.UsrCod;
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.GotFromDBForUsrCod = Gbl.Usrs.Other.UsrDat.UsrCod;
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCrss = Gbl.Usrs.Other.UsrDat.Roles.InCrss;
|
||||
Rol_SetMyRoles ();
|
||||
}
|
||||
|
@ -4134,7 +4134,7 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat,struct Course *
|
|||
extern const char *Txt_THE_USER_X_has_been_removed_from_the_course_Y;
|
||||
extern const char *Txt_User_not_found_or_you_do_not_have_permission_;
|
||||
char Query[1024];
|
||||
bool ItsMe;
|
||||
bool ItsMe = (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
|
||||
if (Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
|
||||
{
|
||||
|
@ -4142,7 +4142,7 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat,struct Course *
|
|||
Att_RemoveUsrFromCrsAttEvents (UsrDat->UsrCod,Crs->CrsCod);
|
||||
|
||||
/***** Remove user from all the groups in course *****/
|
||||
Grp_RemUsrFromAllGrpsInCrs (UsrDat,Crs);
|
||||
Grp_RemUsrFromAllGrpsInCrs (UsrDat->UsrCod,Crs->CrsCod);
|
||||
|
||||
/***** Remove user's status about reading of course information *****/
|
||||
Inf_RemoveUsrFromCrsInfoRead (UsrDat->UsrCod,Crs->CrsCod);
|
||||
|
@ -4170,13 +4170,44 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat,struct Course *
|
|||
Crs->CrsCod,UsrDat->UsrCod);
|
||||
DB_QueryDELETE (Query,"can not remove a user from a course");
|
||||
|
||||
/***** Flush caches *****/
|
||||
Usr_FlushCacheUsrBelongsToIns ();
|
||||
Usr_FlushCacheUsrBelongsToCtr ();
|
||||
Usr_FlushCacheUsrBelongsToDeg ();
|
||||
Usr_FlushCacheUsrBelongsToCrs ();
|
||||
Usr_FlushCacheUsrBelongsToCurrentCrs ();
|
||||
Usr_FlushCacheUsrHasAcceptedInCurrentCrs ();
|
||||
Usr_FlushCacheUsrSharesAnyOfMyCrs ();
|
||||
Rol_FlushCacheRoleUsrInCrs ();
|
||||
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
|
||||
|
||||
/***** If it's me, change my roles *****/
|
||||
ItsMe = (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
if (ItsMe)
|
||||
{
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.UsrCod = UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCrss = UsrDat->Roles.InCrss = -1; // not yet filled/calculated
|
||||
/* Flush caches */
|
||||
Grp_FlushCacheIBelongToGrp ();
|
||||
|
||||
/* Now I don't belong to current course */
|
||||
Gbl.Usrs.Me.IBelongToCurrentCrs =
|
||||
Gbl.Usrs.Me.UsrDat.Accepted = false;
|
||||
|
||||
/* Fill the list with the courses I belong to */
|
||||
Gbl.Usrs.Me.MyCrss.Filled = false;
|
||||
Usr_GetMyCourses ();
|
||||
|
||||
/* Set my roles */
|
||||
Gbl.Usrs.Me.Role.FromSession =
|
||||
Gbl.Usrs.Me.Role.Logged =
|
||||
Gbl.Usrs.Me.Role.LoggedBeforeCloseSession =
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role =
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
|
||||
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.GotFromDBForUsrCod =
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCrss =
|
||||
UsrDat->Roles.InCrss = -1; // not yet filled/calculated
|
||||
|
||||
Rol_SetMyRoles ();
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "swad_icon.h"
|
||||
#include "swad_parameter.h"
|
||||
#include "swad_preference.h"
|
||||
#include "swad_role.h"
|
||||
#include "swad_theme.h"
|
||||
#include "swad_web_service.h"
|
||||
|
||||
|
@ -440,6 +441,22 @@ void Gbl_InitializeGlobals (void)
|
|||
Gbl.WebService.Function = Svc_unknown;
|
||||
|
||||
Gbl.Layout.NestedBox = 0;
|
||||
|
||||
/* Flush caches */
|
||||
Cty_FlushCacheCountryName ();
|
||||
Ins_FlushCacheShortNameOfInstitution ();
|
||||
Ins_FlushCacheFullNameAndCtyOfInstitution ();
|
||||
Usr_FlushCacheUsrIsSuperuser ();
|
||||
Usr_FlushCacheUsrBelongsToIns ();
|
||||
Usr_FlushCacheUsrBelongsToCtr ();
|
||||
Usr_FlushCacheUsrBelongsToDeg ();
|
||||
Usr_FlushCacheUsrBelongsToCrs ();
|
||||
Usr_FlushCacheUsrBelongsToCurrentCrs ();
|
||||
Usr_FlushCacheUsrHasAcceptedInCurrentCrs ();
|
||||
Usr_FlushCacheUsrSharesAnyOfMyCrs ();
|
||||
Rol_FlushCacheRoleUsrInCrs ();
|
||||
Grp_FlushCacheIBelongToGrp ();
|
||||
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -747,6 +747,88 @@ struct Globals
|
|||
{
|
||||
char *Str;
|
||||
} QR;
|
||||
|
||||
/* Cache */
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
long CtyCod;
|
||||
char CtyName[Cty_MAX_BYTES_NAME + 1];
|
||||
} CountryName;
|
||||
struct
|
||||
{
|
||||
long InsCod;
|
||||
char ShrtName[Hie_MAX_BYTES_SHRT_NAME + 1];
|
||||
} InstitutionShrtName;
|
||||
struct
|
||||
{
|
||||
long InsCod;
|
||||
char FullName[Hie_MAX_BYTES_FULL_NAME + 1];
|
||||
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1];
|
||||
} InstitutionFullNameAndCty;
|
||||
struct
|
||||
{
|
||||
long UsrCod;
|
||||
bool IsSuperuser;
|
||||
} UsrIsSuperuser;
|
||||
struct
|
||||
{
|
||||
long UsrCod;
|
||||
long InsCod;
|
||||
bool Belongs;
|
||||
} UsrBelongsToIns;
|
||||
struct
|
||||
{
|
||||
long UsrCod;
|
||||
long CtrCod;
|
||||
bool Belongs;
|
||||
} UsrBelongsToCtr;
|
||||
struct
|
||||
{
|
||||
long UsrCod;
|
||||
long DegCod;
|
||||
bool Belongs;
|
||||
} UsrBelongsToDeg;
|
||||
struct
|
||||
{
|
||||
long UsrCod;
|
||||
long CrsCod;
|
||||
bool CountOnlyAcceptedCourses;
|
||||
bool Belongs;
|
||||
} UsrBelongsToCrs;
|
||||
struct
|
||||
{
|
||||
long UsrCod;
|
||||
bool Belongs;
|
||||
} UsrBelongsToCurrentCrs;
|
||||
struct
|
||||
{
|
||||
long UsrCod;
|
||||
bool Accepted;
|
||||
} UsrHasAcceptedInCurrentCrs;
|
||||
struct
|
||||
{
|
||||
long UsrCod;
|
||||
bool SharesAnyOfMyCrs;
|
||||
} UsrSharesAnyOfMyCrs;
|
||||
struct
|
||||
{
|
||||
long GrpCod;
|
||||
bool IBelong;
|
||||
} IBelongToGrp;
|
||||
struct
|
||||
{
|
||||
long UsrCod;
|
||||
bool Shares;
|
||||
} UsrSharesAnyOfMyGrpsInCurrentCrs;
|
||||
struct
|
||||
{
|
||||
long UsrCod;
|
||||
long CrsCod;
|
||||
Rol_Role_t Role;
|
||||
} RoleUsrInCrs;
|
||||
} Cache;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
205
swad_group.c
205
swad_group.c
|
@ -1130,7 +1130,9 @@ unsigned Grp_RemoveUsrFromGroups (struct UsrData *UsrDat,struct ListCodGrps *Lst
|
|||
extern const char *Txt_THE_USER_X_has_been_removed_from_one_group;
|
||||
extern const char *Txt_THE_USER_X_has_been_removed_from_Y_groups;
|
||||
struct ListCodGrps LstGrpsHeBelongs;
|
||||
unsigned NumGrpSel,NumGrpHeBelongs,NumGrpsHeIsRemoved = 0;
|
||||
unsigned NumGrpSel;
|
||||
unsigned NumGrpHeBelongs;
|
||||
unsigned NumGrpsHeIsRemoved = 0;
|
||||
|
||||
/***** Query in the database the group codes of any group the user belongs to *****/
|
||||
Grp_GetLstCodGrpsUsrBelongs (Gbl.CurrentCrs.Crs.CrsCod,-1L,
|
||||
|
@ -1173,9 +1175,10 @@ unsigned Grp_RemoveUsrFromGroups (struct UsrData *UsrDat,struct ListCodGrps *Lst
|
|||
/*************** Remove a user of all the groups of a course *****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Grp_RemUsrFromAllGrpsInCrs (struct UsrData *UsrDat,struct Course *Crs)
|
||||
void Grp_RemUsrFromAllGrpsInCrs (long UsrCod,long CrsCod)
|
||||
{
|
||||
char Query[512];
|
||||
bool ItsMe = (UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
|
||||
/***** Remove user from all the groups of the course *****/
|
||||
sprintf (Query,"DELETE FROM crs_grp_usr"
|
||||
|
@ -1183,22 +1186,33 @@ void Grp_RemUsrFromAllGrpsInCrs (struct UsrData *UsrDat,struct Course *Crs)
|
|||
" (SELECT crs_grp.GrpCod FROM crs_grp_types,crs_grp"
|
||||
" WHERE crs_grp_types.CrsCod=%ld"
|
||||
" AND crs_grp_types.GrpTypCod=crs_grp.GrpTypCod)",
|
||||
UsrDat->UsrCod,Crs->CrsCod);
|
||||
UsrCod,CrsCod);
|
||||
DB_QueryDELETE (Query,"can not remove a user from all groups of a course");
|
||||
|
||||
/***** Flush caches *****/
|
||||
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
|
||||
if (ItsMe)
|
||||
Grp_FlushCacheIBelongToGrp ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******* Remove a user from all the groups of all the user's courses *********/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Grp_RemUsrFromAllGrps (struct UsrData *UsrDat)
|
||||
void Grp_RemUsrFromAllGrps (long UsrCod)
|
||||
{
|
||||
char Query[128];
|
||||
bool ItsMe = (UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
|
||||
/***** Remove user from all groups *****/
|
||||
sprintf (Query,"DELETE FROM crs_grp_usr WHERE UsrCod=%ld",
|
||||
UsrDat->UsrCod);
|
||||
UsrCod);
|
||||
DB_QueryDELETE (Query,"can not remove a user from the groups he/she belongs to");
|
||||
|
||||
/***** Flush caches *****/
|
||||
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
|
||||
if (ItsMe)
|
||||
Grp_FlushCacheIBelongToGrp ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1208,12 +1222,18 @@ void Grp_RemUsrFromAllGrps (struct UsrData *UsrDat)
|
|||
static void Grp_RemoveUsrFromGroup (long UsrCod,long GrpCod)
|
||||
{
|
||||
char Query[256];
|
||||
bool ItsMe = (UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
|
||||
/***** Remove user from group *****/
|
||||
sprintf (Query,"DELETE FROM crs_grp_usr"
|
||||
" WHERE GrpCod=%ld AND UsrCod=%ld",
|
||||
GrpCod,UsrCod);
|
||||
DB_QueryDELETE (Query,"can not remove a user from a group");
|
||||
|
||||
/***** Flush caches *****/
|
||||
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
|
||||
if (ItsMe)
|
||||
Grp_FlushCacheIBelongToGrp ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -3230,35 +3250,104 @@ static long Grp_GetFirstCodGrpIBelongTo (long GrpTypCod)
|
|||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************* Check if a user belongs to a group ********************/
|
||||
/************************ Check if I belong to a group ***********************/
|
||||
/*****************************************************************************/
|
||||
// Return true if the user identificado belongs al group with código GrpCod
|
||||
// Return true if I belong to group with code GrpCod
|
||||
|
||||
void Grp_FlushCacheIBelongToGrp (void)
|
||||
{
|
||||
Gbl.Cache.IBelongToGrp.GrpCod = -1L;
|
||||
Gbl.Cache.IBelongToGrp.IBelong = false;
|
||||
}
|
||||
|
||||
bool Grp_GetIfIBelongToGrp (long GrpCod)
|
||||
{
|
||||
char Query[256];
|
||||
static struct
|
||||
{
|
||||
long GrpCod;
|
||||
bool IBelongToGrp;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
false
|
||||
}; // A cache. If this function is called consecutive times
|
||||
// with the same group, only the first time is slow
|
||||
|
||||
/***** 1. Fast check: Is already calculated if I belong to group? *****/
|
||||
if (GrpCod == Cached.GrpCod)
|
||||
return Cached.IBelongToGrp;
|
||||
/***** 1. Fast check: Trivial case *****/
|
||||
if (GrpCod <= 0)
|
||||
return false;
|
||||
|
||||
/***** 2. Slow check: Get if I belong to a group from database *****/
|
||||
/***** 2. Fast check: Is already calculated if I belong to group? *****/
|
||||
if (GrpCod == Gbl.Cache.IBelongToGrp.GrpCod)
|
||||
return Gbl.Cache.IBelongToGrp.IBelong;
|
||||
|
||||
/***** 3. Slow check: Get if I belong to a group from database *****/
|
||||
sprintf (Query,"SELECT COUNT(*) FROM crs_grp_usr"
|
||||
" WHERE GrpCod=%ld AND UsrCod=%ld",
|
||||
GrpCod,Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
Cached.IBelongToGrp = DB_QueryCOUNT (Query,"can not check if you belong to a group") != 0;
|
||||
Cached.GrpCod = GrpCod;
|
||||
return Cached.IBelongToGrp;
|
||||
Gbl.Cache.IBelongToGrp.IBelong = DB_QueryCOUNT (Query,"can not check if you belong to a group") != 0;
|
||||
Gbl.Cache.IBelongToGrp.GrpCod = GrpCod;
|
||||
return Gbl.Cache.IBelongToGrp.IBelong;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************** Check if a user belongs to any of my courses ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (void)
|
||||
{
|
||||
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod = -1L;
|
||||
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares = false;
|
||||
}
|
||||
|
||||
bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat)
|
||||
{
|
||||
char Query[512];
|
||||
|
||||
/***** 1. Fast check: Am I logged? *****/
|
||||
if (!Gbl.Usrs.Me.Logged)
|
||||
return false;
|
||||
|
||||
/***** 2. Fast check: Is it a valid user code? *****/
|
||||
if (UsrDat->UsrCod <= 0)
|
||||
return false;
|
||||
|
||||
/***** 3. Fast check: Is it a course selected? *****/
|
||||
if (Gbl.CurrentCrs.Crs.CrsCod <= 0)
|
||||
return false;
|
||||
|
||||
/***** 4. Fast check: Do I belong to the current course? *****/
|
||||
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
|
||||
return false;
|
||||
|
||||
/***** 5. Fast check: It's me? *****/
|
||||
if (Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod)
|
||||
return true;
|
||||
|
||||
/***** 6. Fast check: Is already calculated if user shares
|
||||
any group in the current course with me? *****/
|
||||
if (UsrDat->UsrCod == Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod)
|
||||
return Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares;
|
||||
|
||||
/***** 7. Fast / slow check: Does he/she belong to the current course? *****/
|
||||
if (!Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
|
||||
{
|
||||
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/***** 8. Slow check: Get if user shares any group in this course with me from database *****/
|
||||
/* Check if user shares any group with me */
|
||||
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
sprintf (Query,"SELECT COUNT(*) FROM crs_grp_usr"
|
||||
" WHERE UsrCod=%ld"
|
||||
" AND GrpCod IN"
|
||||
" (SELECT crs_grp_usr.GrpCod"
|
||||
" FROM crs_grp_usr,crs_grp,crs_grp_types"
|
||||
" WHERE crs_grp_usr.UsrCod=%ld"
|
||||
" AND crs_grp_usr.GrpCod=crs_grp.GrpCod"
|
||||
" AND crs_grp.GrpTypCod=crs_grp_types.GrpTypCod"
|
||||
" AND crs_grp_types.CrsCod=%ld)",
|
||||
UsrDat->UsrCod,
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
Gbl.CurrentCrs.Crs.CrsCod);
|
||||
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares = DB_QueryCOUNT (Query,"can not check"
|
||||
" if a user shares any group"
|
||||
" in the current course with you") != 0;
|
||||
return Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -4791,71 +4880,3 @@ void Grp_GetParamWhichGrps (void)
|
|||
AlreadyGot = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************** Check if a user belongs to any of my courses ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat)
|
||||
{
|
||||
char Query[512];
|
||||
static struct
|
||||
{
|
||||
long UsrCod;
|
||||
bool UsrSharesAnyOfMyGrpsInCurrentCrs;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
false
|
||||
}; // A cache. If this function is called consecutive times
|
||||
// with the same user, only the first time is slow
|
||||
|
||||
/***** 1. Fast check: Am I logged? *****/
|
||||
if (!Gbl.Usrs.Me.Logged)
|
||||
return false;
|
||||
|
||||
/***** 2. Fast check: Is it a valid user code? *****/
|
||||
if (UsrDat->UsrCod <= 0)
|
||||
return false;
|
||||
|
||||
/***** 3. Fast check: Is it a course selected? *****/
|
||||
if (Gbl.CurrentCrs.Crs.CrsCod <= 0)
|
||||
return false;
|
||||
|
||||
/***** 4. Fast check: Do I belong to the current course? *****/
|
||||
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
|
||||
return false;
|
||||
|
||||
/***** 5. Fast check: It's me? *****/
|
||||
if (Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod)
|
||||
return true;
|
||||
|
||||
/***** 6. Fast check: Does he/she belong to the current course? *****/
|
||||
if (!Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
|
||||
return false;
|
||||
|
||||
/***** 7. Fast check: Is already calculated if user shares
|
||||
any group in the current course with me? *****/
|
||||
if (UsrDat->UsrCod == Cached.UsrCod)
|
||||
return Cached.UsrSharesAnyOfMyGrpsInCurrentCrs;
|
||||
|
||||
/***** 8. Slow check: Get if user shares any group in this course with me from database *****/
|
||||
/* Check if user shares any group with me */
|
||||
Cached.UsrCod = UsrDat->UsrCod;
|
||||
sprintf (Query,"SELECT COUNT(*) FROM crs_grp_usr"
|
||||
" WHERE UsrCod=%ld"
|
||||
" AND GrpCod IN"
|
||||
" (SELECT crs_grp_usr.GrpCod"
|
||||
" FROM crs_grp_usr,crs_grp,crs_grp_types"
|
||||
" WHERE crs_grp_usr.UsrCod=%ld"
|
||||
" AND crs_grp_usr.GrpCod=crs_grp.GrpCod"
|
||||
" AND crs_grp.GrpTypCod=crs_grp_types.GrpTypCod"
|
||||
" AND crs_grp_types.CrsCod=%ld)",
|
||||
UsrDat->UsrCod,
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
Gbl.CurrentCrs.Crs.CrsCod);
|
||||
Cached.UsrSharesAnyOfMyGrpsInCurrentCrs = DB_QueryCOUNT (Query,"can not check"
|
||||
" if a user shares any group"
|
||||
" in the current course with you") != 0;
|
||||
return Cached.UsrSharesAnyOfMyGrpsInCurrentCrs;
|
||||
}
|
||||
|
|
11
swad_group.h
11
swad_group.h
|
@ -148,8 +148,8 @@ void Grp_ChangeGrpsOtherUsrAtomically (struct ListCodGrps *LstGrpsUsrWants);
|
|||
bool Grp_CheckIfSelectionGrpsSingleEnrolmentIsValid (Rol_Role_t Role,struct ListCodGrps *LstGrps);
|
||||
void Grp_RegisterUsrIntoGroups (struct UsrData *UsrDat,struct ListCodGrps *LstGrps);
|
||||
unsigned Grp_RemoveUsrFromGroups (struct UsrData *UsrDat,struct ListCodGrps *LstGrps);
|
||||
void Grp_RemUsrFromAllGrpsInCrs (struct UsrData *UsrDat,struct Course *Crs);
|
||||
void Grp_RemUsrFromAllGrps (struct UsrData *UsrDat);
|
||||
void Grp_RemUsrFromAllGrpsInCrs (long UsrCod,long CrsCod);
|
||||
void Grp_RemUsrFromAllGrps (long UsrCod);
|
||||
void Grp_ListGrpsToEditAsgAttOrSvy (struct GroupType *GrpTyp,long Cod,Grp_AsgOrSvy_t Grp_AsgOrSvy);
|
||||
|
||||
void Grp_ReqRegisterInGrps (void);
|
||||
|
@ -166,7 +166,12 @@ void Grp_GetDataOfGroupByCod (struct GroupData *GrpDat);
|
|||
bool Grp_CheckIfGroupExists (long GrpCod);
|
||||
bool Grp_CheckIfGroupBelongsToCourse (long GrpCod,long CrsCod);
|
||||
unsigned Grp_CountNumUsrsInGrp (Rol_Role_t Role,long GrpCod);
|
||||
|
||||
void Grp_FlushCacheIBelongToGrp (void);
|
||||
bool Grp_GetIfIBelongToGrp (long GrpCod);
|
||||
void Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (void);
|
||||
bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat);
|
||||
|
||||
unsigned Grp_NumGrpTypesMandatIDontBelongAsStd (void);
|
||||
void Grp_GetLstCodGrpsWithFileZonesIBelong (struct ListCodGrps *LstGrps);
|
||||
void Grp_GetNamesGrpsStdBelongsTo (long GrpTypCod,long UsrCod,char *GrpNames);
|
||||
|
@ -199,6 +204,4 @@ void Grp_PutParamWhichGrpsAllGrps (void);
|
|||
void Grp_ShowFormToSelWhichGrps (Act_Action_t Action,void (*FuncParams) ());
|
||||
void Grp_GetParamWhichGrps (void);
|
||||
|
||||
bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -80,8 +80,8 @@ static void Ins_GetParamInsOrder (void);
|
|||
|
||||
static void Ins_PutIconToViewInstitutions (void);
|
||||
|
||||
static void Ins_GetFullNameAndCtyOfInstitutionByCod (struct Instit *Ins,
|
||||
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1]);
|
||||
static void Ins_GetFullNameAndCtyOfInstitution (struct Instit *Ins,
|
||||
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1]);
|
||||
|
||||
static void Ins_ListInstitutionsForEdition (void);
|
||||
static bool Ins_CheckIfICanEdit (struct Instit *Ins);
|
||||
|
@ -1098,7 +1098,7 @@ void Ins_WriteInstitutionNameAndCty (long InsCod)
|
|||
|
||||
/***** Get institution full name *****/
|
||||
Ins.InsCod = InsCod;
|
||||
Ins_GetFullNameAndCtyOfInstitutionByCod (&Ins,CtyName);
|
||||
Ins_GetFullNameAndCtyOfInstitution (&Ins,CtyName);
|
||||
|
||||
/***** Write institution full name *****/
|
||||
fprintf (Gbl.F.Out,"%s<br />%s",Ins.FullName,CtyName);
|
||||
|
@ -1194,116 +1194,127 @@ bool Ins_GetDataOfInstitutionByCod (struct Instit *Ins,
|
|||
/*********** Get the short name of an institution from its code **************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Ins_GetShortNameOfInstitutionByCod (struct Instit *Ins)
|
||||
void Ins_FlushCacheShortNameOfInstitution (void)
|
||||
{
|
||||
Gbl.Cache.InstitutionShrtName.InsCod = -1L;
|
||||
Gbl.Cache.InstitutionShrtName.ShrtName[0] = '\0';
|
||||
}
|
||||
|
||||
void Ins_GetShortNameOfInstitution (struct Instit *Ins)
|
||||
{
|
||||
char Query[128];
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
static struct
|
||||
{
|
||||
long InsCod;
|
||||
char ShrtName[Hie_MAX_BYTES_SHRT_NAME + 1];
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
{'\0'}
|
||||
};
|
||||
|
||||
/***** 1. Fast check: Trivial case *****/
|
||||
if (Ins->InsCod <= 0)
|
||||
Ins->ShrtName[0] = '\0'; // Empty name
|
||||
else
|
||||
{
|
||||
if (Ins->InsCod != Cached.InsCod) // If not cached...
|
||||
{
|
||||
/***** Get the short name of an institution from database *****/
|
||||
sprintf (Query,"SELECT ShortName FROM institutions WHERE InsCod=%ld",
|
||||
Ins->InsCod);
|
||||
if (DB_QuerySELECT (Query,&mysql_res,"can not get the short name of an institution") == 1)
|
||||
{
|
||||
/***** Get the short name of this institution *****/
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
Ins->ShrtName[0] = '\0'; // Empty name
|
||||
return;
|
||||
}
|
||||
|
||||
Str_Copy (Cached.ShrtName,row[0],
|
||||
Hie_MAX_BYTES_SHRT_NAME);
|
||||
}
|
||||
else
|
||||
Cached.ShrtName[0] = '\0';
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (Ins->InsCod == Gbl.Cache.InstitutionShrtName.InsCod)
|
||||
{
|
||||
Str_Copy (Ins->ShrtName,Gbl.Cache.InstitutionShrtName.ShrtName,
|
||||
Hie_MAX_BYTES_SHRT_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
}
|
||||
/***** 3. Slow: get short name of institution from database *****/
|
||||
Gbl.Cache.InstitutionShrtName.InsCod = Ins->InsCod;
|
||||
|
||||
Str_Copy (Ins->ShrtName,Cached.ShrtName,
|
||||
sprintf (Query,"SELECT ShortName FROM institutions WHERE InsCod=%ld",
|
||||
Ins->InsCod);
|
||||
if (DB_QuerySELECT (Query,&mysql_res,"can not get the short name of an institution") == 1)
|
||||
{
|
||||
/* Get the short name of this institution */
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
Str_Copy (Gbl.Cache.InstitutionShrtName.ShrtName,row[0],
|
||||
Hie_MAX_BYTES_SHRT_NAME);
|
||||
}
|
||||
else
|
||||
Gbl.Cache.InstitutionShrtName.ShrtName[0] = '\0';
|
||||
|
||||
/* Free structure that stores the query result */
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
Str_Copy (Ins->ShrtName,Gbl.Cache.InstitutionShrtName.ShrtName,
|
||||
Hie_MAX_BYTES_SHRT_NAME);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************ Get the full name of an institution from its code **************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Ins_GetFullNameAndCtyOfInstitutionByCod (struct Instit *Ins,
|
||||
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1])
|
||||
void Ins_FlushCacheFullNameAndCtyOfInstitution (void)
|
||||
{
|
||||
Gbl.Cache.InstitutionFullNameAndCty.InsCod = -1L;
|
||||
Gbl.Cache.InstitutionFullNameAndCty.FullName[0] = '\0';
|
||||
Gbl.Cache.InstitutionFullNameAndCty.CtyName[0] = '\0';
|
||||
}
|
||||
|
||||
static void Ins_GetFullNameAndCtyOfInstitution (struct Instit *Ins,
|
||||
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1])
|
||||
{
|
||||
extern const char *Txt_STR_LANG_ID[1 + Txt_NUM_LANGUAGES];
|
||||
char Query[512];
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
static struct
|
||||
{
|
||||
long InsCod;
|
||||
char FullName[Hie_MAX_BYTES_FULL_NAME + 1];
|
||||
char CtyName[Hie_MAX_BYTES_FULL_NAME + 1];
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
{'\0'},
|
||||
{'\0'},
|
||||
};
|
||||
|
||||
/***** 1. Fast check: Trivial case *****/
|
||||
if (Ins->InsCod <= 0)
|
||||
{
|
||||
Ins->FullName[0] = '\0'; // Empty name
|
||||
CtyName[0] = '\0'; // Empty name
|
||||
return;
|
||||
}
|
||||
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (Ins->InsCod == Gbl.Cache.InstitutionFullNameAndCty.InsCod)
|
||||
{
|
||||
Str_Copy (Ins->FullName,Gbl.Cache.InstitutionFullNameAndCty.FullName,
|
||||
Hie_MAX_BYTES_FULL_NAME);
|
||||
Str_Copy (CtyName,Gbl.Cache.InstitutionFullNameAndCty.CtyName,
|
||||
Hie_MAX_BYTES_FULL_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
/***** 3. Slow: get full name and country of institution from database *****/
|
||||
Gbl.Cache.InstitutionFullNameAndCty.InsCod = Ins->InsCod;
|
||||
|
||||
sprintf (Query,"SELECT institutions.FullName,countries.Name_%s"
|
||||
" FROM institutions,countries"
|
||||
" WHERE institutions.InsCod=%ld"
|
||||
" AND institutions.CtyCod=countries.CtyCod",
|
||||
Txt_STR_LANG_ID[Gbl.Prefs.Language],Ins->InsCod);
|
||||
if (DB_QuerySELECT (Query,&mysql_res,"can not get the full name of an institution") == 1)
|
||||
{
|
||||
/* Get row */
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Get the full name of this institution (row[0]) */
|
||||
Str_Copy (Gbl.Cache.InstitutionFullNameAndCty.FullName,row[0],
|
||||
Hie_MAX_BYTES_FULL_NAME);
|
||||
|
||||
/* Get the name of the country (row[1]) */
|
||||
Str_Copy (Gbl.Cache.InstitutionFullNameAndCty.CtyName,row[1],
|
||||
Hie_MAX_BYTES_FULL_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Ins->InsCod != Cached.InsCod) // If not cached...
|
||||
{
|
||||
/***** Get the short name of an institution from database *****/
|
||||
sprintf (Query,"SELECT institutions.FullName,countries.Name_%s"
|
||||
" FROM institutions,countries"
|
||||
" WHERE institutions.InsCod=%ld"
|
||||
" AND institutions.CtyCod=countries.CtyCod",
|
||||
Txt_STR_LANG_ID[Gbl.Prefs.Language],Ins->InsCod);
|
||||
if (DB_QuerySELECT (Query,&mysql_res,"can not get the full name of an institution") == 1)
|
||||
{
|
||||
/* Get row */
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Get the full name of this institution (row[0]) */
|
||||
Str_Copy (Cached.FullName,row[0],
|
||||
Hie_MAX_BYTES_FULL_NAME);
|
||||
|
||||
/* Get the name of the country (row[1]) */
|
||||
Str_Copy (Cached.CtyName,row[1],
|
||||
Hie_MAX_BYTES_FULL_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cached.FullName[0] = '\0';
|
||||
Cached.CtyName[0] = '\0';
|
||||
}
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
}
|
||||
|
||||
Str_Copy (Ins->FullName,Cached.FullName,
|
||||
Hie_MAX_BYTES_FULL_NAME);
|
||||
Str_Copy (CtyName,Cached.CtyName,
|
||||
Hie_MAX_BYTES_FULL_NAME);
|
||||
Gbl.Cache.InstitutionFullNameAndCty.FullName[0] = '\0';
|
||||
Gbl.Cache.InstitutionFullNameAndCty.CtyName[0] = '\0';
|
||||
}
|
||||
|
||||
/* Free structure that stores the query result */
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
Str_Copy (Ins->FullName,Gbl.Cache.InstitutionFullNameAndCty.FullName,
|
||||
Hie_MAX_BYTES_FULL_NAME);
|
||||
Str_Copy (CtyName,Gbl.Cache.InstitutionFullNameAndCty.CtyName,
|
||||
Hie_MAX_BYTES_FULL_NAME);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1711,6 +1722,10 @@ void Ins_RemoveInstitution (void)
|
|||
Ins.InsCod);
|
||||
DB_QueryDELETE (Query,"can not remove an institution");
|
||||
|
||||
/***** Flush caches *****/
|
||||
Ins_FlushCacheShortNameOfInstitution ();
|
||||
Ins_FlushCacheFullNameAndCtyOfInstitution ();
|
||||
|
||||
/***** Write message to show the change made *****/
|
||||
sprintf (Gbl.Alert.Txt,Txt_Institution_X_removed,
|
||||
Ins.FullName);
|
||||
|
@ -1859,6 +1874,10 @@ static void Ins_UpdateInsNameDB (long InsCod,const char *FieldName,const char *N
|
|||
sprintf (Query,"UPDATE institutions SET %s='%s' WHERE InsCod=%ld",
|
||||
FieldName,NewInsName,InsCod);
|
||||
DB_QueryUPDATE (Query,"can not update the name of an institution");
|
||||
|
||||
/***** Flush caches *****/
|
||||
Ins_FlushCacheShortNameOfInstitution ();
|
||||
Ins_FlushCacheFullNameAndCtyOfInstitution ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -106,7 +106,9 @@ void Ins_GetListInstitutions (long CtyCod,Ins_GetExtraData_t GetExtraData);
|
|||
void Ins_WriteInstitutionNameAndCty (long InsCod);
|
||||
bool Ins_GetDataOfInstitutionByCod (struct Instit *Ins,
|
||||
Ins_GetExtraData_t GetExtraData);
|
||||
void Ins_GetShortNameOfInstitutionByCod (struct Instit *Ins);
|
||||
void Ins_FlushCacheShortNameOfInstitution (void);
|
||||
void Ins_GetShortNameOfInstitution (struct Instit *Ins);
|
||||
void Ins_FlushCacheFullNameAndCtyOfInstitution (void);
|
||||
|
||||
void Ins_FreeListInstitutions (void);
|
||||
void Ins_WriteSelectorOfInstitution (void);
|
||||
|
|
|
@ -285,8 +285,9 @@ bool Prf_ShowUserProfile (struct UsrData *UsrDat)
|
|||
Gbl.CurrentCrs.Crs.CrsCod > 0) // ...and a course is selected
|
||||
{
|
||||
/* Get user's role in current course */
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,UsrDat->UsrCod);
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
|
||||
Gbl.CurrentCrs.Crs.CrsCod);
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
|
||||
/* Get if user has accepted enrolment in current course */
|
||||
UsrDat->Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (UsrDat);
|
||||
|
|
|
@ -2139,7 +2139,7 @@ void Rec_ShowFormOtherNewSharedRecord (struct UsrData *UsrDat,Rol_Role_t Default
|
|||
Instead it is initialized with the preferred role. */
|
||||
UsrDat->Roles.InCurrentCrs.Role = (Gbl.CurrentCrs.Crs.CrsCod > 0) ? DefaultRole : // Course selected
|
||||
Rol_UNK; // No course selected
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
Rec_ShowSharedUsrRecord (Rec_SHA_OTHER_NEW_USR_FORM,UsrDat,NULL);
|
||||
}
|
||||
|
||||
|
|
49
swad_role.c
49
swad_role.c
|
@ -68,10 +68,10 @@ void Rol_SetMyRoles (void)
|
|||
bool ICanBeDegAdm = false;
|
||||
|
||||
/***** Get my role in current course if not yet filled *****/
|
||||
if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.UsrCod != Gbl.Usrs.Me.UsrDat.UsrCod)
|
||||
if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.GotFromDBForUsrCod != Gbl.Usrs.Me.UsrDat.UsrCod)
|
||||
{
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetMyRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod);
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetMyRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod);
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.GotFromDBForUsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
|
||||
}
|
||||
|
||||
/***** Set the user's role I am logged *****/
|
||||
|
@ -179,7 +179,7 @@ void Rol_SetMyRoles (void)
|
|||
if (!(Gbl.Usrs.Me.Role.Available & (1 << Gbl.Usrs.Me.Role.Logged))) // Current type I am logged is not available for me
|
||||
/* Set the lowest role available for me */
|
||||
for (Gbl.Usrs.Me.Role.Logged = Rol_UNK;
|
||||
Gbl.Usrs.Me.Role.Logged < Rol_NUM_ROLES;
|
||||
Gbl.Usrs.Me.Role.Logged <= (Rol_Role_t) (Rol_NUM_ROLES - 1);
|
||||
Gbl.Usrs.Me.Role.Logged++)
|
||||
if (Gbl.Usrs.Me.Role.Available & (1 << Gbl.Usrs.Me.Role.Logged))
|
||||
break;
|
||||
|
@ -326,50 +326,45 @@ Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod)
|
|||
/********************** Get role of a user in a course ***********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
Rol_Role_t Rol_GetRoleInCrs (long CrsCod,long UsrCod)
|
||||
void Rol_FlushCacheRoleUsrInCrs (void)
|
||||
{
|
||||
Gbl.Cache.RoleUsrInCrs.UsrCod = -1L;
|
||||
Gbl.Cache.RoleUsrInCrs.CrsCod = -1L;
|
||||
Gbl.Cache.RoleUsrInCrs.Role = Rol_UNK;
|
||||
}
|
||||
|
||||
Rol_Role_t Rol_GetRoleUsrInCrs (long UsrCod,long CrsCod)
|
||||
{
|
||||
char Query[256];
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
static struct
|
||||
{
|
||||
long CrsCod;
|
||||
long UsrCod;
|
||||
Rol_Role_t RoleInCrs;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
-1L,
|
||||
Rol_UNK,
|
||||
}; // A cache. If this function is called consecutive times
|
||||
// with the same user, only the first time is slow
|
||||
|
||||
/***** 1. Fast check: trivial cases *****/
|
||||
if (CrsCod <= 0 ||
|
||||
UsrCod <= 0)
|
||||
if (UsrCod <= 0 ||
|
||||
CrsCod <= 0)
|
||||
return Rol_UNK;
|
||||
|
||||
/***** 2. Fast check: Is role in course already calculated *****/
|
||||
if (CrsCod == Cached.CrsCod &&
|
||||
UsrCod == Cached.UsrCod)
|
||||
return Cached.RoleInCrs;
|
||||
if (UsrCod == Gbl.Cache.RoleUsrInCrs.UsrCod &&
|
||||
CrsCod == Gbl.Cache.RoleUsrInCrs.CrsCod )
|
||||
return Gbl.Cache.RoleUsrInCrs.Role;
|
||||
|
||||
/***** 3. Slow check: Get rol of a user in a course from database.
|
||||
The result of the query will have one row or none *****/
|
||||
Cached.UsrCod = UsrCod;
|
||||
Cached.CrsCod = CrsCod;
|
||||
Cached.RoleInCrs = Rol_UNK;
|
||||
Gbl.Cache.RoleUsrInCrs.UsrCod = UsrCod;
|
||||
Gbl.Cache.RoleUsrInCrs.CrsCod = CrsCod;
|
||||
Gbl.Cache.RoleUsrInCrs.Role = Rol_UNK;
|
||||
sprintf (Query,"SELECT Role FROM crs_usr"
|
||||
" WHERE CrsCod=%ld AND UsrCod=%ld",
|
||||
CrsCod,UsrCod);
|
||||
if (DB_QuerySELECT (Query,&mysql_res,"can not get the role of a user in a course") == 1) // User belongs to the course
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
Cached.RoleInCrs = Rol_ConvertUnsignedStrToRole (row[0]);
|
||||
Gbl.Cache.RoleUsrInCrs.Role = Rol_ConvertUnsignedStrToRole (row[0]);
|
||||
}
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
||||
return Cached.RoleInCrs;
|
||||
return Gbl.Cache.RoleUsrInCrs.Role;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -45,7 +45,8 @@ Rol_Role_t Rol_GetMyMaxRoleInIns (long InsCod);
|
|||
Rol_Role_t Rol_GetMyMaxRoleInCtr (long CtrCod);
|
||||
Rol_Role_t Rol_GetMyMaxRoleInDeg (long DegCod);
|
||||
Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod);
|
||||
Rol_Role_t Rol_GetRoleInCrs (long CrsCod,long UsrCod);
|
||||
void Rol_FlushCacheRoleUsrInCrs (void);
|
||||
Rol_Role_t Rol_GetRoleUsrInCrs (long UsrCod,long CrsCod);
|
||||
void Rol_GetRolesInAllCrssIfNotYetGot (struct UsrData *UsrDat);
|
||||
|
||||
Rol_Role_t Rol_ConvertUnsignedStrToRole (const char *UnsignedStr);
|
||||
|
|
408
swad_user.c
408
swad_user.c
|
@ -296,7 +296,7 @@ void Usr_ResetUsrDataExceptUsrCodAndIDs (struct UsrData *UsrDat)
|
|||
UsrDat->Nickname[0] = '\0';
|
||||
UsrDat->Password[0] = '\0';
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = -1L;
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = -1L;
|
||||
UsrDat->Roles.InCrss = -1; // < 0 ==> not yet got from database
|
||||
UsrDat->Accepted = true;
|
||||
|
||||
|
@ -520,9 +520,9 @@ void Usr_GetUsrDataFromUsrCod (struct UsrData *UsrDat)
|
|||
Pwd_BYTES_ENCRYPTED_PASSWORD);
|
||||
|
||||
/* Get roles */
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,
|
||||
UsrDat->UsrCod);
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
|
||||
Gbl.CurrentCrs.Crs.CrsCod);
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
|
||||
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat);
|
||||
|
||||
|
@ -801,37 +801,32 @@ bool Usr_CheckIfUsrIsAdm (long UsrCod,Sco_Scope_t Scope,long Cod)
|
|||
/********************* Check if a user is a superuser ************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Usr_FlushCacheUsrIsSuperuser (void)
|
||||
{
|
||||
Gbl.Cache.UsrIsSuperuser.UsrCod = -1L;
|
||||
Gbl.Cache.UsrIsSuperuser.IsSuperuser = false;
|
||||
}
|
||||
|
||||
bool Usr_CheckIfUsrIsSuperuser (long UsrCod)
|
||||
{
|
||||
extern const char *Sco_ScopeDB[Sco_NUM_SCOPES];
|
||||
char Query[256];
|
||||
static struct
|
||||
{
|
||||
long UsrCod;
|
||||
bool IsSuperuser;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
false
|
||||
};
|
||||
|
||||
/***** 1. Fast check: Trivial case *****/
|
||||
if (UsrCod <= 0)
|
||||
{
|
||||
/***** Trivial case *****/
|
||||
Cached.UsrCod = -1L;
|
||||
Cached.IsSuperuser = false;
|
||||
}
|
||||
else if (UsrCod != Cached.UsrCod) // If not cached...
|
||||
{
|
||||
/***** Get if a user is superuser from database *****/
|
||||
sprintf (Query,"SELECT COUNT(*) FROM admin"
|
||||
" WHERE UsrCod=%ld AND Scope='%s'",
|
||||
UsrCod,Sco_ScopeDB[Sco_SCOPE_SYS]);
|
||||
Cached.UsrCod = UsrCod;
|
||||
Cached.IsSuperuser = (DB_QueryCOUNT (Query,"can not check if a user is superuser") != 0);
|
||||
}
|
||||
return false;
|
||||
|
||||
return Cached.IsSuperuser;
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (UsrCod == Gbl.Cache.UsrIsSuperuser.UsrCod)
|
||||
return Gbl.Cache.UsrIsSuperuser.IsSuperuser;
|
||||
|
||||
/***** 3. Slow check: If not cached, get if a user is superuser from database *****/
|
||||
sprintf (Query,"SELECT COUNT(*) FROM admin"
|
||||
" WHERE UsrCod=%ld AND Scope='%s'",
|
||||
UsrCod,Sco_ScopeDB[Sco_SCOPE_SYS]);
|
||||
Gbl.Cache.UsrIsSuperuser.UsrCod = UsrCod;
|
||||
Gbl.Cache.UsrIsSuperuser.IsSuperuser = (DB_QueryCOUNT (Query,"can not check if a user is superuser") != 0);
|
||||
return Gbl.Cache.UsrIsSuperuser.IsSuperuser;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1168,19 +1163,15 @@ bool Usr_CheckIfICanViewUsrAgenda (struct UsrData *UsrDat)
|
|||
/*************** Check if a user belongs to any of my courses ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Usr_FlushCacheUsrSharesAnyOfMyCrs (void)
|
||||
{
|
||||
Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = -1L;
|
||||
Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = false;
|
||||
}
|
||||
|
||||
bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat)
|
||||
{
|
||||
char Query[256];
|
||||
static struct
|
||||
{
|
||||
long UsrCod;
|
||||
bool UsrSharesAnyOfMyCrs;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
false
|
||||
}; // A cache. If this function is called consecutive times
|
||||
// with the same user, only the first time is slow
|
||||
|
||||
/***** 1. Fast check: Am I logged? *****/
|
||||
if (!Gbl.Usrs.Me.Logged)
|
||||
|
@ -1195,8 +1186,8 @@ bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat)
|
|||
return true;
|
||||
|
||||
/***** 4. Fast check: Is already calculated if user shares any course with me? *****/
|
||||
if (UsrDat->UsrCod == Cached.UsrCod)
|
||||
return Cached.UsrSharesAnyOfMyCrs;
|
||||
if (UsrDat->UsrCod == Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod)
|
||||
return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs;
|
||||
|
||||
/***** 5. Fast check: Is course selected and we both belong to it? *****/
|
||||
if (Gbl.Usrs.Me.IBelongToCurrentCrs)
|
||||
|
@ -1219,9 +1210,9 @@ bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat)
|
|||
" WHERE UsrCod=%ld"
|
||||
" AND CrsCod IN (SELECT CrsCod FROM my_courses_tmp)",
|
||||
UsrDat->UsrCod);
|
||||
Cached.UsrSharesAnyOfMyCrs = DB_QueryCOUNT (Query,"can not check if a user shares any course with you") != 0;
|
||||
Cached.UsrCod = UsrDat->UsrCod;
|
||||
return Cached.UsrSharesAnyOfMyCrs;
|
||||
Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = DB_QueryCOUNT (Query,"can not check if a user shares any course with you") != 0;
|
||||
Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = UsrDat->UsrCod;
|
||||
return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1622,36 +1613,26 @@ static void Usr_RemoveTemporaryTableMyCourses (void)
|
|||
/**************** Check if a user belongs to an institution ******************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Usr_FlushCacheUsrBelongsToIns (void)
|
||||
{
|
||||
Gbl.Cache.UsrBelongsToIns.UsrCod = -1L;
|
||||
Gbl.Cache.UsrBelongsToIns.InsCod = -1L;
|
||||
Gbl.Cache.UsrBelongsToIns.Belongs = false;
|
||||
}
|
||||
|
||||
bool Usr_CheckIfUsrBelongsToIns (long UsrCod,long InsCod)
|
||||
{
|
||||
char Query[512];
|
||||
static struct
|
||||
{
|
||||
long UsrCod;
|
||||
long InsCod;
|
||||
bool Belongs;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
-1L,
|
||||
false
|
||||
};
|
||||
|
||||
/***** 1. Fast check: Trivial case *****/
|
||||
if (UsrCod <= 0 ||
|
||||
InsCod <= 0)
|
||||
{
|
||||
/***** Trivial case *****/
|
||||
Cached.UsrCod = -1L;
|
||||
Cached.InsCod = -1L;
|
||||
Cached.Belongs = false;
|
||||
return Cached.Belongs;
|
||||
}
|
||||
return false;
|
||||
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (UsrCod == Cached.UsrCod &&
|
||||
InsCod != Cached.InsCod)
|
||||
return Cached.Belongs;
|
||||
if (UsrCod == Gbl.Cache.UsrBelongsToIns.UsrCod &&
|
||||
InsCod != Gbl.Cache.UsrBelongsToIns.InsCod)
|
||||
return Gbl.Cache.UsrBelongsToIns.Belongs;
|
||||
|
||||
/***** 3. Slow check: Get is user belongs to institution from database *****/
|
||||
sprintf (Query,"SELECT COUNT(DISTINCT centres.InsCod)"
|
||||
|
@ -1663,45 +1644,36 @@ bool Usr_CheckIfUsrBelongsToIns (long UsrCod,long InsCod)
|
|||
" AND degrees.CtrCod=centres.CtrCod"
|
||||
" AND centres.InsCod=%ld",
|
||||
UsrCod,InsCod);
|
||||
Cached.UsrCod = UsrCod;
|
||||
Cached.InsCod = InsCod;
|
||||
Cached.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to an institution") != 0);
|
||||
return Cached.Belongs;
|
||||
Gbl.Cache.UsrBelongsToIns.UsrCod = UsrCod;
|
||||
Gbl.Cache.UsrBelongsToIns.InsCod = InsCod;
|
||||
Gbl.Cache.UsrBelongsToIns.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to an institution") != 0);
|
||||
return Gbl.Cache.UsrBelongsToIns.Belongs;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************* Check if a user belongs to a centre *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Usr_FlushCacheUsrBelongsToCtr (void)
|
||||
{
|
||||
Gbl.Cache.UsrBelongsToCtr.UsrCod = -1L;
|
||||
Gbl.Cache.UsrBelongsToCtr.CtrCod = -1L;
|
||||
Gbl.Cache.UsrBelongsToCtr.Belongs = false;
|
||||
}
|
||||
|
||||
bool Usr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod)
|
||||
{
|
||||
char Query[512];
|
||||
static struct
|
||||
{
|
||||
long UsrCod;
|
||||
long CtrCod;
|
||||
bool Belongs;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
-1L,
|
||||
false
|
||||
};
|
||||
|
||||
/***** 1. Fast check: Trivial case *****/
|
||||
if (UsrCod <= 0 ||
|
||||
CtrCod <= 0)
|
||||
{
|
||||
Cached.UsrCod = -1L;
|
||||
Cached.CtrCod = -1L;
|
||||
Cached.Belongs = false;
|
||||
return Cached.Belongs;
|
||||
}
|
||||
return false;
|
||||
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (UsrCod == Cached.UsrCod &&
|
||||
CtrCod == Cached.CtrCod)
|
||||
return Cached.Belongs;
|
||||
if (UsrCod == Gbl.Cache.UsrBelongsToCtr.UsrCod &&
|
||||
CtrCod == Gbl.Cache.UsrBelongsToCtr.CtrCod)
|
||||
return Gbl.Cache.UsrBelongsToCtr.Belongs;
|
||||
|
||||
/***** 3. Slow check: Get is user belongs to centre from database *****/
|
||||
sprintf (Query,"SELECT COUNT(DISTINCT degrees.CtrCod)"
|
||||
|
@ -1712,45 +1684,36 @@ bool Usr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod)
|
|||
" AND courses.DegCod=degrees.DegCod"
|
||||
" AND degrees.CtrCod=%ld",
|
||||
UsrCod,CtrCod);
|
||||
Cached.UsrCod = UsrCod;
|
||||
Cached.CtrCod = CtrCod;
|
||||
Cached.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a centre") != 0);
|
||||
return Cached.Belongs;
|
||||
Gbl.Cache.UsrBelongsToCtr.UsrCod = UsrCod;
|
||||
Gbl.Cache.UsrBelongsToCtr.CtrCod = CtrCod;
|
||||
Gbl.Cache.UsrBelongsToCtr.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a centre") != 0);
|
||||
return Gbl.Cache.UsrBelongsToCtr.Belongs;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************* Check if a user belongs to a degree *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Usr_FlushCacheUsrBelongsToDeg (void)
|
||||
{
|
||||
Gbl.Cache.UsrBelongsToDeg.UsrCod = -1L;
|
||||
Gbl.Cache.UsrBelongsToDeg.DegCod = -1L;
|
||||
Gbl.Cache.UsrBelongsToDeg.Belongs = false;
|
||||
}
|
||||
|
||||
bool Usr_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod)
|
||||
{
|
||||
char Query[512];
|
||||
static struct
|
||||
{
|
||||
long UsrCod;
|
||||
long DegCod;
|
||||
bool Belongs;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
-1L,
|
||||
false
|
||||
};
|
||||
|
||||
/***** 1. Fast check: Trivial case *****/
|
||||
if (UsrCod <= 0 ||
|
||||
DegCod <= 0)
|
||||
{
|
||||
Cached.UsrCod = -1L;
|
||||
Cached.DegCod = -1L;
|
||||
Cached.Belongs = false;
|
||||
return Cached.Belongs;
|
||||
}
|
||||
return false;
|
||||
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (UsrCod == Cached.UsrCod &&
|
||||
DegCod == Cached.DegCod)
|
||||
return Cached.Belongs;
|
||||
if (UsrCod == Gbl.Cache.UsrBelongsToDeg.UsrCod &&
|
||||
DegCod == Gbl.Cache.UsrBelongsToDeg.DegCod)
|
||||
return Gbl.Cache.UsrBelongsToDeg.Belongs;
|
||||
|
||||
/***** 3. Slow check: Get if user belongs to degree from database *****/
|
||||
sprintf (Query,"SELECT COUNT(DISTINCT courses.DegCod)"
|
||||
|
@ -1760,138 +1723,40 @@ bool Usr_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod)
|
|||
" AND crs_usr.CrsCod=courses.CrsCod"
|
||||
" AND courses.DegCod=%ld",
|
||||
UsrCod,DegCod);
|
||||
Cached.UsrCod = UsrCod;
|
||||
Cached.DegCod = DegCod;
|
||||
Cached.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a degree") != 0);
|
||||
return Cached.Belongs;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***** Check if user belongs (no matter if he/she has accepted or not) *******/
|
||||
/***** to the current course *******/
|
||||
/*****************************************************************************/
|
||||
|
||||
bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
long UsrCod;
|
||||
bool Belongs;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
false
|
||||
};
|
||||
|
||||
/***** 1. Fast check: trivial cases *****/
|
||||
if (UsrDat->UsrCod <= 0 ||
|
||||
Gbl.CurrentCrs.Crs.CrsCod <= 0)
|
||||
{
|
||||
Cached.UsrCod = -1L;
|
||||
Cached.Belongs = false;
|
||||
return Cached.Belongs;
|
||||
}
|
||||
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (UsrDat->UsrCod == Cached.UsrCod)
|
||||
return Cached.Belongs;
|
||||
|
||||
/***** 3. Fast check: If we know role of user in the current course *****/
|
||||
if (UsrDat->Roles.InCurrentCrs.UsrCod == UsrDat->UsrCod)
|
||||
{
|
||||
Cached.UsrCod = UsrDat->UsrCod;
|
||||
Cached.Belongs = UsrDat->Roles.InCurrentCrs.Role == Rol_STD ||
|
||||
UsrDat->Roles.InCurrentCrs.Role == Rol_NET ||
|
||||
UsrDat->Roles.InCurrentCrs.Role == Rol_TCH;
|
||||
return Cached.Belongs;
|
||||
}
|
||||
|
||||
/***** 4. Fast / slow check: Get if user belongs to current course *****/
|
||||
Cached.UsrCod = UsrDat->UsrCod;
|
||||
Cached.Belongs = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
|
||||
Gbl.CurrentCrs.Crs.CrsCod,
|
||||
false);
|
||||
return Cached.Belongs;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***** Check if user belongs (no matter if he/she has accepted or not) *******/
|
||||
/***** to the current course *******/
|
||||
/*****************************************************************************/
|
||||
|
||||
bool Usr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
long UsrCod;
|
||||
bool Accepted;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
false
|
||||
};
|
||||
|
||||
/***** 1. Fast check: trivial cases *****/
|
||||
if (UsrDat->UsrCod <= 0 ||
|
||||
Gbl.CurrentCrs.Crs.CrsCod <= 0)
|
||||
{
|
||||
Cached.UsrCod = -1L;
|
||||
Cached.Accepted = false;
|
||||
return Cached.Accepted;
|
||||
}
|
||||
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (UsrDat->UsrCod == Cached.UsrCod)
|
||||
return Cached.Accepted;
|
||||
|
||||
/***** 3. Fast / slow check: Get if user belongs to current course
|
||||
and has accepted *****/
|
||||
Cached.UsrCod = UsrDat->UsrCod;
|
||||
Cached.Accepted = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
|
||||
Gbl.CurrentCrs.Crs.CrsCod,
|
||||
true);
|
||||
return Cached.Accepted;
|
||||
Gbl.Cache.UsrBelongsToDeg.UsrCod = UsrCod;
|
||||
Gbl.Cache.UsrBelongsToDeg.DegCod = DegCod;
|
||||
Gbl.Cache.UsrBelongsToDeg.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a degree") != 0);
|
||||
return Gbl.Cache.UsrBelongsToDeg.Belongs;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Check if a user belongs to a course ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Usr_FlushCacheUsrBelongsToCrs (void)
|
||||
{
|
||||
Gbl.Cache.UsrBelongsToCrs.UsrCod = -1L;
|
||||
Gbl.Cache.UsrBelongsToCrs.CrsCod = -1L;
|
||||
Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses = false;
|
||||
Gbl.Cache.UsrBelongsToCrs.Belongs = false;
|
||||
}
|
||||
|
||||
bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod,
|
||||
bool CountOnlyAcceptedCourses)
|
||||
{
|
||||
char Query[512];
|
||||
const char *SubQuery;
|
||||
static struct
|
||||
{
|
||||
long UsrCod;
|
||||
long CrsCod;
|
||||
bool CountOnlyAcceptedCourses;
|
||||
bool Belongs;
|
||||
} Cached =
|
||||
{
|
||||
-1L,
|
||||
-1L,
|
||||
false,
|
||||
false
|
||||
};
|
||||
|
||||
/***** 1. Fast check: trivial cases *****/
|
||||
/***** 1. Fast check: Trivial cases *****/
|
||||
if (UsrCod <= 0 ||
|
||||
CrsCod <= 0)
|
||||
{
|
||||
Cached.UsrCod = -1L;
|
||||
Cached.CrsCod = -1L;
|
||||
Cached.CountOnlyAcceptedCourses = CountOnlyAcceptedCourses;
|
||||
Cached.Belongs = false;
|
||||
return Cached.Belongs;
|
||||
}
|
||||
return false;
|
||||
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (UsrCod == Cached.UsrCod &&
|
||||
CrsCod == Cached.CrsCod &&
|
||||
CountOnlyAcceptedCourses == Cached.CountOnlyAcceptedCourses)
|
||||
return Cached.Belongs;
|
||||
if (UsrCod == Gbl.Cache.UsrBelongsToCrs.UsrCod &&
|
||||
CrsCod == Gbl.Cache.UsrBelongsToCrs.CrsCod &&
|
||||
CountOnlyAcceptedCourses == Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses)
|
||||
return Gbl.Cache.UsrBelongsToCrs.Belongs;
|
||||
|
||||
/***** 3. Slow check: Get if user belongs to course from database *****/
|
||||
SubQuery = (CountOnlyAcceptedCourses ? " AND crs_usr.Accepted='Y'" :
|
||||
|
@ -1899,11 +1764,82 @@ bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod,
|
|||
sprintf (Query,"SELECT COUNT(*) FROM crs_usr"
|
||||
" WHERE CrsCod=%ld AND UsrCod=%ld%s",
|
||||
CrsCod,UsrCod,SubQuery);
|
||||
Cached.UsrCod = UsrCod;
|
||||
Cached.CrsCod = CrsCod;
|
||||
Cached.CountOnlyAcceptedCourses = CountOnlyAcceptedCourses;
|
||||
Cached.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a course") != 0);
|
||||
return Cached.Belongs;
|
||||
Gbl.Cache.UsrBelongsToCrs.UsrCod = UsrCod;
|
||||
Gbl.Cache.UsrBelongsToCrs.CrsCod = CrsCod;
|
||||
Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses = CountOnlyAcceptedCourses;
|
||||
Gbl.Cache.UsrBelongsToCrs.Belongs = (DB_QueryCOUNT (Query,"can not check if a user belongs to a course") != 0);
|
||||
return Gbl.Cache.UsrBelongsToCrs.Belongs;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***** Check if user belongs (no matter if he/she has accepted or not) *******/
|
||||
/***** to the current course *******/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Usr_FlushCacheUsrBelongsToCurrentCrs (void)
|
||||
{
|
||||
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = -1L;
|
||||
Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = false;
|
||||
}
|
||||
|
||||
bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat)
|
||||
{
|
||||
/***** 1. Fast check: Trivial cases *****/
|
||||
if (UsrDat->UsrCod <= 0 ||
|
||||
Gbl.CurrentCrs.Crs.CrsCod <= 0)
|
||||
return false;
|
||||
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (UsrDat->UsrCod == Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod)
|
||||
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
|
||||
|
||||
/***** 3. Fast check: If we know role of user in the current course *****/
|
||||
if (UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod == UsrDat->UsrCod)
|
||||
{
|
||||
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = UsrDat->Roles.InCurrentCrs.Role == Rol_STD ||
|
||||
UsrDat->Roles.InCurrentCrs.Role == Rol_NET ||
|
||||
UsrDat->Roles.InCurrentCrs.Role == Rol_TCH;
|
||||
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
|
||||
}
|
||||
|
||||
/***** 4. Fast / slow check: Get if user belongs to current course *****/
|
||||
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
|
||||
Gbl.CurrentCrs.Crs.CrsCod,
|
||||
false);
|
||||
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***** Check if user belongs (no matter if he/she has accepted or not) *******/
|
||||
/***** to the current course *******/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Usr_FlushCacheUsrHasAcceptedInCurrentCrs (void)
|
||||
{
|
||||
Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod = -1L;
|
||||
Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted = false;
|
||||
}
|
||||
|
||||
bool Usr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat)
|
||||
{
|
||||
/***** 1. Fast check: Trivial cases *****/
|
||||
if (UsrDat->UsrCod <= 0 ||
|
||||
Gbl.CurrentCrs.Crs.CrsCod <= 0)
|
||||
return false;
|
||||
|
||||
/***** 2. Fast check: If cached... *****/
|
||||
if (UsrDat->UsrCod == Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod)
|
||||
return Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted;
|
||||
|
||||
/***** 3. Fast / slow check: Get if user belongs to current course
|
||||
and has accepted *****/
|
||||
Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
|
||||
Gbl.CurrentCrs.Crs.CrsCod,
|
||||
true);
|
||||
return Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -3111,9 +3047,9 @@ static void Usr_SetMyPrefsAndRoles (void)
|
|||
Hie_InitHierarchy ();
|
||||
|
||||
/* Get again my role in this course */
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role = Rol_GetRoleUsrInCrs (Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||
Gbl.CurrentCrs.Crs.CrsCod);
|
||||
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.GotFromDBForUsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
10
swad_user.h
10
swad_user.h
|
@ -133,7 +133,7 @@ struct UsrData
|
|||
{
|
||||
struct
|
||||
{
|
||||
long UsrCod; // Role was got from database for this user (used to not retrieve role if already retrieved)
|
||||
long GotFromDBForUsrCod; // Role was got from database for this user (used to not retrieve role if already retrieved)
|
||||
Rol_Role_t Role;
|
||||
} InCurrentCrs; // Role in current course (Rol_UNK is no course selected)
|
||||
int InCrss; // Roles in all his/her courses
|
||||
|
@ -244,6 +244,7 @@ void Usr_BuildFullName (struct UsrData *UsrDat);
|
|||
void Usr_WriteFirstNameBRSurnames (const struct UsrData *UsrDat);
|
||||
|
||||
bool Usr_CheckIfUsrIsAdm (long UsrCod,Sco_Scope_t Scope,long Cod);
|
||||
void Usr_FlushCacheUsrIsSuperuser (void);
|
||||
bool Usr_CheckIfUsrIsSuperuser (long UsrCod);
|
||||
|
||||
bool Usr_ICanChangeOtherUsrData (const struct UsrData *UsrDat);
|
||||
|
@ -257,12 +258,15 @@ unsigned Usr_GetNumCrssOfUsrWithARoleNotAccepted (long UsrCod,Rol_Role_t Role);
|
|||
unsigned Usr_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole,
|
||||
Rol_Role_t OthersRole);
|
||||
|
||||
void Usr_FlushCacheUsrBelongsToCurrentCrs (void);
|
||||
bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat);
|
||||
void Usr_FlushCacheUsrHasAcceptedInCurrentCrs (void);
|
||||
bool Usr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat);
|
||||
bool Usr_CheckIfICanViewRecordStd (const struct UsrData *UsrDat);
|
||||
bool Usr_CheckIfICanViewRecordTch (struct UsrData *UsrDat);
|
||||
bool Usr_CheckIfICanViewWrkTstAtt (const struct UsrData *UsrDat);
|
||||
bool Usr_CheckIfICanViewUsrAgenda (struct UsrData *UsrDat);
|
||||
void Usr_FlushCacheUsrSharesAnyOfMyCrs (void);
|
||||
bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat);
|
||||
bool Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod);
|
||||
|
||||
|
@ -278,9 +282,13 @@ void Usr_FreeMyCentres (void);
|
|||
void Usr_FreeMyDegrees (void);
|
||||
void Usr_FreeMyCourses (void);
|
||||
|
||||
void Usr_FlushCacheUsrBelongsToIns (void);
|
||||
bool Usr_CheckIfUsrBelongsToIns (long UsrCod,long InsCod);
|
||||
void Usr_FlushCacheUsrBelongsToCtr (void);
|
||||
bool Usr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod);
|
||||
void Usr_FlushCacheUsrBelongsToDeg (void);
|
||||
bool Usr_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod);
|
||||
void Usr_FlushCacheUsrBelongsToCrs (void);
|
||||
bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod,
|
||||
bool CountOnlyAcceptedCourses);
|
||||
|
||||
|
|
|
@ -594,18 +594,18 @@ static bool Svc_GetSomeUsrDataFromUsrCod (struct UsrData *UsrDat,long CrsCod)
|
|||
{
|
||||
if (sscanf (row[0],"%u",&UsrDat->Roles.InCurrentCrs.Role) != 1)
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
}
|
||||
else // Impossible
|
||||
{
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
}
|
||||
}
|
||||
else // User does not belong to course
|
||||
{
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -621,19 +621,19 @@ static bool Svc_GetSomeUsrDataFromUsrCod (struct UsrData *UsrDat,long CrsCod)
|
|||
{
|
||||
if (sscanf (row[0],"%u",&UsrDat->Roles.InCurrentCrs.Role) != 1)
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
}
|
||||
else
|
||||
// MAX(Role) == NULL if user does not belong to any course
|
||||
{
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
}
|
||||
}
|
||||
else // Impossible
|
||||
{
|
||||
UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
|
||||
UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||
UsrDat->Roles.InCurrentCrs.GotFromDBForUsrCod = UsrDat->UsrCod;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue