From d9562dc2abce273c617ed63ca8b5c4fab0180d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Tue, 13 Dec 2016 13:32:19 +0100 Subject: [PATCH] Version 16.100 --- swad_action.c | 5 +++- swad_announcement.c | 6 +++- swad_attendance.c | 4 ++- swad_centre.h | 2 +- swad_changelog.h | 6 +++- swad_connected.c | 1 + swad_country.h | 2 +- swad_degree.h | 2 +- swad_duplicate.c | 2 +- swad_enrollment.c | 13 ++++---- swad_follow.c | 4 +-- swad_forum.c | 17 ++++++++--- swad_institution.h | 2 +- swad_photo.c | 2 +- swad_photo.h | 2 +- swad_privacy.c | 8 +++-- swad_privacy.h | 2 +- swad_profile.c | 3 +- swad_profile.h | 2 +- swad_record.c | 72 +++++++++++++++++++++++++++++---------------- swad_role.c | 43 ++++++++++++++------------- swad_role.h | 37 +++-------------------- swad_role_type.h | 62 ++++++++++++++++++++++++++++++++++++++ swad_survey.c | 1 + swad_user.c | 40 ++++++++++++++----------- swad_user.h | 12 ++++---- 26 files changed, 221 insertions(+), 131 deletions(-) create mode 100644 swad_role_type.h diff --git a/swad_action.c b/swad_action.c index eece4912..597af6e4 100644 --- a/swad_action.c +++ b/swad_action.c @@ -64,6 +64,7 @@ #include "swad_profile.h" #include "swad_QR.h" #include "swad_report.h" +#include "swad_role.h" #include "swad_search.h" #include "swad_setup.h" #include "swad_social.h" @@ -4873,7 +4874,7 @@ void Act_AdjustActionWhenNoUsrLogged (void) void Act_AdjustCurrentAction (void) { - bool IAmATeacher = (Gbl.Usrs.Me.UsrDat.Roles & (1 << Rol_TEACHER)); + bool IAmATeacher; /***** Don't adjust anything when current action is not a menu option *****/ if (Gbl.Action.Act != Act_Actions[Gbl.Action.Act].SuperAction) // It is not a menu option @@ -4945,6 +4946,8 @@ void Act_AdjustCurrentAction (void) /***** If I haven't filled my institution, or if I'm a teacher and I haven't filled my centre or department, the only action possible is to show a form to change my common record *****/ + Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); + IAmATeacher = (Gbl.Usrs.Me.UsrDat.Roles & (1 << Rol_TEACHER)); if (Gbl.Usrs.Me.UsrDat.InsCod < 0 || (IAmATeacher && (Gbl.Usrs.Me.UsrDat.Tch.CtrCod < 0 || Gbl.Usrs.Me.UsrDat.Tch.DptCod < 0))) diff --git a/swad_announcement.c b/swad_announcement.c index f46a4e1a..7131e205 100644 --- a/swad_announcement.c +++ b/swad_announcement.c @@ -31,6 +31,7 @@ #include "swad_database.h" #include "swad_global.h" #include "swad_parameter.h" +#include "swad_role.h" /*****************************************************************************/ /****************************** Public constants *****************************/ @@ -98,12 +99,15 @@ void Ann_ShowAllAnnouncements (void) " FROM announcements" " ORDER BY AnnCod DESC"); else if (Gbl.Usrs.Me.Logged) + { /* Select only announcements I can see */ + Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); sprintf (Query,"SELECT AnnCod,Status,Roles,Subject,Content" " FROM announcements" " WHERE (Roles&%u)<>0 " " ORDER BY AnnCod DESC", Gbl.Usrs.Me.UsrDat.Roles); // All my roles in different courses + } else // No user logged /* Select only active announcements for unknown users */ sprintf (Query,"SELECT AnnCod,Status,Roles,Subject,Content" @@ -212,7 +216,7 @@ void Ann_ShowMyAnnouncementsNotMarkedAsSeen (void) char Content[Cns_MAX_BYTES_TEXT+1]; /***** Select announcements not seen *****/ - // Roles == 24 ==> Teachers and students + Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); sprintf (Query,"SELECT AnnCod,Subject,Content FROM announcements" " WHERE Status='%u' AND (Roles&%u)<>0 " " AND AnnCod NOT IN" diff --git a/swad_attendance.c b/swad_attendance.c index d1c8b117..1f396dbb 100644 --- a/swad_attendance.c +++ b/swad_attendance.c @@ -412,7 +412,9 @@ static void Att_ShowOneAttEvent (struct AttendanceEvent *Att,bool ShowOnlyThisAt fprintf (Gbl.F.Out,""); /***** Number of students in this event *****/ - fprintf (Gbl.F.Out,"Hidden ? "ASG_TITLE_LIGHT" : + "ASG_TITLE"); if (!ShowOnlyThisAttEventComplete) fprintf (Gbl.F.Out," COLOR%u",Gbl.RowEvenOdd); fprintf (Gbl.F.Out,"\">" diff --git a/swad_centre.h b/swad_centre.h index 965a8fbc..0ad01805 100644 --- a/swad_centre.h +++ b/swad_centre.h @@ -30,7 +30,7 @@ #include "swad_action.h" #include "swad_constant.h" #include "swad_degree.h" -#include "swad_role.h" +#include "swad_role_type.h" /*****************************************************************************/ /************************** Public types and constants ***********************/ diff --git a/swad_changelog.h b/swad_changelog.h index 26acf749..c07cabab 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -181,17 +181,21 @@ // TODO: Fix bug in notification content about files sent to plugins like SWADroid: do not write internal name (for example "comun"). Call instead Brw_GetFileNameToShow or similar. +// TODO: Draw future dates in attendance, surveys, assignments in blue? + /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 16.99.1 (2016-12-13)" +#define Log_PLATFORM_VERSION "SWAD 16.100 (2016-12-13)" #define CSS_FILE "swad16.97.css" #define JS_FILE "swad16.99.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.100: Dec 13, 2016 Changes in layout of list of attendance events. + Code refactoring related with roles. (210820 lines) Version 16.99.1: Dec 13, 2016 Changes in translation of start and end. Changes in layout of assignments and surveys. (210742 lines) Version 16.99: Dec 12, 2016 Changes in script to write local date and time. (210782 lines) diff --git a/swad_connected.c b/swad_connected.c index be66045f..da683df5 100644 --- a/swad_connected.c +++ b/swad_connected.c @@ -35,6 +35,7 @@ #include "swad_global.h" #include "swad_parameter.h" #include "swad_photo.h" +#include "swad_role.h" #include "swad_string.h" #include "swad_user.h" diff --git a/swad_country.h b/swad_country.h index 5f6fdb38..b540c860 100644 --- a/swad_country.h +++ b/swad_country.h @@ -30,7 +30,7 @@ #include // For boolean type #include "swad_action.h" -#include "swad_role.h" +#include "swad_role_type.h" #include "swad_text.h" /*****************************************************************************/ diff --git a/swad_degree.h b/swad_degree.h index e2cd5fa4..53e53306 100644 --- a/swad_degree.h +++ b/swad_degree.h @@ -29,7 +29,7 @@ #include "swad_action.h" #include "swad_constant.h" -#include "swad_role.h" +#include "swad_role_type.h" #include "swad_string.h" /*****************************************************************************/ diff --git a/swad_duplicate.c b/swad_duplicate.c index 1b60cf2e..5df677df 100644 --- a/swad_duplicate.c +++ b/swad_duplicate.c @@ -32,7 +32,7 @@ #include "swad_global.h" #include "swad_layout.h" #include "swad_profile.h" -#include "swad_role.h" +#include "swad_role_type.h" #include "swad_user.h" /*****************************************************************************/ diff --git a/swad_enrollment.c b/swad_enrollment.c index 27ec4976..4b3d15d4 100644 --- a/swad_enrollment.c +++ b/swad_enrollment.c @@ -37,6 +37,7 @@ #include "swad_ID.h" #include "swad_notification.h" #include "swad_parameter.h" +#include "swad_role.h" #include "swad_user.h" /*****************************************************************************/ @@ -210,7 +211,8 @@ void Enr_ModifyRoleInCurrentCrs (struct UsrData *UsrDat, } UsrDat->RoleInCurrentCrsDB = NewRole; - UsrDat->Roles |= (1 << NewRole); + UsrDat->Roles = -1; // Force roles to be got from database + Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get roles } } @@ -255,7 +257,8 @@ void Enr_RegisterUsrInCurrentCrs (struct UsrData *UsrDat,Rol_Role_t NewRole, 'N'); DB_QueryINSERT (Query,"can not register user in course"); UsrDat->RoleInCurrentCrsDB = NewRole; - UsrDat->Roles |= NewRole; + UsrDat->Roles = -1; // Force roles to be got from database + Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get roles /***** Create notification for this user. If this user wants to receive notifications by email, @@ -3072,12 +3075,6 @@ static void Enr_AskIfRegRemUsr (struct ListUsrCods *ListUsrCods,Rol_Role_t Role) if (NewUsrIDValid) { - /* Initialize some data of this new user */ - Gbl.Usrs.Other.UsrDat.RoleInCurrentCrsDB = - (Gbl.CurrentCrs.Crs.CrsCod > 0) ? Rol_STUDENT : // Course selected - Rol_UNKNOWN; // No course selected - Gbl.Usrs.Other.UsrDat.Roles = (1 << Gbl.Usrs.Other.UsrDat.RoleInCurrentCrsDB); - /***** Show form to enter the data of a new user *****/ sprintf (Gbl.Message,Txt_The_user_is_new_does_not_exists_yet_in_X, Cfg_PLATFORM_SHORT_NAME); diff --git a/swad_follow.c b/swad_follow.c index 6cc800b8..e4952999 100644 --- a/swad_follow.c +++ b/swad_follow.c @@ -78,7 +78,7 @@ static void Fol_ShowNumberOfFollowingOrFollowers (const struct UsrData *UsrDat, static void Fol_ListFollowingUsr (struct UsrData *UsrDat); static void Fol_ListFollowersUsr (struct UsrData *UsrDat); -static void Fol_ShowFollowedOrFollower (const struct UsrData *UsrDat); +static void Fol_ShowFollowedOrFollower (struct UsrData *UsrDat); /*****************************************************************************/ /********************** Put link to show users to follow **********************/ @@ -676,7 +676,7 @@ static void Fol_ListFollowersUsr (struct UsrData *UsrDat) /************************* Show followed or follower *************************/ /*****************************************************************************/ -static void Fol_ShowFollowedOrFollower (const struct UsrData *UsrDat) +static void Fol_ShowFollowedOrFollower (struct UsrData *UsrDat) { extern const char *Txt_View_public_profile; extern const char *Txt_Following_unfollow; diff --git a/swad_forum.c b/swad_forum.c index c438a18e..28034f9e 100644 --- a/swad_forum.c +++ b/swad_forum.c @@ -41,6 +41,7 @@ #include "swad_notification.h" #include "swad_parameter.h" #include "swad_profile.h" +#include "swad_role.h" #include "swad_social.h" /*****************************************************************************/ @@ -293,7 +294,8 @@ static void For_PutFormWhichForums (void); static void For_WriteLinkToTopLevelOfForums (void); static void For_PutParamsForumInsDegCrs (void); static void For_WriteLinksToGblForums (bool IsLastItemInLevel[1+For_FORUM_MAX_LEVELS]); -static void For_WriteLinksToPlatformForums (bool IsLastForum,bool IsLastItemInLevel[1+For_FORUM_MAX_LEVELS]); +static void For_WriteLinksToPlatformForums (bool IsLastForum, + bool IsLastItemInLevel[1+For_FORUM_MAX_LEVELS]); static long For_WriteLinksToInsForums (long InsCod,bool IsLastIns,bool IsLastItemInLevel[1+For_FORUM_MAX_LEVELS]); static long For_WriteLinksToCtrForums (long CtrCod,bool IsLastCtr,bool IsLastItemInLevel[1+For_FORUM_MAX_LEVELS]); static long For_WriteLinksToDegForums (long DegCod,bool IsLastDeg,bool IsLastItemInLevel[1+For_FORUM_MAX_LEVELS]); @@ -1702,6 +1704,7 @@ void For_SetForumTypeAndRestrictAccess (void) break; case For_FORUM_GLOBAL_TCHS: case For_FORUM_SWAD_TCHS: + Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); ICanSeeForum = (Gbl.Usrs.Me.UsrDat.Roles >= (1 << Rol_TEACHER)); break; } @@ -1945,6 +1948,7 @@ static void For_WriteLinksToGblForums (bool IsLastItemInLevel[1+For_FORUM_MAX_LE For_WriteLinkToAForum (For_FORUM_GLOBAL_USRS,false,1,IsLastItemInLevel); /***** Link to forum of teachers global *****/ + Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); if (Gbl.Usrs.Me.UsrDat.Roles >= (1 << Rol_TEACHER)) { IsLastItemInLevel[1] = false; @@ -1956,10 +1960,15 @@ static void For_WriteLinksToGblForums (bool IsLastItemInLevel[1+For_FORUM_MAX_LE /****************** Write links to forums about the platform *****************/ /*****************************************************************************/ -static void For_WriteLinksToPlatformForums (bool IsLastForum,bool IsLastItemInLevel[1+For_FORUM_MAX_LEVELS]) +static void For_WriteLinksToPlatformForums (bool IsLastForum, + bool IsLastItemInLevel[1+For_FORUM_MAX_LEVELS]) { - bool ICanSeeTeacherForum = (Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM || - Gbl.Usrs.Me.UsrDat.Roles >= (1 << Rol_TEACHER)); + bool ICanSeeTeacherForum; + + /***** Can I see teachers's forums? *****/ + Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); + ICanSeeTeacherForum = (Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM || + Gbl.Usrs.Me.UsrDat.Roles >= (1 << Rol_TEACHER)); /***** Link to forum of users about the platform *****/ IsLastItemInLevel[1] = (IsLastForum && !ICanSeeTeacherForum); diff --git a/swad_institution.h b/swad_institution.h index 0a381fda..70683533 100644 --- a/swad_institution.h +++ b/swad_institution.h @@ -28,7 +28,7 @@ /*****************************************************************************/ #include "swad_constant.h" -#include "swad_role.h" +#include "swad_role_type.h" /*****************************************************************************/ /************************ Public types and constants *************************/ diff --git a/swad_photo.c b/swad_photo.c index 76804163..478c18ca 100644 --- a/swad_photo.c +++ b/swad_photo.c @@ -950,7 +950,7 @@ void Pho_RemoveUsrFromTableClicksWithoutPhoto (long UsrCod) // Returns true if the photo can be shown and false if not. // Public photo means two different things depending on the user's type -bool Pho_ShowUsrPhotoIsAllowed (const struct UsrData *UsrDat,char *PhotoURL) +bool Pho_ShowUsrPhotoIsAllowed (struct UsrData *UsrDat,char *PhotoURL) { bool ICanSeePhoto; diff --git a/swad_photo.h b/swad_photo.h index edd2b31c..8737d1bd 100644 --- a/swad_photo.h +++ b/swad_photo.h @@ -103,7 +103,7 @@ void Pho_UpdateUsrPhoto2 (void); unsigned Pho_UpdateMyClicksWithoutPhoto (void); void Pho_RemoveUsrFromTableClicksWithoutPhoto (long UsrCod); -bool Pho_ShowUsrPhotoIsAllowed (const struct UsrData *UsrDat,char *PhotoURL); +bool Pho_ShowUsrPhotoIsAllowed (struct UsrData *UsrDat,char *PhotoURL); bool Pho_BuildLinkToPhoto (const struct UsrData *UsrDat,char *PhotoURL); bool Pho_CheckIfPrivPhotoExists (long UsrCod,char *PathPrivRelPhoto); bool Pho_RemovePhoto (struct UsrData *UsrDat); diff --git a/swad_privacy.c b/swad_privacy.c index adc2f6f1..b65ec34b 100644 --- a/swad_privacy.c +++ b/swad_privacy.c @@ -246,7 +246,7 @@ Pri_Visibility_t Pri_GetParamVisibility (const char *ParamName) /*****************************************************************************/ // Returns true if it can be shown and false if not. -bool Pri_ShowIsAllowed (Pri_Visibility_t Visibility,const struct UsrData *UsrDat) +bool Pri_ShowIsAllowed (Pri_Visibility_t Visibility,struct UsrData *UsrDat) { /***** It's me? I always can see my things *****/ if (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) @@ -262,9 +262,11 @@ bool Pri_ShowIsAllowed (Pri_Visibility_t Visibility,const struct UsrData *UsrDat case Pri_VISIBILITY_UNKNOWN: return false; // It's not me case Pri_VISIBILITY_USER: // Only visible by me and my teachers if I am a student or me and my students if I am a teacher - return Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (UsrDat->UsrCod); // Both users share the same course but whit different role + // Do both users share the same course but whit different role? + return Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (UsrDat->UsrCod); case Pri_VISIBILITY_COURSE: // Visible by users sharing courses with me - return Usr_CheckIfUsrSharesAnyOfMyCrs (UsrDat); // Both users share the same course + // Do both users share the same course? + return Usr_CheckIfUsrSharesAnyOfMyCrs (UsrDat); case Pri_VISIBILITY_SYSTEM: // Visible by any user logged in platform return Gbl.Usrs.Me.Logged; case Pri_VISIBILITY_WORLD: // Public, visible by everyone, even unlogged visitors diff --git a/swad_privacy.h b/swad_privacy.h index a8b81d75..65da4a61 100644 --- a/swad_privacy.h +++ b/swad_privacy.h @@ -48,6 +48,6 @@ void Pri_EditMyPrivacy (void); Pri_Visibility_t Pri_GetVisibilityFromStr (const char *Str); Pri_Visibility_t Pri_GetParamVisibility (const char *ParamName); -bool Pri_ShowIsAllowed (Pri_Visibility_t Visibility,const struct UsrData *UsrDat); +bool Pri_ShowIsAllowed (Pri_Visibility_t Visibility,struct UsrData *UsrDat); #endif diff --git a/swad_profile.c b/swad_profile.c index f7e171a2..26d8314e 100644 --- a/swad_profile.c +++ b/swad_profile.c @@ -39,6 +39,7 @@ #include "swad_privacy.h" #include "swad_profile.h" #include "swad_role.h" +#include "swad_role_type.h" #include "swad_social.h" #include "swad_text.h" #include "swad_theme.h" @@ -1480,7 +1481,7 @@ void Prf_GetAndShowRankingClicksPerDay (void) /************** Show user's photo and nickname in ranking list ***************/ /*****************************************************************************/ -void Prf_ShowUsrInRanking (const struct UsrData *UsrDat,unsigned Rank) +void Prf_ShowUsrInRanking (struct UsrData *UsrDat,unsigned Rank) { extern const char *Txt_View_public_profile; bool ShowPhoto; diff --git a/swad_profile.h b/swad_profile.h index 30a543ad..7acc2a8e 100644 --- a/swad_profile.h +++ b/swad_profile.h @@ -77,6 +77,6 @@ void Prf_GetAndShowRankingForPst (void); void Prf_GetAndShowRankingMsgSnt (void); void Prf_ShowRankingFigure (const char *Query); void Prf_GetAndShowRankingClicksPerDay (void); -void Prf_ShowUsrInRanking (const struct UsrData *UsrDat,unsigned Rank); +void Prf_ShowUsrInRanking (struct UsrData *UsrDat,unsigned Rank); #endif diff --git a/swad_record.c b/swad_record.c index 4a7d06a0..77ae7b9c 100644 --- a/swad_record.c +++ b/swad_record.c @@ -45,6 +45,7 @@ #include "swad_privacy.h" #include "swad_QR.h" #include "swad_record.h" +#include "swad_role.h" #include "swad_user.h" /*****************************************************************************/ @@ -2069,34 +2070,45 @@ void Rec_ShowSharedUsrRecord (Rec_SharedRecordViewType_t TypeOfView, }; char StrRecordWidth[10+1]; const char *ClassForm = "REC_DAT"; - bool ItsMe = (Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod); - bool IAmLoggedAsTeacher = (Gbl.Usrs.Me.LoggedRole == Rol_TEACHER); // My current role is teacher - bool IAmLoggedAsSysAdm = (Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM); // My current role is superuser - bool CountryForm = (TypeOfView == Rec_SHA_MY_RECORD_FORM); - bool DataForm = (TypeOfView == Rec_SHA_MY_RECORD_FORM || - TypeOfView == Rec_SHA_OTHER_NEW_USR_FORM || - (TypeOfView == Rec_SHA_OTHER_EXISTING_USR_FORM && - Gbl.Usrs.Me.LoggedRole >= Rol_DEG_ADM)); + bool ItsMe; + bool IAmLoggedAsTeacher; + bool IAmLoggedAsSysAdm; + bool CountryForm; + bool DataForm; bool PutFormLinks; // Put links (forms) inside record card - bool ShowData = (ItsMe || - Gbl.Usrs.Me.LoggedRole >= Rol_DEG_ADM || - UsrDat->Accepted); - bool ShowIDRows = (TypeOfView != Rec_SHA_RECORD_PUBLIC); - bool ShowAddressRows = (TypeOfView == Rec_SHA_MY_RECORD_FORM || - TypeOfView == Rec_SHA_MY_RECORD_CHECK || - ((TypeOfView == Rec_SHA_RECORD_LIST || - TypeOfView == Rec_SHA_RECORD_PRINT) && - (IAmLoggedAsTeacher || IAmLoggedAsSysAdm) && - UsrDat->RoleInCurrentCrsDB == Rol_STUDENT)); - bool ShowTeacherRows = (((TypeOfView == Rec_SHA_MY_RECORD_FORM || - TypeOfView == Rec_SHA_MY_RECORD_CHECK) && - (UsrDat->Roles & (1 << Rol_TEACHER))) || // He/she (me, really) is a teacher in any course - ((TypeOfView == Rec_SHA_RECORD_LIST || - TypeOfView == Rec_SHA_RECORD_PRINT) && - UsrDat->RoleInCurrentCrsDB == Rol_TEACHER)); // He/she is a teacher in the current course + bool ShowData; + bool ShowIDRows; + bool ShowAddressRows; + bool ShowTeacherRows; struct Instit Ins; /***** Initializations *****/ + ItsMe = (Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod); + IAmLoggedAsTeacher = (Gbl.Usrs.Me.LoggedRole == Rol_TEACHER); // My current role is teacher + IAmLoggedAsSysAdm = (Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM); // My current role is superuser + CountryForm = (TypeOfView == Rec_SHA_MY_RECORD_FORM); + DataForm = (TypeOfView == Rec_SHA_MY_RECORD_FORM || + TypeOfView == Rec_SHA_OTHER_NEW_USR_FORM || + (TypeOfView == Rec_SHA_OTHER_EXISTING_USR_FORM && + Gbl.Usrs.Me.LoggedRole >= Rol_DEG_ADM)); + ShowData = (ItsMe || + Gbl.Usrs.Me.LoggedRole >= Rol_DEG_ADM || + UsrDat->Accepted); + ShowIDRows = (TypeOfView != Rec_SHA_RECORD_PUBLIC); + ShowAddressRows = (TypeOfView == Rec_SHA_MY_RECORD_FORM || + TypeOfView == Rec_SHA_MY_RECORD_CHECK || + ((TypeOfView == Rec_SHA_RECORD_LIST || + TypeOfView == Rec_SHA_RECORD_PRINT) && + (IAmLoggedAsTeacher || IAmLoggedAsSysAdm) && + UsrDat->RoleInCurrentCrsDB == Rol_STUDENT)); + Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); // Get user's roles if not got + ShowTeacherRows = (((TypeOfView == Rec_SHA_MY_RECORD_FORM || + TypeOfView == Rec_SHA_MY_RECORD_CHECK) && + (UsrDat->Roles & (1 << Rol_TEACHER))) || // He/she (me, really) is a teacher in any course + ((TypeOfView == Rec_SHA_RECORD_LIST || + TypeOfView == Rec_SHA_RECORD_PRINT) && + UsrDat->RoleInCurrentCrsDB == Rol_TEACHER)); // He/she is a teacher in the current course + switch (TypeOfView) { case Rec_SHA_SIGN_UP_FORM: @@ -2718,6 +2730,9 @@ static void Rec_ShowRole (struct UsrData *UsrDat, if (RoleForm) { + /* Get user's roles if not got */ + Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); + fprintf (Gbl.F.Out,"" "" "%s:" @@ -3464,6 +3479,7 @@ Rol_Role_t Rec_GetRoleFromRecordForm (void) if the other is already teacher in any course. That is, a teacher can not upgrade a student (in all other courses) to teacher */ + Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Other.UsrDat); if ( Role == Rol_STUDENT || (Role == Rol_TEACHER && // He/she will be a teacher in current course (Gbl.Usrs.Other.UsrDat.Roles & (1 << Rol_TEACHER)))) // He/she was a teacher in some courses @@ -3601,7 +3617,13 @@ void Rec_ShowFormMyInsCtrDpt (void) unsigned NumIns; unsigned NumCtr; unsigned NumDpt; - bool IAmTeacher = (Gbl.Usrs.Me.UsrDat.Roles & (1 << Rol_TEACHER)); + bool IAmTeacher; + + /***** Get my roles if not yet got *****/ + Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); + + /***** Check if I am a teacher *****/ + IAmTeacher = (Gbl.Usrs.Me.UsrDat.Roles & (1 << Rol_TEACHER)); /***** If there is no country, institution, centre or department *****/ if (Gbl.Usrs.Me.UsrDat.InsCtyCod < 0) diff --git a/swad_role.c b/swad_role.c index 556e8676..7b78e312 100644 --- a/swad_role.c +++ b/swad_role.c @@ -29,6 +29,7 @@ #include "swad_global.h" #include "swad_parameter.h" #include "swad_role.h" +#include "swad_role_type.h" /*****************************************************************************/ /****************************** Public constants *****************************/ @@ -221,35 +222,37 @@ Rol_Role_t Rol_GetRoleInCrs (long CrsCod,long UsrCod) /*****************************************************************************/ /**************** Get roles of a user in all his/her courses *****************/ /*****************************************************************************/ +// Roles >=0 ==> already filled/calculated ==> nothing to do +// Roles <0 ==> not yet filled/calculated ==> get roles -unsigned Rol_GetRolesInAllCrss (long UsrCod) +void Rol_GetRolesInAllCrssIfNotYetGot (struct UsrData *UsrDat) { - char Query[512]; + char Query[128]; MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumRole; unsigned NumRoles; - Rol_Role_t Role; - unsigned Roles = 0; - /***** Get distinct roles in all the courses of the user from database *****/ - sprintf (Query,"SELECT DISTINCT(Role) FROM crs_usr" - " WHERE UsrCod='%ld'", - UsrCod); - NumRoles = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get the roles of a user in all his/her courses"); - for (NumRole = 0; - NumRole < NumRoles; - NumRole++) + /***** If roles is already filled ==> nothing to do *****/ + if (UsrDat->Roles < 0) // Not yet filled { - row = mysql_fetch_row (mysql_res); - if ((Role = Rol_ConvertUnsignedStrToRole (row[0])) != Rol_UNKNOWN) - Roles |= (1 << Role); + /***** Get distinct roles in all courses of the user from database *****/ + sprintf (Query,"SELECT DISTINCT(Role) FROM crs_usr WHERE UsrCod='%ld'", + UsrDat->UsrCod); + NumRoles = (unsigned) DB_QuerySELECT (Query,&mysql_res, + "can not get the roles of a user" + " in all his/her courses"); + for (NumRole = 0, UsrDat->Roles = 0; + NumRole < NumRoles; + NumRole++) + { + row = mysql_fetch_row (mysql_res); + UsrDat->Roles |= (int) (1 << Rol_ConvertUnsignedStrToRole (row[0])); + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - - return Roles; } /*****************************************************************************/ diff --git a/swad_role.h b/swad_role.h index 2096da3f..a32b04b8 100644 --- a/swad_role.h +++ b/swad_role.h @@ -27,41 +27,12 @@ /********************************** Headers **********************************/ /*****************************************************************************/ -/*****************************************************************************/ -/****************************** Public constants *****************************/ -/*****************************************************************************/ +#include "swad_user.h" /*****************************************************************************/ -/******************************** Public types *******************************/ +/************************** Public constant and types ************************/ /*****************************************************************************/ -// Related with user's roles -/* - Don't change these numbers! - They are used for users' permissions and for user's types in database - - Only Rol_ROLE_STUDENT and Rol_ROLE_TEACHER are allowed - as user permanent roles in courses, - but a user may be logged temporarily as other roles -*/ -// TODO: Teachers/students should be teachers/students only inside their courses -// Outside their courses a user (not logged as admin) should be Rol_VISITOR -// (with similar permissions as Rol_VISITOR but labeled as "User") -#define Rol_NUM_ROLES 9 -typedef enum - { - Rol_UNKNOWN = 0, // User not logged in - Rol__GUEST_ = 1, // User not belonging to any course - Rol_VISITOR = 2, // Student or teacher in other courses... - // ...but not belonging to the current course - Rol_STUDENT = 3, // Student in current course - Rol_TEACHER = 4, // Teacher in current course - Rol_DEG_ADM = 5, // Degree administrator - Rol_CTR_ADM = 6, // Centre administrator - Rol_INS_ADM = 7, // Institution administrator - Rol_SYS_ADM = 8, // System administrator (superuser) - } Rol_Role_t; - /*****************************************************************************/ /****************************** Public prototypes ****************************/ /*****************************************************************************/ @@ -73,7 +44,7 @@ Rol_Role_t Rol_GetMyMaxRoleInCtr (long CtrCod); Rol_Role_t Rol_GetMyMaxRoleInDeg (long DegCod); Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod); Rol_Role_t Rol_GetRoleInCrs (long CrsCod,long UsrCod); -unsigned Rol_GetRolesInAllCrss (long UsrCod); +void Rol_GetRolesInAllCrssIfNotYetGot (struct UsrData *UsrDat); Rol_Role_t Rol_ConvertUnsignedStrToRole (const char *UnsignedStr); unsigned Rol_ConvertUnsignedStrToRoles (const char *UnsignedStr); @@ -83,7 +54,7 @@ void Rol_ChangeMyRole (void); void Rol_WriteSelectorRoles (unsigned RolesAllowed,unsigned RolesSelected, bool Disabled,bool SendOnChange); -void Rol_PutHiddenParamRoles (unsigned Role); +void Rol_PutHiddenParamRoles (unsigned Roles); unsigned Rol_GetSelectedRoles (void); Rol_Role_t Rol_GetRequestedRole (long UsrCod); diff --git a/swad_role_type.h b/swad_role_type.h new file mode 100644 index 00000000..22a4cc15 --- /dev/null +++ b/swad_role_type.h @@ -0,0 +1,62 @@ +// swad_role_type.h: user's role type + +#ifndef _SWAD_ROL_T +#define _SWAD_ROL_T +/* + SWAD (Shared Workspace At a Distance in Spanish), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2016 Antonio Caņas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/********************************** Headers **********************************/ +/*****************************************************************************/ + + +/*****************************************************************************/ +/************************** Public constant and types ************************/ +/*****************************************************************************/ + +// Related with user's roles +/* + Don't change these numbers! + They are used for users' permissions and for user's types in database + + Only Rol_ROLE_STUDENT and Rol_ROLE_TEACHER are allowed + as user permanent roles in courses, + but a user may be logged temporarily as other roles +*/ +// TODO: Teachers/students should be teachers/students only inside their courses +// A user with courses (but not logged as admin) should be Rol_VISITOR outside his/her courses +// (Rol_VISITOR should be labeled as "User" instead "Visitor") +#define Rol_NUM_ROLES 9 +typedef enum + { + Rol_UNKNOWN = 0, // User not logged in + Rol__GUEST_ = 1, // User not belonging to any course + Rol_VISITOR = 2, // Student or teacher in other courses... + // ...but not belonging to the current course + Rol_STUDENT = 3, // Student in current course + Rol_TEACHER = 4, // Teacher in current course + Rol_DEG_ADM = 5, // Degree administrator + Rol_CTR_ADM = 6, // Centre administrator + Rol_INS_ADM = 7, // Institution administrator + Rol_SYS_ADM = 8, // System administrator (superuser) + } Rol_Role_t; + +#endif diff --git a/swad_survey.c b/swad_survey.c index 51d062da..0dcb2032 100644 --- a/swad_survey.c +++ b/swad_survey.c @@ -36,6 +36,7 @@ #include "swad_notification.h" #include "swad_pagination.h" #include "swad_parameter.h" +#include "swad_role.h" #include "swad_survey.h" /*****************************************************************************/ diff --git a/swad_user.c b/swad_user.c index e523ac8c..17b855fb 100644 --- a/swad_user.c +++ b/swad_user.c @@ -57,6 +57,7 @@ #include "swad_privacy.h" #include "swad_QR.h" #include "swad_record.h" +#include "swad_role.h" #include "swad_tab.h" #include "swad_user.h" @@ -260,7 +261,7 @@ void Usr_ResetUsrDataExceptUsrCodAndIDs (struct UsrData *UsrDat) UsrDat->Nickname[0] = '\0'; UsrDat->Password[0] = '\0'; UsrDat->RoleInCurrentCrsDB = Rol_UNKNOWN; - UsrDat->Roles = 0; + UsrDat->Roles = -1; // < 0 ==> not yet got from database UsrDat->Accepted = true; UsrDat->Sex = Usr_SEX_UNKNOWN; @@ -486,7 +487,8 @@ void Usr_GetUsrDataFromUsrCod (struct UsrData *UsrDat) /* Get roles */ UsrDat->RoleInCurrentCrsDB = Rol_GetRoleInCrs (Gbl.CurrentCrs.Crs.CrsCod,UsrDat->UsrCod); - UsrDat->Roles = Rol_GetRolesInAllCrss (UsrDat->UsrCod); + UsrDat->Roles = -1; // Force roles to be got from database + Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); if (UsrDat->RoleInCurrentCrsDB == Rol_UNKNOWN) UsrDat->RoleInCurrentCrsDB = (UsrDat->Roles < (1 << Rol_STUDENT)) ? Rol__GUEST_ : // User does not belong to any course @@ -916,15 +918,18 @@ bool Usr_CheckIfICanViewRecordStd (const struct UsrData *UsrDat) /************ Check if I can view the record card of a teacher ***************/ /*****************************************************************************/ -bool Usr_CheckIfICanViewRecordTch (const struct UsrData *UsrDat) +bool Usr_CheckIfICanViewRecordTch (struct UsrData *UsrDat) { - /***** 1. Fast check: Is he/she a teacher in any course? *****/ + /***** 1. Fast check: Am I logged? *****/ + if (!Gbl.Usrs.Me.Logged) + return false; + + /***** 2. Fast/slow check: Is he/she a teacher in any course? *****/ + Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); if (!(UsrDat->Roles & (1 << Rol_TEACHER))) return false; - /***** 2. Fast check: Am I logged? *****/ - if (!Gbl.Usrs.Me.Logged) - return false; + // He/she is a teacher /***** 3. Fast check: It's me? *****/ if (Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod) @@ -942,7 +947,7 @@ bool Usr_CheckIfICanViewRecordTch (const struct UsrData *UsrDat) /******************* Check if I can view a user's agenda *********************/ /*****************************************************************************/ -bool Usr_CheckIfICanViewUsrAgenda (const struct UsrData *UsrDat) +bool Usr_CheckIfICanViewUsrAgenda (struct UsrData *UsrDat) { /***** 1. Fast check: Am I logged? *****/ if (!Gbl.Usrs.Me.Logged) @@ -964,7 +969,7 @@ bool Usr_CheckIfICanViewUsrAgenda (const struct UsrData *UsrDat) /*************** Check if a user belongs to any of my courses ****************/ /*****************************************************************************/ -bool Usr_CheckIfUsrSharesAnyOfMyCrs (const struct UsrData *UsrDat) +bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat) { char Query[256]; bool IBelongToCurrentCrs; @@ -992,10 +997,9 @@ bool Usr_CheckIfUsrSharesAnyOfMyCrs (const struct UsrData *UsrDat) if (Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod) return true; - /***** 4. Fast check: Does he/she belong to any course? *****/ - if (!(UsrDat->Roles & ((1 << Rol_STUDENT) | // Any of his/her roles is student - (1 << Rol_TEACHER)))) // or teacher? - return false; + /***** 4. Fast check: Is already calculated if user shares any course with me? *****/ + if (UsrDat->UsrCod == Cached.UsrCod) + return Cached.UsrSharesAnyOfMyCrs; /***** 5. Fast check: Is course selected and we both belong to it? *****/ IBelongToCurrentCrs = Gbl.Usrs.Me.UsrDat.RoleInCurrentCrsDB == Rol_STUDENT || @@ -1005,9 +1009,11 @@ bool Usr_CheckIfUsrSharesAnyOfMyCrs (const struct UsrData *UsrDat) if (IBelongToCurrentCrs && HeBelongsToCurrentCrs) // Course selected and we both belong to it return true; - /***** 6. Fast check: Is already calculated if user shares any course with me? *****/ - if (UsrDat->UsrCod == Cached.UsrCod) - return Cached.UsrSharesAnyOfMyCrs; + /***** 6. Fast/slow check: Does he/she belong to any course? *****/ + Rol_GetRolesInAllCrssIfNotYetGot (UsrDat); + if (!(UsrDat->Roles & ((1 << Rol_STUDENT) | // Any of his/her roles is student + (1 << Rol_TEACHER)))) // or teacher? + return false; /***** 7. Slow check: Get if user shares any course with me from database *****/ sprintf (Query,"SELECT COUNT(*) FROM crs_usr" @@ -2725,6 +2731,7 @@ static void Usr_SetUsrRoleAndPrefs (void) } /***** Set the user's role I am logged *****/ + Rol_GetRolesInAllCrssIfNotYetGot (&Gbl.Usrs.Me.UsrDat); // Get my roles if not yet got Gbl.Usrs.Me.MaxRole = Rol_GetMaxRole (Gbl.Usrs.Me.UsrDat.Roles); Gbl.Usrs.Me.LoggedRole = (Gbl.Usrs.Me.RoleFromSession == Rol_UNKNOWN) ? // If no logged role retrieved from session... Gbl.Usrs.Me.MaxRole : // ...set current logged role to maximum role in database @@ -3923,7 +3930,6 @@ static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role,char *Query) /*****************************************************************************/ /*********** Get list of users with a given role in a given scope ************/ /*****************************************************************************/ - // Role can be: // - Rol_STUDENT // - Rol_TEACHER diff --git a/swad_user.h b/swad_user.h index 5cd7b703..0f250b1f 100644 --- a/swad_user.h +++ b/swad_user.h @@ -39,7 +39,7 @@ #include "swad_menu.h" #include "swad_nickname.h" #include "swad_privacy_visibility_type.h" -#include "swad_role.h" +#include "swad_role_type.h" #include "swad_scope.h" #include "swad_search.h" #include "swad_string.h" @@ -122,7 +122,9 @@ struct UsrData char Nickname [Nck_MAX_LENGTH_NICKNAME_WITHOUT_ARROBA+1]; char Password [Cry_LENGTH_ENCRYPTED_STR_SHA512_BASE64+1]; Rol_Role_t RoleInCurrentCrsDB; - unsigned Roles; + int Roles; // Check always if filled/calculated + // >=0 ==> filled/calculated + // <0 ==> not yet filled/calculated bool Accepted; // User has accepted joining to current course? char Surname1 [Usr_MAX_BYTES_NAME+1]; char Surname2 [Usr_MAX_BYTES_NAME+1]; @@ -234,9 +236,9 @@ unsigned Usr_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole, Rol_Role_t OthersRole); bool Usr_CheckIfICanViewRecordStd (const struct UsrData *UsrDat); -bool Usr_CheckIfICanViewRecordTch (const struct UsrData *UsrDat); -bool Usr_CheckIfICanViewUsrAgenda (const struct UsrData *UsrDat); -bool Usr_CheckIfUsrSharesAnyOfMyCrs (const struct UsrData *UsrDat); +bool Usr_CheckIfICanViewRecordTch (struct UsrData *UsrDat); +bool Usr_CheckIfICanViewUsrAgenda (struct UsrData *UsrDat); +bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat); bool Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod); void Usr_GetMyCountrs (void);