diff --git a/sql/cambios.sql b/sql/cambios.sql
index 37c0b272..e60471f6 100644
--- a/sql/cambios.sql
+++ b/sql/cambios.sql
@@ -11941,5 +11941,4 @@ CALL update_log_full();
-
-
+SELECT COUNT(*) FROM crs_grp_usr WHERE UsrCod=1 AND GrpCod IN (SELECT crs_grp_usr.GrpCod FROM crs_grp_usr,crs_grp,crs_grp_types WHERE crs_grp_usr.UsrCod=7 AND crs_grp_usr.GrpCod=crs_grp.GrpCod AND crs_grp.GrpTypCod=crs_grp_types.GrpTypCod AND crs_grp_types.CrsCod=19);
diff --git a/swad_ID.c b/swad_ID.c
index 3def9c2e..9b33eace 100644
--- a/swad_ID.c
+++ b/swad_ID.c
@@ -413,7 +413,7 @@ bool ID_ICanSeeOtherUsrIDs (const struct UsrData *UsrDat)
return true;
/* Check 2: I can see the IDs of confirmed students */
- if (UsrDat->Role.InCurrentCrs == Rol_STD && // A student
+ if (UsrDat->Roles.InCurrentCrs.Role == Rol_STD && // A student
UsrDat->Accepted) // who accepted registration
return true;
@@ -452,7 +452,7 @@ static void ID_PutLinkToConfirmID (struct UsrData *UsrDat,unsigned NumID,
Act_Action_t NextAction;
/***** Start form *****/
- switch (UsrDat->Role.InCurrentCrs)
+ switch (UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActCnfID_Std;
@@ -512,7 +512,7 @@ void ID_PutLinkToChangeUsrIDs (void)
NULL);
else // Not me
{
- switch (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActFrmIDsStd;
@@ -614,7 +614,7 @@ void ID_ShowFormChangeUsrID (const struct UsrData *UsrDat,bool ItsMe)
Act_FormStart (ActRemID_Me);
else
{
- switch (UsrDat->Role.InCurrentCrs)
+ switch (UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActRemID_Std;
@@ -679,7 +679,7 @@ void ID_ShowFormChangeUsrID (const struct UsrData *UsrDat,bool ItsMe)
Act_FormStart (ActNewIDMe);
else
{
- switch (UsrDat->Role.InCurrentCrs)
+ switch (UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActNewID_Std;
diff --git a/swad_action.c b/swad_action.c
index a2da377e..20b2aeb5 100644
--- a/swad_action.c
+++ b/swad_action.c
@@ -5101,7 +5101,7 @@ void Act_AdjustCurrentAction (void)
/***** Check if I am a teacher *****/
Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat);
- IAmATeacher = (Gbl.Usrs.Me.UsrDat.Role.InCrss & ((1 << Rol_NET) | // I am a non-editing teacher...
+ IAmATeacher = (Gbl.Usrs.Me.UsrDat.Roles.InCrss & ((1 << Rol_NET) | // I am a non-editing teacher...
(1 << Rol_TCH))); // ...or a teacher in any course
/***** If I haven't filled my institution,
@@ -5144,7 +5144,7 @@ void Act_AdjustCurrentAction (void)
the only action possible is show a form to ask for enrolment *****/
if (!Gbl.Usrs.Me.UsrDat.Accepted && Gbl.Action.Act != ActLogOut)
{
- switch (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
Gbl.Action.Act = ActReqAccEnrStd;
diff --git a/swad_announcement.c b/swad_announcement.c
index 07bb1455..5a5520ce 100644
--- a/swad_announcement.c
+++ b/swad_announcement.c
@@ -106,7 +106,7 @@ void Ann_ShowAllAnnouncements (void)
" FROM announcements"
" WHERE (Roles&%u)<>0 "
" ORDER BY AnnCod DESC",
- (unsigned) Gbl.Usrs.Me.UsrDat.Role.InCrss); // All my roles in different courses
+ (unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss); // All my roles in different courses
}
else // No user logged
/* Select only active announcements for unknown users */
@@ -223,7 +223,7 @@ void Ann_ShowMyAnnouncementsNotMarkedAsSeen (void)
" (SELECT AnnCod FROM ann_seen WHERE UsrCod=%ld)"
" ORDER BY AnnCod DESC", // Newest first
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
- (unsigned) Gbl.Usrs.Me.UsrDat.Role.InCrss, // All my roles in different courses
+ (unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss, // All my roles in different courses
Gbl.Usrs.Me.UsrDat.UsrCod);
NumAnnouncements = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get announcements");
diff --git a/swad_changelog.h b/swad_changelog.h
index 79fd7b30..17829816 100644
--- a/swad_changelog.h
+++ b/swad_changelog.h
@@ -242,13 +242,15 @@
/****************************** Public constants *****************************/
/*****************************************************************************/
-#define Log_PLATFORM_VERSION "SWAD 16.235.3 (2017-06-04)"
+#define Log_PLATFORM_VERSION "SWAD 16.236 (2017-06-08)"
#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.236: Jun 08, 2017 Changes in permissions related to record card contextual commands.
+ Code refactoring related to roles. (221306 lines)
Version 16.235.3: Jun 04, 2017 Non-editing teachers can not select/unselect groups to which they don't belong. (221107 lines)
Version 16.235.2: Jun 04, 2017 Non-editing teachers can access and edit works of students. (221032 lines)
Version 16.235.1: Jun 04, 2017 Limited length of connected users at right column. (221027 lines)
diff --git a/swad_enrolment.c b/swad_enrolment.c
index 2b2d737b..1f7e24d9 100644
--- a/swad_enrolment.c
+++ b/swad_enrolment.c
@@ -228,8 +228,9 @@ void Enr_ModifyRoleInCurrentCrs (struct UsrData *UsrDat,Rol_Role_t NewRole)
activate the sending of a notification *****/
Enr_NotifyAfterEnrolment (UsrDat,NewRole);
- UsrDat->Role.InCurrentCrs = NewRole;
- UsrDat->Role.InCrss = -1; // Force roles to be got from database
+ UsrDat->Roles.InCurrentCrs.Role = NewRole;
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
+ UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get roles
}
@@ -276,8 +277,9 @@ void Enr_RegisterUsrInCurrentCrs (struct UsrData *UsrDat,Rol_Role_t NewRole,
Usr_LIST_WITH_PHOTOS_DEF ? 'Y' :
'N');
DB_QueryINSERT (Query,"can not register user in course");
- UsrDat->Role.InCurrentCrs = NewRole;
- UsrDat->Role.InCrss = -1; // Force roles to be got from database
+ UsrDat->Roles.InCurrentCrs.Role = NewRole;
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
+ UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get roles
/***** Create notification for this user.
@@ -379,12 +381,12 @@ void Enr_ReqAcceptRegisterInCrs (void)
/***** Show message *****/
sprintf (Gbl.Alert.Txt,Txt_A_teacher_or_administrator_has_enroled_you_as_X_into_the_course_Y,
- Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs][Gbl.Usrs.Me.UsrDat.Sex],
+ Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role][Gbl.Usrs.Me.UsrDat.Sex],
Gbl.CurrentCrs.Crs.FullName);
Ale_ShowAlert (Ale_INFO,Gbl.Alert.Txt);
/***** Send button to accept register in the current course *****/
- switch (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
Act_FormStart (ActAccEnrStd);
@@ -402,7 +404,7 @@ void Enr_ReqAcceptRegisterInCrs (void)
Act_FormEnd ();
/***** Send button to refuse register in the current course *****/
- switch (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
Act_FormStart (ActRemMe_Std);
@@ -423,7 +425,7 @@ void Enr_ReqAcceptRegisterInCrs (void)
Lay_EndRoundFrame ();
/***** Mark possible notification as seen *****/
- switch (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
NotifyEvent = Ntf_EVENT_ENROLMENT_STD;
@@ -1808,7 +1810,7 @@ static void Enr_RegisterUsr (struct UsrData *UsrDat,Rol_Role_t RegRemRole,
Gbl.CurrentCrs.Crs.CrsCod,
false)) // User does belong to current course
{
- if (RegRemRole != UsrDat->Role.InCurrentCrs) // The role must be updated
+ if (RegRemRole != UsrDat->Roles.InCurrentCrs.Role) // The role must be updated
/* Modify role */
Enr_ModifyRoleInCurrentCrs (UsrDat,RegRemRole);
}
@@ -1945,10 +1947,10 @@ void Enr_ReqSignUpInCrs (void)
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
/***** Check if I already belong to course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs >= Rol_STD)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role >= Rol_STD)
{
sprintf (Gbl.Alert.Txt,Txt_You_were_already_enroled_as_X_in_the_course_Y,
- Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs][Gbl.Usrs.Me.UsrDat.Sex],
+ Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role][Gbl.Usrs.Me.UsrDat.Sex],
Gbl.CurrentCrs.Crs.FullName);
Ale_ShowAlert (Ale_WARNING,Gbl.Alert.Txt);
}
@@ -1976,10 +1978,10 @@ void Enr_SignUpInCrs (void)
long ReqCod = -1L;
/***** Check if I already belong to course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs >= Rol_STD)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role >= Rol_STD)
{
sprintf (Gbl.Alert.Txt,Txt_You_were_already_enroled_as_X_in_the_course_Y,
- Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs][Gbl.Usrs.Me.UsrDat.Sex],
+ Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role][Gbl.Usrs.Me.UsrDat.Sex],
Gbl.CurrentCrs.Crs.FullName);
Ale_ShowAlert (Ale_WARNING,Gbl.Alert.Txt);
}
@@ -3770,7 +3772,7 @@ void Enr_CreateNewUsr1 (void)
Gbl.CurrentCrs.Crs.CrsCod,
false)) // User does belong to current course
{
- OldRole = Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs; // Remember old role before changing it
+ OldRole = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role; // Remember old role before changing it
if (NewRole != OldRole) // The role must be updated
{
/* Modify role */
@@ -3895,7 +3897,7 @@ void Enr_ModifyUsr1 (void)
Gbl.CurrentCrs.Crs.CrsCod,
false)) // User does belong to current course
{
- OldRole = Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs; // Remember old role before changing it
+ OldRole = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role; // Remember old role before changing it
if (NewRole != OldRole) // The role must be updated
{
/* Modify role */
@@ -3933,8 +3935,9 @@ void Enr_ModifyUsr1 (void)
/***** If it's me, change my roles *****/
if (ItsMe)
{
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs = Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs;
- Gbl.Usrs.Me.UsrDat.Role.InCrss = Gbl.Usrs.Other.UsrDat.Role.InCrss;
+ 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.InCrss = Gbl.Usrs.Other.UsrDat.Roles.InCrss;
Rol_SetMyRoles ();
}
@@ -4107,7 +4110,7 @@ static void Enr_AskIfRemoveUsrFromCrs (struct UsrData *UsrDat)
Rec_ShowSharedRecordUnmodifiable (UsrDat);
/* Show form to request confirmation */
- switch (UsrDat->Role.InCurrentCrs)
+ switch (UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActRemStdCrs;
@@ -4189,8 +4192,9 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat,struct Course *
ItsMe = (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod);
if (ItsMe)
{
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs = UsrDat->Role.InCurrentCrs = Rol_UNK;
- Gbl.Usrs.Me.UsrDat.Role.InCrss = UsrDat->Role.InCrss = -1; // not yet filled/calculated
+ 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
Rol_SetMyRoles ();
}
diff --git a/swad_file_browser.c b/swad_file_browser.c
index a7776a91..865bbfd3 100644
--- a/swad_file_browser.c
+++ b/swad_file_browser.c
@@ -3431,7 +3431,7 @@ static void Brw_ShowDataOwnerAsgWrk (struct UsrData *UsrDat)
fprintf (Gbl.F.Out,"
Role.InCurrentCrs)
+ switch (UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActSeeRecOneStd;
diff --git a/swad_forum.c b/swad_forum.c
index 074e6b13..452e3f8a 100644
--- a/swad_forum.c
+++ b/swad_forum.c
@@ -1823,7 +1823,7 @@ static void For_WriteLinksToGblForums (bool IsLastItemInLevel[1 + For_FORUM_MAX_
/***** Can I see teachers's forums? *****/
Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat);
ICanSeeTeacherForum = Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
- (Gbl.Usrs.Me.UsrDat.Role.InCrss & ((1 << Rol_NET) |
+ (Gbl.Usrs.Me.UsrDat.Roles.InCrss & ((1 << Rol_NET) |
(1 << Rol_TCH)));
/***** Link to forum global *****/
@@ -1859,7 +1859,7 @@ static void For_WriteLinksToPlatformForums (bool IsLastForum,
/***** Can I see teachers's forums? *****/
Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat);
ICanSeeTeacherForum = Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
- (Gbl.Usrs.Me.UsrDat.Role.InCrss & ((1 << Rol_NET) |
+ (Gbl.Usrs.Me.UsrDat.Roles.InCrss & ((1 << Rol_NET) |
(1 << Rol_TCH)));
/***** Link to forum of users about the platform *****/
@@ -3775,7 +3775,7 @@ static void For_RestrictAccess (void)
case For_FORUM_GLOBAL_TCHS:
case For_FORUM__SWAD__TCHS:
Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat);
- ICanSeeForum = (Gbl.Usrs.Me.UsrDat.Role.InCrss & ((1 << Rol_NET) |
+ ICanSeeForum = (Gbl.Usrs.Me.UsrDat.Roles.InCrss & ((1 << Rol_NET) |
(1 << Rol_TCH)));
break;
case For_FORUM_INSTIT_USRS:
diff --git a/swad_group.c b/swad_group.c
index d77b81a2..9b481aa3 100644
--- a/swad_group.c
+++ b/swad_group.c
@@ -713,7 +713,7 @@ void Grp_ChangeOtherUsrGrps (void)
/***** A student can not be enroled in more than one group
if the type of group is of single enrolment *****/
- if (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs == Rol_STD &&
+ if (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role == Rol_STD &&
LstGrpsUsrWants.NumGrps >= 2)
SelectionIsValid = Grp_CheckIfSelectionGrpsIsValid (&LstGrpsUsrWants);
@@ -896,7 +896,7 @@ void Grp_ChangeGrpsOtherUsrAtomically (struct ListCodGrps *LstGrpsUsrWants)
bool RemoveUsrFromThisGrp;
bool RegisterUsrInThisGrp;
- if (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs == Rol_STD)
+ if (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role == Rol_STD)
{
/***** Lock tables to make the inscription atomic *****/
DB_Query ("LOCK TABLES crs_grp_types WRITE,crs_grp WRITE,"
@@ -944,7 +944,7 @@ void Grp_ChangeGrpsOtherUsrAtomically (struct ListCodGrps *LstGrpsUsrWants)
Grp_FreeListCodGrp (&LstGrpsUsrBelongs);
/***** Unlock tables after changes in my groups *****/
- if (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs == Rol_STD)
+ if (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role == Rol_STD)
{
Gbl.DB.LockedTables = false; // Set to false before the following unlock...
// ...to not retry the unlock if error in unlocking
@@ -4681,3 +4681,71 @@ 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[256];
+ 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 */
+ 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;
+ Cached.UsrCod = UsrDat->UsrCod;
+ return Cached.UsrSharesAnyOfMyGrpsInCurrentCrs;
+ }
diff --git a/swad_group.h b/swad_group.h
index 84860718..41c472c4 100644
--- a/swad_group.h
+++ b/swad_group.h
@@ -199,4 +199,6 @@ 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
diff --git a/swad_help.c b/swad_help.c
index a3c2be4f..6546b4e0 100644
--- a/swad_help.c
+++ b/swad_help.c
@@ -140,13 +140,13 @@ void Hlp_ShowHelpWhatWouldYouLikeToDo (void)
if (Gbl.Action.Act != ActLogIn &&
Gbl.Action.Act != ActLogInNew &&
Gbl.Action.Act != ActLogInLan) // I am not just logged
- if (ActionsRemoveMe[Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs] != ActUnk)
+ if (ActionsRemoveMe[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role] != ActUnk)
{
/* Request my removing from this course */
sprintf (Gbl.Title,Txt_Remove_me_from_the_course_X,
Gbl.CurrentCrs.Crs.ShrtName);
Hlp_ShowRowHelpWhatWouldYouLikeToDo (Gbl.Title,
- ActionsRemoveMe[Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs],
+ ActionsRemoveMe[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role],
Lay_REMOVE_BUTTON,Txt_Remove_me);
}
}
@@ -165,7 +165,7 @@ void Hlp_ShowHelpWhatWouldYouLikeToDo (void)
{
if (Gbl.CurrentCrs.Crs.CrsCod > 0 && // Course selected
!Gbl.CurrentCrs.Crs.NumUsrs[Rol_STD] && // Current course has no students
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs == Rol_TCH) // I am a teacher in current course
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role == Rol_TCH) // I am a teacher in current course
{
/* Request students enrolment */
sprintf (Gbl.Title,Txt_Register_students_in_the_course_X,
diff --git a/swad_mail.c b/swad_mail.c
index 84edaa1d..88c25430 100644
--- a/swad_mail.c
+++ b/swad_mail.c
@@ -1144,7 +1144,7 @@ void Mai_PutLinkToChangeOtherUsrEmails (void)
NULL);
else // Not me
{
- switch (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActFrmMaiStd;
@@ -1270,7 +1270,7 @@ void Mai_ShowFormChangeUsrEmail (const struct UsrData *UsrDat,bool ItsMe)
Act_FormStart (ActRemMaiMe);
else
{
- switch (UsrDat->Role.InCurrentCrs)
+ switch (UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActRemMaiStd;
@@ -1317,7 +1317,7 @@ void Mai_ShowFormChangeUsrEmail (const struct UsrData *UsrDat,bool ItsMe)
Act_FormStart (ActNewMaiMe);
else
{
- switch (UsrDat->Role.InCurrentCrs)
+ switch (UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActNewMaiStd;
@@ -1358,7 +1358,7 @@ void Mai_ShowFormChangeUsrEmail (const struct UsrData *UsrDat,bool ItsMe)
Act_FormStart (ActNewMaiMe);
else
{
- switch (UsrDat->Role.InCurrentCrs)
+ switch (UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActNewMaiStd;
@@ -1889,17 +1889,15 @@ bool Mai_ICanSeeOtherUsrEmail (const struct UsrData *UsrDat)
case Rol_STD:
/* If I am a student in the current course,
I can see the email of confirmed teachers */
- return (UsrDat->Role.InCurrentCrs == Rol_NET || // A non-editing teacher
- UsrDat->Role.InCurrentCrs == Rol_TCH) && // or a teacher
+ return (UsrDat->Roles.InCurrentCrs.Role == Rol_NET || // A non-editing teacher
+ UsrDat->Roles.InCurrentCrs.Role == Rol_TCH) && // or a teacher
UsrDat->Accepted; // who accepted registration
case Rol_NET:
case Rol_TCH:
/* If I am a teacher in the current course,
I can see the email of confirmed students and teachers */
- return (UsrDat->Role.InCurrentCrs == Rol_STD || // A student
- UsrDat->Role.InCurrentCrs == Rol_NET || // or a non-editing teacher
- UsrDat->Role.InCurrentCrs == Rol_TCH) && // or a teacher
- UsrDat->Accepted; // who accepted registration
+ return Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat) && // A user belonging to the current course
+ UsrDat->Accepted; // who accepted registration
case Rol_DEG_ADM:
/* If I am an administrator of current degree,
I only can see the user's email of users from current degree */
diff --git a/swad_password.c b/swad_password.c
index f9da6a67..28564c2d 100644
--- a/swad_password.c
+++ b/swad_password.c
@@ -829,7 +829,7 @@ void Pwd_ShowFormOthPwd (void)
/***** Form to change password *****/
/* Start form */
- switch (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActChgPwdStd;
@@ -893,7 +893,7 @@ void Pwd_PutLinkToChangeOtherUsrPassword (void)
Pwd_PutLinkToChangeMyPassword ();
else // Not me
{
- switch (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActFrmPwdStd;
diff --git a/swad_photo.c b/swad_photo.c
index 3e9def6e..2586247c 100644
--- a/swad_photo.c
+++ b/swad_photo.c
@@ -141,8 +141,8 @@ bool Pho_ICanChangeOtherUsrPhoto (const struct UsrData *UsrDat)
{
case Rol_TCH:
/* A teacher can change the photo of confirmed students */
- if (UsrDat->Role.InCurrentCrs == Rol_STD && // A student
- UsrDat->Accepted) // who accepted registration
+ if (UsrDat->Roles.InCurrentCrs.Role == Rol_STD && // A student
+ UsrDat->Accepted) // who accepted registration
return true;
return false;
@@ -196,7 +196,7 @@ void Pho_PutLinkToChangeOtherUsrPhoto (void)
PhotoExists = Pho_BuildLinkToPhoto (&Gbl.Usrs.Other.UsrDat,PhotoURL);
TitleText = PhotoExists ? Txt_Change_photo :
Txt_Upload_photo;
- switch (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActReqStdPho;
@@ -248,7 +248,7 @@ static void Pho_PutIconToRequestRemoveOtherUsrPhoto (void)
PhotoExists = Pho_BuildLinkToPhoto (&Gbl.Usrs.Other.UsrDat,PhotoURL);
if (PhotoExists)
{
- switch (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActReqRemStdPho;
@@ -334,7 +334,7 @@ static void Pho_ReqPhoto (const struct UsrData *UsrDat,const char *PhotoURL)
Act_FormStart (ActDetMyPho);
else
{
- switch (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActDetStdPho;
@@ -524,7 +524,7 @@ void Pho_ReqRemoveUsrPhoto (void)
"PHOTO186x248",Pho_NO_ZOOM,false);
/* End alert */
- switch (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActRemStdPho;
@@ -706,7 +706,7 @@ static bool Pho_ReceivePhotoAndDetectFaces (bool ItsMe,const struct UsrData *Usr
Act_FormStart (ActUpdMyPho);
else
{
- switch (Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs)
+ switch (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActUpdStdPho;
diff --git a/swad_profile.c b/swad_profile.c
index 33c89f0a..f96ec984 100644
--- a/swad_profile.c
+++ b/swad_profile.c
@@ -283,7 +283,8 @@ bool Prf_ShowUserProfile (struct UsrData *UsrDat)
Gbl.CurrentCrs.Crs.CrsCod > 0) // ...and a course is selected
{
/* Get user's role in current course */
- UsrDat->Role.InCurrentCrs = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,UsrDat->UsrCod);
+ UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,UsrDat->UsrCod);
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
/* Get if user has accepted enrolment in current course */
UsrDat->Accepted = Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,
diff --git a/swad_record.c b/swad_record.c
index 558e165f..4628e930 100644
--- a/swad_record.c
+++ b/swad_record.c
@@ -2139,8 +2139,9 @@ void Rec_ShowFormOtherNewSharedRecord (struct UsrData *UsrDat,Rol_Role_t Default
/* In this case UsrDat->Roles.InCurrentCrsDB
is not the current role in current course.
Instead it is initialized with the preferred role. */
- UsrDat->Role.InCurrentCrs = (Gbl.CurrentCrs.Crs.CrsCod > 0) ? DefaultRole : // Course selected
- Rol_GST; // No course selected
+ UsrDat->Roles.InCurrentCrs.Role = (Gbl.CurrentCrs.Crs.CrsCod > 0) ? DefaultRole : // Course selected
+ Rol_UNK; // No course selected
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
Rec_ShowSharedUsrRecord (Rec_SHA_OTHER_NEW_USR_FORM,UsrDat,NULL);
}
@@ -2253,11 +2254,11 @@ void Rec_ShowSharedUsrRecord (Rec_SharedRecordViewType_t TypeOfView,
UsrDat->Accepted);
ShowIDRows = (TypeOfView != Rec_SHA_RECORD_PUBLIC);
- StudentInCurrentCrs = UsrDat->Role.InCurrentCrs == Rol_STD;
- TeacherInCurrentCrs = UsrDat->Role.InCurrentCrs == Rol_NET ||
- UsrDat->Role.InCurrentCrs == Rol_TCH;
- TeacherInAnyCrs = UsrDat->Role.InCrss & ((1 << Rol_NET) |
- (1 << Rol_TCH));
+ StudentInCurrentCrs = UsrDat->Roles.InCurrentCrs.Role == Rol_STD;
+ TeacherInCurrentCrs = UsrDat->Roles.InCurrentCrs.Role == Rol_NET ||
+ UsrDat->Roles.InCurrentCrs.Role == Rol_TCH;
+ TeacherInAnyCrs = UsrDat->Roles.InCrss & ((1 << Rol_NET) |
+ (1 << Rol_TCH));
ShowAddressRows = (TypeOfView == Rec_SHA_MY_RECORD_FORM ||
TypeOfView == Rec_SHA_MY_RECORD_CHECK ||
@@ -2306,7 +2307,7 @@ void Rec_ShowSharedUsrRecord (Rec_SharedRecordViewType_t TypeOfView,
break;
}
- Rec_RecordHelp[Rec_SHA_RECORD_LIST] = Rec_RecordListHelp[UsrDat->Role.InCurrentCrs];
+ Rec_RecordHelp[Rec_SHA_RECORD_LIST] = Rec_RecordListHelp[UsrDat->Roles.InCurrentCrs.Role];
PutFormLinks = !Gbl.Form.Inside && // Only if not inside another form
Act_Actions[Gbl.Action.Act].BrowserWindow == Act_THIS_WINDOW; // Only in main window
@@ -2551,10 +2552,6 @@ static void Rec_PutIconsCommands (void)
extern const char *Txt_Following_unfollow;
extern const char *Txt_Follow;
bool ItsMe = (Gbl.Usrs.Me.UsrDat.UsrCod == Gbl.Record.UsrDat->UsrCod);
- bool IAmLoggedAsStudent = (Gbl.Usrs.Me.Role.Logged == Rol_STD); // My current role is student
- bool IAmLoggedAsTeacher = (Gbl.Usrs.Me.Role.Logged == Rol_NET || // My current role is non-editing teacher
- Gbl.Usrs.Me.Role.Logged == Rol_TCH); // My current role is teacher
- bool IAmLoggedAsSysAdm = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM); // My current role is superuser
bool ICanViewUsrProfile;
Act_Action_t NextAction;
@@ -2618,7 +2615,7 @@ static void Rec_PutIconsCommands (void)
(Gbl.CurrentIns.Ins.InsCod > 0 && Gbl.Usrs.Me.Role.Logged == Rol_INS_ADM) ||
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
{
- switch (Gbl.Record.UsrDat->Role.InCurrentCrs)
+ switch (Gbl.Record.UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActReqMdfStd;
@@ -2640,58 +2637,58 @@ static void Rec_PutIconsCommands (void)
NULL);
}
- if (Gbl.CurrentCrs.Crs.CrsCod > 0 && // A course is selected
- Gbl.Record.UsrDat->Role.InCurrentCrs == Rol_STD && // He/she is a student in the current course
- (ItsMe || IAmLoggedAsTeacher || IAmLoggedAsSysAdm)) // I can view
+ if (Gbl.CurrentCrs.Crs.CrsCod > 0) // A course is selected
{
- /***** Button to view user's assignments and works *****/
- if (ItsMe) // I am a student
- Lay_PutContextualLink (ActAdmAsgWrkUsr,NULL,NULL,
- "folder64x64.gif",
- Txt_View_homework,NULL,
- NULL);
- else // I am a teacher or superuser
- Lay_PutContextualLink (ActAdmAsgWrkCrs,NULL,Rec_PutParamsWorks,
- "folder64x64.gif",
- Txt_View_homework,NULL,
- NULL);
+ if (Usr_CheckIfICanViewWrkTstAtt (Gbl.Record.UsrDat))
+ {
+ /***** Button to view user's assignments and works *****/
+ if (ItsMe) // I am a student
+ Lay_PutContextualLink (ActAdmAsgWrkUsr,NULL,NULL,
+ "folder64x64.gif",
+ Txt_View_homework,NULL,
+ NULL);
+ else // I am a teacher or superuser
+ Lay_PutContextualLink (ActAdmAsgWrkCrs,NULL,Rec_PutParamsWorks,
+ "folder64x64.gif",
+ Txt_View_homework,NULL,
+ NULL);
- /***** Button to view user's test exams *****/
- if (ItsMe)
- Lay_PutContextualLink (ActSeeMyTstRes,NULL,NULL,
- "exam64x64.png",
- Txt_View_test_results,NULL,
- NULL);
- else
- Lay_PutContextualLink (ActSeeUsrTstRes,NULL,Rec_PutParamsStudent,
- "exam64x64.png",
- Txt_View_test_results,NULL,
- NULL);
+ /***** Button to view user's test exams *****/
+ if (ItsMe)
+ Lay_PutContextualLink (ActSeeMyTstRes,NULL,NULL,
+ "exam64x64.png",
+ Txt_View_test_results,NULL,
+ NULL);
+ else
+ Lay_PutContextualLink (ActSeeUsrTstRes,NULL,Rec_PutParamsStudent,
+ "exam64x64.png",
+ Txt_View_test_results,NULL,
+ NULL);
- /***** Button to view user's attendance *****/
- if (ItsMe && IAmLoggedAsStudent)
- // As student, I can see my attendance
- Lay_PutContextualLink (ActSeeLstMyAtt,NULL,NULL,
- "rollcall64x64.png",
- Txt_View_attendance,NULL,
- NULL);
- else if (IAmLoggedAsTeacher || IAmLoggedAsSysAdm)
- // As teacher, I can see attendance of the student
- Lay_PutContextualLink (ActSeeLstStdAtt,NULL,Rec_PutParamsStudent,
- "rollcall64x64.png",
- Txt_View_attendance,NULL,
- NULL);
- }
+ /***** Button to view user's attendance *****/
+ if (Gbl.Record.UsrDat->Roles.InCurrentCrs.Role == Rol_STD)
+ {
+ if (ItsMe)
+ // As student, I can see my attendance
+ Lay_PutContextualLink (ActSeeLstMyAtt,NULL,NULL,
+ "rollcall64x64.png",
+ Txt_View_attendance,NULL,
+ NULL);
+ else
+ // I can see attendance of the student
+ Lay_PutContextualLink (ActSeeLstStdAtt,NULL,Rec_PutParamsStudent,
+ "rollcall64x64.png",
+ Txt_View_attendance,NULL,
+ NULL);
+ }
+ }
- /***** Button to print QR code *****/
- if (ItsMe || IAmLoggedAsSysAdm ||
- (Gbl.CurrentCrs.Crs.CrsCod > 0 && // A course is selected
- Gbl.Record.UsrDat->Role.InCurrentCrs == Rol_STD && // He/she is a student in the current course
- IAmLoggedAsTeacher)) // I am a teacher in the current course
+ /***** Button to print QR code *****/
Lay_PutContextualLink (ActPrnUsrQR,NULL,Rec_PutParamUsrCodEncrypted,
"qr64x64.gif",
Txt_QR_code,NULL,
NULL);
+ }
/***** Button to send a message *****/
Lay_PutContextualLink (ActReqMsgUsr,NULL,Rec_PutParamsMsgUsr,
@@ -2984,9 +2981,9 @@ static void Rec_ShowRole (struct UsrData *UsrDat,
case Rec_SHA_SIGN_UP_IN_CRS_FORM: // I want to apply for enrolment
/***** Set default role *****/
if (UsrDat->UsrCod == Gbl.CurrentCrs.Crs.RequesterUsrCod || // Creator of the course
- (UsrDat->Role.InCrss & (1 << Rol_TCH))) // Teacher in other courses
+ (UsrDat->Roles.InCrss & (1 << Rol_TCH))) // Teacher in other courses
DefaultRoleInForm = Rol_TCH; // Request sign up as a teacher
- else if ((UsrDat->Role.InCrss & (1 << Rol_NET))) // Non-editing teacher in other courses
+ else if ((UsrDat->Roles.InCrss & (1 << Rol_NET))) // Non-editing teacher in other courses
DefaultRoleInForm = Rol_NET; // Request sign up as a non-editing teacher
else
DefaultRoleInForm = Rol_STD; // Request sign up as a student
@@ -3009,12 +3006,12 @@ static void Rec_ShowRole (struct UsrData *UsrDat,
if (Gbl.CurrentCrs.Crs.CrsCod > 0) // Course selected
{
/***** Set default role *****/
- switch (UsrDat->Role.InCurrentCrs)
+ switch (UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD: // Student in current course
case Rol_NET: // Non-editing teacher in current course
case Rol_TCH: // Teacher in current course
- DefaultRoleInForm = UsrDat->Role.InCurrentCrs;
+ DefaultRoleInForm = UsrDat->Roles.InCurrentCrs.Role;
default: // User does not belong to current course
/* If there is a request of this user, default role is the requested role */
DefaultRoleInForm = Rol_GetRequestedRole (UsrDat->UsrCod);
@@ -3038,9 +3035,9 @@ static void Rec_ShowRole (struct UsrData *UsrDat,
DefaultRoleInForm = Rol_TCH;
break;
default:
- if ((UsrDat->Role.InCrss & (1 << Rol_TCH))) // Teacher in other courses
+ if ((UsrDat->Roles.InCrss & (1 << Rol_TCH))) // Teacher in other courses
DefaultRoleInForm = Rol_TCH;
- else if ((UsrDat->Role.InCrss & (1 << Rol_NET))) // Non-editing teacher in other courses
+ else if ((UsrDat->Roles.InCrss & (1 << Rol_NET))) // Non-editing teacher in other courses
DefaultRoleInForm = Rol_NET;
else
DefaultRoleInForm = Rol_STD;
@@ -3090,7 +3087,7 @@ static void Rec_ShowRole (struct UsrData *UsrDat,
else // No course selected
{
/***** Set default role *****/
- DefaultRoleInForm = (UsrDat->Role.InCrss & ((1 << Rol_STD) |
+ DefaultRoleInForm = (UsrDat->Roles.InCrss & ((1 << Rol_STD) |
(1 << Rol_NET) |
(1 << Rol_TCH))) ? Rol_USR : // If user belongs to any course
Rol_GST; // If user don't belong to any course
@@ -3212,7 +3209,7 @@ static void Rec_ShowRole (struct UsrData *UsrDat,
TypeOfView == Rec_SHA_MY_RECORD_CHECK ? Txt_Sex :
Txt_Role,
TypeOfView == Rec_SHA_MY_RECORD_CHECK ? Txt_SEX_SINGULAR_Abc[UsrDat->Sex] :
- Txt_ROLES_SINGUL_Abc[UsrDat->Role.InCurrentCrs][UsrDat->Sex]);
+ Txt_ROLES_SINGUL_Abc[UsrDat->Roles.InCurrentCrs.Role][UsrDat->Sex]);
}
/*****************************************************************************/
@@ -3982,7 +3979,7 @@ void Rec_ShowFormMyInsCtrDpt (void)
Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat);
/***** Check if I am a teacher *****/
- IAmATeacher = (Gbl.Usrs.Me.UsrDat.Role.InCrss & ((1 << Rol_NET) | // I am a non-editing teacher...
+ IAmATeacher = (Gbl.Usrs.Me.UsrDat.Roles.InCrss & ((1 << Rol_NET) | // I am a non-editing teacher...
(1 << Rol_TCH))); // ...or a teacher in any course
/***** If there is no country, institution, centre or department *****/
diff --git a/swad_role.c b/swad_role.c
index b9fcb47d..f0353d1c 100644
--- a/swad_role.c
+++ b/swad_role.c
@@ -67,15 +67,20 @@ void Rol_SetMyRoles (void)
bool ICanBeCtrAdm = false;
bool ICanBeDegAdm = false;
- // In this point Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrsDB is set
+ /***** Get my role in current course if not yet filled *****/
+ if (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.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
+ }
/***** Set the user's role I am logged *****/
Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); // Get my roles if not yet got
- Gbl.Usrs.Me.Role.Max = Rol_GetMaxRoleInCrss ((unsigned) Gbl.Usrs.Me.UsrDat.Role.InCrss);
+ Gbl.Usrs.Me.Role.Max = Rol_GetMaxRoleInCrss ((unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss);
Gbl.Usrs.Me.Role.Logged = (Gbl.Usrs.Me.Role.FromSession == Rol_UNK) ? // If no logged role retrieved from session...
- ((Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs == Rol_UNK) ? Rol_USR :
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs) :
- Gbl.Usrs.Me.Role.FromSession; // Get logged role from session
+ ((Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role == Rol_UNK) ? Rol_USR :
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role) :
+ Gbl.Usrs.Me.Role.FromSession; // Get logged role from session
/***** Check if I am administrator of current institution/centre/degree *****/
if (Gbl.CurrentIns.Ins.InsCod > 0)
@@ -101,9 +106,7 @@ void Rol_SetMyRoles (void)
/***** Check if I belong to current course *****/
if (Gbl.CurrentCrs.Crs.CrsCod > 0) // Course selected
{
- Gbl.Usrs.Me.IBelongToCurrentCrs = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs == Rol_STD ||
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs == Rol_NET ||
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs == Rol_TCH;
+ Gbl.Usrs.Me.IBelongToCurrentCrs = Usr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Me.UsrDat);
if (Gbl.Usrs.Me.IBelongToCurrentCrs)
Gbl.Usrs.Me.UsrDat.Accepted = Usr_CheckIfUsrBelongsToCrs (Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.CurrentCrs.Crs.CrsCod,
@@ -154,7 +157,7 @@ void Rol_SetMyRoles (void)
if (Gbl.CurrentCrs.Crs.CrsCod > 0)
{
if (Gbl.Usrs.Me.IBelongToCurrentCrs)
- Gbl.Usrs.Me.Role.Available = (1 << Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs);
+ Gbl.Usrs.Me.Role.Available = (1 << Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role);
else if (Gbl.Usrs.Me.Role.Max >= Rol_STD)
Gbl.Usrs.Me.Role.Available = (1 << Rol_USR);
else
@@ -310,15 +313,15 @@ Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod)
/***** Fill the list with the courses I belong to (if not already filled) *****/
Usr_GetMyCourses ();
- /***** Check if the course passed as parameter is any of my courses *****/
+ /***** Check if the course is any of my courses *****/
for (NumMyCrs = 0;
NumMyCrs < Gbl.Usrs.Me.MyCrss.Num;
NumMyCrs++)
if (Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].CrsCod == CrsCod)
return Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].Role;
- return Rol_GST;
}
- return Rol_UNK; // No course
+
+ return Rol_UNK;
}
/*****************************************************************************/
@@ -330,26 +333,45 @@ Rol_Role_t Rol_GetRoleInCrs (long CrsCod,long UsrCod)
char Query[256];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
- Rol_Role_t Role = Rol_UNK; // Default role (if no course selected or user don't belong to it)
-
- if (CrsCod > 0)
+ static struct
{
- /***** Get rol of a user in a course from database.
- The result of the query will have one row or none *****/
- 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);
- Role = Rol_ConvertUnsignedStrToRole (row[0]);
- }
+ 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
- /***** Free structure that stores the query result *****/
- DB_FreeMySQLResult (&mysql_res);
+ /***** 1. Fast check: trivial cases *****/
+ if (CrsCod <= 0 ||
+ UsrCod <= 0)
+ return Rol_UNK;
+
+ /***** 2. Fast check: Is role in course already calculated *****/
+ if (CrsCod == Cached.CrsCod &&
+ UsrCod == Cached.UsrCod)
+ return Cached.RoleInCrs;
+
+ /***** 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;
+ 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]);
}
+ DB_FreeMySQLResult (&mysql_res);
- return Role;
+ return Cached.RoleInCrs;
}
/*****************************************************************************/
@@ -367,7 +389,7 @@ void Rol_GetRolesInAllCrssIfNotYetGot (struct UsrData *UsrDat)
unsigned NumRoles;
/***** If roles is already filled ==> nothing to do *****/
- if (UsrDat->Role.InCrss < 0) // Not yet filled
+ if (UsrDat->Roles.InCrss < 0) // Not yet filled
{
/***** Get distinct roles in all courses of the user from database *****/
sprintf (Query,"SELECT DISTINCT(Role) FROM crs_usr WHERE UsrCod=%ld",
@@ -375,12 +397,12 @@ void Rol_GetRolesInAllCrssIfNotYetGot (struct UsrData *UsrDat)
NumRoles = (unsigned) DB_QuerySELECT (Query,&mysql_res,
"can not get the roles of a user"
" in all his/her courses");
- for (NumRole = 0, UsrDat->Role.InCrss = 0;
+ for (NumRole = 0, UsrDat->Roles.InCrss = 0;
NumRole < NumRoles;
NumRole++)
{
row = mysql_fetch_row (mysql_res);
- UsrDat->Role.InCrss |= (int) (1 << Rol_ConvertUnsignedStrToRole (row[0]));
+ UsrDat->Roles.InCrss |= (int) (1 << Rol_ConvertUnsignedStrToRole (row[0]));
}
/***** Free structure that stores the query result *****/
diff --git a/swad_statistic.c b/swad_statistic.c
index 9cda9883..6b414154 100644
--- a/swad_statistic.c
+++ b/swad_statistic.c
@@ -1949,7 +1949,7 @@ static void Sta_ShowNumHitsPerUsr (unsigned long NumRows,MYSQL_RES *mysql_res)
"%s "
"",
Gbl.RowEvenOdd,
- Txt_ROLES_SINGUL_Abc[UsrDat.Role.InCurrentCrs][UsrDat.Sex]);
+ Txt_ROLES_SINGUL_Abc[UsrDat.Roles.InCurrentCrs.Role][UsrDat.Sex]);
/* Write the number of clicks */
Hits.Num = Str_GetFloatNumFromStr (row[1]);
@@ -1972,8 +1972,8 @@ static void Sta_ShowNumHitsPerUsr (unsigned long NumRows,MYSQL_RES *mysql_res)
" style=\"width:%upx; height:18px;\" />"
" ",
Gbl.Prefs.IconsURL,
- UsrDat.Role.InCurrentCrs == Rol_STD ? 'c' : // Student
- 'v', // Non-editing teacher or teacher
+ UsrDat.Roles.InCurrentCrs.Role == Rol_STD ? 'c' : // Student
+ 'v', // Non-editing teacher or teacher
BarWidth);
Str_WriteFloatNum (Gbl.F.Out,Hits.Num);
fprintf (Gbl.F.Out," "
diff --git a/swad_test.c b/swad_test.c
index b491692b..0988e328 100644
--- a/swad_test.c
+++ b/swad_test.c
@@ -7558,7 +7558,7 @@ static void Tst_ShowDataUsr (struct UsrData *UsrDat,unsigned NumTestResults)
fprintf (Gbl.F.Out,"rowspan=\"%u\"",NumTestResults + 1);
fprintf (Gbl.F.Out," class=\"LEFT_TOP COLOR%u\">",
Gbl.RowEvenOdd);
- switch (UsrDat->Role.InCurrentCrs)
+ switch (UsrDat->Roles.InCurrentCrs.Role)
{
case Rol_STD:
NextAction = ActSeeRecOneStd;
@@ -7716,7 +7716,7 @@ void Tst_ShowOneTestResult (void)
"%s:"
""
"
",
- Txt_ROLES_SINGUL_Abc[Gbl.Usrs.Other.UsrDat.Role.InCurrentCrs][Gbl.Usrs.Other.UsrDat.Sex]);
+ Txt_ROLES_SINGUL_Abc[Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs.Role][Gbl.Usrs.Other.UsrDat.Sex]);
ID_WriteUsrIDs (&Gbl.Usrs.Other.UsrDat,NULL);
fprintf (Gbl.F.Out," %s",
Gbl.Usrs.Other.UsrDat.Surname1);
diff --git a/swad_user.c b/swad_user.c
index ab700f2b..47514bc9 100644
--- a/swad_user.c
+++ b/swad_user.c
@@ -293,8 +293,9 @@ void Usr_ResetUsrDataExceptUsrCodAndIDs (struct UsrData *UsrDat)
UsrDat->EncryptedUsrCod[0] = '\0';
UsrDat->Nickname[0] = '\0';
UsrDat->Password[0] = '\0';
- UsrDat->Role.InCurrentCrs = Rol_UNK;
- UsrDat->Role.InCrss = -1; // < 0 ==> not yet got from database
+ UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
+ UsrDat->Roles.InCurrentCrs.UsrCod = -1L;
+ UsrDat->Roles.InCrss = -1; // < 0 ==> not yet got from database
UsrDat->Accepted = true;
UsrDat->Sex = Usr_SEX_UNKNOWN;
@@ -517,14 +518,11 @@ void Usr_GetUsrDataFromUsrCod (struct UsrData *UsrDat)
Pwd_BYTES_ENCRYPTED_PASSWORD);
/* Get roles */
- UsrDat->Role.InCurrentCrs = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,
- UsrDat->UsrCod);
- UsrDat->Role.InCrss = -1; // Force roles to be got from database
+ UsrDat->Roles.InCurrentCrs.Role = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,
+ UsrDat->UsrCod);
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
+ UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat);
- if (UsrDat->Role.InCurrentCrs == Rol_UNK)
- UsrDat->Role.InCurrentCrs = (UsrDat->Role.InCrss < (1 << Rol_STD)) ?
- Rol_GST : // User does not belong to any course
- Rol_USR; // User belongs to some courses
/* Get name */
Str_Copy (UsrDat->Surname1,row[2],
@@ -1050,7 +1048,7 @@ unsigned Usr_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole,
bool Usr_CheckIfICanViewRecordStd (const struct UsrData *UsrDat)
{
- if (UsrDat->Role.InCurrentCrs != Rol_STD) // Not a student in the current course
+ if (UsrDat->Roles.InCurrentCrs.Role != Rol_STD) // Not a student in the current course
return false;
// The user is a student in the current course
@@ -1081,7 +1079,7 @@ bool Usr_CheckIfICanViewRecordTch (struct UsrData *UsrDat)
/***** 2. Fast/slow check: Is he/she a non-editing teacher or a teacher in any course? *****/
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat);
- if ((UsrDat->Role.InCrss & ((1 << Rol_NET) |
+ if ((UsrDat->Roles.InCrss & ((1 << Rol_NET) |
(1 << Rol_TCH))) == 0)
return false;
@@ -1099,6 +1097,49 @@ bool Usr_CheckIfICanViewRecordTch (struct UsrData *UsrDat)
return Usr_CheckIfUsrSharesAnyOfMyCrs (UsrDat);
}
+/*****************************************************************************/
+/*** Check if a user belongs to any of my courses but has a different role ***/
+/*****************************************************************************/
+
+bool Usr_CheckIfICanViewWrkTstAtt (const struct UsrData *UsrDat)
+ {
+ /***** 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 / slow check depending on roles *****/
+ switch (Gbl.Usrs.Me.Role.Logged)
+ {
+ case Rol_NET:
+ return Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (Gbl.Record.UsrDat);
+ case Rol_TCH:
+ case Rol_SYS_ADM:
+ return true;
+ default:
+ return false;
+ }
+ }
+
/*****************************************************************************/
/******************* Check if I can view a user's agenda *********************/
/*****************************************************************************/
@@ -1128,7 +1169,6 @@ bool Usr_CheckIfICanViewUsrAgenda (struct UsrData *UsrDat)
bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat)
{
char Query[256];
- bool HeBelongsToCurrentCrs;
static struct
{
long UsrCod;
@@ -1158,19 +1198,14 @@ bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat)
/***** 5. Fast check: Is course selected and we both belong to it? *****/
if (Gbl.Usrs.Me.IBelongToCurrentCrs)
- {
- HeBelongsToCurrentCrs = UsrDat->Role.InCurrentCrs == Rol_STD ||
- UsrDat->Role.InCurrentCrs == Rol_NET ||
- UsrDat->Role.InCurrentCrs == Rol_TCH;
- if (HeBelongsToCurrentCrs) // Course selected and we both belong to it
+ if (Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) // Course selected and we both belong to it
return true;
- }
/***** 6. Fast/slow check: Does he/she belong to any course? *****/
Rol_GetRolesInAllCrssIfNotYetGot (UsrDat);
- if (!(UsrDat->Role.InCrss & ((1 << Rol_STD) | // Any of his/her roles is student
- (1 << Rol_NET) | // or non-editing teacher
- (1 << Rol_TCH)))) // or teacher?
+ if (!(UsrDat->Roles.InCrss & ((1 << Rol_STD) | // Any of his/her roles is student
+ (1 << Rol_NET) | // or non-editing teacher
+ (1 << Rol_TCH)))) // or teacher?
return false;
/***** 7. Slow check: Get if user shares any course with me from database *****/
@@ -1600,6 +1635,7 @@ bool Usr_CheckIfUsrBelongsToIns (long UsrCod,long InsCod)
false
};
+ /***** 1. Fast check: Trivial case *****/
if (UsrCod <= 0 ||
InsCod <= 0)
{
@@ -1607,25 +1643,27 @@ bool Usr_CheckIfUsrBelongsToIns (long UsrCod,long InsCod)
Cached.UsrCod = -1L;
Cached.InsCod = -1L;
Cached.Belongs = false;
- }
- else if (UsrCod != Cached.UsrCod ||
- InsCod != Cached.InsCod) // If not cached...
- {
- /***** Get is a user belongs to an institution from database *****/
- sprintf (Query,"SELECT COUNT(DISTINCT centres.InsCod)"
- " FROM crs_usr,courses,degrees,centres"
- " WHERE crs_usr.UsrCod=%ld"
- " AND crs_usr.Accepted='Y'"
- " AND crs_usr.CrsCod=courses.CrsCod"
- " AND courses.DegCod=degrees.DegCod"
- " 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;
}
+ /***** 2. Fast check: If cached... *****/
+ if (UsrCod == Cached.UsrCod &&
+ InsCod != Cached.InsCod)
+ return Cached.Belongs;
+
+ /***** 3. Slow check: Get is user belongs to institution from database *****/
+ sprintf (Query,"SELECT COUNT(DISTINCT centres.InsCod)"
+ " FROM crs_usr,courses,degrees,centres"
+ " WHERE crs_usr.UsrCod=%ld"
+ " AND crs_usr.Accepted='Y'"
+ " AND crs_usr.CrsCod=courses.CrsCod"
+ " AND courses.DegCod=degrees.DegCod"
+ " 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;
}
@@ -1648,31 +1686,33 @@ bool Usr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod)
false
};
+ /***** 1. Fast check: Trivial case *****/
if (UsrCod <= 0 ||
CtrCod <= 0)
{
- /***** Trivial case *****/
Cached.UsrCod = -1L;
Cached.CtrCod = -1L;
Cached.Belongs = false;
- }
- else if (UsrCod != Cached.UsrCod ||
- CtrCod != Cached.CtrCod) // If not cached...
- {
- /***** Get is a user belongs to a centre from database *****/
- sprintf (Query,"SELECT COUNT(DISTINCT degrees.CtrCod)"
- " FROM crs_usr,courses,degrees"
- " WHERE crs_usr.UsrCod=%ld"
- " AND crs_usr.Accepted='Y'" // Only if user accepted
- " AND crs_usr.CrsCod=courses.CrsCod"
- " 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;
}
+ /***** 2. Fast check: If cached... *****/
+ if (UsrCod == Cached.UsrCod &&
+ CtrCod == Cached.CtrCod)
+ return Cached.Belongs;
+
+ /***** 3. Slow check: Get is user belongs to centre from database *****/
+ sprintf (Query,"SELECT COUNT(DISTINCT degrees.CtrCod)"
+ " FROM crs_usr,courses,degrees"
+ " WHERE crs_usr.UsrCod=%ld"
+ " AND crs_usr.Accepted='Y'" // Only if user accepted
+ " AND crs_usr.CrsCod=courses.CrsCod"
+ " 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;
}
@@ -1695,33 +1735,75 @@ bool Usr_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod)
false
};
+ /***** 1. Fast check: Trivial case *****/
if (UsrCod <= 0 ||
DegCod <= 0)
{
- /***** Trivial case *****/
Cached.UsrCod = -1L;
Cached.DegCod = -1L;
Cached.Belongs = false;
- }
- else if (UsrCod != Cached.UsrCod ||
- DegCod != Cached.DegCod) // If not cached...
- {
- /***** Get is a user belongs to a degree from database *****/
- sprintf (Query,"SELECT COUNT(DISTINCT courses.DegCod)"
- " FROM crs_usr,courses"
- " WHERE crs_usr.UsrCod=%ld"
- " AND crs_usr.Accepted='Y'" // Only if user accepted
- " 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;
}
+ /***** 2. Fast check: If cached... *****/
+ if (UsrCod == Cached.UsrCod &&
+ DegCod == Cached.DegCod)
+ return Cached.Belongs;
+
+ /***** 3. Slow check: Get if user belongs to degree from database *****/
+ sprintf (Query,"SELECT COUNT(DISTINCT courses.DegCod)"
+ " FROM crs_usr,courses"
+ " WHERE crs_usr.UsrCod=%ld"
+ " AND crs_usr.Accepted='Y'" // Only if user accepted
+ " 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 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)
+ return UsrDat->Roles.InCurrentCrs.Role == Rol_STD ||
+ UsrDat->Roles.InCurrentCrs.Role == Rol_NET ||
+ UsrDat->Roles.InCurrentCrs.Role == Rol_TCH;
+
+ /***** 4. Fast / slow check: Get if user belongs to current course *****/
+ return Usr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod,Gbl.CurrentCrs.Crs.CrsCod,
+ false);
+ }
+
/*****************************************************************************/
/******************** Check if a user belongs to a course ********************/
/*****************************************************************************/
@@ -1731,19 +1813,48 @@ bool Usr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod,
{
char Query[512];
const char *SubQuery;
+ static struct
+ {
+ long UsrCod;
+ long CrsCod;
+ bool CountOnlyAcceptedCourses;
+ bool Belongs;
+ } Cached =
+ {
+ -1L,
+ -1L,
+ false,
+ false
+ };
- /***** Trivial case *****/
+ /***** 1. Fast check: trivial cases *****/
if (UsrCod <= 0 ||
CrsCod <= 0)
- return false;
+ {
+ Cached.UsrCod = -1L;
+ Cached.CrsCod = -1L;
+ Cached.CountOnlyAcceptedCourses = CountOnlyAcceptedCourses;
+ Cached.Belongs = false;
+ return Cached.Belongs;
+ }
- /***** Get if a user belongs to a course from database *****/
+ /***** 2. Fast check: If cached... *****/
+ if (UsrCod == Cached.UsrCod &&
+ CrsCod == Cached.CrsCod &&
+ CountOnlyAcceptedCourses == Cached.CountOnlyAcceptedCourses)
+ return Cached.Belongs;
+
+ /***** 3. Slow check: Get if user belongs to course from database *****/
SubQuery = (CountOnlyAcceptedCourses ? " AND crs_usr.Accepted='Y'" :
"");
sprintf (Query,"SELECT COUNT(*) FROM crs_usr"
" WHERE CrsCod=%ld AND UsrCod=%ld%s",
CrsCod,UsrCod,SubQuery);
- return (DB_QueryCOUNT (Query,"can not check if a user belongs to a course") != 0);
+ 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;
}
/*****************************************************************************/
@@ -2950,13 +3061,12 @@ static void Usr_SetMyPrefsAndRoles (void)
Hie_InitHierarchy ();
/* Get again my role in this course */
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,
- Gbl.Usrs.Me.UsrDat.UsrCod);
+ 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;
}
}
- // In this point Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrsDB is set
-
Rol_SetMyRoles ();
}
@@ -4996,11 +5106,11 @@ void Usr_CopyBasicUsrDataFromList (struct UsrData *UsrDat,const struct UsrInList
UsrDat->Sex = UsrInList->Sex;
Str_Copy (UsrDat->Photo,UsrInList->Photo,
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
- UsrDat->PhotoVisibility = UsrInList->PhotoVisibility;
- UsrDat->CtyCod = UsrInList->CtyCod;
- UsrDat->InsCod = UsrInList->InsCod;
- UsrDat->Role.InCurrentCrs = UsrInList->RoleInCurrentCrsDB;
- UsrDat->Accepted = UsrInList->Accepted;
+ UsrDat->PhotoVisibility = UsrInList->PhotoVisibility;
+ UsrDat->CtyCod = UsrInList->CtyCod;
+ UsrDat->InsCod = UsrInList->InsCod;
+ UsrDat->Roles.InCurrentCrs.Role = UsrInList->RoleInCurrentCrsDB;
+ UsrDat->Accepted = UsrInList->Accepted;
}
/*****************************************************************************/
diff --git a/swad_user.h b/swad_user.h
index 101916d6..54c2f9c5 100644
--- a/swad_user.h
+++ b/swad_user.h
@@ -131,11 +131,16 @@ struct UsrData
char Password [Pwd_BYTES_ENCRYPTED_PASSWORD + 1];
struct
{
- Rol_Role_t InCurrentCrs;
- int InCrss; // Check always if filled/calculated
- // >=0 ==> filled/calculated
- // <0 ==> not yet filled/calculated
- } Role;
+ struct
+ {
+ long UsrCod; // 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
+ // Check always if filled/calculated
+ // >=0 ==> filled/calculated
+ // <0 ==> not yet filled/calculated
+ } Roles;
bool Accepted; // User has accepted joining to current course?
char Surname1 [Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME + 1];
char Surname2 [Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME + 1];
@@ -252,8 +257,10 @@ unsigned Usr_GetNumCrssOfUsrWithARoleNotAccepted (long UsrCod,Rol_Role_t Role);
unsigned Usr_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole,
Rol_Role_t OthersRole);
+bool Usr_CheckIfUsrBelongsToCurrentCrs (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);
bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat);
bool Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod);
diff --git a/swad_web_service.c b/swad_web_service.c
index 568d5330..c2c31a39 100644
--- a/swad_web_service.c
+++ b/swad_web_service.c
@@ -592,14 +592,21 @@ static bool Svc_GetSomeUsrDataFromUsrCod (struct UsrData *UsrDat,long CrsCod)
row = mysql_fetch_row (mysql_res);
if (row[0])
{
- if (sscanf (row[0],"%u",&UsrDat->Role.InCurrentCrs) != 1)
- UsrDat->Role.InCurrentCrs = Rol_UNK;
+ if (sscanf (row[0],"%u",&UsrDat->Roles.InCurrentCrs.Role) != 1)
+ UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
}
else // Impossible
- UsrDat->Role.InCurrentCrs = Rol_UNK;
+ {
+ UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
+ }
}
else // User does not belong to course
- UsrDat->Role.InCurrentCrs = Rol_USR;
+ {
+ UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
+ }
}
else
{
@@ -612,15 +619,22 @@ static bool Svc_GetSomeUsrDataFromUsrCod (struct UsrData *UsrDat,long CrsCod)
row = mysql_fetch_row (mysql_res);
if (row[0])
{
- if (sscanf (row[0],"%u",&UsrDat->Role.InCurrentCrs) != 1)
- UsrDat->Role.InCurrentCrs = Rol_UNK;
+ if (sscanf (row[0],"%u",&UsrDat->Roles.InCurrentCrs.Role) != 1)
+ UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
}
else
// MAX(Role) == NULL if user does not belong to any course
- UsrDat->Role.InCurrentCrs = Rol_GST;
+ {
+ UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
+ }
}
else // Impossible
- UsrDat->Role.InCurrentCrs = Rol_GST;
+ {
+ UsrDat->Roles.InCurrentCrs.Role = Rol_UNK;
+ UsrDat->Roles.InCurrentCrs.UsrCod = UsrDat->UsrCod;
+ }
}
/* Free structure that stores the query result */
@@ -878,7 +892,7 @@ int swad__loginByUserPasswordKey (struct soap *soap,
if (UsrFound)
{
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
loginByUserPasswordKeyOut->userCode = (int) Gbl.Usrs.Me.UsrDat.UsrCod;
@@ -909,7 +923,7 @@ int swad__loginByUserPasswordKey (struct soap *soap,
Gbl.Usrs.Me.UsrDat.Birthday.YYYYMMDD,
Dat_LENGTH_YYYYMMDD);
- loginByUserPasswordKeyOut->userRole = Svc_RolRole_to_SvcRole[Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs];
+ loginByUserPasswordKeyOut->userRole = Svc_RolRole_to_SvcRole[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role];
/***** Generate a key used in subsequents calls to other web services *****/
return Svc_GenerateNewWSKey ((long) loginByUserPasswordKeyOut->userCode,
@@ -1033,7 +1047,7 @@ int swad__loginBySessionKey (struct soap *soap,
if (UsrFound)
{
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
loginBySessionKeyOut->userCode = (int) Gbl.Usrs.Me.UsrDat.UsrCod;
@@ -1063,7 +1077,7 @@ int swad__loginBySessionKey (struct soap *soap,
Gbl.Usrs.Me.UsrDat.Birthday.YYYYMMDD,
Dat_LENGTH_YYYYMMDD);
- loginBySessionKeyOut->userRole = Svc_RolRole_to_SvcRole[Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs];
+ loginBySessionKeyOut->userRole = Svc_RolRole_to_SvcRole[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role];
/***** Generate a key used in subsequents calls to other web services *****/
return Svc_GenerateNewWSKey ((long) loginBySessionKeyOut->userCode,
@@ -1196,7 +1210,7 @@ int swad__getCourses (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Query my courses from database *****/
sprintf (Query,"SELECT courses.CrsCod,courses.ShortName,courses.FullName,crs_usr.Role FROM crs_usr,courses"
@@ -1306,12 +1320,12 @@ int swad__getCourseInfo (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
@@ -1411,12 +1425,12 @@ int swad__getUsers (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
@@ -1490,13 +1504,13 @@ int swad__findUsers (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
if (Gbl.CurrentCrs.Crs.CrsCod > 0)
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
@@ -1652,12 +1666,12 @@ int swad__getGroupTypes (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
@@ -1761,12 +1775,12 @@ int swad__getGroups (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
@@ -1888,12 +1902,12 @@ int swad__sendMyGroups (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
@@ -2104,10 +2118,10 @@ int swad__getAttendanceEvents (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must be a teacher");
@@ -2308,10 +2322,10 @@ int swad__sendAttendanceEvent (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must be a teacher");
@@ -2429,10 +2443,10 @@ int swad__removeAttendanceEvent (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must be a teacher");
@@ -2525,10 +2539,10 @@ int swad__getAttendanceUsers (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must be a teacher");
@@ -2679,7 +2693,7 @@ int swad__sendAttendanceUsers (struct soap *soap,
struct AttendanceEvent Att;
const char *Ptr;
char LongStr[1 + 10 + 1];
- long UsrCod;
+ struct UsrData UsrDat;
unsigned NumCodsInList;
char SubQuery[256];
size_t Length = 0; // Initialized to avoid warning
@@ -2713,14 +2727,17 @@ int swad__sendAttendanceUsers (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must be a teacher");
+ /***** Initialize structure with user's data *****/
+ Usr_UsrDataConstructor (&UsrDat);
+
if (setOthersAsAbsent)
{
/* Count number of codes in list */
@@ -2747,23 +2764,23 @@ int swad__sendAttendanceUsers (struct soap *soap,
{
/* Find next string in text until comma (leading and trailing spaces are removed) */
Str_GetNextStringUntilComma (&Ptr,LongStr,1 + 10);
- if ((UsrCod = Str_ConvertStrCodToLongCod (LongStr)) > 0)
- if (Usr_ChkIfUsrCodExists (UsrCod))
+ if ((UsrDat.UsrCod = Str_ConvertStrCodToLongCod (LongStr)) > 0)
+ if (Usr_ChkIfUsrCodExists (UsrDat.UsrCod))
// The user must belong to course,
// but it's not necessary he/she belongs to groups associated to the event
- if (Usr_CheckIfUsrBelongsToCrs (UsrCod,
+ if (Usr_CheckIfUsrBelongsToCrs (UsrDat.UsrCod,
Gbl.CurrentCrs.Crs.CrsCod,
false))
{
/* Mark user as present */
- Att_RegUsrInAttEventNotChangingComments (Att.AttCod,UsrCod);
+ Att_RegUsrInAttEventNotChangingComments (Att.AttCod,UsrDat.UsrCod);
/* Add this user to query used to mark not present users as absent */
if (setOthersAsAbsent)
{
sprintf (SubQuery,sendAttendanceUsersOut->numUsers ? ",%ld" :
" AND UsrCod NOT IN (%ld",
- UsrCod);
+ UsrDat.UsrCod);
Str_Concat (Query,SubQuery,
Length);
}
@@ -2786,6 +2803,9 @@ int swad__sendAttendanceUsers (struct soap *soap,
Att_RemoveUsrsAbsentWithoutCommentsFromAttEvent (Att.AttCod);
}
+ /***** Free memory used for user's data *****/
+ Usr_UsrDataDestructor (&UsrDat);
+
sendAttendanceUsersOut->success = 1;
return SOAP_OK;
@@ -2845,7 +2865,7 @@ int swad__getNotifications (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Get my language from database *****/
if ((ReturnCode = Svc_GetMyLanguage ()) != SOAP_OK)
@@ -3103,7 +3123,7 @@ int swad__markNotificationsAsRead (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
if (notifications[0])
{
@@ -3174,7 +3194,7 @@ int swad__sendMessage (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if the message is a reply to a previous message *****/
if (messageCode)
@@ -3445,7 +3465,7 @@ int swad__sendNotice (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check course and group codes *****/
if ((ReturnCode = Svc_CheckCourseAndGroupCodes (Gbl.CurrentCrs.Crs.CrsCod,-1L)) != SOAP_OK)
@@ -3456,7 +3476,7 @@ int swad__sendNotice (struct soap *soap,
return ReturnCode;
/***** Check if I am a teacher *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must be a teacher");
@@ -3513,7 +3533,7 @@ int swad__getTestConfig (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if course code is correct *****/
if (Gbl.CurrentCrs.Crs.CrsCod <= 0)
@@ -3522,9 +3542,9 @@ int swad__getTestConfig (struct soap *soap,
"Course code must be a integer greater than 0");
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
@@ -3645,7 +3665,7 @@ int swad__getTests (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if course code is correct *****/
if (Gbl.CurrentCrs.Crs.CrsCod <= 0)
@@ -3654,9 +3674,9 @@ int swad__getTests (struct soap *soap,
"Course code must be a integer greater than 0");
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
@@ -4045,7 +4065,7 @@ int swad__getTrivialQuestion (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Loop over recipients' nicknames building query *****/
DegreesStr[0] = '\0';
@@ -4280,16 +4300,16 @@ int swad__getDirectoryTree (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check course and group codes *****/
if ((ReturnCode = Svc_CheckCourseAndGroupCodes (Gbl.CurrentCrs.Crs.CrsCod,Gbl.CurrentCrs.Grps.GrpCod)) != SOAP_OK)
return ReturnCode;
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
@@ -4598,16 +4618,16 @@ int swad__getFile (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check course and group codes *****/
if ((ReturnCode = Svc_CheckCourseAndGroupCodes (Gbl.CurrentCrs.Crs.CrsCod,Gbl.CurrentCrs.Grps.GrpCod)) != SOAP_OK)
return ReturnCode;
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
@@ -4630,7 +4650,7 @@ int swad__getFile (struct soap *soap,
case Brw_ADMI_MARKS_CRS:
case Brw_ADMI_MARKS_GRP:
// Downloading a file of marks is only allowed for teachers
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Wrong tree",
"Wrong file zone");
@@ -4745,12 +4765,12 @@ int swad__getMarks (struct soap *soap,
"Can not get user's data from database",
"User does not exist in database");
Gbl.Usrs.Me.Logged = true;
- Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs;
+ Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role;
/***** Check if I am a student, non-editing teacher or teacher in the course *****/
- if (Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_STD &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_NET &&
- Gbl.Usrs.Me.UsrDat.Role.InCurrentCrs != Rol_TCH)
+ if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_STD &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_NET &&
+ Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role != Rol_TCH)
return soap_receiver_fault (Gbl.soap,
"Request forbidden",
"Requester must belong to course");
|