From e4b2c08d7096a85dead3b563f47c39bf0c472cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Wed, 8 Jan 2020 23:49:04 +0100 Subject: [PATCH] Version19.114 --- Makefile | 1 + swad_QR.c | 22 +- swad_action.c | 16 +- swad_action.h | 81 +++---- swad_centre.c | 18 +- swad_centre_config.c | 6 +- swad_changelog.h | 4 +- swad_country.c | 21 +- swad_country_config.c | 50 ++++- swad_course.c | 38 ++-- swad_course_config.c | 6 +- swad_degree.c | 1 - swad_degree_config.c | 6 +- swad_department.c | 6 +- swad_enrolment.c | 22 +- swad_figure.c | 63 ++++-- swad_global.c | 4 - swad_global.h | 25 --- swad_help.c | 3 +- swad_help_URL.c | 21 ++ swad_hierarchy_config.c | 28 ++- swad_indicator.c | 8 +- swad_institution.c | 20 +- swad_institution_config.c | 6 +- swad_mark.c | 3 +- swad_menu.c | 11 +- swad_network.c | 17 +- swad_notification.c | 7 +- swad_report.c | 8 +- swad_tab.c | 8 +- swad_text.c | 85 ++++++-- swad_text_action.c | 80 +++++-- swad_user.c | 442 ++++++-------------------------------- swad_user.h | 12 +- 34 files changed, 550 insertions(+), 599 deletions(-) diff --git a/Makefile b/Makefile index 015b82b2..e215a063 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,7 @@ OBJS = swad_account.o swad_action.o swad_agenda.o swad_alert.o \ swad_record.o swad_report.o swad_role.o swad_RSS.o \ swad_scope.o swad_search.o swad_session.o swad_setting.o swad_setup.o \ swad_statistic.o swad_string.o swad_survey.o swad_syllabus.o \ + swad_system_config.o \ swad_tab.o swad_test.o swad_test_import.o swad_theme.o swad_timeline.o \ swad_timetable.o \ swad_user.o \ diff --git a/swad_QR.c b/swad_QR.c index c43505b3..2a6118a2 100644 --- a/swad_QR.c +++ b/swad_QR.c @@ -135,12 +135,22 @@ void QR_LinkTo (unsigned Size,const char *ParamName,long Cod) extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; char *URL; - /***** Show QR code with direct link to the current centre *****/ - if (asprintf (&URL,"https://chart.googleapis.com/chart?cht=qr&chs=%ux%u&chl=%s/%s?%s=%ld", - Size,Size, - Cfg_URL_SWAD_CGI, - Lan_STR_LANG_ID[Gbl.Prefs.Language],ParamName,Cod) < 0) - Lay_NotEnoughMemoryExit (); + /***** Show QR code with link *****/ + if (ParamName) + { + if (asprintf (&URL,"https://chart.googleapis.com/chart?cht=qr&chs=%ux%u&chl=%s/%s?%s=%ld", + Size,Size, + Cfg_URL_SWAD_CGI,Lan_STR_LANG_ID[Gbl.Prefs.Language], + ParamName,Cod) < 0) + Lay_NotEnoughMemoryExit (); + } + else + { + if (asprintf (&URL,"https://chart.googleapis.com/chart?cht=qr&chs=%ux%u&chl=%s/%s", + Size,Size, + Cfg_URL_SWAD_CGI,Lan_STR_LANG_ID[Gbl.Prefs.Language]) < 0) + Lay_NotEnoughMemoryExit (); + } HTM_IMG (URL,NULL,Txt_Shortcut, "style=\"width:%upx;height:%upx;\"",Size,Size); free (URL); diff --git a/swad_action.c b/swad_action.c index 29a9511d..e3bbf977 100644 --- a/swad_action.c +++ b/swad_action.c @@ -79,6 +79,7 @@ #include "swad_search.h" #include "swad_setting.h" #include "swad_setup.h" +#include "swad_system_config.h" #include "swad_tab.h" #include "swad_test_import.h" #include "swad_timeline.h" @@ -186,13 +187,16 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = // TabSys ****************************************************************** // Actions in menu: - [ActSeeCty ] = { 862, 0,TabSys,ActSeeCty , 0, 0, 0, 0, 0, 0,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,Cty_ListCountries1 ,Cty_ListCountries2 ,"globe" }, - [ActSeePen ] = {1060, 1,TabSys,ActSeePen , 0, 0, 0, 0, 0, 0,0x3C0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Hie_SeePending ,"sitemap" }, - [ActSeeLnk ] = { 748, 2,TabSys,ActSeeLnk , 0, 0, 0, 0, 0, 0,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Lnk_SeeLinks ,"link" }, - [ActLstPlg ] = { 777, 3,TabSys,ActLstPlg , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Plg_ListPlugins ,"puzzle-piece" }, - [ActSetUp ] = { 840, 4,TabSys,ActSetUp , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,SUp_SetUp ,"bolt" }, + [ActSeeSysInf ] = {1818, 0,TabSys,ActSeeSysInf , 0, 0, 0, 0, 0, 0,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,SysCfg_ShowConfiguration ,"info" }, + [ActSeeCty ] = { 862, 1,TabSys,ActSeeCty , 0, 0, 0, 0, 0, 0,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,Cty_ListCountries1 ,Cty_ListCountries2 ,"globe" }, + [ActSeePen ] = {1060, 2,TabSys,ActSeePen , 0, 0, 0, 0, 0, 0,0x3C0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Hie_SeePending ,"sitemap" }, + [ActSeeLnk ] = { 748, 3,TabSys,ActSeeLnk , 0, 0, 0, 0, 0, 0,0x3C7,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Lnk_SeeLinks ,"link" }, + [ActLstPlg ] = { 777, 4,TabSys,ActLstPlg , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Plg_ListPlugins ,"puzzle-piece" }, + [ActSetUp ] = { 840, 5,TabSys,ActSetUp , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,SUp_SetUp ,"bolt" }, // Actions not in menu: + [ActPrnSysInf ] = {1819,-1,TabUnk,ActSeeSysInf , 0, 0, 0, 0, 0, 0,0x3C7,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,SysCfg_PrintConfiguration ,NULL}, + [ActEdiCty ] = { 863,-1,TabUnk,ActSeeCty , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Cty_EditCountries ,NULL}, [ActNewCty ] = { 864,-1,TabUnk,ActSeeCty , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,Cty_RecFormNewCountry ,Cty_ContEditAfterChgCty ,NULL}, [ActRemCty ] = { 893,-1,TabUnk,ActSeeCty , 0, 0, 0, 0, 0, 0,0x200,Act_CONT_NORM,Act_BRW_1ST_TAB,Cty_RemoveCountry ,Cty_ContEditAfterChgCty ,NULL}, @@ -3527,6 +3531,8 @@ Act_Action_t Act_FromActCodToAction[1 + Act_MAX_ACTION_COD] = // Do not reuse un ActChgCtrLatCfg, // #1815 ActChgCtrLgtCfg, // #1816 ActChgCtrAltCfg, // #1817 + ActSeeSysInf, // #1818 + ActPrnSysInf, // #1819 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index 85d3d260..ae62948e 100644 --- a/swad_action.h +++ b/swad_action.h @@ -64,7 +64,7 @@ typedef enum typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action -#define Act_MAX_ACTION_COD 1817 +#define Act_MAX_ACTION_COD 1819 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 13 @@ -165,50 +165,53 @@ typedef signed int Act_Action_t; // Must be a signed type, because -1 is used to /******************************** System tab *********************************/ /*****************************************************************************/ // Actions in menu -#define ActSeeCty (ActRenMaiFul + 1) -#define ActSeePen (ActRenMaiFul + 2) -#define ActSeeLnk (ActRenMaiFul + 3) -#define ActLstPlg (ActRenMaiFul + 4) -#define ActSetUp (ActRenMaiFul + 5) +#define ActSeeSysInf (ActRenMaiFul + 1) +#define ActSeeCty (ActRenMaiFul + 2) +#define ActSeePen (ActRenMaiFul + 3) +#define ActSeeLnk (ActRenMaiFul + 4) +#define ActLstPlg (ActRenMaiFul + 5) +#define ActSetUp (ActRenMaiFul + 6) // Secondary actions -#define ActEdiCty (ActRenMaiFul + 6) -#define ActNewCty (ActRenMaiFul + 7) -#define ActRemCty (ActRenMaiFul + 8) -#define ActRenCty (ActRenMaiFul + 9) -#define ActChgCtyWWW (ActRenMaiFul + 10) +#define ActPrnSysInf (ActRenMaiFul + 7) -#define ActReqRemOldCrs (ActRenMaiFul + 11) -#define ActRemOldCrs (ActRenMaiFul + 12) +#define ActEdiCty (ActRenMaiFul + 8) +#define ActNewCty (ActRenMaiFul + 9) +#define ActRemCty (ActRenMaiFul + 10) +#define ActRenCty (ActRenMaiFul + 11) +#define ActChgCtyWWW (ActRenMaiFul + 12) -#define ActSeeBan (ActRenMaiFul + 13) -#define ActEdiBan (ActRenMaiFul + 14) -#define ActNewBan (ActRenMaiFul + 15) -#define ActRemBan (ActRenMaiFul + 16) -#define ActShoBan (ActRenMaiFul + 17) -#define ActHidBan (ActRenMaiFul + 18) -#define ActRenBanSho (ActRenMaiFul + 19) -#define ActRenBanFul (ActRenMaiFul + 20) -#define ActChgBanImg (ActRenMaiFul + 21) -#define ActChgBanWWW (ActRenMaiFul + 22) -#define ActClkBan (ActRenMaiFul + 23) +#define ActReqRemOldCrs (ActRenMaiFul + 13) +#define ActRemOldCrs (ActRenMaiFul + 14) -#define ActEdiLnk (ActRenMaiFul + 24) -#define ActNewLnk (ActRenMaiFul + 25) -#define ActRemLnk (ActRenMaiFul + 26) -#define ActRenLnkSho (ActRenMaiFul + 27) -#define ActRenLnkFul (ActRenMaiFul + 28) -#define ActChgLnkWWW (ActRenMaiFul + 29) +#define ActSeeBan (ActRenMaiFul + 15) +#define ActEdiBan (ActRenMaiFul + 16) +#define ActNewBan (ActRenMaiFul + 17) +#define ActRemBan (ActRenMaiFul + 18) +#define ActShoBan (ActRenMaiFul + 19) +#define ActHidBan (ActRenMaiFul + 20) +#define ActRenBanSho (ActRenMaiFul + 21) +#define ActRenBanFul (ActRenMaiFul + 22) +#define ActChgBanImg (ActRenMaiFul + 23) +#define ActChgBanWWW (ActRenMaiFul + 24) +#define ActClkBan (ActRenMaiFul + 25) -#define ActEdiPlg (ActRenMaiFul + 30) -#define ActNewPlg (ActRenMaiFul + 31) -#define ActRemPlg (ActRenMaiFul + 32) -#define ActRenPlg (ActRenMaiFul + 33) -#define ActChgPlgDes (ActRenMaiFul + 34) -#define ActChgPlgLog (ActRenMaiFul + 35) -#define ActChgPlgAppKey (ActRenMaiFul + 36) -#define ActChgPlgURL (ActRenMaiFul + 37) -#define ActChgPlgIP (ActRenMaiFul + 38) +#define ActEdiLnk (ActRenMaiFul + 26) +#define ActNewLnk (ActRenMaiFul + 27) +#define ActRemLnk (ActRenMaiFul + 28) +#define ActRenLnkSho (ActRenMaiFul + 29) +#define ActRenLnkFul (ActRenMaiFul + 30) +#define ActChgLnkWWW (ActRenMaiFul + 31) + +#define ActEdiPlg (ActRenMaiFul + 32) +#define ActNewPlg (ActRenMaiFul + 33) +#define ActRemPlg (ActRenMaiFul + 34) +#define ActRenPlg (ActRenMaiFul + 35) +#define ActChgPlgDes (ActRenMaiFul + 36) +#define ActChgPlgLog (ActRenMaiFul + 37) +#define ActChgPlgAppKey (ActRenMaiFul + 38) +#define ActChgPlgURL (ActRenMaiFul + 39) +#define ActChgPlgIP (ActRenMaiFul + 40) /*****************************************************************************/ /******************************** Country tab ********************************/ diff --git a/swad_centre.c b/swad_centre.c index cd6c2b42..2ccf5b8b 100644 --- a/swad_centre.c +++ b/swad_centre.c @@ -416,8 +416,10 @@ static void Ctr_ListOneCentreForSeeing (struct Centre *Ctr,unsigned NumCtr) /***** Number of users in courses of this centre *****/ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Usr_GetNumUsrsInCrssOfCtr (Rol_UNK, // Here Rol_UNK means "all users" - Ctr->CtrCod)); + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_CTR,Ctr->CtrCod, + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH)); // Any user HTM_TD_End (); /***** Centre status *****/ @@ -954,7 +956,10 @@ static void Ctr_ListCentresForEdition (void) Ctr = &Gbl.Hierarchy.Ctrs.Lst[NumCtr]; ICanEdit = Ctr_CheckIfICanEditACentre (Ctr); - NumUsrsInCrssOfCtr = Usr_GetNumUsrsInCrssOfCtr (Rol_UNK,Ctr->CtrCod); // Here Rol_UNK means "all users" + NumUsrsInCrssOfCtr = Usr_GetNumUsrsInCrss (Hie_CTR,Ctr->CtrCod, + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH); // Any user /* Put icon to remove centre */ HTM_TR_Begin (NULL); @@ -1233,8 +1238,10 @@ void Ctr_RemoveCentre (void) else if (Usr_GetNumUsrsWhoClaimToBelongToCtr (Ctr_EditingCtr)) // Centre has users who claim to belong to it Ale_ShowAlert (Ale_WARNING, Txt_To_remove_a_centre_you_must_first_remove_all_degrees_and_teachers_in_the_centre); - else if (Usr_GetNumUsrsInCrssOfCtr (Rol_UNK, // Here Rol_UNK means "all users" - Ctr_EditingCtr->CtrCod)) // Centre has users + else if (Usr_GetNumUsrsInCrss (Hie_CTR,Ctr_EditingCtr->CtrCod, + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH)) // Centre has users Ale_ShowAlert (Ale_WARNING, Txt_To_remove_a_centre_you_must_first_remove_all_degrees_and_teachers_in_the_centre); else // Centre has no degrees or users ==> remove it @@ -1268,7 +1275,6 @@ void Ctr_RemoveCentre (void) Deg_FlushCacheNumDegsInCtr (); Crs_FlushCacheNumCrssInCtr (); Usr_FlushCacheNumUsrsWhoClaimToBelongToCtr (); - Usr_FlushCacheNumUsrsInCrssOfCtr (); /***** Write message to show the change made *****/ Ale_CreateAlert (Ale_SUCCESS,NULL, diff --git a/swad_centre_config.c b/swad_centre_config.c index 7382a210..9cf4334f 100644 --- a/swad_centre_config.c +++ b/swad_centre_config.c @@ -826,7 +826,11 @@ static void CtrCfg_NumUsrsInCrssOfCtr (Rol_Role_t Role) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Usr_GetNumUsrsInCrssOfCtr (Role,Gbl.Hierarchy.Ctr.CtrCod)); + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_CTR,Gbl.Hierarchy.Ctr.CtrCod, + Role == Rol_UNK ? 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH : // Any user + 1 << Role)); HTM_TD_End (); HTM_TR_End (); diff --git a/swad_changelog.h b/swad_changelog.h index 13afd4ac..c6814dbf 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -492,7 +492,7 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.113 (2020-01-08)" +#define Log_PLATFORM_VERSION "SWAD 19.114 (2020-01-08)" #define CSS_FILE "swad19.112.css" #define JS_FILE "swad19.91.1.js" /* @@ -501,6 +501,8 @@ ps2pdf source.ps destination.pdf // TODO: No se puede entrar con DNI '1' suponiendo que no tenga password ¿por qué? // TODO: Mapas más estrechos en móvil + Version 19.114: Jan 08, 2020 New option in System tab to view platform configuration. + Optimizations in number of users in courses. (278462 lines) Version 19.113: Jan 08, 2020 Code refactoring related to hierarchy. Changing action descriptions from database to swad-core. Not finished. (278076 lines) Version 19.112.27:Jan 08, 2020 Changing action descriptions from database to swad-core. Not finished. (278715 lines) diff --git a/swad_country.c b/swad_country.c index 99c63085..332673fc 100644 --- a/swad_country.c +++ b/swad_country.c @@ -277,7 +277,9 @@ void Cty_ListCountries2 (void) HTM_TD_End (); HTM_TD_Begin ("class=\"DAT RM\""); - HTM_Unsigned (Usr_GetNumUsrsInCrssOfCty (Rol_TCH,0)); + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_CTY,0, + 1 << Rol_NET | // Non-editing teachers + 1 << Rol_TCH)); // Teachers HTM_TD_End (); HTM_TR_End (); @@ -436,7 +438,10 @@ static void Cty_ListOneCountryForSeeing (struct Country *Cty,unsigned NumCty) HTM_TD_End (); HTM_TD_Begin ("class=\"DAT RM %s\"",BgColor); - HTM_Unsigned (Usr_GetNumUsrsInCrssOfCty (Rol_UNK,Cty->CtyCod)); // Here Rol_UNK means "all users" + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_CTY,Cty->CtyCod, + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH)); // Any user HTM_TD_End (); HTM_TR_End (); @@ -1186,8 +1191,10 @@ static void Cty_ListCountriesForEdition (void) else if (Usr_GetNumUsrsWhoClaimToBelongToCty (Cty)) // Country has users // Deletion forbidden Ico_PutIconRemovalNotAllowed (); - else if (Usr_GetNumUsrsInCrssOfCty (Rol_UNK, // Here Rol_UNK means "all users" - Cty->CtyCod)) // Country has users + else if (Usr_GetNumUsrsInCrss (Hie_CTY,Cty->CtyCod, + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH)) // Country has users // Deletion forbidden Ico_PutIconRemovalNotAllowed (); else @@ -1327,8 +1334,10 @@ void Cty_RemoveCountry (void) else if (Usr_GetNumUsrsWhoClaimToBelongToCty (Cty_EditingCty)) // Country has users ==> don't remove Ale_CreateAlert (Ale_WARNING,NULL, Txt_You_can_not_remove_a_country_with_institutions_or_users); - else if (Usr_GetNumUsrsInCrssOfCty (Rol_UNK, // Here Rol_UNK means "all users" - Cty_EditingCty->CtyCod)) // Country has users + else if (Usr_GetNumUsrsInCrss (Hie_CTY,Cty_EditingCty->CtyCod, + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH)) // Country has users Ale_CreateAlert (Ale_WARNING,NULL, Txt_You_can_not_remove_a_country_with_institutions_or_users); else // Country has no users ==> remove it diff --git a/swad_country_config.c b/swad_country_config.c index e1e6a8e5..f23911e3 100644 --- a/swad_country_config.c +++ b/swad_country_config.c @@ -68,6 +68,7 @@ static bool CtyCfg_GetIfMapIsAvailable (void); static void CtyCfg_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom); static void CtyCfg_Map (void); static void CtyCfg_MapImage (bool PrintView,bool PutLink); +static void CtyCfg_Platform (bool PrintView); static void CtyCfg_Name (bool PutLink); static void CtyCfg_Shortcut (bool PrintView); static void CtyCfg_QR (void); @@ -137,6 +138,9 @@ static void CtyCfg_Configuration (bool PrintView) /***** Begin table *****/ HTM_TABLE_BeginWidePadding (2); + /***** Platform *****/ + CtyCfg_Platform (PrintView); + /***** Country name (an link to WWW if exists) *****/ CtyCfg_Name (PutLink); @@ -148,7 +152,7 @@ static void CtyCfg_Configuration (bool PrintView) CtyCfg_QR (); else { - /***** Number of users who claim to belong to this centre, + /***** Number of users who claim to belong to this country, number of institutions, number of centres, number of degrees, @@ -311,7 +315,7 @@ static void CtyCfg_Map (void) /* Get centres with coordinates */ NumCtrs = (unsigned) DB_QuerySELECT (&mysql_res,"can not get centres" " with coordinates", - "SELECT CtrCod" // row[0] + "SELECT centres.CtrCod" // row[0] " FROM institutions,centres" " WHERE institutions.CtyCod=%ld" " AND institutions.InsCod=centres.InsCod" @@ -398,6 +402,42 @@ static void CtyCfg_MapImage (bool PrintView,bool PutLink) CtyCfg_FreeMapAttr (&MapAttribution); } +/*****************************************************************************/ +/****************** Show platform in country configuration *******************/ +/*****************************************************************************/ + +static void CtyCfg_Platform (bool PrintView) + { + extern const char *Txt_Platform; + + /***** Institution *****/ + HTM_TR_Begin (NULL); + + /* Label */ + Frm_LabelColumn ("RT",NULL,Txt_Platform); + + /* Data */ + HTM_TD_Begin ("class=\"DAT LB\""); + if (!PrintView) + { + Frm_StartFormGoTo (ActSeeSysInf); + HTM_BUTTON_SUBMIT_Begin (Hie_BuildGoToMsg (Cfg_PLATFORM_SHORT_NAME), + "BT_LINK LT DAT",NULL); + Hie_FreeGoToMsg (); + } + Ico_PutIcon ("swad64x64.png",Cfg_PLATFORM_FULL_NAME,"ICO20x20"); + HTM_NBSP (); + HTM_Txt (Cfg_PLATFORM_SHORT_NAME); + if (!PrintView) + { + HTM_BUTTON_End (); + Frm_EndForm (); + } + HTM_TD_End (); + + HTM_TR_End (); + } + /*****************************************************************************/ /**************** Show country name in country configuration *****************/ /*****************************************************************************/ @@ -581,7 +621,11 @@ static void CtyCfg_NumUsrsInCrssOfCty (Rol_Role_t Role) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Usr_GetNumUsrsInCrssOfCty (Role,Gbl.Hierarchy.Cty.CtyCod)); + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_CTY,Gbl.Hierarchy.Cty.CtyCod, + Role == Rol_UNK ? 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH : // Any user + 1 << Role)); HTM_TD_End (); HTM_TR_End (); diff --git a/swad_course.c b/swad_course.c index d5fd6ddc..31f4cd11 100644 --- a/swad_course.c +++ b/swad_course.c @@ -918,10 +918,12 @@ static bool Crs_ListCoursesOfAYearForSeeing (unsigned Year) HTM_TR_Begin (NULL); /* Get number of users */ - NumUsrs[Rol_UNK] = Usr_GetNumUsrsInCrs (Rol_UNK,Crs->CrsCod); - NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrs (Rol_STD,Crs->CrsCod); - NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrs (Rol_NET,Crs->CrsCod); - NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrs (Rol_TCH,Crs->CrsCod); + NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrss (Hie_CRS,Crs->CrsCod,1 << Rol_STD); + NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrss (Hie_CRS,Crs->CrsCod,1 << Rol_NET); + NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrss (Hie_CRS,Crs->CrsCod,1 << Rol_TCH); + NumUsrs[Rol_UNK] = NumUsrs[Rol_STD] + + NumUsrs[Rol_NET] + + NumUsrs[Rol_TCH]; /* Put green tip if course has users */ HTM_TD_Begin ("class=\"%s CM %s\" title=\"%s\"", @@ -1114,10 +1116,12 @@ static void Crs_ListCoursesOfAYearForEdition (unsigned Year) ICanEdit = Crs_CheckIfICanEdit (Crs); /* Get number of users */ - NumUsrs[Rol_UNK] = Usr_GetNumUsrsInCrs (Rol_UNK,Crs->CrsCod); - NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrs (Rol_STD,Crs->CrsCod); - NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrs (Rol_NET,Crs->CrsCod); - NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrs (Rol_TCH,Crs->CrsCod); + NumUsrs[Rol_STD] = Usr_GetNumUsrsInCrss (Hie_CRS,Crs->CrsCod,1 << Rol_STD); + NumUsrs[Rol_NET] = Usr_GetNumUsrsInCrss (Hie_CRS,Crs->CrsCod,1 << Rol_NET); + NumUsrs[Rol_TCH] = Usr_GetNumUsrsInCrss (Hie_CRS,Crs->CrsCod,1 << Rol_TCH); + NumUsrs[Rol_UNK] = NumUsrs[Rol_STD] + + NumUsrs[Rol_NET] + + NumUsrs[Rol_TCH]; HTM_TR_Begin (NULL); @@ -1610,10 +1614,13 @@ void Crs_RemoveCourse (void) if (Crs_CheckIfICanEdit (Crs_EditingCrs)) { /***** Check if this course has users *****/ - if (Usr_GetNumUsrsInCrs (Rol_UNK,Crs_EditingCrs->CrsCod)) // Course has users ==> don't remove + if (Usr_GetNumUsrsInCrss (Hie_CRS,Crs_EditingCrs->CrsCod, + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH)) // Course has users ==> don't remove Ale_ShowAlert (Ale_WARNING, Txt_To_remove_a_course_you_must_first_remove_all_users_in_the_course); - else // Course has no users ==> remove it + else // Course has no users ==> remove it { /***** Remove course *****/ Crs_RemoveCourseCompletely (Crs_EditingCrs->CrsCod); @@ -1771,9 +1778,6 @@ void Crs_RemoveCourseCompletely (long CrsCod) DB_QueryDELETE ("can not remove a course", "DELETE FROM courses WHERE CrsCod=%ld", CrsCod); - - /***** Flush caches *****/ - Usr_FlushCacheNumUsrsInCrs (); } } @@ -2641,9 +2645,11 @@ static void Crs_WriteRowCrsData (unsigned NumCrs,MYSQL_ROW row,bool WriteColumnA Lay_ShowErrorAndExit ("Wrong code of course."); /***** Get number of teachers and students in this course *****/ - NumTchs = Usr_GetNumUsrsInCrs (Rol_TCH,CrsCod) + - Usr_GetNumUsrsInCrs (Rol_NET,CrsCod); - NumStds = Usr_GetNumUsrsInCrs (Rol_STD,CrsCod); + NumTchs = Usr_GetNumUsrsInCrss (Hie_CRS,CrsCod, + 1 << Rol_NET | + 1 << Rol_TCH); + NumStds = Usr_GetNumUsrsInCrss (Hie_CRS,CrsCod, + 1 << Rol_STD); if (NumTchs + NumStds) { ClassTxt = "DAT_N"; diff --git a/swad_course_config.c b/swad_course_config.c index e6f09308..c050d610 100644 --- a/swad_course_config.c +++ b/swad_course_config.c @@ -427,7 +427,11 @@ static void CrsCfg_NumUsrsInCrs (Rol_Role_t Role) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Usr_GetNumUsrsInCrs (Role,Gbl.Hierarchy.Crs.CrsCod)); + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Crs.CrsCod, + Role == Rol_UNK ? 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH : // Any user + 1 << Role)); HTM_TD_End (); HTM_TR_End (); diff --git a/swad_degree.c b/swad_degree.c index 813e3841..5217fd68 100644 --- a/swad_degree.c +++ b/swad_degree.c @@ -1512,7 +1512,6 @@ void Deg_RemoveDegreeCompletely (long DegCod) /***** Flush caches *****/ Crs_FlushCacheNumCrssInDeg (); - Usr_FlushCacheNumUsrsInCrssOfDeg (); /***** Delete all the degrees in sta_degrees table not present in degrees table *****/ Pho_RemoveObsoleteStatDegrees (); diff --git a/swad_degree_config.c b/swad_degree_config.c index d1ddd565..be6724c7 100644 --- a/swad_degree_config.c +++ b/swad_degree_config.c @@ -365,7 +365,11 @@ static void DegCfg_NumUsrsInCrssOfDeg (Rol_Role_t Role) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Usr_GetNumUsrsInCrssOfDeg (Role,Gbl.Hierarchy.Deg.DegCod)); + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_DEG,Gbl.Hierarchy.Deg.DegCod, + Role == Rol_UNK ? 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH : // Any user + 1 << Role)); HTM_TD_End (); HTM_TR_End (); diff --git a/swad_department.c b/swad_department.c index 12c321d9..8da83590 100644 --- a/swad_department.c +++ b/swad_department.c @@ -197,9 +197,9 @@ void Dpt_SeeDepts (void) HTM_TD_End (); HTM_TD_Begin ("class=\"DAT RM\""); - HTM_Unsigned (Usr_GetTotalNumberOfUsersInCourses (Hie_INS, - 1 << Rol_NET | - 1 << Rol_TCH) - + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_INS,Gbl.Hierarchy.Ins.InsCod, + 1 << Rol_NET | // Non-editing teachers + 1 << Rol_TCH) - // Teachers NumTchsInsWithDpt); HTM_TD_End (); diff --git a/swad_enrolment.c b/swad_enrolment.c index f7b6fa27..d5cd9f9a 100644 --- a/swad_enrolment.c +++ b/swad_enrolment.c @@ -184,8 +184,9 @@ void Enr_CheckStdsAndPutButtonToRegisterStdsInCurrentCrs (void) { /***** Put link to register students *****/ if (Gbl.Usrs.Me.Role.Logged == Rol_TCH) // Course selected and I am logged as teacher - if (!Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // No students in course - Usr_ShowWarningNoUsersFound (Rol_STD); + if (!Usr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Crs.CrsCod, + 1 << Rol_STD)) // No students in course + Usr_ShowWarningNoUsersFound (Rol_STD); } /*****************************************************************************/ @@ -196,8 +197,9 @@ void Enr_PutButtonInlineToRegisterStds (long CrsCod) { extern const char *Txt_Register_students; - if (Rol_GetRoleUsrInCrs (Gbl.Usrs.Me.UsrDat.UsrCod,CrsCod) == Rol_TCH) // I am a teacher in course - if (!Usr_GetNumUsrsInCrs (Rol_STD,CrsCod)) // No students in course + if (Gbl.Usrs.Me.Role.Logged == Rol_TCH) // Course selected and I am logged as teacher + if (!Usr_GetNumUsrsInCrss (Hie_CRS,CrsCod, + 1 << Rol_STD)) // No students in course { Frm_StartForm (ActReqEnrSevStd); Crs_PutParamCrsCod (CrsCod); @@ -675,7 +677,8 @@ static void Enr_ShowFormRegRemSeveralUsrs (Rol_Role_t Role) Enr_PutLinkToAdminOneUsr (ActReqMdfOneStd); /* Put link to remove all the students in the current course */ - if (Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // This course has students + if (Usr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Crs.CrsCod, + 1 << Rol_STD)) // This course has students Enr_PutLinkToRemAllStdsThisCrs (); break; case Rol_NET: @@ -1821,7 +1824,8 @@ void Enr_AskRemAllStdsThisCrs (void) extern const char *Hlp_USERS_Administration_remove_all_students; extern const char *Txt_Remove_all_students; extern const char *Txt_Do_you_really_want_to_remove_the_X_students_from_the_course_Y_; - unsigned NumStds = Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod); + unsigned NumStds = Usr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Crs.CrsCod, + 1 << Rol_STD); // This course has students /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Remove_all_students,NULL, @@ -2004,7 +2008,8 @@ void Enr_SignUpInCrs (void) // If this course has teachers ==> send notification to teachers // If this course has no teachers and I want to be a teacher ==> send notification to administrators or superusers if (RoleFromForm == Rol_TCH) // TODO: What happens in user wants to enrole as a non-editing teacher? - if (Usr_GetNumUsrsInCrs (Rol_TCH,Gbl.Hierarchy.Crs.CrsCod)) + if (Usr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Crs.CrsCod, + 1 << Rol_TCH)) // This course has teachers Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_ENROLMENT_REQUEST,ReqCod); } } @@ -2837,7 +2842,8 @@ static void Enr_ShowEnrolmentRequestsGivenRoles (unsigned RolesSelected) /***** Number of teachers in the course *****/ HTM_TD_Begin ("class=\"DAT RT\""); - HTM_Unsigned (Usr_GetNumUsrsInCrs (Rol_TCH,Crs.CrsCod)); + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_CRS,Crs.CrsCod, + 1 << Rol_TCH)); HTM_TD_End (); /***** User photo *****/ diff --git a/swad_figure.c b/swad_figure.c index cb140080..126ce733 100644 --- a/swad_figure.c +++ b/swad_figure.c @@ -411,11 +411,17 @@ static void Fig_GetAndShowNumUsrsInCrss (Rol_Role_t Role) unsigned Roles = (Role == Rol_UNK) ? ((1 << Rol_STD) | (1 << Rol_NET) | (1 << Rol_TCH)) : - (1 << Role); + (1 << Role); /***** Get the number of users belonging to any course *****/ - NumUsrs = Usr_GetTotalNumberOfUsersInCourses (Gbl.Scope.Current, - Roles); + NumUsrs = Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + (Gbl.Scope.Current == Hie_CTY ? Gbl.Hierarchy.Cty.CtyCod : + (Gbl.Scope.Current == Hie_INS ? Gbl.Hierarchy.Ins.InsCod : + (Gbl.Scope.Current == Hie_CTR ? Gbl.Hierarchy.Ctr.CtrCod : + (Gbl.Scope.Current == Hie_DEG ? Gbl.Hierarchy.Deg.DegCod : + (Gbl.Scope.Current == Hie_CRS ? Gbl.Hierarchy.Crs.CrsCod : + -1L))))), + Roles); /***** Get average number of courses per user *****/ NumCrssPerUsr = Usr_GetNumCrssPerUsr (Role); @@ -3286,11 +3292,18 @@ static void Fig_GetAndShowTimelineActivityStats (void) HTM_TR_End (); /***** Get total number of users *****/ - NumUsrsTotal = (Gbl.Scope.Current == Hie_SYS) ? Usr_GetTotalNumberOfUsersInPlatform () : - Usr_GetTotalNumberOfUsersInCourses (Gbl.Scope.Current, - 1 << Rol_STD | - 1 << Rol_NET | - 1 << Rol_TCH); + NumUsrsTotal = + (Gbl.Scope.Current == Hie_SYS) ? Usr_GetTotalNumberOfUsersInPlatform () : + Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + (Gbl.Scope.Current == Hie_CTY ? Gbl.Hierarchy.Cty.CtyCod : + (Gbl.Scope.Current == Hie_INS ? Gbl.Hierarchy.Ins.InsCod : + (Gbl.Scope.Current == Hie_CTR ? Gbl.Hierarchy.Ctr.CtrCod : + (Gbl.Scope.Current == Hie_DEG ? Gbl.Hierarchy.Deg.DegCod : + (Gbl.Scope.Current == Hie_CRS ? Gbl.Hierarchy.Crs.CrsCod : + -1L))))), + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH); /***** Get total number of following/followers from database *****/ for (NoteType = (TL_NoteType_t) 0; @@ -3590,11 +3603,18 @@ static void Fig_GetAndShowFollowStats (void) HTM_TR_End (); /***** Get total number of users *****/ - NumUsrsTotal = (Gbl.Scope.Current == Hie_SYS) ? Usr_GetTotalNumberOfUsersInPlatform () : - Usr_GetTotalNumberOfUsersInCourses (Gbl.Scope.Current, - 1 << Rol_STD | - 1 << Rol_NET | - 1 << Rol_TCH); + NumUsrsTotal = + (Gbl.Scope.Current == Hie_SYS) ? Usr_GetTotalNumberOfUsersInPlatform () : + Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + (Gbl.Scope.Current == Hie_CTY ? Gbl.Hierarchy.Cty.CtyCod : + (Gbl.Scope.Current == Hie_INS ? Gbl.Hierarchy.Ins.InsCod : + (Gbl.Scope.Current == Hie_CTR ? Gbl.Hierarchy.Ctr.CtrCod : + (Gbl.Scope.Current == Hie_DEG ? Gbl.Hierarchy.Deg.DegCod : + (Gbl.Scope.Current == Hie_CRS ? Gbl.Hierarchy.Crs.CrsCod : + -1L))))), + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH); /***** Get total number of following/followers from database *****/ for (Fol = 0; @@ -4220,11 +4240,18 @@ static void Fig_GetAndShowNumUsrsPerNotifyEvent (void) HTM_TR_End (); /***** Get total number of users *****/ - NumUsrsTotal = (Gbl.Scope.Current == Hie_SYS) ? Usr_GetTotalNumberOfUsersInPlatform () : - Usr_GetTotalNumberOfUsersInCourses (Gbl.Scope.Current, - 1 << Rol_STD | - 1 << Rol_NET | - 1 << Rol_TCH); + NumUsrsTotal = + (Gbl.Scope.Current == Hie_SYS) ? Usr_GetTotalNumberOfUsersInPlatform () : + Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + (Gbl.Scope.Current == Hie_CTY ? Gbl.Hierarchy.Cty.CtyCod : + (Gbl.Scope.Current == Hie_INS ? Gbl.Hierarchy.Ins.InsCod : + (Gbl.Scope.Current == Hie_CTR ? Gbl.Hierarchy.Ctr.CtrCod : + (Gbl.Scope.Current == Hie_DEG ? Gbl.Hierarchy.Deg.DegCod : + (Gbl.Scope.Current == Hie_CRS ? Gbl.Hierarchy.Crs.CrsCod : + -1L))))), + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH); /***** Get total number of users who want to be notified by email on some event, from database *****/ diff --git a/swad_global.c b/swad_global.c index 73d46846..ddcb91dd 100644 --- a/swad_global.c +++ b/swad_global.c @@ -431,10 +431,6 @@ void Gbl_InitializeGlobals (void) Usr_FlushCacheNumUsrsWhoClaimToBelongToCty (); Usr_FlushCacheNumUsrsWhoClaimToBelongToIns (); Usr_FlushCacheNumUsrsWhoClaimToBelongToCtr (); - Usr_FlushCacheNumUsrsInCrssOfIns (); - Usr_FlushCacheNumUsrsInCrssOfCtr (); - Usr_FlushCacheNumUsrsInCrssOfDeg (); - Usr_FlushCacheNumUsrsInCrs (); Usr_FlushCacheUsrIsSuperuser (); Usr_FlushCacheUsrBelongsToIns (); Usr_FlushCacheUsrBelongsToCtr (); diff --git a/swad_global.h b/swad_global.h index 26afc79b..befec44b 100644 --- a/swad_global.h +++ b/swad_global.h @@ -857,31 +857,6 @@ struct Globals long CtrCod; unsigned NumUsrs; } NumUsrsWhoClaimToBelongToCtr; - struct - { - long CtyCod; - unsigned NumUsrs; - } NumUsrsInCrssOfCty[Rol_NUM_ROLES]; - struct - { - long InsCod; - unsigned NumUsrs; - } NumUsrsInCrssOfIns[Rol_NUM_ROLES]; - struct - { - long CtrCod; - unsigned NumUsrs; - } NumUsrsInCrssOfCtr[Rol_NUM_ROLES]; - struct - { - long DegCod; - unsigned NumUsrs; - } NumUsrsInCrssOfDeg[Rol_NUM_ROLES]; - struct - { - long CrsCod; - unsigned NumUsrs; - } NumUsrsInCrs[Rol_NUM_ROLES]; struct { long UsrCod; diff --git a/swad_help.c b/swad_help.c index 7f95ecef..15333a1a 100644 --- a/swad_help.c +++ b/swad_help.c @@ -163,7 +163,8 @@ void Hlp_ShowHelpWhatWouldYouLikeToDo (void) { if (Gbl.Hierarchy.Level == Hie_CRS && // Course selected Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs.Role == Rol_TCH) // I am a teacher in current course - if (!Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod))// Current course has no students + if (!Usr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Crs.CrsCod, + 1 << Rol_STD)) // Current course has no students { /* Request students enrolment */ Hlp_ShowRowHelpWhatWouldYouLikeToDo (Str_BuildStringStr (Txt_Register_students_in_COURSE_X, diff --git a/swad_help_URL.c b/swad_help_URL.c index 0c85107d..2ba3fbe6 100644 --- a/swad_help_URL.c +++ b/swad_help_URL.c @@ -159,6 +159,27 @@ const char *Hlp_START_Calendar = /***** SYSTEM tab *****/ +const char *Hlp_SYSTEM_Information = +#if L==1 + "SYSTEM.Information.es"; +#elif L==2 + "SYSTEM.Information.en"; +#elif L==3 + "SYSTEM.Information.en"; +#elif L==4 + "SYSTEM.Information.es"; +#elif L==5 + "SYSTEM.Information.en"; +#elif L==6 + "SYSTEM.Information.es"; +#elif L==7 + "SYSTEM.Information.en"; +#elif L==8 + "SYSTEM.Information.en"; +#elif L==9 + "SYSTEM.Information.en"; +#endif + const char *Hlp_SYSTEM_Countries = #if L==1 "SYSTEM.Countries.es"; diff --git a/swad_hierarchy_config.c b/swad_hierarchy_config.c index 196d4f2d..eba1d09d 100644 --- a/swad_hierarchy_config.c +++ b/swad_hierarchy_config.c @@ -206,14 +206,26 @@ void HieCfg_Shortcut (bool PrintView,const char *ParamName,long HieCod) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); if (!PrintView) - HTM_A_Begin ("href=\"%s/%s?%s=%ld\" class=\"DAT\" target=\"_blank\"", - Cfg_URL_SWAD_CGI, - Lan_STR_LANG_ID[Gbl.Prefs.Language], - ParamName,HieCod); - HTM_TxtF ("%s/%s?%s=%ld", - Cfg_URL_SWAD_CGI, - Lan_STR_LANG_ID[Gbl.Prefs.Language], - ParamName,HieCod); + { + if (ParamName) + HTM_A_Begin ("href=\"%s/%s?%s=%ld\" class=\"DAT\" target=\"_blank\"", + Cfg_URL_SWAD_CGI, + Lan_STR_LANG_ID[Gbl.Prefs.Language], + ParamName,HieCod); + else + HTM_A_Begin ("href=\"%s/%s\" class=\"DAT\" target=\"_blank\"", + Cfg_URL_SWAD_CGI, + Lan_STR_LANG_ID[Gbl.Prefs.Language]); + } + if (ParamName) + HTM_TxtF ("%s/%s?%s=%ld", + Cfg_URL_SWAD_CGI, + Lan_STR_LANG_ID[Gbl.Prefs.Language], + ParamName,HieCod); + else + HTM_TxtF ("%s/%s", + Cfg_URL_SWAD_CGI, + Lan_STR_LANG_ID[Gbl.Prefs.Language]); if (!PrintView) HTM_A_End (); HTM_TD_End (); diff --git a/swad_indicator.c b/swad_indicator.c index edc1eeaa..1e188cca 100644 --- a/swad_indicator.c +++ b/swad_indicator.c @@ -999,9 +999,11 @@ static void Ind_ShowTableOfCoursesWithIndicators (Ind_IndicatorsLayout_t Indicat break; case Ind_INDICATORS_FULL: /* Get number of users */ - NumStds = Usr_GetNumUsrsInCrs (Rol_STD,CrsCod); // Students - NumTchs = Usr_GetNumUsrsInCrs (Rol_NET,CrsCod) + // Non-editing teachers - Usr_GetNumUsrsInCrs (Rol_TCH,CrsCod); // Teachers + NumTchs = Usr_GetNumUsrsInCrss (Hie_CRS,CrsCod, + 1 << Rol_NET | // Non-editing teachers + 1 << Rol_TCH); // Teachers + NumStds = Usr_GetNumUsrsInCrss (Hie_CRS,CrsCod, + 1 << Rol_STD); // Students HTM_TR_Begin (NULL); diff --git a/swad_institution.c b/swad_institution.c index 63b825c9..40c91590 100644 --- a/swad_institution.c +++ b/swad_institution.c @@ -429,7 +429,10 @@ static void Ins_ListOneInstitutionForSeeing (struct Instit *Ins,unsigned NumIns) /* Number of users in courses of this institution */ HTM_TD_Begin ("class=\"%s RM %s\"",TxtClassNormal,BgColor); - HTM_Unsigned (Usr_GetNumUsrsInCrssOfIns (Rol_UNK,Ins->InsCod)); // Here Rol_UNK means "all users" + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_INS,Ins->InsCod, + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH)); // Any user HTM_TD_End (); /***** Institution status *****/ @@ -1086,7 +1089,10 @@ static void Ins_ListInstitutionsForEdition (void) ICanEdit = Ins_CheckIfICanEdit (Ins); NumCtrss = Ctr_GetNumCtrsInIns (Ins->InsCod); - NumUsrsInCrssOfIns = Usr_GetNumUsrsInCrssOfIns (Rol_UNK,Ins->InsCod); // Here Rol_UNK means "all users" + NumUsrsInCrssOfIns = Usr_GetNumUsrsInCrss (Hie_INS,Ins->InsCod, + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH); // Any user NumUsrsWhoClaimToBelongToIns = Usr_GetNumUsrsWhoClaimToBelongToIns (Ins); HTM_TR_Begin (NULL); @@ -1350,11 +1356,14 @@ void Ins_RemoveInstitution (void) // Institution has centres ==> don't remove Ale_CreateAlert (Ale_WARNING,NULL, Txt_To_remove_an_institution_you_must_first_remove_all_centres_and_users_in_the_institution); - else if (Usr_GetNumUsrsInCrssOfIns (Rol_UNK,Ins_EditingIns->InsCod)) // Here Rol_UNK means "all users" + else if (Usr_GetNumUsrsWhoClaimToBelongToIns (Ins_EditingIns)) // Institution has users ==> don't remove Ale_CreateAlert (Ale_WARNING,NULL, Txt_To_remove_an_institution_you_must_first_remove_all_centres_and_users_in_the_institution); - else if (Usr_GetNumUsrsWhoClaimToBelongToIns (Ins_EditingIns)) + else if (Usr_GetNumUsrsInCrss (Hie_INS,Ins_EditingIns->InsCod, + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH)) // Any user // Institution has users ==> don't remove Ale_CreateAlert (Ale_WARNING,NULL, Txt_To_remove_an_institution_you_must_first_remove_all_centres_and_users_in_the_institution); @@ -1390,7 +1399,6 @@ void Ins_RemoveInstitution (void) Deg_FlushCacheNumDegsInIns (); Crs_FlushCacheNumCrssInIns (); Usr_FlushCacheNumUsrsWhoClaimToBelongToIns (); - Usr_FlushCacheNumUsrsInCrssOfIns (); /***** Write message to show the change made *****/ Ale_CreateAlert (Ale_SUCCESS,NULL, @@ -1908,7 +1916,7 @@ static void Ins_CreateInstitution (unsigned Status) unsigned Ins_GetNumInssTotal (void) { - /***** Get total number of degrees from database *****/ + /***** Get total number of institutions from database *****/ return (unsigned) DB_GetNumRowsTable ("institutions"); } diff --git a/swad_institution_config.c b/swad_institution_config.c index bf908811..5810cf7e 100644 --- a/swad_institution_config.c +++ b/swad_institution_config.c @@ -605,7 +605,11 @@ static void InsCfg_NumUsrsInCrssOfIns (Rol_Role_t Role) /* Data */ HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Usr_GetNumUsrsInCrssOfIns (Role,Gbl.Hierarchy.Ins.InsCod)); + HTM_Unsigned (Usr_GetNumUsrsInCrss (Hie_INS,Gbl.Hierarchy.Ins.InsCod, + Role == Rol_UNK ? 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH : // Any user + 1 << Role)); HTM_TD_End (); HTM_TR_End (); diff --git a/swad_mark.c b/swad_mark.c index bc9fce13..03739dbf 100644 --- a/swad_mark.c +++ b/swad_mark.c @@ -623,7 +623,8 @@ void Mrk_ShowMyMarks (void) } else // Course zone { - if (Usr_GetNumUsrsInCrs (Rol_STD,Gbl.Hierarchy.Crs.CrsCod)) // If there are students in this course + if (Usr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Crs.CrsCod, + 1 << Rol_STD)) // If there are students in this course { Gbl.Usrs.Other.UsrDat.UsrCod = Usr_GetRamdomStdFromCrs (Gbl.Hierarchy.Crs.CrsCod); UsrDat = &Gbl.Usrs.Other.UsrDat; diff --git a/swad_menu.c b/swad_menu.c index 6e3cf563..b156f3ca 100644 --- a/swad_menu.c +++ b/swad_menu.c @@ -72,11 +72,12 @@ static const Act_Action_t Mnu_MenuActions[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_ [ 5] = ActSeeNtf, }, [TabSys] = { - [ 0] = ActSeeCty, - [ 1] = ActSeePen, - [ 2] = ActSeeLnk, - [ 3] = ActLstPlg, - [ 4] = ActSetUp, + [ 0] = ActSeeSysInf, + [ 1] = ActSeeCty, + [ 2] = ActSeePen, + [ 3] = ActSeeLnk, + [ 4] = ActLstPlg, + [ 5] = ActSetUp, }, [TabCty] = { [ 0] = ActSeeCtyInf, diff --git a/swad_network.c b/swad_network.c index 5b354b09..2d755c14 100644 --- a/swad_network.c +++ b/swad_network.c @@ -441,11 +441,18 @@ void Net_ShowWebAndSocialNetworksStats (void) unsigned NumUsrs; /***** Get total number of users in current scope *****/ - NumUsrsTotal = (Gbl.Scope.Current == Hie_SYS) ? Usr_GetTotalNumberOfUsersInPlatform () : - Usr_GetTotalNumberOfUsersInCourses (Gbl.Scope.Current, - 1 << Rol_STD | - 1 << Rol_NET | - 1 << Rol_TCH); + NumUsrsTotal = + (Gbl.Scope.Current == Hie_SYS) ? Usr_GetTotalNumberOfUsersInPlatform () : + Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + (Gbl.Scope.Current == Hie_CTY ? Gbl.Hierarchy.Cty.CtyCod : + (Gbl.Scope.Current == Hie_INS ? Gbl.Hierarchy.Ins.InsCod : + (Gbl.Scope.Current == Hie_CTR ? Gbl.Hierarchy.Ctr.CtrCod : + (Gbl.Scope.Current == Hie_DEG ? Gbl.Hierarchy.Deg.DegCod : + (Gbl.Scope.Current == Hie_CRS ? Gbl.Hierarchy.Crs.CrsCod : + -1L))))), + 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH); // Any user /***** Get number of users with a web / social network *****/ switch (Gbl.Scope.Current) diff --git a/swad_notification.c b/swad_notification.c index 3dbc5fdc..dee0842c 100644 --- a/swad_notification.c +++ b/swad_notification.c @@ -1244,8 +1244,8 @@ unsigned Ntf_StoreNotifyEventsToAllUsrs (Ntf_NotifyEvent_t NotifyEvent,long Cod) case Ntf_EVENT_ENROLMENT_TCH: // This function should not be called in this case return 0; case Ntf_EVENT_ENROLMENT_REQUEST: - if (Usr_GetNumUsrsInCrs (Rol_TCH,Gbl.Hierarchy.Crs.CrsCod)) - { + if (Usr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Crs.CrsCod, + 1 << Rol_TCH)) // If this course has teachers ==> send notification to teachers NumRows = DB_QuerySELECT (&mysql_res,"can not get users" " to be notified", @@ -1256,9 +1256,7 @@ unsigned Ntf_StoreNotifyEventsToAllUsrs (Ntf_NotifyEvent_t NotifyEvent,long Cod) Gbl.Hierarchy.Crs.CrsCod, Gbl.Usrs.Me.UsrDat.UsrCod, (unsigned) Rol_TCH); - } else // Course without teachers - { // If this course has no teachers // and I want to be a teacher (checked before calling this function // to not send requests to be a student to admins) @@ -1276,7 +1274,6 @@ unsigned Ntf_StoreNotifyEventsToAllUsrs (Ntf_NotifyEvent_t NotifyEvent,long Cod) Sco_GetDBStrFromScope (Hie_CTR),Gbl.Hierarchy.Ctr.CtrCod, Sco_GetDBStrFromScope (Hie_DEG),Gbl.Hierarchy.Deg.DegCod, Gbl.Usrs.Me.UsrDat.UsrCod); - } break; case Ntf_EVENT_TIMELINE_COMMENT: // New comment to one of my social notes or comments // Cod is the code of the social publishing diff --git a/swad_report.c b/swad_report.c index b464152d..77d4024e 100644 --- a/swad_report.c +++ b/swad_report.c @@ -1187,10 +1187,12 @@ static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role, /***** Write number of teachers / students in course *****/ if (WriteNumUsrs) fprintf (Gbl.F.Rep," (%u %s / %u %s)", - Usr_GetNumUsrsInCrs (Rol_NET,Crs.CrsCod) + - Usr_GetNumUsrsInCrs (Rol_TCH,Crs.CrsCod), + Usr_GetNumUsrsInCrss (Hie_CRS,Crs.CrsCod, + 1 << Rol_NET | + 1 << Rol_TCH), Txt_teachers_ABBREVIATION, - Usr_GetNumUsrsInCrs (Rol_STD,Crs.CrsCod), + Usr_GetNumUsrsInCrss (Hie_CRS,Crs.CrsCod, + 1 << Rol_STD), Txt_students_ABBREVIATION); } else diff --git a/swad_tab.c b/swad_tab.c index 4500c61a..e6da56d7 100644 --- a/swad_tab.c +++ b/swad_tab.c @@ -222,7 +222,10 @@ void Tab_SetCurrentTab (void) { case TabCty: if (Gbl.Hierarchy.Cty.CtyCod <= 0) // No country selected + { Gbl.Action.Act = ActSeeCty; + Gbl.Action.Tab = Act_GetTab (Gbl.Action.Act); + } break; case TabIns: if (Gbl.Hierarchy.Ins.InsCod <= 0) // No institution selected @@ -231,6 +234,7 @@ void Tab_SetCurrentTab (void) Gbl.Action.Act = ActSeeIns; else // No country selected Gbl.Action.Act = ActSeeCty; + Gbl.Action.Tab = Act_GetTab (Gbl.Action.Act); } break; case TabCtr: @@ -242,6 +246,7 @@ void Tab_SetCurrentTab (void) Gbl.Action.Act = ActSeeIns; else // No country selected Gbl.Action.Act = ActSeeCty; + Gbl.Action.Tab = Act_GetTab (Gbl.Action.Act); } break; case TabDeg: @@ -255,14 +260,13 @@ void Tab_SetCurrentTab (void) Gbl.Action.Act = ActSeeIns; else // No country selected Gbl.Action.Act = ActSeeCty; + Gbl.Action.Tab = Act_GetTab (Gbl.Action.Act); } break; default: break; } - Gbl.Action.Tab = Act_GetTab (Act_GetSuperAction (Gbl.Action.Act)); - Tab_DisableIncompatibleTabs (); } diff --git a/swad_text.c b/swad_text.c index 110d937b..c74643f3 100644 --- a/swad_text.c +++ b/swad_text.c @@ -18761,7 +18761,28 @@ const char *Txt_MENU_TITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = }, [TabSys] = { - // 0: ActSeeCty + // 0: ActSeeSysInf +#if L==1 // ca + "Informació" +#elif L==2 // de + "Information" +#elif L==3 // en + "Information" +#elif L==4 // es + "Información" +#elif L==5 // fr + "Information" +#elif L==6 // gn + "Información" // Okoteve traducción +#elif L==7 // it + "Informazione" +#elif L==8 // pl + "Informacja" +#elif L==9 // pt + "Informação" +#endif + , + // 1: ActSeeCty #if L==1 // ca "Països" #elif L==2 // de @@ -18782,7 +18803,7 @@ const char *Txt_MENU_TITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Países" #endif , - // 1: ActSeePen + // 2: ActSeePen #if L==1 // ca "Jerarquia" #elif L==2 // de @@ -18803,7 +18824,7 @@ const char *Txt_MENU_TITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Hierarquia" #endif , - // 2: ActSeeLnk + // 3: ActSeeLnk #if L==1 // ca "Enllaços" #elif L==2 // de @@ -18824,7 +18845,7 @@ const char *Txt_MENU_TITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Ligações" #endif , - // 3: ActLstPlg + // 4: ActLstPlg #if L==1 // ca "Complements" #elif L==2 // de @@ -18845,7 +18866,7 @@ const char *Txt_MENU_TITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Plugins" #endif , - // 4: ActSetUp + // 5: ActSetUp #if L==1 // ca "Instal lar" #elif L==2 // de @@ -18866,7 +18887,6 @@ const char *Txt_MENU_TITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Instalar" #endif , - NULL, // 5 NULL, // 6 NULL, // 7 NULL, // 8 @@ -20568,7 +20588,28 @@ const char *Txt_MENU_SUBTITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = }, [TabSys] = { - // 0: ActSeeCty + // 0: ActSeeSysInf +#if L==1 // ca + "Informació sobre aquesta plataforma" +#elif L==2 // de + "Informationen auf dieser Plattform" +#elif L==3 // en + "Information on this platform" +#elif L==4 // es + "Información sobre esta plataforma" +#elif L==5 // fr + "Information sur cette plateforme" +#elif L==6 // gn + "Información sobre esta plataforma" // Okoteve traducción +#elif L==7 // it + "Informazione su questa piattaforma" +#elif L==8 // pl + "Informacja na temat tej platformy" +#elif L==9 // pt + "Informação sobre esta plataforma" +#endif + , + // 1: ActSeeCty #if L==1 // ca "Llista de països i del nombre d'usuaris de cada país" #elif L==2 // de @@ -20589,7 +20630,7 @@ const char *Txt_MENU_SUBTITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Países" #endif , - // 1: ActSeePen + // 2: ActSeePen #if L==1 // ca "Institutions, centres, titulacions i assignatures pendents d'activar" #elif L==2 // de @@ -20610,7 +20651,7 @@ const char *Txt_MENU_SUBTITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Instituções, centros, graus e disciplinas pendentes" #endif , - // 2: ActSeeLnk + // 3: ActSeeLnk #if L==1 // ca "Llista d'enllaços institucionals" #elif L==2 // de @@ -20631,7 +20672,7 @@ const char *Txt_MENU_SUBTITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Ligações institucionais" #endif , - // 3: ActLstPlg + // 4: ActLstPlg #if L==1 // ca "Llista de complements (versió beta)" #elif L==2 // de @@ -20652,7 +20693,7 @@ const char *Txt_MENU_SUBTITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Lista de plugins" #endif , - // 4: ActSetUp + // 5: ActSetUp #if L==1 // ca "Instal lació de la plataforma (en proves)" #elif L==2 // de @@ -20673,7 +20714,6 @@ const char *Txt_MENU_SUBTITLE[Tab_NUM_TABS][Act_MAX_OPTIONS_IN_MENU_PER_TAB] = "Instalar" #endif , - NULL, // 5 NULL, // 6 NULL, // 7 NULL, // 8 @@ -29533,6 +29573,27 @@ const char *Txt_PLACES_ORDER[Plc_NUM_ORDERS] = #endif }; +const char *Txt_Platform = +#if L==1 // ca + "Plataforma"; +#elif L==2 // de + "Plattform"; +#elif L==3 // en + "Platform"; +#elif L==4 // es + "Plataforma"; +#elif L==5 // fr + "Plate-forme"; +#elif L==6 // gn + "Plataforma"; // Okoteve traducción +#elif L==7 // it + "Piattaforma"; +#elif L==8 // pl + "Platforma"; +#elif L==9 // pt + "Plataforma"; +#endif + const char *Txt_Play = // To play a game match #if L==1 // ca "Jugar"; diff --git a/swad_text_action.c b/swad_text_action.c index 4ccfb87a..44b4df0e 100644 --- a/swad_text_action.c +++ b/swad_text_action.c @@ -1530,6 +1530,27 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "Change email domain information" // Potrzebujesz tlumaczenie #elif L==9 // pt "Change email domain information" // Precisa de tradução +#endif + , + [ActSeeSysInf] = +#if L==1 // ca + "" // Necessita traducció +#elif L==2 // de + "" // Need Übersetzung +#elif L==3 // en + "Show information on the platform" +#elif L==4 // es + "Mostrar información sobre la plataforma" +#elif L==5 // fr + "" // Besoin de traduction +#elif L==6 // gn + "" // Okoteve traducción +#elif L==7 // it + "" // Bisogno di traduzione +#elif L==8 // pl + "" // Potrzebujesz tlumaczenie +#elif L==9 // pt + "" // Precisa de tradução #endif , [ActSeeCty] = @@ -1635,6 +1656,27 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = "" // Potrzebujesz tlumaczenie #elif L==9 // pt "" // Precisa de tradução +#endif + , + [ActPrnSysInf] = +#if L==1 // ca + "" // Necessita traducció +#elif L==2 // de + "" // Need Übersetzung +#elif L==3 // en + "Print information on the platform" +#elif L==4 // es + "Imprimir información sobre la plataforma" +#elif L==5 // fr + "" // Besoin de traduction +#elif L==6 // gn + "" // Okoteve traducción +#elif L==7 // it + "" // Bisogno di traduzione +#elif L==8 // pl + "" // Potrzebujesz tlumaczenie +#elif L==9 // pt + "" // Precisa de tradução #endif , [ActEdiCty] = @@ -2336,9 +2378,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Show information on the current country" + "Show information on the country" #elif L==4 // es - "" + "Mostrar información sobre el país" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -2378,9 +2420,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Print information on the current country" + "Print information on the country" #elif L==4 // es - "" + "Imprimir información sobre el país" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -2588,9 +2630,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Show information on the current institution" + "Show information on the institution" #elif L==4 // es - "" + "Mostrar información sobre la institución" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -2693,9 +2735,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Print information on the current institution" + "Print information on the institution" #elif L==4 // es - "" + "Imprimir información sobre la institución" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -3470,9 +3512,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Show information on the current centre" + "Show information on the centre" #elif L==4 // es - "" + "Mostrar información sobre el centro" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -3533,9 +3575,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Print information on the current centre" + "Print information on the centre" #elif L==4 // es - "" + "Imprimir información sobre el centro" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -4289,9 +4331,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Show information on the current degree" + "Show information on the degree" #elif L==4 // es - "" + "Mostrar información sobre la titulación" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -4331,9 +4373,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Print information on the current degree" + "Print information on the degree" #elif L==4 // es - "" + "Imprimir información sobre la titulación" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -4688,9 +4730,9 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = #elif L==2 // de "" // Need Übersetzung #elif L==3 // en - "Show information on the current course" + "Show information on the course" #elif L==4 // es - "" + "Mostrar información sobre la asignatura" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn @@ -4837,7 +4879,7 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = #elif L==3 // en "Print information on the course" #elif L==4 // es - "" + "Imprimir información sobre la asignatura" #elif L==5 // fr "" // Besoin de traduction #elif L==6 // gn diff --git a/swad_user.c b/swad_user.c index b1321ab9..f5e8a96d 100644 --- a/swad_user.c +++ b/swad_user.c @@ -4163,335 +4163,6 @@ static void Usr_WriteUsrData (const char *BgColor, HTM_TD_End (); } -/*****************************************************************************/ -/************* Get number of users with a role in a course *******************/ -/*****************************************************************************/ - -void Usr_FlushCacheNumUsrsInCrs (void) - { - Gbl.Cache.NumUsrsInCrs[Rol_UNK].CrsCod = - Gbl.Cache.NumUsrsInCrs[Rol_STD].CrsCod = - Gbl.Cache.NumUsrsInCrs[Rol_NET].CrsCod = - Gbl.Cache.NumUsrsInCrs[Rol_TCH].CrsCod = -1L; - - Gbl.Cache.NumUsrsInCrs[Rol_UNK].NumUsrs = - Gbl.Cache.NumUsrsInCrs[Rol_STD].NumUsrs = - Gbl.Cache.NumUsrsInCrs[Rol_NET].NumUsrs = - Gbl.Cache.NumUsrsInCrs[Rol_TCH].NumUsrs = 0; - } - -unsigned Usr_GetNumUsrsInCrs (Rol_Role_t Role,long CrsCod) - { - /***** 1. Fast check: Trivial case *****/ - if (CrsCod <= 0) - return 0; - - /***** 2. Fast check: Trivial case *****/ - switch (Role) - { - case Rol_UNK: // Here Rol_UNK means all - case Rol_STD: - case Rol_NET: - case Rol_TCH: - break; - default: - return 0; - } - - /***** 3. Fast check: If cached... *****/ - if (CrsCod == Gbl.Cache.NumUsrsInCrs[Role].CrsCod) - return Gbl.Cache.NumUsrsInCrs[Role].NumUsrs; - - /***** 4. Slow: number of users in a course from database *****/ - Gbl.Cache.NumUsrsInCrs[Role].CrsCod = CrsCod; - if (Role == Rol_UNK) - Gbl.Cache.NumUsrsInCrs[Rol_UNK].NumUsrs = - (unsigned) DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(*) FROM crs_usr" - " WHERE CrsCod=%ld", - CrsCod); - else - Gbl.Cache.NumUsrsInCrs[Role].NumUsrs = - (unsigned) DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(*) FROM crs_usr" - " WHERE CrsCod=%ld AND Role=%u", - CrsCod,(unsigned) Role); - return Gbl.Cache.NumUsrsInCrs[Role].NumUsrs; - } - -/*****************************************************************************/ -/*********** Count how many users with a role belong to a degree *************/ -/*****************************************************************************/ -// Here Rol_UNK means any user (students, non-editing teachers or teachers) - -void Usr_FlushCacheNumUsrsInCrssOfDeg (void) - { - Gbl.Cache.NumUsrsInCrssOfDeg[Rol_UNK].DegCod = - Gbl.Cache.NumUsrsInCrssOfDeg[Rol_STD].DegCod = - Gbl.Cache.NumUsrsInCrssOfDeg[Rol_NET].DegCod = - Gbl.Cache.NumUsrsInCrssOfDeg[Rol_TCH].DegCod = -1L; - - Gbl.Cache.NumUsrsInCrssOfDeg[Rol_UNK].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfDeg[Rol_STD].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfDeg[Rol_NET].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfDeg[Rol_TCH].NumUsrs = 0; - } - -unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod) - { - /***** 1. Fast check: Trivial case *****/ - if (DegCod <= 0) - return 0; - - /***** 2. Fast check: Trivial case *****/ - switch (Role) - { - case Rol_UNK: // Here Rol_UNK means all - case Rol_STD: - case Rol_NET: - case Rol_TCH: - break; - default: - return 0; - } - - /***** 3. Fast check: If cached... *****/ - if (DegCod == Gbl.Cache.NumUsrsInCrssOfDeg[Role].DegCod) - return Gbl.Cache.NumUsrsInCrssOfDeg[Role].NumUsrs; - - /***** 4. Slow: number of users in courses of a degree from database *****/ - Gbl.Cache.NumUsrsInCrssOfDeg[Role].DegCod = DegCod; - if (Role == Rol_UNK) // Any user - Gbl.Cache.NumUsrsInCrssOfDeg[Rol_UNK].NumUsrs = - (unsigned) DB_QueryCOUNT ("can not get number of users" - " in courses of a degree", - "SELECT COUNT(DISTINCT crs_usr.UsrCod)" - " FROM courses,crs_usr" - " WHERE courses.DegCod=%ld" - " AND courses.CrsCod=crs_usr.CrsCod", - DegCod); - else - Gbl.Cache.NumUsrsInCrssOfDeg[Role].NumUsrs = - (unsigned) DB_QueryCOUNT ("can not get number of users" - " in courses of a degree", - "SELECT COUNT(DISTINCT crs_usr.UsrCod)" - " FROM courses,crs_usr" - " WHERE courses.DegCod=%ld" - " AND courses.CrsCod=crs_usr.CrsCod" - " AND crs_usr.Role=%u", - DegCod,(unsigned) Role); - return Gbl.Cache.NumUsrsInCrssOfDeg[Role].NumUsrs; - } - -/*****************************************************************************/ -/************ Count how many users with a role belong to a centre ************/ -/*****************************************************************************/ -// Here Rol_UNK means any user (students, non-editing teachers or teachers) - -void Usr_FlushCacheNumUsrsInCrssOfCtr (void) - { - Gbl.Cache.NumUsrsInCrssOfCtr[Rol_UNK].CtrCod = - Gbl.Cache.NumUsrsInCrssOfCtr[Rol_STD].CtrCod = - Gbl.Cache.NumUsrsInCrssOfCtr[Rol_NET].CtrCod = - Gbl.Cache.NumUsrsInCrssOfCtr[Rol_TCH].CtrCod = -1L; - - Gbl.Cache.NumUsrsInCrssOfCtr[Rol_UNK].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfCtr[Rol_STD].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfCtr[Rol_NET].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfCtr[Rol_TCH].NumUsrs = 0; - } - -unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod) - { - /***** 1. Fast check: Trivial case *****/ - if (CtrCod <= 0) - return 0; - - /***** 2. Fast check: Trivial case *****/ - switch (Role) - { - case Rol_UNK: // Here Rol_UNK means all - case Rol_STD: - case Rol_NET: - case Rol_TCH: - break; - default: - return 0; - } - - /***** 3. Fast check: If cached... *****/ - if (CtrCod == Gbl.Cache.NumUsrsInCrssOfCtr[Role].CtrCod) - return Gbl.Cache.NumUsrsInCrssOfCtr[Role].NumUsrs; - - /***** 4. Slow: get number of users in courses of a centre - from database *****/ - Gbl.Cache.NumUsrsInCrssOfCtr[Role].CtrCod = CtrCod; - if (Role == Rol_UNK) // Any user - Gbl.Cache.NumUsrsInCrssOfCtr[Rol_UNK].NumUsrs = - (unsigned) DB_QueryCOUNT ("can not get number of users" - " in courses of a centre", - "SELECT COUNT(DISTINCT crs_usr.UsrCod)" - " FROM degrees,courses,crs_usr" - " WHERE degrees.CtrCod=%ld" - " AND degrees.DegCod=courses.DegCod" - " AND courses.CrsCod=crs_usr.CrsCod", - CtrCod); - else - // This query is very slow. - // It's a bad idea to get number of teachers or students for a big list of centres - Gbl.Cache.NumUsrsInCrssOfCtr[Role].NumUsrs = - (unsigned) DB_QueryCOUNT ("can not get number of users" - " in courses of a centre", - "SELECT COUNT(DISTINCT crs_usr.UsrCod)" - " FROM degrees,courses,crs_usr" - " WHERE degrees.CtrCod=%ld" - " AND degrees.DegCod=courses.DegCod" - " AND courses.CrsCod=crs_usr.CrsCod" - " AND crs_usr.Role=%u", - CtrCod,(unsigned) Role); - return Gbl.Cache.NumUsrsInCrssOfCtr[Role].NumUsrs; - } - -/*****************************************************************************/ -/********* Count how many users with a role belong to an institution *********/ -/*****************************************************************************/ -// Here Rol_UNK means any user (students, non-editing teachers or teachers) - -void Usr_FlushCacheNumUsrsInCrssOfIns (void) - { - Gbl.Cache.NumUsrsInCrssOfIns[Rol_UNK].InsCod = - Gbl.Cache.NumUsrsInCrssOfIns[Rol_STD].InsCod = - Gbl.Cache.NumUsrsInCrssOfIns[Rol_NET].InsCod = - Gbl.Cache.NumUsrsInCrssOfIns[Rol_TCH].InsCod = -1L; - - Gbl.Cache.NumUsrsInCrssOfIns[Rol_UNK].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfIns[Rol_STD].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfIns[Rol_NET].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfIns[Rol_TCH].NumUsrs = 0; - } - -unsigned Usr_GetNumUsrsInCrssOfIns (Rol_Role_t Role,long InsCod) - { - /***** 1. Fast check: Trivial case *****/ - if (InsCod <= 0) - return 0; - - /***** 2. Fast check: Trivial case *****/ - switch (Role) - { - case Rol_UNK: // Here Rol_UNK means all - case Rol_STD: - case Rol_NET: - case Rol_TCH: - break; - default: - return 0; - } - - /***** 3. Fast check: If cached... *****/ - if (InsCod == Gbl.Cache.NumUsrsInCrssOfIns[Role].InsCod) - return Gbl.Cache.NumUsrsInCrssOfIns[Role].NumUsrs; - - /***** 4. Slow: get number of users in courses of an institution - from database *****/ - Gbl.Cache.NumUsrsInCrssOfIns[Role].InsCod = InsCod; - if (Role == Rol_UNK) // Any user - Gbl.Cache.NumUsrsInCrssOfIns[Rol_UNK].NumUsrs = - (unsigned) DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_usr.UsrCod)" - " FROM centres,degrees,courses,crs_usr" - " WHERE centres.InsCod=%ld" - " AND centres.CtrCod=degrees.CtrCod" - " AND degrees.DegCod=courses.DegCod" - " AND courses.CrsCod=crs_usr.CrsCod", - InsCod); - else - // This query is very slow. - // It's a bad idea to get number of teachers or students for a big list of institutions - Gbl.Cache.NumUsrsInCrssOfIns[Role].NumUsrs = - (unsigned) DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_usr.UsrCod)" - " FROM centres,degrees,courses,crs_usr" - " WHERE centres.InsCod=%ld" - " AND centres.CtrCod=degrees.CtrCod" - " AND degrees.DegCod=courses.DegCod" - " AND courses.CrsCod=crs_usr.CrsCod" - " AND crs_usr.Role=%u", - InsCod,(unsigned) Role); - return Gbl.Cache.NumUsrsInCrssOfIns[Role].NumUsrs; - } - -/*****************************************************************************/ -/****** Count how many users with a role belong to courses of a country ******/ -/*****************************************************************************/ -// Here Rol_UNK means any user (students, non-editing teachers or teachers) - -void Usr_FlushCacheNumUsrsInCrssOfCty (void) - { - Gbl.Cache.NumUsrsInCrssOfCty[Rol_UNK].CtyCod = - Gbl.Cache.NumUsrsInCrssOfCty[Rol_STD].CtyCod = - Gbl.Cache.NumUsrsInCrssOfCty[Rol_NET].CtyCod = - Gbl.Cache.NumUsrsInCrssOfCty[Rol_TCH].CtyCod = -1L; - - Gbl.Cache.NumUsrsInCrssOfCty[Rol_UNK].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfCty[Rol_STD].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfCty[Rol_NET].NumUsrs = - Gbl.Cache.NumUsrsInCrssOfCty[Rol_TCH].NumUsrs = 0; - } - -unsigned Usr_GetNumUsrsInCrssOfCty (Rol_Role_t Role,long CtyCod) - { - /***** 1. Fast check: Trivial case *****/ - if (CtyCod <= 0) - return 0; - - /***** 2. Fast check: Trivial case *****/ - switch (Role) - { - case Rol_UNK: // Here Rol_UNK means all - case Rol_STD: - case Rol_NET: - case Rol_TCH: - break; - default: - return 0; - } - - /***** 3. Fast check: If cached... *****/ - if (CtyCod == Gbl.Cache.NumUsrsInCrssOfCty[Role].CtyCod) - return Gbl.Cache.NumUsrsInCrssOfCty[Role].NumUsrs; - - /***** 4. Slow: get number of users in courses of a country - from database *****/ - Gbl.Cache.NumUsrsInCrssOfCty[Role].CtyCod = CtyCod; - if (Role == Rol_UNK) // Any user - Gbl.Cache.NumUsrsInCrssOfCty[Rol_UNK].NumUsrs = - (unsigned) DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_usr.UsrCod)" - " FROM institutions,centres,degrees,courses,crs_usr" - " WHERE institutions.CtyCod=%ld" - " AND institutions.InsCod=centres.InsCod" - " AND centres.CtrCod=degrees.CtrCod" - " AND degrees.DegCod=courses.DegCod" - " AND courses.CrsCod=crs_usr.CrsCod", - CtyCod); - else - // This query is very slow. - // It's a bad idea to get number of teachers or students for a big list of countries - Gbl.Cache.NumUsrsInCrssOfCty[Role].NumUsrs = - (unsigned) DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_usr.UsrCod)" - " FROM institutions,centres,degrees,courses,crs_usr" - " WHERE institutions.CtyCod=%ld" - " AND institutions.InsCod=centres.InsCod" - " AND centres.CtrCod=degrees.CtrCod" - " AND degrees.DegCod=courses.DegCod" - " AND courses.CrsCod=crs_usr.CrsCod" - " AND crs_usr.Role=%u", - CtyCod,(unsigned) Role); - return Gbl.Cache.NumUsrsInCrssOfCty[Role].NumUsrs; - } - /*****************************************************************************/ /******** Get the user's code of a random student from current course ********/ /*****************************************************************************/ @@ -5667,31 +5338,33 @@ static void Usr_GetGstsLst (Hie_Level_t Scope) void Usr_GetUnorderedStdsCodesInDeg (long DegCod) { - char *Query = NULL; + char *Query; - if (Usr_GetNumUsrsInCrssOfDeg (Rol_STD,DegCod)) - /***** Get the students in a degree from database *****/ - DB_BuildQuery (&Query, - "SELECT DISTINCT usr_data.UsrCod," // row[ 0] - "usr_data.EncryptedUsrCod," // row[ 1] - "usr_data.Password," // row[ 2] - "usr_data.Surname1," // row[ 3] - "usr_data.Surname2," // row[ 4] - "usr_data.FirstName," // row[ 5] - "usr_data.Sex," // row[ 6] - "usr_data.Photo," // row[ 7] - "usr_data.PhotoVisibility," // row[ 8] - "usr_data.CtyCod," // row[ 9] - "usr_data.InsCod" // row[10] - " FROM courses,crs_usr,usr_data" - " WHERE courses.DegCod=%ld" - " AND courses.CrsCod=crs_usr.CrsCod" - " AND crs_usr.Role=%u" - " AND crs_usr.UsrCod=usr_data.UsrCod", - DegCod,(unsigned) Rol_STD); + /***** Get the students in a degree from database *****/ + DB_BuildQuery (&Query, + "SELECT DISTINCT usr_data.UsrCod," // row[ 0] + "usr_data.EncryptedUsrCod," // row[ 1] + "usr_data.Password," // row[ 2] + "usr_data.Surname1," // row[ 3] + "usr_data.Surname2," // row[ 4] + "usr_data.FirstName," // row[ 5] + "usr_data.Sex," // row[ 6] + "usr_data.Photo," // row[ 7] + "usr_data.PhotoVisibility," // row[ 8] + "usr_data.CtyCod," // row[ 9] + "usr_data.InsCod" // row[10] + " FROM courses,crs_usr,usr_data" + " WHERE courses.DegCod=%ld" + " AND courses.CrsCod=crs_usr.CrsCod" + " AND crs_usr.Role=%u" + " AND crs_usr.UsrCod=usr_data.UsrCod", + DegCod,(unsigned) Rol_STD); /***** Get list of students from database *****/ Usr_GetListUsrsFromQuery (Query,Rol_STD,Hie_DEG); + + /***** Free query string *****/ + free (Query); } /*****************************************************************************/ @@ -7574,9 +7247,15 @@ void Usr_ListAllDataTchs (void) NumUsrs = Gbl.Usrs.LstUsrs[Rol_NET].NumUsrs + Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs; else - NumUsrs = Usr_GetTotalNumberOfUsersInCourses (Gbl.Scope.Current, - 1 << Rol_NET | - 1 << Rol_TCH); + NumUsrs = Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + (Gbl.Scope.Current == Hie_CTY ? Gbl.Hierarchy.Cty.CtyCod : + (Gbl.Scope.Current == Hie_INS ? Gbl.Hierarchy.Ins.InsCod : + (Gbl.Scope.Current == Hie_CTR ? Gbl.Hierarchy.Ctr.CtrCod : + (Gbl.Scope.Current == Hie_DEG ? Gbl.Hierarchy.Deg.DegCod : + (Gbl.Scope.Current == Hie_CRS ? Gbl.Hierarchy.Crs.CrsCod : + -1L))))), + 1 << Rol_NET | + 1 << Rol_TCH); if (NumUsrs) { @@ -8610,9 +8289,15 @@ void Usr_SeeTeachers (void) NumUsrs = Gbl.Usrs.LstUsrs[Rol_NET].NumUsrs + Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs; else - NumUsrs = Usr_GetTotalNumberOfUsersInCourses (Gbl.Scope.Current, - 1 << Rol_NET | - 1 << Rol_TCH); + NumUsrs = Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + (Gbl.Scope.Current == Hie_CTY ? Gbl.Hierarchy.Cty.CtyCod : + (Gbl.Scope.Current == Hie_INS ? Gbl.Hierarchy.Ins.InsCod : + (Gbl.Scope.Current == Hie_CTR ? Gbl.Hierarchy.Ctr.CtrCod : + (Gbl.Scope.Current == Hie_DEG ? Gbl.Hierarchy.Deg.DegCod : + (Gbl.Scope.Current == Hie_CRS ? Gbl.Hierarchy.Crs.CrsCod : + -1L))))), + 1 << Rol_NET | + 1 << Rol_TCH); /***** Begin box *****/ Box_BoxBegin (NULL,Txt_ROLES_PLURAL_Abc[Rol_TCH][Usr_SEX_UNKNOWN],Usr_PutIconsListTchs, @@ -9294,9 +8979,15 @@ void Usr_SeeTchClassPhotoPrn (void) NumUsrs = Gbl.Usrs.LstUsrs[Rol_NET].NumUsrs + Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs; else - NumUsrs = Usr_GetTotalNumberOfUsersInCourses (Gbl.Scope.Current, - 1 << Rol_NET | - 1 << Rol_TCH); + NumUsrs = Usr_GetNumUsrsInCrss (Gbl.Scope.Current, + (Gbl.Scope.Current == Hie_CTY ? Gbl.Hierarchy.Cty.CtyCod : + (Gbl.Scope.Current == Hie_INS ? Gbl.Hierarchy.Ins.InsCod : + (Gbl.Scope.Current == Hie_CTR ? Gbl.Hierarchy.Ctr.CtrCod : + (Gbl.Scope.Current == Hie_DEG ? Gbl.Hierarchy.Deg.DegCod : + (Gbl.Scope.Current == Hie_CRS ? Gbl.Hierarchy.Crs.CrsCod : + -1L))))), + 1 << Rol_NET | + 1 << Rol_TCH); if (NumUsrs) { @@ -9570,7 +9261,7 @@ unsigned Usr_GetTotalNumberOfUsersInPlatform (void) #define Usr_MAX_BYTES_SUBQUERY_ROLES (Rol_NUM_ROLES*(10+1)-1) -unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) +unsigned Usr_GetNumUsrsInCrss (Hie_Level_t Scope,long Cod,unsigned Roles) { char UnsignedStr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char SubQueryRoles[Usr_MAX_BYTES_SUBQUERY_ROLES + 1]; @@ -9602,7 +9293,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) /***** Get first role requested *****/ FirstRoleRequested = Rol_UNK; - for (Role = Rol_STD; + for (Role = Rol_STD; Role <= Rol_TCH; Role++) if (Roles & (1 << Role)) @@ -9627,7 +9318,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) if (MoreThanOneRole) { Str_Copy (SubQueryRoles," IN (",Usr_MAX_BYTES_SUBQUERY_ROLES); - for (Role = Rol_STD, FirstRole = true; + for (Role = Rol_STD, FirstRole = true; Role <= Rol_TCH; Role++) if (Roles & (1 << Role)) @@ -9673,7 +9364,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) " AND centres.CtrCod=degrees.CtrCod" " AND degrees.DegCod=courses.DegCod" " AND courses.CrsCod=crs_usr.CrsCod", - Gbl.Hierarchy.Cty.CtyCod); + Cod); else NumUsrs = (unsigned) DB_QueryCOUNT ("can not get number of users", @@ -9685,7 +9376,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) " AND degrees.DegCod=courses.DegCod" " AND courses.CrsCod=crs_usr.CrsCod" " AND crs_usr.Role%s", - Gbl.Hierarchy.Cty.CtyCod,SubQueryRoles); + Cod,SubQueryRoles); break; case Hie_INS: if (AnyUserInCourses) // Any user @@ -9697,7 +9388,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) " AND centres.CtrCod=degrees.CtrCod" " AND degrees.DegCod=courses.DegCod" " AND courses.CrsCod=crs_usr.CrsCod", - Gbl.Hierarchy.Ins.InsCod); + Cod); else NumUsrs = (unsigned) DB_QueryCOUNT ("can not get number of users", @@ -9708,7 +9399,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) " AND degrees.DegCod=courses.DegCod" " AND courses.CrsCod=crs_usr.CrsCod" " AND crs_usr.Role%s", - Gbl.Hierarchy.Ins.InsCod,SubQueryRoles); + Cod,SubQueryRoles); break; case Hie_CTR: if (AnyUserInCourses) // Any user @@ -9719,7 +9410,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) " WHERE degrees.CtrCod=%ld" " AND degrees.DegCod=courses.DegCod" " AND courses.CrsCod=crs_usr.CrsCod", - Gbl.Hierarchy.Ctr.CtrCod); + Cod); else NumUsrs = (unsigned) DB_QueryCOUNT ("can not get number of users", @@ -9729,7 +9420,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) " AND degrees.DegCod=courses.DegCod" " AND courses.CrsCod=crs_usr.CrsCod" " AND crs_usr.Role%s", - Gbl.Hierarchy.Ctr.CtrCod,SubQueryRoles); + Cod,SubQueryRoles); break; case Hie_DEG: if (AnyUserInCourses) // Any user @@ -9739,7 +9430,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) " FROM courses,crs_usr" " WHERE courses.DegCod=%ld" " AND courses.CrsCod=crs_usr.CrsCod", - Gbl.Hierarchy.Deg.DegCod); + Cod); else NumUsrs = (unsigned) DB_QueryCOUNT ("can not get number of users", @@ -9748,7 +9439,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) " WHERE courses.DegCod=%ld" " AND courses.CrsCod=crs_usr.CrsCod" " AND crs_usr.Role%s", - Gbl.Hierarchy.Deg.DegCod,SubQueryRoles); + Cod,SubQueryRoles); break; case Hie_CRS: if (AnyUserInCourses) // Any user @@ -9756,7 +9447,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) (unsigned) DB_QueryCOUNT ("can not get number of users", "SELECT COUNT(DISTINCT UsrCod) FROM crs_usr" " WHERE CrsCod=%ld", - Gbl.Hierarchy.Crs.CrsCod); + Cod); else NumUsrs = (unsigned) DB_QueryCOUNT ("can not get number of users", @@ -9764,7 +9455,7 @@ unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles) " FROM crs_usr" " WHERE CrsCod=%ld" " AND Role%s", - Gbl.Hierarchy.Crs.CrsCod,SubQueryRoles); + Cod,SubQueryRoles); break; default: Lay_WrongScopeExit (); @@ -10063,7 +9754,12 @@ double Usr_GetNumUsrsPerCrs (Rol_Role_t Role) (unsigned) Role); break; case Hie_CRS: - return (double) Usr_GetNumUsrsInCrs (Role,Gbl.Hierarchy.Crs.CrsCod); + return (double) Usr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Crs.CrsCod, + Role == Rol_UNK ? 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH : // Any user + 1 << Role); + default: Lay_WrongScopeExit (); break; diff --git a/swad_user.h b/swad_user.h index 38153665..c70cbbe2 100644 --- a/swad_user.h +++ b/swad_user.h @@ -408,16 +408,6 @@ void Usr_WriteRowUsrMainData (unsigned NumUsr,struct UsrData *UsrDat, bool PutCheckBoxToSelectUsr,Rol_Role_t Role, struct SelectedUsrs *SelectedUsrs); -void Usr_FlushCacheNumUsrsInCrs (void); -unsigned Usr_GetNumUsrsInCrs (Rol_Role_t Role,long CrsCod); -void Usr_FlushCacheNumUsrsInCrssOfDeg (void); -unsigned Usr_GetNumUsrsInCrssOfDeg (Rol_Role_t Role,long DegCod); -void Usr_FlushCacheNumUsrsInCrssOfCtr (void); -unsigned Usr_GetNumUsrsInCrssOfCtr (Rol_Role_t Role,long CtrCod); -void Usr_FlushCacheNumUsrsInCrssOfIns (void); -unsigned Usr_GetNumUsrsInCrssOfIns (Rol_Role_t Role,long InsCod); -unsigned Usr_GetNumUsrsInCrssOfCty (Rol_Role_t Role,long CtyCod); - long Usr_GetRamdomStdFromCrs (long CrsCod); long Usr_GetRamdomStdFromGrp (long GrpCod); @@ -522,7 +512,7 @@ bool Usr_ChkIfUsrCodExists (long UsrCod); void Usr_ShowWarningNoUsersFound (Rol_Role_t Role); unsigned Usr_GetTotalNumberOfUsersInPlatform (void); -unsigned Usr_GetTotalNumberOfUsersInCourses (Hie_Level_t Scope,unsigned Roles); +unsigned Usr_GetNumUsrsInCrss (Hie_Level_t Scope,long Cod,unsigned Roles); unsigned Usr_GetNumUsrsNotBelongingToAnyCrs (void); double Usr_GetNumCrssPerUsr (Rol_Role_t Role); double Usr_GetNumUsrsPerCrs (Rol_Role_t Role);