From 91bdda94d09282f9c03ae38b35ae931c4137320a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Thu, 8 Jun 2017 15:32:33 +0200 Subject: [PATCH] Version 16.236 --- sql/cambios.sql | 3 +- swad_ID.c | 10 +- swad_action.c | 4 +- swad_announcement.c | 4 +- swad_changelog.h | 4 +- swad_enrolment.c | 44 +++---- swad_file_browser.c | 2 +- swad_forum.c | 6 +- swad_group.c | 74 +++++++++++- swad_group.h | 2 + swad_help.c | 6 +- swad_mail.c | 18 ++- swad_password.c | 4 +- swad_photo.c | 14 +-- swad_profile.c | 3 +- swad_record.c | 129 ++++++++++---------- swad_role.c | 84 ++++++++----- swad_statistic.c | 6 +- swad_test.c | 4 +- swad_user.c | 278 +++++++++++++++++++++++++++++++------------- swad_user.h | 17 ++- swad_web_service.c | 180 +++++++++++++++------------- 22 files changed, 563 insertions(+), 333 deletions(-) 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");