From 91319694d2c4630c06b6f5ed24179f187deaf1b5 Mon Sep 17 00:00:00 2001 From: acanas Date: Sat, 23 May 2020 15:53:53 +0200 Subject: [PATCH] Version19.242 --- sql/swad.sql | 2 +- swad_changelog.h | 6 ++- swad_database.c | 4 +- swad_exam_log.c | 75 ++++++++++++++++++------------- swad_exam_log.h | 25 ++++++++--- swad_exam_print.c | 51 ++++++++++++++------- swad_exam_result.c | 8 +++- swad_text.c | 109 +++++++++++++++++++++++++++++++++++++++++++++ swad_text_action.c | 42 ++++++++--------- 9 files changed, 242 insertions(+), 80 deletions(-) diff --git a/sql/swad.sql b/sql/swad.sql index f941fdcf..a07abb01 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -491,7 +491,7 @@ CREATE TABLE IF NOT EXISTS exa_log ( PrnCod INT NOT NULL, ActCod INT NOT NULL, QstInd INT NOT NULL DEFAULT -1, - Saved ENUM('N','Y') NOT NULL DEFAULT 'N', + Open ENUM('N','Y') NOT NULL DEFAULT 'N', ClickTime DATETIME NOT NULL, IP CHAR(15) NOT NULL, SessionId CHAR(43) NOT NULL, diff --git a/swad_changelog.h b/swad_changelog.h index 8984934e..5695c033 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -557,10 +557,14 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.241.1 (2020-05-22)" +#define Log_PLATFORM_VERSION "SWAD 19.242 (2020-05-23)" #define CSS_FILE "swad19.238.2.css" #define JS_FILE "swad19.239.6.js" /* + Version 19.242: May 23, 2020 Changes in exam log. (301911 lines) + 1 change necessary in database: +ALTER TABLE exa_log CHANGE COLUMN Saved Open ENUM('N','Y') NOT NULL DEFAULT 'N'; + Version 19.241.1: May 23, 2020 Question index added to exam log. (301756 lines) 2 changes necessary in database: ALTER TABLE exa_log ADD COLUMN QstInd INT NOT NULL DEFAULT -1 AFTER ActCod; diff --git a/swad_database.c b/swad_database.c index 6d1862d0..9b9137d2 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1054,7 +1054,7 @@ mysql> DESCRIBE exa_log; | PrnCod | int(11) | NO | MUL | NULL | | | ActCod | int(11) | NO | | NULL | | | QstInd | int(11) | NO | | -1 | | -| Saved | enum('N','Y') | NO | | N | | +| Open | enum('N','Y') | NO | | N | | | ClickTime | datetime | NO | MUL | NULL | | | IP | char(15) | NO | | NULL | | | SessionId | char(43) | NO | | NULL | | @@ -1067,7 +1067,7 @@ mysql> DESCRIBE exa_log; "PrnCod INT NOT NULL," "ActCod INT NOT NULL," "QstInd INT NOT NULL DEFAULT -1," - "Saved ENUM('N','Y') NOT NULL DEFAULT 'N'," + "Open ENUM('N','Y') NOT NULL DEFAULT 'N'," "ClickTime DATETIME NOT NULL," "IP CHAR(15) NOT NULL," // Cns_MAX_BYTES_IP "SessionId CHAR(43) NOT NULL," // Cns_BYTES_SESSION_ID diff --git a/swad_exam_log.c b/swad_exam_log.c index 475c861f..5b06e701 100644 --- a/swad_exam_log.c +++ b/swad_exam_log.c @@ -27,6 +27,7 @@ #include "swad_action.h" #include "swad_database.h" +#include "swad_exam_log.h" #include "swad_global.h" /*****************************************************************************/ @@ -49,14 +50,16 @@ extern struct Globals Gbl; static struct { - long PrnCod; - int QstInd; - bool AnswerIsSaved; - } ExaLog_CurrentPrint = + long PrnCod; // Exam print code + int QstInd; // Exam print question index + ExaLog_Action_t Action; // Action performed by user + bool Open; // Exam print is open and accesible to answer by the user + } ExaLog_Log = { .PrnCod = -1L, // -1 means no print code set .QstInd = -1, // -1 means no question index set - .AnswerIsSaved = false, // By default, answer is not saved + .Action = ExaLog_UNKNOWN_ACTION, + .Open = false, }; /*****************************************************************************/ @@ -67,42 +70,56 @@ static struct /************* Set and get current exam print code (used in log) *************/ /*****************************************************************************/ -void ExaLog_SetCurrentPrnCod (long PrnCod) +void ExaLog_SetAction (ExaLog_Action_t Action) { - ExaLog_CurrentPrint.PrnCod = PrnCod; + ExaLog_Log.Action = Action; } -long ExaLog_GetCurrentPrnCod (void) +ExaLog_Action_t ExaLog_GetAction (void) { - return ExaLog_CurrentPrint.PrnCod; + return ExaLog_Log.Action; + } + +/*****************************************************************************/ +/************* Set and get current exam print code (used in log) *************/ +/*****************************************************************************/ + +void ExaLog_SetPrnCod (long PrnCod) + { + ExaLog_Log.PrnCod = PrnCod; + } + +long ExaLog_GetPrnCod (void) + { + return ExaLog_Log.PrnCod; } /*****************************************************************************/ /****** Set and get current question index in exam print (used in log) *******/ /*****************************************************************************/ -void ExaLog_SetCurrentQstInd (unsigned QstInd) +void ExaLog_SetQstInd (unsigned QstInd) { - ExaLog_CurrentPrint.QstInd = (int) QstInd; + ExaLog_Log.QstInd = (int) QstInd; } -int ExaLog_GetCurrentQstInd (void) +int ExaLog_GetQstInd (void) { - return ExaLog_CurrentPrint.QstInd; + return ExaLog_Log.QstInd; } /*****************************************************************************/ /******** Set and get if answer is saved in exam print (used in log) *********/ /*****************************************************************************/ -void ExaLog_SetAnswerIsSaved (void) +void ExaLog_SetOpen (bool Open) { - ExaLog_CurrentPrint.AnswerIsSaved = true; + ExaLog_Log.Open = Open; } -bool ExaLog_GetAnswerIsSaved (void) +bool ExaLog_GetOpen (void) { - return ExaLog_CurrentPrint.AnswerIsSaved; + return ExaLog_Log.Open; } /*****************************************************************************/ @@ -111,15 +128,13 @@ bool ExaLog_GetAnswerIsSaved (void) void ExaLog_LogAccess (long LogCod) { + ExaLog_Action_t Action; long PrnCod; - /* WARNING: Don't change the codes os the actions. - If the codes of the actions change ==> change them in exam log table */ - if (Gbl.Action.Act == ActAnsExaPrn || // Answer question - Gbl.Action.Act == ActSeeExaPrn || // Create/resume print exam - Gbl.Action.Act == ActEndExaPrn) // End print exam + Action = ExaLog_GetAction (); + if (Action != ExaLog_UNKNOWN_ACTION) { - PrnCod = ExaLog_GetCurrentPrnCod (); + PrnCod = ExaLog_GetPrnCod (); if (PrnCod > 0) // Only if exam print is accesible (visible, open...) /***** Insert access into database *****/ @@ -127,17 +142,17 @@ void ExaLog_LogAccess (long LogCod) Redundant data (also present in log table) are stored for speed */ DB_QueryINSERT ("can not log exam access", "INSERT INTO exa_log " - "(LogCod,PrnCod,ActCod,QstInd,Saved,ClickTime,IP,SessionId)" + "(LogCod,PrnCod,ActCod,QstInd,Open,ClickTime,IP,SessionId)" " VALUES " "(%ld,%ld,%ld,%d,'%c',NOW(),'%s','%s')", LogCod, PrnCod, - Act_GetActCod (Gbl.Action.Act), // Redundant, for speed - ExaLog_GetCurrentQstInd (), - ExaLog_GetAnswerIsSaved () ? 'Y' : - 'N', - // NOW() Redundant, for speed - Gbl.IP, // Redundant, for speed + (unsigned) Action, + ExaLog_GetQstInd (), + ExaLog_GetOpen () ? 'Y' : + 'N', + // NOW() Redundant, for speed + Gbl.IP, // Redundant, for speed Gbl.Session.Id); } } diff --git a/swad_exam_log.h b/swad_exam_log.h index 3a52a3ae..c9d5267a 100644 --- a/swad_exam_log.h +++ b/swad_exam_log.h @@ -31,16 +31,29 @@ /************************* Public types and constants ************************/ /*****************************************************************************/ +#define ExaLog_NUM_ACTIONS 5 +// Don't change the numbers! If change ==> update them in table exa_log +typedef enum + { + ExaLog_UNKNOWN_ACTION = 0, + ExaLog_START_EXAM = 1, + ExaLog_RESUME_EXAM = 2, + ExaLog_ANSWER_QUESTION = 3, + ExaLog_FINISH_EXAM = 4, + } ExaLog_Action_t; + /*****************************************************************************/ /***************************** Public prototypes *****************************/ /*****************************************************************************/ -void ExaLog_SetCurrentPrnCod (long PrnCod); -long ExaLog_GetCurrentPrnCod (void); -void ExaLog_SetCurrentQstInd (unsigned QstInd); -int ExaLog_GetCurrentQstInd (void); -void ExaLog_SetAnswerIsSaved (void); -bool ExaLog_GetAnswerIsSaved (void); +void ExaLog_SetPrnCod (long PrnCod); +long ExaLog_GetPrnCod (void); +void ExaLog_SetAction (ExaLog_Action_t Action); +ExaLog_Action_t ExaLog_GetAction (void); +void ExaLog_SetQstInd (unsigned QstInd); +int ExaLog_GetQstInd (void); +void ExaLog_SetOpen (bool Open); +bool ExaLog_GetOpen (void); void ExaLog_LogAccess (long LogCod); diff --git a/swad_exam_print.c b/swad_exam_print.c index 7907955a..3a0d1f8f 100644 --- a/swad_exam_print.c +++ b/swad_exam_print.c @@ -198,26 +198,38 @@ void ExaPrn_ShowExamPrint (void) Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod; ExaPrn_GetPrintDataBySesCodAndUsrCod (&Print); - if (Print.PrnCod > 0) // Print exists and I can access to it - /***** Get questions and user's answers of exam print from database *****/ - ExaPrn_GetPrintQuestionsFromDB (&Print); - else + if (Print.PrnCod <= 0) // Print does not exists { /***** Get questions from database *****/ ExaPrn_GetQuestionsForNewPrintFromDB (&Print,Exam.ExaCod); if (Print.NumQsts) + { /***** Create/update new exam print in database *****/ ExaPrn_CreatePrintInDB (&Print); - } - /***** Set current print code (to be used in log) *****/ - ExaLog_SetCurrentPrnCod (Print.PrnCod); + /***** Set log print code and action *****/ + ExaLog_SetPrnCod (Print.PrnCod); + ExaLog_SetAction (ExaLog_START_EXAM); + ExaLog_SetOpen (true); + } + } + else // Print exists + { + /***** Get questions and current user's answers from database *****/ + ExaPrn_GetPrintQuestionsFromDB (&Print); + + /***** Set log print code and action *****/ + ExaLog_SetPrnCod (Print.PrnCod); + ExaLog_SetAction (ExaLog_RESUME_EXAM); + ExaLog_SetOpen (true); + } /***** Show test exam to be answered *****/ ExaPrn_ShowExamPrintToFillIt (&Exams,&Exam,&Print); } - else + else // Session not open or accessible + /***** Show warning *****/ Ale_ShowAlert (Ale_INFO,Txt_You_dont_have_access_to_the_exam); } @@ -983,21 +995,23 @@ void ExaPrn_ReceivePrintAnswer (void) if (Print.PrnCod <= 0) Lay_WrongExamExit (); - /***** Set current print code (to be used in log) *****/ - ExaLog_SetCurrentPrnCod (Print.PrnCod); - /***** Get questions and current user's answers of exam print from database *****/ ExaPrn_GetPrintQuestionsFromDB (&Print); /***** Get question index from form *****/ QstInd = ExaPrn_GetParamQstInd (); - /***** Set current question index (to be used in log) *****/ - ExaLog_SetCurrentQstInd (QstInd); + /***** Set log print code, action and question index *****/ + ExaLog_SetPrnCod (Print.PrnCod); + ExaLog_SetAction (ExaLog_ANSWER_QUESTION); + ExaLog_SetQstInd (QstInd); /***** Check if session if visible and open *****/ if (ExaSes_CheckIfSessionIsVisibleAndOpen (Print.SesCod)) { + /***** Set log open ****/ + ExaLog_SetOpen (true); + /***** Get answers from form to assess a test *****/ ExaPrn_GetAnswerFromForm (&Print,QstInd); @@ -1010,14 +1024,17 @@ void ExaPrn_ReceivePrintAnswer (void) ExaPrn_ComputeTotalScoreOfPrint (&Print); ExaPrn_UpdatePrintInDB (&Print); - /***** Set success saving answer (to be used in log) *****/ - ExaLog_SetAnswerIsSaved (); - /***** Show table with questions to answer *****/ ExaPrn_ShowTableWithQstsToFill (&Print); } - else + else // Not accessible to answer + { + /***** Set log open ****/ + ExaLog_SetOpen (true); + + /***** Show warning *****/ Ale_ShowAlert (Ale_INFO,Txt_You_dont_have_access_to_the_exam); + } } /*****************************************************************************/ diff --git a/swad_exam_result.c b/swad_exam_result.c index 1a8006f3..8a886e3a 100644 --- a/swad_exam_result.c +++ b/swad_exam_result.c @@ -1132,8 +1132,12 @@ void ExaRes_ShowOneExaResult (void) Print.UsrCod = UsrDat->UsrCod; ExaPrn_GetPrintDataBySesCodAndUsrCod (&Print); - /***** Set current print code (to be used in log) *****/ - ExaLog_SetCurrentPrnCod (Print.PrnCod); + /***** Set log action and print code *****/ + if (Gbl.Action.Act == ActEndExaPrn) + { + ExaLog_SetAction (ExaLog_FINISH_EXAM); + ExaLog_SetPrnCod (Print.PrnCod); + } /***** Check if I can view this print result *****/ switch (Gbl.Usrs.Me.Role.Logged) diff --git a/swad_text.c b/swad_text.c index a82ad317..a329495b 100644 --- a/swad_text.c +++ b/swad_text.c @@ -67,6 +67,7 @@ #include "swad_degree.h" #include "swad_degree_type.h" #include "swad_department.h" +#include "swad_exam_log.h" #include "swad_figure.h" #include "swad_file_browser.h" #include "swad_forum.h" @@ -11876,6 +11877,114 @@ const char *Txt_EXAM_ANNOUNCEMENT_Year_or_semester = // 1, 2, 3..., not 1984, 20 "Ano ou semestre"; #endif +const char *Txt_EXAM_LOG_ACTIONS[ExaLog_NUM_ACTIONS] = + { + [ExaLog_UNKNOWN_ACTION] = +#if L==1 // ca + "Acció desconeguda" +#elif L==2 // de + "Unbekannte Aktion" +#elif L==3 // en + "Unknown action" +#elif L==4 // es + "Acción desconocida" +#elif L==5 // fr + "Action inconnue" +#elif L==6 // gn + "Acción desconocida" // Okoteve traducción +#elif L==7 // it + "Azione sconosciuta" +#elif L==8 // pl + "Nieznana akcja" +#elif L==9 // pt + "Ação desconhecida" +#endif + , + [ExaLog_START_EXAM] = +#if L==1 // ca + "Va començar l'examen" +#elif L==2 // de + "Begann die Prúfung" +#elif L==3 // en + "Started the exam" +#elif L==4 // es + "Comenzó el examen" +#elif L==5 // fr + "A commencé l'examen" +#elif L==6 // gn + "Comenzó el examen" // Okoteve traducción +#elif L==7 // it + "Ha iniziato l'esame" +#elif L==8 // pl + "Rozpoczął egzamin" +#elif L==9 // pt + "Iniciou o exame" +#endif + , + [ExaLog_RESUME_EXAM] = +#if L==1 // ca + "Va reprendre l'examen" +#elif L==2 // de + "Nahm die Prüfung wieder auf" +#elif L==3 // en + "Resumed the exam" +#elif L==4 // es + "Reanudó el examen" +#elif L==5 // fr + "A repris l'examen" +#elif L==6 // gn + "Reanudó el examen" // Okoteve traducción +#elif L==7 // it + "Ha ripreso l'esame" +#elif L==8 // pl + "Wznowił egzamin" +#elif L==9 // pt + "Retomou o exame" +#endif + , + [ExaLog_ANSWER_QUESTION] = +#if L==1 // ca + "Va respondre una pregunta" +#elif L==2 // de + "Beantwortete eine Frage" +#elif L==3 // en + "Answer exam question" +#elif L==4 // es + "Respondió una pregunta" +#elif L==5 // fr + "A répondu à une question" +#elif L==6 // gn + "Respondió una pregunta" // Okoteve traducción +#elif L==7 // it + "Ha risposto a una domanda" +#elif L==8 // pl + "Odpowiedział na pytanie" +#elif L==9 // pt + "Respondeu a uma pergunta" +#endif + , + [ExaLog_FINISH_EXAM] = +#if L==1 // ca + "Va acabar l'examen" +#elif L==2 // de + "Beendete die Prüfung" +#elif L==3 // en + "Finished the exam" +#elif L==4 // es + "Terminó el examen" +#elif L==5 // fr + "A terminé l'examen" +#elif L==6 // gn + "Terminó el examen" // Okoteve traducción +#elif L==7 // it + "Ha terminato l'esame" +#elif L==8 // pl + "Zakończył egzamin" +#elif L==9 // pt + "Terminou o exame" +#endif + }; + const char *Txt_Exam_of_X = // Warning: it is very important to include %s in the following sentences #if L==1 // ca "Examen de %s"; diff --git a/swad_text_action.c b/swad_text_action.c index bf54c1e6..b0dc7d97 100644 --- a/swad_text_action.c +++ b/swad_text_action.c @@ -10900,65 +10900,65 @@ const char *Txt_Actions[Act_NUM_ACTIONS] = , [ActSeeExaPrn] = #if L==1 // ca - "" // Necessita traducció + "Començar / reprendre examen" #elif L==2 // de - "" // Need Übersetzung + "Prúfung starten / fortsetzen" #elif L==3 // en "Start / resume exam" #elif L==4 // es "Comenzar / reanudar examen" #elif L==5 // fr - "" // Besoin de traduction + "Commencer / reprendre examen" #elif L==6 // gn - "" // Okoteve traducción + "Comenzar / reanudar examen" // Okoteve traducción #elif L==7 // it - "" // Bisogno di traduzione + "Avvia / riprendi esame" #elif L==8 // pl - "" // Potrzebujesz tlumaczenie + "Rozpocznij / wznów egzamin" #elif L==9 // pt - "" // Precisa de tradução + "Iniciar / retomar exame" #endif , [ActAnsExaPrn] = #if L==1 // ca - "" // Necessita traducció + "Respondre pregunta d'examen" #elif L==2 // de - "" // Need Übersetzung + "Beantworten Sie die Prüfungsfrage" #elif L==3 // en "Answer exam question" #elif L==4 // es "Responder pregunta de examen" #elif L==5 // fr - "" // Besoin de traduction + "Répondre question d'examen" #elif L==6 // gn - "" // Okoteve traducción + "Responder pregunta de examen" // Okoteve traducción #elif L==7 // it - "" // Bisogno di traduzione + "Rispondi domanda d'esame" #elif L==8 // pl - "" // Potrzebujesz tlumaczenie + "Odpowiedz pytanie egzaminacyjne" #elif L==9 // pt - "" // Precisa de tradução + "Responda pergunta do exame" #endif , [ActEndExaPrn] = #if L==1 // ca - "" // Necessita traducció + "Finalitzar examen" #elif L==2 // de - "" // Need Übersetzung + "Prüfung beenden" #elif L==3 // en "End exam" #elif L==4 // es "Finalizar examen" #elif L==5 // fr - "" // Besoin de traduction + "Terminer examen" #elif L==6 // gn - "" // Okoteve traducción + "Finalizar examen" // Okoteve traducción #elif L==7 // it - "" // Bisogno di traduzione + "Finire esame" #elif L==8 // pl - "" // Potrzebujesz tlumaczenie + "Zakończyć egzamin" #elif L==9 // pt - "" // Precisa de tradução + "Terminar exame" #endif , [ActSeeMyExaResCrs] =