From 304d2c1275fcaf9c31d7f56ed847633287adb8df Mon Sep 17 00:00:00 2001 From: acanas Date: Mon, 13 Sep 2021 23:11:15 +0200 Subject: [PATCH] Version 21.0.1: Sep 13, 2021 Queries moved to module swad_follow_database. --- swad_changelog.h | 4 +- swad_course_config.c | 2 +- swad_degree.c | 12 +- swad_figure.c | 214 +------------------------------ swad_follow.h | 3 - swad_follow_database.c | 208 ++++++++++++++++++++++++++++++ swad_follow_database.h | 3 + swad_photo.c | 61 +++++---- swad_statistic.c | 282 +++++++++++++++++++++-------------------- swad_user.c | 46 +++---- 10 files changed, 422 insertions(+), 413 deletions(-) diff --git a/swad_changelog.h b/swad_changelog.h index 9de562e2..bfcdac5d 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,13 +602,15 @@ TODO: FIX BUG, URGENT! En las fechas como par TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo. */ -#define Log_PLATFORM_VERSION "SWAD 20.100.5 (2021-09-12)" +#define Log_PLATFORM_VERSION "SWAD 21.0.1 (2021-09-13)" #define CSS_FILE "swad20.45.css" #define JS_FILE "swad20.69.1.js" /* TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams + Version 21.0.1: Sep 13, 2021 Queries moved to module swad_follow_database. (314910 lines) + Version 21.0: Sep 13, 2021 Fixed bug in degrees photo. (314914 lines) Version 20.100.5: Sep 12, 2021 Fixed bug removing all students in a course. Reported by José Luis Bernier Villamor and Francisco J. Pelayo Valle. (314909 lines) Version 20.100.4: Sep 11, 2021 Queries moved to module swad_timeline_database. (314934 lines) Version 20.100.3: Sep 11, 2021 Queries moved to module swad_file_browser. (314923 lines) diff --git a/swad_course_config.c b/swad_course_config.c index 8c1f7d6c..a4457819 100644 --- a/swad_course_config.c +++ b/swad_course_config.c @@ -472,7 +472,7 @@ void CrsCfg_ChangeCrsDeg (void) struct Deg_Degree NewDeg; /***** Get parameter with degree code *****/ - NewDeg.DegCod = Deg_GetAndCheckParamOtherDegCod (1); + NewDeg.DegCod = Deg_GetAndCheckParamOtherDegCod (1L); /***** Check if degree has changed *****/ if (NewDeg.DegCod != Gbl.Hierarchy.Crs.DegCod) diff --git a/swad_degree.c b/swad_degree.c index 2acb61c2..3af87911 100644 --- a/swad_degree.c +++ b/swad_degree.c @@ -1194,7 +1194,7 @@ void Deg_RemoveDegree (void) Deg_EditingDegreeConstructor (); /***** Get degree code *****/ - Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1); + Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L); /***** Get data of degree *****/ Deg_GetDataOfDegreeByCod (Deg_EditingDeg); @@ -1387,7 +1387,7 @@ void Deg_RenameDegreeShort (void) Deg_EditingDegreeConstructor (); /***** Rename degree *****/ - Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1); + Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L); Deg_RenameDegree (Deg_EditingDeg,Cns_SHRT_NAME); } @@ -1397,7 +1397,7 @@ void Deg_RenameDegreeFull (void) Deg_EditingDegreeConstructor (); /***** Rename degree *****/ - Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1); + Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L); Deg_RenameDegree (Deg_EditingDeg,Cns_FULL_NAME); } @@ -1488,7 +1488,7 @@ void Deg_ChangeDegreeType (void) /***** Get parameters from form *****/ /* Get degree code */ - Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1); + Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L); /* Get the new degree type */ NewDegTypCod = DegTyp_GetAndCheckParamOtherDegTypCod (1); @@ -1521,7 +1521,7 @@ void Deg_ChangeDegWWW (void) /***** Get parameters from form *****/ /* Get the code of the degree */ - Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1); + Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L); /* Get the new WWW for the degree */ Par_GetParToText ("WWW",NewWWW,Cns_MAX_BYTES_WWW); @@ -1561,7 +1561,7 @@ void Deg_ChangeDegStatus (void) /***** Get parameters from form *****/ /* Get degree code */ - Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1); + Deg_EditingDeg->DegCod = Deg_GetAndCheckParamOtherDegCod (1L); /* Get parameter with status */ Status = (Deg_Status_t) diff --git a/swad_figure.c b/swad_figure.c index b7e248c4..dcda38f7 100644 --- a/swad_figure.c +++ b/swad_figure.c @@ -41,6 +41,7 @@ #include "swad_figure_cache.h" #include "swad_file_browser.h" #include "swad_follow.h" +#include "swad_follow_database.h" #include "swad_form.h" #include "swad_forum.h" #include "swad_global.h" @@ -2380,11 +2381,6 @@ static void Fig_GetAndShowFollowStats (void) extern const char *Txt_Followed; extern const char *Txt_Followers; extern const char *Txt_FollowPerFollow[2]; - static const char *FieldDB[2] = - { - "FollowedCod", - "FollowerCod" - }; unsigned Fol; unsigned NumUsrsTotal; unsigned NumUsrs; @@ -2410,100 +2406,7 @@ static void Fig_GetAndShowFollowStats (void) Fol < 2; Fol++) { - switch (Gbl.Scope.Current) - { - case HieLvl_SYS: - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get the total number of following/followers", - "SELECT COUNT(DISTINCT %s)" - " FROM usr_follow", - FieldDB[Fol]); - break; - case HieLvl_CTY: - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get the total number of following/followers", - "SELECT COUNT(DISTINCT usr_follow.%s)" - " FROM ins_instits," - "ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users," - "usr_follow" - " WHERE ins_instits.CtyCod=%ld" - " AND ins_instits.InsCod=ctr_centers.InsCod" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.UsrCod=usr_follow.%s", - FieldDB[Fol], - Gbl.Hierarchy.Cty.CtyCod, - FieldDB[Fol]); - break; - case HieLvl_INS: - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get the total number of following/followers", - "SELECT COUNT(DISTINCT usr_follow.%s)" - " FROM ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users," - "usr_follow" - " WHERE ctr_centers.InsCod=%ld" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.UsrCod=usr_follow.%s", - FieldDB[Fol], - Gbl.Hierarchy.Ins.InsCod, - FieldDB[Fol]); - break; - case HieLvl_CTR: - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get the total number of following/followers", - "SELECT COUNT(DISTINCT usr_follow.%s)" - " FROM deg_degrees," - "crs_courses," - "crs_users," - "usr_follow" - " WHERE deg_degrees.CtrCod=%ld" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.UsrCod=usr_follow.%s", - FieldDB[Fol], - Gbl.Hierarchy.Ctr.CtrCod, - FieldDB[Fol]); - break; - case HieLvl_DEG: - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get the total number of following/followers", - "SELECT COUNT(DISTINCT usr_follow.%s)" - " FROM crs_courses," - "crs_users," - "usr_follow" - " WHERE crs_courses.DegCod=%ld" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.UsrCod=usr_follow.%s", - FieldDB[Fol], - Gbl.Hierarchy.Deg.DegCod, - FieldDB[Fol]); - break; - case HieLvl_CRS: - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get the total number of following/followers", - "SELECT COUNT(DISTINCT usr_follow.%s)" - " FROM crs_users," - "usr_follow" - " WHERE crs_users.CrsCod=%ld" - " AND crs_users.UsrCod=usr_follow.%s", - FieldDB[Fol], - Gbl.Hierarchy.Crs.CrsCod, - FieldDB[Fol]); - break; - default: - Err_WrongScopeExit (); - NumUsrs = 0; // Not reached. Initialized to av oid warning - break; - } + NumUsrs = Fol_DB_GetNumFollowinFollowers (Fol); /***** Write number of followed / followers *****/ HTM_TR_Begin (NULL); @@ -2531,118 +2434,7 @@ static void Fig_GetAndShowFollowStats (void) Fol < 2; Fol++) { - switch (Gbl.Scope.Current) - { - case HieLvl_SYS: - Average = DB_QuerySELECTDouble ("can not get number of questions" - " per survey", - "SELECT AVG(N)" - " FROM (SELECT COUNT(%s) AS N" - " FROM usr_follow" - " GROUP BY %s) AS F", - FieldDB[Fol], - FieldDB[1 - Fol]); - break; - case HieLvl_CTY: - Average = DB_QuerySELECTDouble ("can not get number of questions" - " per survey", - "SELECT AVG(N)" - " FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N" - " FROM ins_instits," - "ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users," - "usr_follow" - " WHERE ins_instits.CtyCod=%ld" - " AND ins_instits.InsCod=ctr_centers.InsCod" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.UsrCod=usr_follow.%s" - " GROUP BY %s) AS F", - FieldDB[Fol], - Gbl.Hierarchy.Cty.CtyCod, - FieldDB[Fol], - FieldDB[1 - Fol]); - break; - case HieLvl_INS: - Average = DB_QuerySELECTDouble ("can not get number of questions" - " per survey", - "SELECT AVG(N)" - " FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N" - " FROM ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users," - "usr_follow" - " WHERE ctr_centers.InsCod=%ld" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.UsrCod=usr_follow.%s" - " GROUP BY %s) AS F", - FieldDB[Fol], - Gbl.Hierarchy.Ins.InsCod, - FieldDB[Fol], - FieldDB[1 - Fol]); - break; - case HieLvl_CTR: - Average = DB_QuerySELECTDouble ("can not get number of questions" - " per survey", - "SELECT AVG(N)" - " FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N" - " FROM deg_degrees," - "crs_courses," - "crs_users," - "usr_follow" - " WHERE deg_degrees.CtrCod=%ld" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.UsrCod=usr_follow.%s" - " GROUP BY %s) AS F", - FieldDB[Fol], - Gbl.Hierarchy.Ctr.CtrCod, - FieldDB[Fol], - FieldDB[1 - Fol]); - break; - case HieLvl_DEG: - Average = DB_QuerySELECTDouble ("can not get number of questions" - " per survey", - "SELECT AVG(N)" - " FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N" - " FROM crs_courses," - "crs_users," - "usr_follow" - " WHERE crs_courses.DegCod=%ld" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.UsrCod=usr_follow.%s" - " GROUP BY %s) AS F", - FieldDB[Fol], - Gbl.Hierarchy.Deg.DegCod, - FieldDB[Fol], - FieldDB[1 - Fol]); - break; - case HieLvl_CRS: - Average = DB_QuerySELECTDouble ("can not get number of questions" - " per survey", - "SELECT AVG(N)" - " FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N" - " FROM crs_users," - "usr_follow" - " WHERE crs_users.CrsCod=%ld" - " AND crs_users.UsrCod=usr_follow.%s" - " GROUP BY %s) AS F", - FieldDB[Fol], - Gbl.Hierarchy.Crs.CrsCod, - FieldDB[Fol], - FieldDB[1 - Fol]); - break; - default: - Err_WrongScopeExit (); - Average = 0.0; // Not reached - break; - } + Average = Fol_DB_GetNumFollowedPerFollower (Fol); /***** Write number of followed per follower *****/ HTM_TR_Begin (NULL); diff --git a/swad_follow.h b/swad_follow.h index 4964505f..e8c4fad6 100644 --- a/swad_follow.h +++ b/swad_follow.h @@ -80,7 +80,4 @@ void Fol_GetNotifFollower (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], void Fol_RemoveUsrFromUsrFollow (long UsrCod); -void Fol_DB_CreateTmpTableMeAndUsrsIFollow (void); -void Fol_DB_DropTmpTableMeAndUsrsIFollow (void); - #endif diff --git a/swad_follow_database.c b/swad_follow_database.c index 903dee82..ec2cc437 100644 --- a/swad_follow_database.c +++ b/swad_follow_database.c @@ -40,6 +40,12 @@ /***************************** Private constants *****************************/ /*****************************************************************************/ +static const char *FieldDB[2] = + { + "FollowedCod", + "FollowerCod" + }; + /*****************************************************************************/ /******************************* Private types *******************************/ /*****************************************************************************/ @@ -311,6 +317,208 @@ unsigned Fol_DB_GetListFollowers (long UsrCod,MYSQL_RES **mysql_res) UsrCod); } +/*****************************************************************************/ +/************** Get and show number of following and followers ***************/ +/*****************************************************************************/ + +unsigned Fol_DB_GetNumFollowinFollowers (unsigned Fol) + { + switch (Gbl.Scope.Current) + { + case HieLvl_SYS: + return (unsigned) + DB_QueryCOUNT ("can not get the total number of following/followers", + "SELECT COUNT(DISTINCT %s)" + " FROM usr_follow", + FieldDB[Fol]); + case HieLvl_CTY: + return (unsigned) + DB_QueryCOUNT ("can not get the total number of following/followers", + "SELECT COUNT(DISTINCT usr_follow.%s)" + " FROM ins_instits," + "ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users," + "usr_follow" + " WHERE ins_instits.CtyCod=%ld" + " AND ins_instits.InsCod=ctr_centers.InsCod" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.UsrCod=usr_follow.%s", + FieldDB[Fol], + Gbl.Hierarchy.Cty.CtyCod, + FieldDB[Fol]); + case HieLvl_INS: + return (unsigned) + DB_QueryCOUNT ("can not get the total number of following/followers", + "SELECT COUNT(DISTINCT usr_follow.%s)" + " FROM ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users," + "usr_follow" + " WHERE ctr_centers.InsCod=%ld" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.UsrCod=usr_follow.%s", + FieldDB[Fol], + Gbl.Hierarchy.Ins.InsCod, + FieldDB[Fol]); + case HieLvl_CTR: + return (unsigned) + DB_QueryCOUNT ("can not get the total number of following/followers", + "SELECT COUNT(DISTINCT usr_follow.%s)" + " FROM deg_degrees," + "crs_courses," + "crs_users," + "usr_follow" + " WHERE deg_degrees.CtrCod=%ld" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.UsrCod=usr_follow.%s", + FieldDB[Fol], + Gbl.Hierarchy.Ctr.CtrCod, + FieldDB[Fol]); + case HieLvl_DEG: + return (unsigned) + DB_QueryCOUNT ("can not get the total number of following/followers", + "SELECT COUNT(DISTINCT usr_follow.%s)" + " FROM crs_courses," + "crs_users," + "usr_follow" + " WHERE crs_courses.DegCod=%ld" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.UsrCod=usr_follow.%s", + FieldDB[Fol], + Gbl.Hierarchy.Deg.DegCod, + FieldDB[Fol]); + case HieLvl_CRS: + return (unsigned) + DB_QueryCOUNT ("can not get the total number of following/followers", + "SELECT COUNT(DISTINCT usr_follow.%s)" + " FROM crs_users," + "usr_follow" + " WHERE crs_users.CrsCod=%ld" + " AND crs_users.UsrCod=usr_follow.%s", + FieldDB[Fol], + Gbl.Hierarchy.Crs.CrsCod, + FieldDB[Fol]); + default: + Err_WrongScopeExit (); + return 0; // Not reached + } + } + +/*****************************************************************************/ +/************** Get and show number of following and followers ***************/ +/*****************************************************************************/ + +double Fol_DB_GetNumFollowedPerFollower (unsigned Fol) + { + switch (Gbl.Scope.Current) + { + case HieLvl_SYS: + return DB_QuerySELECTDouble ("can not get number of followed per follower", + "SELECT AVG(N)" + " FROM (SELECT COUNT(%s) AS N" + " FROM usr_follow" + " GROUP BY %s) AS F", + FieldDB[Fol], + FieldDB[1 - Fol]); + case HieLvl_CTY: + return DB_QuerySELECTDouble ("can not get number of followed per follower", + "SELECT AVG(N)" + " FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N" + " FROM ins_instits," + "ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users," + "usr_follow" + " WHERE ins_instits.CtyCod=%ld" + " AND ins_instits.InsCod=ctr_centers.InsCod" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.UsrCod=usr_follow.%s" + " GROUP BY %s) AS F", + FieldDB[Fol], + Gbl.Hierarchy.Cty.CtyCod, + FieldDB[Fol], + FieldDB[1 - Fol]); + case HieLvl_INS: + return DB_QuerySELECTDouble ("can not get number of followed per follower", + "SELECT AVG(N)" + " FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N" + " FROM ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users," + "usr_follow" + " WHERE ctr_centers.InsCod=%ld" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.UsrCod=usr_follow.%s" + " GROUP BY %s) AS F", + FieldDB[Fol], + Gbl.Hierarchy.Ins.InsCod, + FieldDB[Fol], + FieldDB[1 - Fol]); + case HieLvl_CTR: + return DB_QuerySELECTDouble ("can not get number of followed per follower", + "SELECT AVG(N)" + " FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N" + " FROM deg_degrees," + "crs_courses," + "crs_users," + "usr_follow" + " WHERE deg_degrees.CtrCod=%ld" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.UsrCod=usr_follow.%s" + " GROUP BY %s) AS F", + FieldDB[Fol], + Gbl.Hierarchy.Ctr.CtrCod, + FieldDB[Fol], + FieldDB[1 - Fol]); + case HieLvl_DEG: + return DB_QuerySELECTDouble ("can not get number of followed per follower", + "SELECT AVG(N)" + " FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N" + " FROM crs_courses," + "crs_users," + "usr_follow" + " WHERE crs_courses.DegCod=%ld" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.UsrCod=usr_follow.%s" + " GROUP BY %s) AS F", + FieldDB[Fol], + Gbl.Hierarchy.Deg.DegCod, + FieldDB[Fol], + FieldDB[1 - Fol]); + case HieLvl_CRS: + return DB_QuerySELECTDouble ("can not get number of followed per follower", + "SELECT AVG(N)" + " FROM (SELECT COUNT(DISTINCT usr_follow.%s) AS N" + " FROM crs_users," + "usr_follow" + " WHERE crs_users.CrsCod=%ld" + " AND crs_users.UsrCod=usr_follow.%s" + " GROUP BY %s) AS F", + FieldDB[Fol], + Gbl.Hierarchy.Crs.CrsCod, + FieldDB[Fol], + FieldDB[1 - Fol]); + default: + Err_WrongScopeExit (); + return 0.0; // Not reached + } + } + /*****************************************************************************/ /******************************** Follow user ********************************/ /*****************************************************************************/ diff --git a/swad_follow_database.h b/swad_follow_database.h index 72476c4e..bfba3bc5 100644 --- a/swad_follow_database.h +++ b/swad_follow_database.h @@ -53,6 +53,9 @@ unsigned Fol_DB_GetNumFollowers (long UsrCod); unsigned Fol_DB_GetListFollowing (long UsrCod,MYSQL_RES **mysql_res); unsigned Fol_DB_GetListFollowers (long UsrCod,MYSQL_RES **mysql_res); +unsigned Fol_DB_GetNumFollowinFollowers (unsigned Fol); +double Fol_DB_GetNumFollowedPerFollower (unsigned Fol); + void Fol_DB_FollowUsr (long UsrCod); void Fol_DB_UnfollowUsr (long UsrCod); diff --git a/swad_photo.c b/swad_photo.c index 3832f33a..3d11548b 100644 --- a/swad_photo.c +++ b/swad_photo.c @@ -1388,39 +1388,43 @@ void Pho_CalcPhotoDegree (void) Fil_CreateDirIfNotExists (Cfg_PATH_PHOTO_TMP_PRIVATE); /***** Get the degree which photo will be computed *****/ - DegCod = Deg_GetAndCheckParamOtherDegCod (1); + DegCod = Deg_GetAndCheckParamOtherDegCod (-1L); // Parameter may be omitted + // (when selecting classphoto/list) - /***** Prevent the computing of an average photo too recently updated *****/ - if (Pho_GetTimeAvgPhotoWasComputed (DegCod) >= - Gbl.StartExecutionTimeUTC - Cfg_MIN_TIME_TO_RECOMPUTE_AVG_PHOTO) - Err_ShowErrorAndExit ("Average photo has been computed recently."); - - /***** Get list of students in this degree *****/ - Usr_GetUnorderedStdsCodesInDeg (DegCod); - - for (Sex = (Usr_Sex_t) 0; - Sex <= (Usr_Sex_t) (Usr_NUM_SEXS - 1); - Sex++) + if (DegCod > 0) { - TotalTimeToComputeAvgPhotoInMicroseconds = 0; - for (TypeOfAverage = (Pho_AvgPhotoTypeOfAverage_t) 0; - TypeOfAverage <= (Pho_AvgPhotoTypeOfAverage_t) (Pho_NUM_AVERAGE_PHOTO_TYPES - 1); - TypeOfAverage++) - { - /***** Compute average photos of students belonging this degree *****/ - Pho_ComputeAveragePhoto (DegCod,Sex,Rol_STD, - TypeOfAverage,DirAvgPhotosRelPath[TypeOfAverage], - &NumStds,&NumStdsWithPhoto,&PartialTimeToComputeAvgPhotoInMicroseconds); - TotalTimeToComputeAvgPhotoInMicroseconds += PartialTimeToComputeAvgPhotoInMicroseconds; - } + /***** Prevent the computing of an average photo too recently updated *****/ + if (Pho_GetTimeAvgPhotoWasComputed (DegCod) >= + Gbl.StartExecutionTimeUTC - Cfg_MIN_TIME_TO_RECOMPUTE_AVG_PHOTO) + Err_ShowErrorAndExit ("Average photo has been computed recently."); - /***** Store stats in database *****/ - Pho_DB_UpdateDegStats (DegCod,Sex,NumStds,NumStdsWithPhoto,TotalTimeToComputeAvgPhotoInMicroseconds); + /***** Get list of students in this degree *****/ + Usr_GetUnorderedStdsCodesInDeg (DegCod); + + for (Sex = (Usr_Sex_t) 0; + Sex <= (Usr_Sex_t) (Usr_NUM_SEXS - 1); + Sex++) + { + TotalTimeToComputeAvgPhotoInMicroseconds = 0; + for (TypeOfAverage = (Pho_AvgPhotoTypeOfAverage_t) 0; + TypeOfAverage <= (Pho_AvgPhotoTypeOfAverage_t) (Pho_NUM_AVERAGE_PHOTO_TYPES - 1); + TypeOfAverage++) + { + /***** Compute average photos of students belonging this degree *****/ + Pho_ComputeAveragePhoto (DegCod,Sex,Rol_STD, + TypeOfAverage,DirAvgPhotosRelPath[TypeOfAverage], + &NumStds,&NumStdsWithPhoto,&PartialTimeToComputeAvgPhotoInMicroseconds); + TotalTimeToComputeAvgPhotoInMicroseconds += PartialTimeToComputeAvgPhotoInMicroseconds; + } + + /***** Store stats in database *****/ + Pho_DB_UpdateDegStats (DegCod,Sex,NumStds,NumStdsWithPhoto,TotalTimeToComputeAvgPhotoInMicroseconds); + } + + /***** Free memory for students list *****/ + Usr_FreeUsrsList (Rol_STD); } - /***** Free memory for students list *****/ - Usr_FreeUsrsList (Rol_STD); - /***** Show photos *****/ Pho_ShowOrPrintPhotoDegree (Pho_DEGREES_SEE); } @@ -2134,6 +2138,7 @@ static void Pho_ShowOrPrintClassPhotoDegrees (struct Pho_DegPhotos *DegPhotos, /***** Form to select type of list used to display degree photos *****/ if (SeeOrPrint == Pho_DEGREES_SEE) Usr_ShowFormsToSelectUsrListType (Pho_PutParamsDegPhoto,DegPhotos); + HTM_TABLE_BeginCenter (); /***** Get and print degrees *****/ diff --git a/swad_statistic.c b/swad_statistic.c index 8e478161..03eac6fe 100644 --- a/swad_statistic.c +++ b/swad_statistic.c @@ -289,159 +289,161 @@ static void Sta_PutFormCrsHits (struct Sta_Stats *Stats) Hlp_ANALYTICS_Visits_visits_to_course,Box_NOT_CLOSABLE); Str_FreeString (); - /***** Show form to select the groups *****/ - Grp_ShowFormToSelectSeveralGroups (NULL,NULL, - Grp_MY_GROUPS); + /***** Show form to select the groups *****/ + Grp_ShowFormToSelectSeveralGroups (NULL,NULL, + Grp_MY_GROUPS); - /***** Begin section with user list *****/ - HTM_SECTION_Begin (Usr_USER_LIST_SECTION_ID); + /***** Begin section with user list *****/ + HTM_SECTION_Begin (Usr_USER_LIST_SECTION_ID); - if (NumTotalUsrs) - { - if (Usr_GetIfShowBigList (NumTotalUsrs, - NULL,NULL, - NULL)) - { - /***** Form to select type of list used for select several users *****/ - Usr_ShowFormsToSelectUsrListType (NULL,NULL); + if (NumTotalUsrs) + { + if (Usr_GetIfShowBigList (NumTotalUsrs, + NULL,NULL, + NULL)) + { + /***** Form to select type of list used for select several users *****/ + Usr_ShowFormsToSelectUsrListType (NULL,NULL); - /***** Put link to register students *****/ - Enr_CheckStdsAndPutButtonToRegisterStdsInCurrentCrs (); + /***** Put link to register students *****/ + Enr_CheckStdsAndPutButtonToRegisterStdsInCurrentCrs (); - /***** Begin form *****/ - Frm_BeginFormAnchor (ActSeeAccCrs,Sta_STAT_RESULTS_SECTION_ID); + /***** Begin form *****/ + Frm_BeginFormAnchor (ActSeeAccCrs,Sta_STAT_RESULTS_SECTION_ID); - Grp_PutParamsCodGrps (); - Par_PutHiddenParamLong (NULL,"FirstRow",0); - Par_PutHiddenParamLong (NULL,"LastRow",0); + Grp_PutParamsCodGrps (); + Par_PutHiddenParamLong (NULL,"FirstRow",0); + Par_PutHiddenParamLong (NULL,"LastRow",0); - /***** Put list of users to select some of them *****/ - HTM_TABLE_BeginCenterPadding (2); + /***** Put list of users to select some of them *****/ + HTM_TABLE_BeginCenterPadding (2); - HTM_TR_Begin (NULL); + HTM_TR_Begin (NULL); - HTM_TD_Begin ("class=\"RT %s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); - HTM_TxtColon (Txt_Users); - HTM_TD_End (); + HTM_TD_Begin ("class=\"RT %s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); + HTM_TxtColon (Txt_Users); + HTM_TD_End (); - HTM_TD_Begin ("class=\"%s LT\"",The_ClassFormInBox[Gbl.Prefs.Theme]); - HTM_TABLE_Begin (NULL); - Usr_ListUsersToSelect (Rol_TCH,&Gbl.Usrs.Selected); - Usr_ListUsersToSelect (Rol_NET,&Gbl.Usrs.Selected); - Usr_ListUsersToSelect (Rol_STD,&Gbl.Usrs.Selected); - HTM_TABLE_End (); - HTM_TD_End (); + HTM_TD_Begin ("class=\"%s LT\"",The_ClassFormInBox[Gbl.Prefs.Theme]); + HTM_TABLE_Begin (NULL); + Usr_ListUsersToSelect (Rol_TCH,&Gbl.Usrs.Selected); + Usr_ListUsersToSelect (Rol_NET,&Gbl.Usrs.Selected); + Usr_ListUsersToSelect (Rol_STD,&Gbl.Usrs.Selected); + HTM_TABLE_End (); + HTM_TD_End (); - HTM_TR_End (); + HTM_TR_End (); - /***** Initial and final dates of the search *****/ - if (Gbl.Action.Act == ActReqAccCrs) - { - SetHMS[Dat_START_TIME] = Dat_HMS_TO_000000; - SetHMS[Dat_END_TIME ] = Dat_HMS_TO_235959; + /***** Initial and final dates of the search *****/ + if (Gbl.Action.Act == ActReqAccCrs) + { + SetHMS[Dat_START_TIME] = Dat_HMS_TO_000000; + SetHMS[Dat_END_TIME ] = Dat_HMS_TO_235959; + } + else + { + SetHMS[Dat_START_TIME] = Dat_HMS_DO_NOT_SET; + SetHMS[Dat_END_TIME ] = Dat_HMS_DO_NOT_SET; + } + Dat_PutFormStartEndClientLocalDateTimesWithYesterdayToday (SetHMS); + + /***** Selection of action *****/ + Sta_WriteSelectorAction (Stats); + + /***** Option a) Listing of clicks distributed by some metric *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); + HTM_TxtColon (Txt_Show); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"LM\""); + + if ((Stats->ClicksGroupedBy < Sta_CLICKS_CRS_PER_USR || + Stats->ClicksGroupedBy > Sta_CLICKS_CRS_PER_ACTION) && + Stats->ClicksGroupedBy != Sta_CLICKS_CRS_DETAILED_LIST) + Stats->ClicksGroupedBy = Sta_CLICKS_GROUPED_BY_DEFAULT; + + HTM_INPUT_RADIO ("GroupedOrDetailed",false, + "value=\"%u\"%s onclick=\"disableDetailedClicks();\"", + (unsigned) Sta_CLICKS_GROUPED, + Stats->ClicksGroupedBy == Sta_CLICKS_CRS_DETAILED_LIST ? "" : + " checked=\"checked\""); + + /* Selection of count type (number of pages generated, accesses per user, etc.) */ + Sta_WriteSelectorCountType (Stats); + + HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); + HTM_TxtF (" %s ",Txt_distributed_by); + HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, + "id=\"GroupedBy\" name=\"GroupedBy\""); + for (ClicksGroupedBy = Sta_CLICKS_CRS_PER_USR; + ClicksGroupedBy <= Sta_CLICKS_CRS_PER_ACTION; + ClicksGroupedBy++) + { + ClicksGroupedByUnsigned = (unsigned) ClicksGroupedBy; + HTM_OPTION (HTM_Type_UNSIGNED,&ClicksGroupedByUnsigned, + ClicksGroupedBy == Stats->ClicksGroupedBy,false, + "%s",Txt_STAT_CLICKS_GROUPED_BY[ClicksGroupedBy]); + } + HTM_SELECT_End (); + HTM_LABEL_End (); + + /***** Separator *****/ + HTM_BR (); + + /***** Option b) Listing of detailed clicks to this course *****/ + HTM_LABEL_Begin (NULL); + HTM_INPUT_RADIO ("GroupedOrDetailed",false, + "value=\"%u\"%s onclick=\"enableDetailedClicks();\"", + (unsigned) Sta_CLICKS_DETAILED, + Stats->ClicksGroupedBy == Sta_CLICKS_CRS_DETAILED_LIST ? " checked=\"checked\"" : + ""); + HTM_Txt (Txt_STAT_CLICKS_GROUPED_BY[Sta_CLICKS_CRS_DETAILED_LIST]); + HTM_LABEL_End (); + + /* Separator */ + HTM_Txt (" "); + + /* Number of rows per page */ + // To use getElementById in Firefox, it's necessary to have the id attribute + HTM_LABEL_Begin (NULL); + HTM_TxtF ("(%s: ",Txt_results_per_page); + HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, + "id=\"RowsPage\" name=\"RowsPage\"%s", + Stats->ClicksGroupedBy == Sta_CLICKS_CRS_DETAILED_LIST ? "" : + " disabled=\"disabled\""); + for (i = 0; + i < NUM_OPTIONS_ROWS_PER_PAGE; + i++) + HTM_OPTION (HTM_Type_UNSIGNED,&RowsPerPage[i], + RowsPerPage[i] == Stats->RowsPerPage,false, + "%u",RowsPerPage[i]); + HTM_SELECT_End (); + HTM_Txt (")"); + HTM_LABEL_End (); + + HTM_TD_End (); + + HTM_TR_End (); + + HTM_TABLE_End (); + + /***** Hidden param used to get client time zone *****/ + Dat_PutHiddenParBrowserTZDiff (); + + /***** Send button *****/ + Btn_PutConfirmButton (Txt_Show_hits); + + /***** End form *****/ + Frm_EndForm (); + } } - else - { - SetHMS[Dat_START_TIME] = Dat_HMS_DO_NOT_SET; - SetHMS[Dat_END_TIME ] = Dat_HMS_DO_NOT_SET; - } - Dat_PutFormStartEndClientLocalDateTimesWithYesterdayToday (SetHMS); + else // No teachers nor students found + Ale_ShowAlert (Ale_WARNING,Txt_No_teachers_or_students_found); - /***** Selection of action *****/ - Sta_WriteSelectorAction (Stats); - - /***** Option a) Listing of clicks distributed by some metric *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); - HTM_TxtColon (Txt_Show); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"LM\""); - - if ((Stats->ClicksGroupedBy < Sta_CLICKS_CRS_PER_USR || - Stats->ClicksGroupedBy > Sta_CLICKS_CRS_PER_ACTION) && - Stats->ClicksGroupedBy != Sta_CLICKS_CRS_DETAILED_LIST) - Stats->ClicksGroupedBy = Sta_CLICKS_GROUPED_BY_DEFAULT; - - HTM_INPUT_RADIO ("GroupedOrDetailed",false, - "value=\"%u\"%s onclick=\"disableDetailedClicks();\"", - (unsigned) Sta_CLICKS_GROUPED, - Stats->ClicksGroupedBy == Sta_CLICKS_CRS_DETAILED_LIST ? "" : - " checked=\"checked\""); - - /* Selection of count type (number of pages generated, accesses per user, etc.) */ - Sta_WriteSelectorCountType (Stats); - - HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); - HTM_TxtF (" %s ",Txt_distributed_by); - HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, - "id=\"GroupedBy\" name=\"GroupedBy\""); - for (ClicksGroupedBy = Sta_CLICKS_CRS_PER_USR; - ClicksGroupedBy <= Sta_CLICKS_CRS_PER_ACTION; - ClicksGroupedBy++) - { - ClicksGroupedByUnsigned = (unsigned) ClicksGroupedBy; - HTM_OPTION (HTM_Type_UNSIGNED,&ClicksGroupedByUnsigned, - ClicksGroupedBy == Stats->ClicksGroupedBy,false, - "%s",Txt_STAT_CLICKS_GROUPED_BY[ClicksGroupedBy]); - } - HTM_SELECT_End (); - HTM_LABEL_End (); - - /***** Separator *****/ - HTM_BR (); - - /***** Option b) Listing of detailed clicks to this course *****/ - HTM_LABEL_Begin (NULL); - HTM_INPUT_RADIO ("GroupedOrDetailed",false, - "value=\"%u\"%s onclick=\"enableDetailedClicks();\"", - (unsigned) Sta_CLICKS_DETAILED, - Stats->ClicksGroupedBy == Sta_CLICKS_CRS_DETAILED_LIST ? " checked=\"checked\"" : - ""); - HTM_Txt (Txt_STAT_CLICKS_GROUPED_BY[Sta_CLICKS_CRS_DETAILED_LIST]); - HTM_LABEL_End (); - - /* Separator */ - HTM_Txt (" "); - - /* Number of rows per page */ - // To use getElementById in Firefox, it's necessary to have the id attribute - HTM_LABEL_Begin (NULL); - HTM_TxtF ("(%s: ",Txt_results_per_page); - HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, - "id=\"RowsPage\" name=\"RowsPage\"%s", - Stats->ClicksGroupedBy == Sta_CLICKS_CRS_DETAILED_LIST ? "" : - " disabled=\"disabled\""); - for (i = 0; - i < NUM_OPTIONS_ROWS_PER_PAGE; - i++) - HTM_OPTION (HTM_Type_UNSIGNED,&RowsPerPage[i], - RowsPerPage[i] == Stats->RowsPerPage,false, - "%u",RowsPerPage[i]); - HTM_SELECT_End (); - HTM_Txt (")"); - HTM_LABEL_End (); - HTM_TD_End (); - - HTM_TR_End (); - HTM_TABLE_End (); - - /***** Hidden param used to get client time zone *****/ - Dat_PutHiddenParBrowserTZDiff (); - - /***** Send button *****/ - Btn_PutConfirmButton (Txt_Show_hits); - - /***** End form *****/ - Frm_EndForm (); - } - } - else // No teachers nor students found - Ale_ShowAlert (Ale_WARNING,Txt_No_teachers_or_students_found); - - /***** End section with user list *****/ - HTM_SECTION_End (); + /***** End section with user list *****/ + HTM_SECTION_End (); /***** End box *****/ Box_BoxEnd (); diff --git a/swad_user.c b/swad_user.c index 3115140f..7eeb0df0 100644 --- a/swad_user.c +++ b/swad_user.c @@ -6386,37 +6386,37 @@ void Usr_ShowFormsToSelectUsrListType (void (*FuncParams) (void *Args),void *Arg HTM_DIV_Begin ("class=\"%s\"", Gbl.Usrs.Me.ListType == Usr_LIST_AS_CLASS_PHOTO ? "PREF_ON" : "PREF_OFF"); - Usr_FormToSelectUsrListType (FuncParams,Args, - Usr_LIST_AS_CLASS_PHOTO); + Usr_FormToSelectUsrListType (FuncParams,Args, + Usr_LIST_AS_CLASS_PHOTO); - /* Number of columns in the class photo */ - Frm_BeginFormAnchor (Gbl.Action.Act, // Repeat current action - Usr_USER_LIST_SECTION_ID); - Grp_PutParamsCodGrps (); - Usr_PutParamUsrListType (Usr_LIST_AS_CLASS_PHOTO); - Usr_PutParamListWithPhotos (); - Usr_PutSelectorNumColsClassPhoto (); - if (FuncParams) - FuncParams (Args); - Frm_EndForm (); + /* Number of columns in the class photo */ + Frm_BeginFormAnchor (Gbl.Action.Act, // Repeat current action + Usr_USER_LIST_SECTION_ID); + Grp_PutParamsCodGrps (); + Usr_PutParamUsrListType (Usr_LIST_AS_CLASS_PHOTO); + Usr_PutParamListWithPhotos (); + Usr_PutSelectorNumColsClassPhoto (); + if (FuncParams) + FuncParams (Args); + Frm_EndForm (); HTM_DIV_End (); /***** Select Usr_LIST_AS_LISTING *****/ HTM_DIV_Begin ("class=\"%s\"", Gbl.Usrs.Me.ListType == Usr_LIST_AS_LISTING ? "PREF_ON" : "PREF_OFF"); - Usr_FormToSelectUsrListType (FuncParams,Args, - Usr_LIST_AS_LISTING); + Usr_FormToSelectUsrListType (FuncParams,Args, + Usr_LIST_AS_LISTING); - /* See the photos in list? */ - Frm_BeginFormAnchor (Gbl.Action.Act, // Repeat current action - Usr_USER_LIST_SECTION_ID); - Grp_PutParamsCodGrps (); - Usr_PutParamUsrListType (Usr_LIST_AS_LISTING); - if (FuncParams) - FuncParams (Args); - Usr_PutCheckboxListWithPhotos (); - Frm_EndForm (); + /* See the photos in list? */ + Frm_BeginFormAnchor (Gbl.Action.Act, // Repeat current action + Usr_USER_LIST_SECTION_ID); + Grp_PutParamsCodGrps (); + Usr_PutParamUsrListType (Usr_LIST_AS_LISTING); + if (FuncParams) + FuncParams (Args); + Usr_PutCheckboxListWithPhotos (); + Frm_EndForm (); HTM_DIV_End (); Set_EndOneSettingSelector ();