From 1b80819347dd58ffb5d3d9f3b304934d61bb12a7 Mon Sep 17 00:00:00 2001 From: acanas Date: Fri, 29 May 2020 12:40:07 +0200 Subject: [PATCH] Version19.247.1 --- swad_changelog.h | 14 +++---------- swad_exam_result.c | 51 ++++++++++++++++++++++++++++++++++++--------- swad_exam_session.c | 2 +- swad_match.c | 2 +- 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/swad_changelog.h b/swad_changelog.h index 784f8a64c..879156359 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -490,16 +490,7 @@ contiene una de las que yo imparto. As /* TODO: Geolocalización: - -Función API sendCurrentLocation... -Parámetros a enviar a la función: - 1. Código único de la sala (número roomCode) -Almacenaría esa ubicación en una tabla -- Código usuario -- Código de ubicación (sacado de la tabla de ubicaciones) -- Fecha-hora - -La tabla contendría todas las ubicaciones de todos los usuarios en las últimas 12/24 horas como mucho. +La tabla room_check_in contiene todas las ubicaciones de todos los usuarios en las últimas 12/24 horas como mucho. Se eliminaría periódicamante en Lay_RefreshNotifsAndConnected(). Haría falta una función API que envíe el histórico reciente de ubicaciones de un usuario @@ -565,10 +556,11 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.247 (2020-05-25)" +#define Log_PLATFORM_VERSION "SWAD 19.247.1 (2020-05-25)" #define CSS_FILE "swad19.238.2.css" #define JS_FILE "swad19.246.1.js" /* + Version 19.247.1: May 29, 2020 Do not show exam results in hidden exams or hidden exam sessions. (302646 lines) Version 19.247: May 24, 2020 New API function getCurrentLocation. (302622 lines) 1 change necessary in database: CREATE TABLE IF NOT EXISTS room_check_in (ChkCod INT NOT NULL AUTO_INCREMENT,UsrCod INT NOT NULL,RooCod INT NOT NULL,CheckInTime DATETIME NOT NULL,UNIQUE INDEX(ChkCod),INDEX(UsrCod,CheckInTime),INDEX(CheckInTime)); diff --git a/swad_exam_result.c b/swad_exam_result.c index 2906acb4f..b77049abd 100644 --- a/swad_exam_result.c +++ b/swad_exam_result.c @@ -113,7 +113,9 @@ static void ExaRes_ShowExamResult (const struct Exa_Exam *Exam, struct ExaPrn_Print *Print, struct UsrData *UsrDat); -static bool ExaRes_CheckIfICanSeePrintResult (const struct ExaSes_Session *Session,long UsrCod); +static bool ExaRes_CheckIfICanSeePrintResult (const struct Exa_Exam *Exam, + const struct ExaSes_Session *Session, + long UsrCod); static bool ExaRes_CheckIfICanViewScore (bool ICanViewResult,unsigned Visibility); static void ExaRes_ShowExamAnswers (struct UsrData *UsrDat, @@ -758,6 +760,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams, { extern const char *Txt_Result; char *SesSubQuery; + char *HidSubQuery; char *ExaSubQuery; MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -790,26 +793,43 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams, &Gbl.Usrs.Other.UsrDat; /***** Build sessions subquery *****/ - if (SesCod > 0) + if (SesCod > 0) // One unique session { if (asprintf (&SesSubQuery," AND exa_prints.SesCod=%ld",SesCod) < 0) Lay_NotEnoughMemoryExit (); } - else + else // All sessions of selected exams { if (asprintf (&SesSubQuery,"%s","") < 0) Lay_NotEnoughMemoryExit (); } + /***** Subquery: get hidden sessions? + · A student will not be able to see their results in hidden sessions + · A teacher will be able to see results from other users + even in hidden sessions + *****/ + switch (MeOrOther) + { + case Usr_ME: // A student watching her/his results + if (asprintf (&HidSubQuery," AND exa_sessions.Hidden='N'") < 0) + Lay_NotEnoughMemoryExit (); + break; + default: // A teacher/admin watching the results of other users + if (asprintf (&HidSubQuery,"%s","") < 0) + Lay_NotEnoughMemoryExit (); + break; + } + /***** Build exams subquery *****/ - if (ExaCod > 0) + if (ExaCod > 0) // One unique exams { if (asprintf (&ExaSubQuery," AND exa_sessions.ExaCod=%ld",ExaCod) < 0) Lay_NotEnoughMemoryExit (); } else if (ExamsSelectedCommas) { - if (ExamsSelectedCommas[0]) + if (ExamsSelectedCommas[0]) // Selected exams { if (asprintf (&ExaSubQuery," AND exa_sessions.ExaCod IN (%s)", ExamsSelectedCommas) < 0) @@ -821,13 +841,15 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams, Lay_NotEnoughMemoryExit (); } } - else + else // All exams { if (asprintf (&ExaSubQuery,"%s","") < 0) Lay_NotEnoughMemoryExit (); } /***** Make database query *****/ + // Do not filter by groups, because a student who has changed groups + // must be able to access exams taken in other groups NumResults = (unsigned) DB_QuerySELECT (&mysql_res,"can not get sessions results", "SELECT exa_prints.SesCod," // row[0] @@ -842,15 +864,18 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams, " WHERE exa_prints.UsrCod=%ld" "%s" // Session subquery " AND exa_prints.SesCod=exa_sessions.SesCod" + "%s" // Hidden sessions subquery "%s" // Exams subquery " AND exa_sessions.ExaCod=exa_exams.ExaCod" " AND exa_exams.CrsCod=%ld" // Extra check " ORDER BY exa_sessions.Title", UsrDat->UsrCod, SesSubQuery, + HidSubQuery, ExaSubQuery, Gbl.Hierarchy.Crs.CrsCod); free (ExaSubQuery); + free (HidSubQuery); free (SesSubQuery); /***** Show user's data *****/ @@ -875,7 +900,7 @@ static void ExaRes_ShowResults (struct Exa_Exams *Exams, Visibility = TstVis_GetVisibilityFromStr (row[7]); /* Show session result? */ - ICanViewResult = ExaRes_CheckIfICanSeePrintResult (&Session,UsrDat->UsrCod); + ICanViewResult = true; // Filtering is already made in the query ICanViewScore = ExaRes_CheckIfICanViewScore (ICanViewResult,Visibility); if (NumResult) @@ -1126,6 +1151,7 @@ void ExaRes_ShowOneExaResult (void) /***** Set log action and print code *****/ if (Gbl.Action.Act == ActEndExaPrn) { + // The user has clicked on the "I have finished" button in an exam print ExaLog_SetAction (ExaLog_FINISH_EXAM); ExaLog_SetPrnCod (Print.PrnCod); ExaLog_SetIfCanAnswer (ExaSes_CheckIfICanAnswerThisSession (&Exam,&Session)); @@ -1173,7 +1199,7 @@ static void ExaRes_ShowExamResult (const struct Exa_Exam *Exam, { case Rol_STD: // Depends on visibility of result for this session (eye icon) - ICanView.Result = ExaRes_CheckIfICanSeePrintResult (Session,UsrDat->UsrCod); + ICanView.Result = ExaRes_CheckIfICanSeePrintResult (Exam,Session,UsrDat->UsrCod); if (ICanView.Result) // Depends on 5 visibility icons @@ -1340,7 +1366,9 @@ static void ExaRes_ShowExamResult (const struct Exa_Exam *Exam, /********************** Get if I can see session result ************************/ /*****************************************************************************/ -static bool ExaRes_CheckIfICanSeePrintResult (const struct ExaSes_Session *Session,long UsrCod) +static bool ExaRes_CheckIfICanSeePrintResult (const struct Exa_Exam *Exam, + const struct ExaSes_Session *Session, + long UsrCod) { bool ItsMe; @@ -1348,7 +1376,10 @@ static bool ExaRes_CheckIfICanSeePrintResult (const struct ExaSes_Session *Sessi { case Rol_STD: ItsMe = Usr_ItsMe (UsrCod); - if (ItsMe && Session->ShowUsrResults) + if (ItsMe && // The result is mine + !Exam->Hidden && // The exam is visible + !Session->Hidden && // The session is visible + Session->ShowUsrResults) // The results of the session are visible to users return ExaSes_CheckIfICanListThisSessionBasedOnGrps (Session->SesCod); return false; case Rol_NET: diff --git a/swad_exam_session.c b/swad_exam_session.c index b7817730d..9d628de1a 100644 --- a/swad_exam_session.c +++ b/swad_exam_session.c @@ -1704,7 +1704,7 @@ bool ExaSes_CheckIfICanListThisSessionBasedOnGrps (long SesCod) " (SELECT exa_groups.SesCod" " FROM exa_groups,crs_grp_usr" " WHERE crs_grp_usr.UsrCod=%ld" - " AND exa_groups.GrpCod=crs_grp_usr.GrpCod))", + " AND crs_grp_usr.GrpCod=exa_groups.GrpCod))", SesCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0); break; case Rol_NET: diff --git a/swad_match.c b/swad_match.c index b4de61c3d..29dabe166 100644 --- a/swad_match.c +++ b/swad_match.c @@ -2313,7 +2313,7 @@ bool Mch_CheckIfICanPlayThisMatchBasedOnGrps (const struct Mch_Match *Match) " (SELECT mch_groups.MchCod" " FROM mch_groups,crs_grp_usr" " WHERE crs_grp_usr.UsrCod=%ld" - " AND mch_groups.GrpCod=crs_grp_usr.GrpCod))", + " AND crs_grp_usr.GrpCod=mch_groups.GrpCod))", Match->MchCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0); break; case Rol_NET: