diff --git a/swad_changelog.h b/swad_changelog.h index e735fe1c..2ed12453 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -456,12 +456,13 @@ En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 18.110.1 (2019-04-11)" +#define Log_PLATFORM_VERSION "SWAD 18.110.2 (2019-04-11)" #define CSS_FILE "swad18.92.css" #define JS_FILE "swad18.92.js" /* Comprobar si Gbl.AttEvents.AttCodToEdit puede ser sustituido por Gbl.AttEvents.AttCod + Version 18.110.2: Apr 11, 2019 A user can have several roles in the same project. (242527 lines) Version 18.110.1: Apr 11, 2019 Code refactoring in selection of groups and users. (242553 lines) Version 18.110: Apr 11, 2019 Code refactoring in selection of groups and users. Adding multiple users ad once to a project, suggested by Pedro Villar Castro. (242563 lines) diff --git a/swad_file_browser.c b/swad_file_browser.c index a08d5615..967b0660 100644 --- a/swad_file_browser.c +++ b/swad_file_browser.c @@ -1386,8 +1386,8 @@ static bool Brw_CheckIfICanEditFileOrFolder (unsigned Level); static bool Brw_CheckIfICanCreateIntoFolder (unsigned Level); static bool Brw_CheckIfICanModifySharedFileOrFolder (void); static bool Brw_CheckIfICanModifyPrivateFileOrFolder (void); -static bool Brw_CheckIfICanViewProjectDocuments (Prj_RoleInProject_t MyRoleInProject); -static bool Brw_CheckIfICanViewProjectAssessment (Prj_RoleInProject_t MyRoleInProject); +static bool Brw_CheckIfICanViewProjectDocuments (unsigned MyRolesInProject); +static bool Brw_CheckIfICanViewProjectAssessment (unsigned MyRolesInProject); static bool Brw_CheckIfICanModifyPrjDocFileOrFolder (void); static bool Brw_CheckIfICanModifyPrjAssFileOrFolder (void); static long Brw_GetPublisherOfSubtree (void); @@ -3083,7 +3083,7 @@ static void Brw_ShowFileBrowserProject (void) { extern const char *Hlp_ASSESSMENT_Projects; struct Project Prj; - Prj_RoleInProject_t MyRoleInProject; + unsigned MyRolesInProject; /***** Allocate memory for the project *****/ Prj_AllocMemProject (&Prj); @@ -3101,12 +3101,12 @@ static void Brw_ShowFileBrowserProject (void) Prj_ShowOneUniqueProject (&Prj); /***** Show project file browsers *****/ - MyRoleInProject = Prj_GetMyRoleInProject (Gbl.Prjs.PrjCod); - if (Prj_CheckIfICanViewProjectFiles (MyRoleInProject)) + MyRolesInProject = Prj_GetMyRolesInProject (Gbl.Prjs.PrjCod); + if (Prj_CheckIfICanViewProjectFiles (MyRolesInProject)) { Brw_WriteTopBeforeShowingFileBrowser (); - if (Brw_CheckIfICanViewProjectDocuments (MyRoleInProject)) + if (Brw_CheckIfICanViewProjectDocuments (MyRolesInProject)) { /***** Show the tree with the project documents *****/ Gbl.FileBrowser.Type = Brw_ADMI_DOC_PRJ; @@ -3114,7 +3114,7 @@ static void Brw_ShowFileBrowserProject (void) Brw_ShowFileBrowser (); } - if (Brw_CheckIfICanViewProjectAssessment (MyRoleInProject)) + if (Brw_CheckIfICanViewProjectAssessment (MyRolesInProject)) { /***** Show the tree with the project assessment *****/ Gbl.FileBrowser.Type = Brw_ADMI_ASS_PRJ; @@ -11619,23 +11619,14 @@ static bool Brw_CheckIfICanModifyPrivateFileOrFolder (void) /******** Check if I have permission to view project documents zone **********/ /*****************************************************************************/ -static bool Brw_CheckIfICanViewProjectDocuments (Prj_RoleInProject_t MyRoleInProject) +static bool Brw_CheckIfICanViewProjectDocuments (unsigned MyRolesInProject) { switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: case Rol_NET: case Rol_TCH: - switch (MyRoleInProject) - { - case Prj_ROLE_UNK: // I am not a member - return false; - case Prj_ROLE_STD: - case Prj_ROLE_TUT: - case Prj_ROLE_EVL: - return true; - } - break; + return (MyRolesInProject != 0); // Am I a member? case Rol_SYS_ADM: return true; default: @@ -11648,23 +11639,15 @@ static bool Brw_CheckIfICanViewProjectDocuments (Prj_RoleInProject_t MyRoleInPro /******** Check if I have permission to view project assessment zone *********/ /*****************************************************************************/ -static bool Brw_CheckIfICanViewProjectAssessment (Prj_RoleInProject_t MyRoleInProject) +static bool Brw_CheckIfICanViewProjectAssessment (unsigned MyRolesInProject) { switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: case Rol_NET: case Rol_TCH: - switch (MyRoleInProject) - { - case Prj_ROLE_UNK: // I am not a member - case Prj_ROLE_STD: // Students can not view or edit project assessment - return false; - case Prj_ROLE_TUT: - case Prj_ROLE_EVL: - return true; - } - break; + return ((MyRolesInProject & (1 << Prj_ROLE_TUT | // Tutor... + 1 << Prj_ROLE_EVL)) != 0); // ...or evaluator case Rol_SYS_ADM: return true; default: @@ -11683,21 +11666,17 @@ static bool Brw_CheckIfICanViewProjectAssessment (Prj_RoleInProject_t MyRoleInPr static bool Brw_CheckIfICanModifyPrjDocFileOrFolder (void) { + unsigned MyRolesInProject; + switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: case Rol_NET: case Rol_TCH: - switch (Prj_GetMyRoleInProject (Gbl.Prjs.PrjCod)) - { - case Prj_ROLE_UNK: // I am not a member - return false; - case Prj_ROLE_STD: - case Prj_ROLE_TUT: - case Prj_ROLE_EVL: - return (Gbl.Usrs.Me.UsrDat.UsrCod == Brw_GetPublisherOfSubtree ()); // Am I the publisher of subtree? - } - break; + MyRolesInProject = Prj_GetMyRolesInProject (Gbl.Prjs.PrjCod); + if (MyRolesInProject) // I am a member + return (Gbl.Usrs.Me.UsrDat.UsrCod == Brw_GetPublisherOfSubtree ()); // Am I the publisher of subtree? + return false; case Rol_SYS_ADM: return true; default: @@ -11716,21 +11695,18 @@ static bool Brw_CheckIfICanModifyPrjDocFileOrFolder (void) static bool Brw_CheckIfICanModifyPrjAssFileOrFolder (void) { + unsigned MyRolesInProject; + switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: case Rol_NET: case Rol_TCH: - switch (Prj_GetMyRoleInProject (Gbl.Prjs.PrjCod)) - { - case Prj_ROLE_UNK: // I am not a member - case Prj_ROLE_STD: // Students can not view or edit project assessment - return false; - case Prj_ROLE_TUT: - case Prj_ROLE_EVL: - return (Gbl.Usrs.Me.UsrDat.UsrCod == Brw_GetPublisherOfSubtree ()); // Am I the publisher of subtree? - } - break; + MyRolesInProject = Prj_GetMyRolesInProject (Gbl.Prjs.PrjCod); + if ((MyRolesInProject & (1 << Prj_ROLE_TUT | // Tutor... + 1 << Prj_ROLE_EVL))) // ...or evaluator + return (Gbl.Usrs.Me.UsrDat.UsrCod == Brw_GetPublisherOfSubtree ()); // Am I the publisher of subtree? + return false; case Rol_SYS_ADM: return true; default: diff --git a/swad_global.c b/swad_global.c index be712672..62185a74 100644 --- a/swad_global.c +++ b/swad_global.c @@ -416,7 +416,7 @@ void Gbl_InitializeGlobals (void) Usr_FlushCacheUsrHasAcceptedInCurrentCrs (); Usr_FlushCacheUsrSharesAnyOfMyCrs (); Rol_FlushCacheRoleUsrInCrs (); - Prj_FlushCacheMyRoleInProject (); + Prj_FlushCacheMyRolesInProject (); Grp_FlushCacheIBelongToGrp (); Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (); Fol_FlushCacheFollow (); diff --git a/swad_global.h b/swad_global.h index 2dc6ce9c..a442edfb 100644 --- a/swad_global.h +++ b/swad_global.h @@ -838,8 +838,8 @@ struct Globals struct { long PrjCod; - Prj_RoleInProject_t RoleInProject; - } MyRoleInProject; + unsigned RolesInProject; + } MyRolesInProject; struct { long UsrCod; diff --git a/swad_project.c b/swad_project.c index b75d3eb2..6762bff0 100644 --- a/swad_project.c +++ b/swad_project.c @@ -923,7 +923,7 @@ static void Prj_ShowOneProject (unsigned NumIndex,struct Project *Prj, extern const char *Txt_Required_knowledge; extern const char *Txt_Required_materials; static unsigned UniqueId = 0; - bool ICanViewProjectFiles = Prj_CheckIfICanViewProjectFiles (Prj_GetMyRoleInProject (Prj->PrjCod)); + bool ICanViewProjectFiles = Prj_CheckIfICanViewProjectFiles (Prj_GetMyRolesInProject (Prj->PrjCod)); /***** Write first row of data of this project *****/ fprintf (Gbl.F.Out,""); @@ -1804,41 +1804,49 @@ static unsigned Prj_GetUsrsInPrj (long PrjCod,Prj_RoleInProject_t RoleInProject, /************************** Get my role in a project *************************/ /*****************************************************************************/ -void Prj_FlushCacheMyRoleInProject (void) +void Prj_FlushCacheMyRolesInProject (void) { - Gbl.Cache.MyRoleInProject.PrjCod = -1L; - Gbl.Cache.MyRoleInProject.RoleInProject = Prj_ROLE_UNK; + Gbl.Cache.MyRolesInProject.PrjCod = -1L; + Gbl.Cache.MyRolesInProject.RolesInProject = 0; } -Prj_RoleInProject_t Prj_GetMyRoleInProject (long PrjCod) +unsigned Prj_GetMyRolesInProject (long PrjCod) { MYSQL_RES *mysql_res; MYSQL_ROW row; + unsigned NumRows; + unsigned NumRow; + Prj_RoleInProject_t RoleInProject; /***** 1. Fast check: trivial cases *****/ if (Gbl.Usrs.Me.UsrDat.UsrCod <= 0 || PrjCod <= 0) - return Prj_ROLE_UNK; + return 0; /***** 2. Fast check: Is my role in project already calculated *****/ - if (PrjCod == Gbl.Cache.MyRoleInProject.PrjCod) - return Gbl.Cache.MyRoleInProject.RoleInProject; + if (PrjCod == Gbl.Cache.MyRolesInProject.PrjCod) + return Gbl.Cache.MyRolesInProject.RolesInProject; /***** 3. Slow check: Get my role in project from database. The result of the query will have one row or none *****/ - Gbl.Cache.MyRoleInProject.PrjCod = PrjCod; - Gbl.Cache.MyRoleInProject.RoleInProject = Prj_ROLE_UNK; - if (DB_QuerySELECT (&mysql_res,"can not get my role in project", - "SELECT RoleInProject FROM prj_usr" - " WHERE PrjCod=%ld AND UsrCod=%ld", - PrjCod,Gbl.Usrs.Me.UsrDat.UsrCod)) + Gbl.Cache.MyRolesInProject.PrjCod = PrjCod; + Gbl.Cache.MyRolesInProject.RolesInProject = 0; + NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get my roles in project", + "SELECT RoleInProject FROM prj_usr" + " WHERE PrjCod=%ld AND UsrCod=%ld", + PrjCod,Gbl.Usrs.Me.UsrDat.UsrCod); + for (NumRow = 0; + NumRow < NumRows; + NumRow++) { row = mysql_fetch_row (mysql_res); - Gbl.Cache.MyRoleInProject.RoleInProject = Prj_ConvertUnsignedStrToRoleInProject (row[0]); + RoleInProject = Prj_ConvertUnsignedStrToRoleInProject (row[0]); + if (RoleInProject != Prj_ROLE_UNK) + Gbl.Cache.MyRolesInProject.RolesInProject |= (1 << RoleInProject); } DB_FreeMySQLResult (&mysql_res); - return Gbl.Cache.MyRoleInProject.RoleInProject; + return Gbl.Cache.MyRolesInProject.RolesInProject; } /*****************************************************************************/ @@ -1982,7 +1990,7 @@ static void Prj_AddUsrsToProject (Prj_RoleInProject_t RoleInProject) /* Flush cache */ ItsMe = Usr_ItsMe (Gbl.Usrs.Other.UsrDat.UsrCod); if (ItsMe) - Prj_FlushCacheMyRoleInProject (); + Prj_FlushCacheMyRolesInProject (); /* Show success alert */ Ale_ShowAlert (Ale_SUCCESS,Txt_THE_USER_X_has_been_enroled_as_a_Y_in_the_project, @@ -2140,7 +2148,7 @@ static void Prj_RemUsrFromPrj (Prj_RoleInProject_t RoleInProject) /***** Flush cache *****/ ItsMe = Usr_ItsMe (Gbl.Usrs.Other.UsrDat.UsrCod); if (ItsMe) - Prj_FlushCacheMyRoleInProject (); + Prj_FlushCacheMyRolesInProject (); /***** Show success alert *****/ Ale_ShowAlert (Ale_SUCCESS,Txt_THE_USER_X_has_been_removed_as_a_Y_from_the_project_Z, @@ -2224,23 +2232,14 @@ static void Prj_PutFormsToRemEditOnePrj (long PrjCod,Prj_HiddenVisibl_t Hidden, /******************** Can I view files of a given project? *******************/ /*****************************************************************************/ -bool Prj_CheckIfICanViewProjectFiles (Prj_RoleInProject_t MyRoleInProject) +bool Prj_CheckIfICanViewProjectFiles (unsigned MyRolesInProject) { switch (Gbl.Usrs.Me.Role.Logged) { case Rol_STD: case Rol_NET: case Rol_TCH: - switch (MyRoleInProject) - { - case Prj_ROLE_UNK: // I am not a member - return false; - case Prj_ROLE_STD: - case Prj_ROLE_TUT: - case Prj_ROLE_EVL: - return true; - } - return false; + return (MyRolesInProject != 0); // Am I a member? case Rol_SYS_ADM: return true; default: @@ -2257,7 +2256,7 @@ static bool Prj_CheckIfICanEditProject (long PrjCod) switch (Gbl.Usrs.Me.Role.Logged) { case Rol_NET: - return (Prj_GetMyRoleInProject (PrjCod) == Prj_ROLE_TUT); + return ((Prj_GetMyRolesInProject (PrjCod) & (1 << Prj_ROLE_TUT)) != 0); // Am I tutor? case Rol_TCH: case Rol_SYS_ADM: return true; @@ -2742,7 +2741,7 @@ void Prj_RemoveProject (void) Prj.PrjCod,Gbl.Hierarchy.Crs.CrsCod); /***** Flush cache *****/ - Prj_FlushCacheMyRoleInProject (); + Prj_FlushCacheMyRolesInProject (); /***** Remove project *****/ DB_QueryDELETE ("can not remove project", @@ -3337,7 +3336,7 @@ static void Prj_CreateProject (struct Project *Prj) Gbl.Usrs.Me.UsrDat.UsrCod); /***** Flush cache *****/ - Prj_FlushCacheMyRoleInProject (); + Prj_FlushCacheMyRolesInProject (); } /*****************************************************************************/ @@ -3394,7 +3393,7 @@ void Prj_RemoveCrsProjects (long CrsCod) CrsCod); /***** Flush cache *****/ - Prj_FlushCacheMyRoleInProject (); + Prj_FlushCacheMyRolesInProject (); /***** Remove projects *****/ DB_QueryDELETE ("can not remove all the projects of a course", @@ -3418,7 +3417,7 @@ void Prj_RemoveUsrFromProjects (long UsrCod) /***** Flush cache *****/ ItsMe = Usr_ItsMe (UsrCod); if (ItsMe) - Prj_FlushCacheMyRoleInProject (); + Prj_FlushCacheMyRolesInProject (); } /*****************************************************************************/ diff --git a/swad_project.h b/swad_project.h index dcbc9ab3..fe9795d7 100644 --- a/swad_project.h +++ b/swad_project.h @@ -151,8 +151,8 @@ void Prj_ShowOneUniqueProject (struct Project *Prj); void Prj_PrintOneProject (void); -void Prj_FlushCacheMyRoleInProject (void); -Prj_RoleInProject_t Prj_GetMyRoleInProject (long PrjCod); +void Prj_FlushCacheMyRolesInProject (void); +Prj_RoleInProject_t Prj_GetMyRolesInProject (long PrjCod); void Prj_ReqAddStds (void); void Prj_ReqAddTuts (void); @@ -172,7 +172,7 @@ void Prj_RemEvl (void); void Prj_PutHiddenParamPrjOrder (void); -bool Prj_CheckIfICanViewProjectFiles (Prj_RoleInProject_t MyRoleInProject); +bool Prj_CheckIfICanViewProjectFiles (unsigned MyRolesInProject); void Prj_RequestCreatePrj (void); void Prj_RequestEditPrj (void);