Version19.242

This commit is contained in:
acanas 2020-05-23 15:53:53 +02:00
parent 0a90198755
commit 91319694d2
9 changed files with 242 additions and 80 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);
}
}
/*****************************************************************************/

View File

@ -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)

View File

@ -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&oacute; desconeguda"
#elif L==2 // de
"Unbekannte Aktion"
#elif L==3 // en
"Unknown action"
#elif L==4 // es
"Acci&oacute;n desconocida"
#elif L==5 // fr
"Action inconnue"
#elif L==6 // gn
"Acci&oacute;n desconocida" // Okoteve traducción
#elif L==7 // it
"Azione sconosciuta"
#elif L==8 // pl
"Nieznana akcja"
#elif L==9 // pt
"A&ccedil;&atilde;o desconhecida"
#endif
,
[ExaLog_START_EXAM] =
#if L==1 // ca
"Va comen&ccedil;ar l'examen"
#elif L==2 // de
"Begann die Pr&uacute;fung"
#elif L==3 // en
"Started the exam"
#elif L==4 // es
"Comenz&oacute; el examen"
#elif L==5 // fr
"A commenc&eacute; l'examen"
#elif L==6 // gn
"Comenz&oacute; el examen" // Okoteve traducción
#elif L==7 // it
"Ha iniziato l'esame"
#elif L==8 // pl
"Rozpocz&aogon;&lstrok; 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&uuml;fung wieder auf"
#elif L==3 // en
"Resumed the exam"
#elif L==4 // es
"Reanud&oacute; el examen"
#elif L==5 // fr
"A repris l'examen"
#elif L==6 // gn
"Reanud&oacute; el examen" // Okoteve traducción
#elif L==7 // it
"Ha ripreso l'esame"
#elif L==8 // pl
"Wznowi&lstrok; 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&oacute; una pregunta"
#elif L==5 // fr
"A r&eacute;pondu &agrave; une question"
#elif L==6 // gn
"Respondi&oacute; una pregunta" // Okoteve traducción
#elif L==7 // it
"Ha risposto a una domanda"
#elif L==8 // pl
"Odpowiedzia&lstrok; 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&uuml;fung"
#elif L==3 // en
"Finished the exam"
#elif L==4 // es
"Termin&oacute; el examen"
#elif L==5 // fr
"A termin&eacute; l'examen"
#elif L==6 // gn
"Termin&oacute; el examen" // Okoteve traducción
#elif L==7 // it
"Ha terminato l'esame"
#elif L==8 // pl
"Zako&nacute;czy&lstrok; 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";

View File

@ -10900,65 +10900,65 @@ const char *Txt_Actions[Act_NUM_ACTIONS] =
,
[ActSeeExaPrn] =
#if L==1 // ca
"" // Necessita traducció
"Comen&ccedil;ar / reprendre examen"
#elif L==2 // de
"" // Need Übersetzung
"Pr&uacute;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&oacute;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&uuml;fungsfrage"
#elif L==3 // en
"Answer exam question"
#elif L==4 // es
"Responder pregunta de examen"
#elif L==5 // fr
"" // Besoin de traduction
"R&eacute;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&uuml;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&nacute;czy&cacute; egzamin"
#elif L==9 // pt
"" // Precisa de tradução
"Terminar exame"
#endif
,
[ActSeeMyExaResCrs] =