diff --git a/Makefile b/Makefile
index 5ee496c4..2151c144 100644
--- a/Makefile
+++ b/Makefile
@@ -48,8 +48,8 @@ OBJS = swad_account.o swad_action.o swad_agenda.o swad_alert.o \
swad_institution_config.o \
swad_language.o swad_layout.o swad_link.o swad_log.o swad_logo.o \
swad_mail.o swad_main.o swad_maintenance.o swad_map.o swad_mark.o \
- swad_match.o swad_match_result.o swad_media.o swad_menu.o \
- swad_message.o swad_MFU.o \
+ swad_match.o swad_match_print.o swad_match_result.o swad_media.o \
+ swad_menu.o swad_message.o swad_MFU.o \
swad_network.o swad_nickname.o swad_notice.o swad_notification.o \
swad_pagination.o swad_parameter.o swad_password.o swad_photo.o \
swad_place.o swad_plugin.o swad_privacy.o swad_profile.o \
diff --git a/swad_changelog.h b/swad_changelog.h
index ff59ec47..d43567c3 100644
--- a/swad_changelog.h
+++ b/swad_changelog.h
@@ -556,7 +556,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.256 (2020-06-24)"
+#define Log_PLATFORM_VERSION "SWAD 19.257 (2020-06-24)"
#define CSS_FILE "swad19.253.css"
#define JS_FILE "swad19.254.js"
/*
@@ -567,6 +567,7 @@ TODO: Fix bug: Cuando se pulsa en ver fichas, y luego en una ficha en "Ver traba
TODO: No limitar el número de preguntas en un examen a ExaPrn_MAX_QUESTIONS_PER_EXAM_PRINT, sino asignar PrintedQuestions dinámicamente con malloc
TODO: Que al generar un examen sólo se cojan preguntas válidas. Y si ya está generado, al entrar de nuevo, que se vean en rojo.
+ Version 19.257: Jun 24, 2020 New module swad_match_print. (303887 lines)
Version 19.256: Jun 24, 2020 Code refactoring in tests, exams and matches results. (303841 lines)
Version 19.255.2: Jun 24, 2020 Changes in listing of tests and exams results. (303701 lines)
Version 19.255.1: Jun 23, 2020 Changes in listing of tests results. (303655 lines)
diff --git a/swad_match.c b/swad_match.c
index 1d5968e9..53fdac5b 100644
--- a/swad_match.c
+++ b/swad_match.c
@@ -3758,7 +3758,7 @@ void Mch_RemoveMyQuestionAnswer (void)
Mch_RemoveMyAnswerToMatchQuestion (&Match);
/***** Compute score and update my match result *****/
- MchRes_ComputeScoreAndUpdateMyMatchResult (Match.MchCod);
+ MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (Match.MchCod);
}
/***** Show current match status *****/
@@ -3989,7 +3989,7 @@ void Mch_ReceiveQuestionAnswer (void)
Mch_UpdateMyAnswerToMatchQuestion (&Match,&UsrAnswer);
/***** Compute score and update my match result *****/
- MchRes_ComputeScoreAndUpdateMyMatchResult (Match.MchCod);
+ MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (Match.MchCod);
}
}
diff --git a/swad_match_print.c b/swad_match_print.c
new file mode 100644
index 00000000..7a9799d1
--- /dev/null
+++ b/swad_match_print.c
@@ -0,0 +1,192 @@
+// swad_match_print.c: matches prints in games using remote control
+
+/*
+ SWAD (Shared Workspace At a Distance),
+ is a web platform developed at the University of Granada (Spain),
+ and used to support university teaching.
+
+ This file is part of SWAD core.
+ Copyright (C) 1999-2020 Antonio Cañas Vargas
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+/*****************************************************************************/
+/********************************* Headers ***********************************/
+/*****************************************************************************/
+
+#include "swad_database.h"
+#include "swad_date.h"
+#include "swad_global.h"
+#include "swad_match.h"
+#include "swad_match_print.h"
+
+/*****************************************************************************/
+/************** External global variables from others modules ****************/
+/*****************************************************************************/
+
+extern struct Globals Gbl;
+
+/*****************************************************************************/
+/***************************** Private constants *****************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/******************************* Private types *******************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/***************************** Private constants *****************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/***************************** Private variables *****************************/
+/*****************************************************************************/
+
+/*****************************************************************************/
+/***************************** Private prototypes ****************************/
+/*****************************************************************************/
+
+static void MchPrn_UpdateMyMatchPrintInDB (struct MchPrn_Print *Print);
+
+/*****************************************************************************/
+/**************************** Reset match print ******************************/
+/*****************************************************************************/
+
+void MchPrn_ResetPrint (struct MchPrn_Print *Print)
+ {
+ Print->MchCod = -1L;
+ Print->UsrCod = -1L;
+ Print->TimeUTC[Dat_START_TIME] =
+ Print->TimeUTC[Dat_END_TIME ] = (time_t) 0;
+ Print->NumQsts.All =
+ Print->NumQsts.NotBlank = 0;
+ Print->Score = 0.0;
+ }
+
+/*****************************************************************************/
+/*********** Compute score and create/update my result in a match ************/
+/*****************************************************************************/
+
+void MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (long MchCod)
+ {
+ struct MchPrn_Print Print;
+
+ /***** Compute my match result *****/
+ MchPrn_ResetPrint (&Print);
+ Print.MchCod = MchCod;
+ Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
+ Mch_GetMatchQuestionsFromDB (&Print);
+ Mch_ComputeScore (&Print);
+
+ /***** Update my match result in database *****/
+ MchPrn_UpdateMyMatchPrintInDB (&Print);
+ }
+
+/*****************************************************************************/
+/******************** Create/update my result in a match *********************/
+/*****************************************************************************/
+
+static void MchPrn_UpdateMyMatchPrintInDB (struct MchPrn_Print *Print)
+ {
+ Str_SetDecimalPointToUS (); // To print the floating point as a dot
+ if (DB_QueryCOUNT ("can not get if match result exists",
+ "SELECT COUNT(*) FROM mch_results"
+ " WHERE MchCod=%ld AND UsrCod=%ld",
+ Print->MchCod,Print->UsrCod)) // Match print exists
+ /* Update result */
+ DB_QueryUPDATE ("can not update match result",
+ "UPDATE mch_results"
+ " SET EndTime=NOW(),"
+ "NumQsts=%u,"
+ "NumQstsNotBlank=%u,"
+ "Score='%.15lg'"
+ " WHERE MchCod=%ld AND UsrCod=%ld",
+ Print->NumQsts.All,
+ Print->NumQsts.NotBlank,
+ Print->Score,
+ Print->MchCod,Print->UsrCod);
+ else // Match print doesn't exist
+ /* Create result */
+ DB_QueryINSERT ("can not create match result",
+ "INSERT mch_results "
+ "(MchCod,UsrCod,StartTime,EndTime,NumQsts,NumQstsNotBlank,Score)"
+ " VALUES "
+ "(%ld," // MchCod
+ "%ld," // UsrCod
+ "NOW()," // StartTime
+ "NOW()," // EndTime
+ "%u," // NumQsts
+ "%u," // NumQstsNotBlank
+ "'%.15lg')", // Score
+ Print->MchCod,Print->UsrCod,
+ Print->NumQsts.All,
+ Print->NumQsts.NotBlank,
+ Print->Score);
+ Str_SetDecimalPointToLocal (); // Return to local system
+ }
+
+/*****************************************************************************/
+/********* Get data of a match print using match code and user code **********/
+/*****************************************************************************/
+
+void MchPrn_GetMatchPrintDataByMchCodAndUsrCod (struct MchPrn_Print *Print)
+ {
+ MYSQL_RES *mysql_res;
+ MYSQL_ROW row;
+ Dat_StartEndTime_t StartEndTime;
+
+ /***** Make database query *****/
+ if (DB_QuerySELECT (&mysql_res,"can not get data of a match print",
+ "SELECT UNIX_TIMESTAMP(mch_results.StartTime)," // row[1]
+ "UNIX_TIMESTAMP(mch_results.EndTime)," // row[2]
+ "mch_results.NumQsts," // row[3]
+ "mch_results.NumQstsNotBlank," // row[4]
+ "mch_results.Score" // row[5]
+ " FROM mch_results,mch_matches,gam_games"
+ " WHERE mch_results.MchCod=%ld"
+ " AND mch_results.UsrCod=%ld"
+ " AND mch_results.MchCod=mch_matches.MchCod"
+ " AND mch_matches.GamCod=gam_games.GamCod"
+ " AND gam_games.CrsCod=%ld", // Extra check
+ Print->MchCod,Print->UsrCod,
+ Gbl.Hierarchy.Crs.CrsCod) == 1)
+ {
+ row = mysql_fetch_row (mysql_res);
+
+ /* Get start time (row[0] and row[1] hold UTC date-times) */
+ for (StartEndTime = (Dat_StartEndTime_t) 0;
+ StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
+ StartEndTime++)
+ Print->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]);
+
+ /* Get number of questions (row[2]) */
+ if (sscanf (row[2],"%u",&Print->NumQsts.All) != 1)
+ Print->NumQsts.All = 0;
+
+ /* Get number of questions not blank (row[3]) */
+ if (sscanf (row[3],"%u",&Print->NumQsts.NotBlank) != 1)
+ Print->NumQsts.NotBlank = 0;
+
+ /* Get score (row[4]) */
+ Str_SetDecimalPointToUS (); // To get the decimal point as a dot
+ if (sscanf (row[4],"%lf",&Print->Score) != 1)
+ Print->Score = 0.0;
+ Str_SetDecimalPointToLocal (); // Return to local system
+ }
+ else
+ MchPrn_ResetPrint (Print);
+
+ /***** Free structure that stores the query result *****/
+ DB_FreeMySQLResult (&mysql_res);
+ }
diff --git a/swad_match_print.h b/swad_match_print.h
index d9244fd7..36fe3954 100644
--- a/swad_match_print.h
+++ b/swad_match_print.h
@@ -53,4 +53,10 @@ struct MchPrn_Print
/***************************** Public prototypes *****************************/
/*****************************************************************************/
+void MchPrn_ResetPrint (struct MchPrn_Print *Print);
+
+void MchPrn_ComputeScoreAndUpdateMyMatchPrintInDB (long MchCod);
+
+void MchPrn_GetMatchPrintDataByMchCodAndUsrCod (struct MchPrn_Print *Print);
+
#endif
diff --git a/swad_match_result.c b/swad_match_result.c
index f7254483..0a2339d3 100644
--- a/swad_match_result.c
+++ b/swad_match_result.c
@@ -77,10 +77,6 @@ struct MchRes_ICanView
/***************************** Private prototypes ****************************/
/*****************************************************************************/
-static void MchPrn_ResetPrint (struct MchPrn_Print *Print);
-
-static void MchRes_UpdateMyMatchResult (struct MchPrn_Print *Print);
-
static void MchRes_PutFormToSelUsrsToViewMchResults (void *Games);
static void MchRes_ListMyMchResultsInCrs (struct Gam_Games *Games);
@@ -110,91 +106,11 @@ static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults,
double TotalScore,
double TotalGrade);
-static void MchRes_GetMatchResultDataByMchCodAndUsrCod (struct MchPrn_Print *Print);
-
static void MchRes_CheckIfICanSeeMatchResult (const struct Gam_Game *Game,
const struct Mch_Match *Match,
long UsrCod,
struct MchRes_ICanView *ICanView);
-
-/*****************************************************************************/
-/**************************** Reset match print ******************************/
-/*****************************************************************************/
-
-static void MchPrn_ResetPrint (struct MchPrn_Print *Print)
- {
- Print->MchCod = -1L;
- Print->UsrCod = -1L;
- Print->TimeUTC[Dat_START_TIME] =
- Print->TimeUTC[Dat_END_TIME ] = (time_t) 0;
- Print->NumQsts.All =
- Print->NumQsts.NotBlank = 0;
- Print->Score = 0.0;
- }
-
-/*****************************************************************************/
-/*********** Compute score and create/update my result in a match ************/
-/*****************************************************************************/
-
-void MchRes_ComputeScoreAndUpdateMyMatchResult (long MchCod)
- {
- struct MchPrn_Print Print;
-
- /***** Compute my match result *****/
- MchPrn_ResetPrint (&Print);
- Print.MchCod = MchCod;
- Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
- Mch_GetMatchQuestionsFromDB (&Print);
- Mch_ComputeScore (&Print);
-
- /***** Update my match result in database *****/
- MchRes_UpdateMyMatchResult (&Print);
- }
-
-/*****************************************************************************/
-/******************** Create/update my result in a match *********************/
-/*****************************************************************************/
-
-static void MchRes_UpdateMyMatchResult (struct MchPrn_Print *Print)
- {
- Str_SetDecimalPointToUS (); // To print the floating point as a dot
- if (DB_QueryCOUNT ("can not get if match result exists",
- "SELECT COUNT(*) FROM mch_results"
- " WHERE MchCod=%ld AND UsrCod=%ld",
- Print->MchCod,Print->UsrCod)) // Match print exists
- /* Update result */
- DB_QueryUPDATE ("can not update match result",
- "UPDATE mch_results"
- " SET EndTime=NOW(),"
- "NumQsts=%u,"
- "NumQstsNotBlank=%u,"
- "Score='%.15lg'"
- " WHERE MchCod=%ld AND UsrCod=%ld",
- Print->NumQsts.All,
- Print->NumQsts.NotBlank,
- Print->Score,
- Print->MchCod,Print->UsrCod);
- else // Match print doesn't exist
- /* Create result */
- DB_QueryINSERT ("can not create match result",
- "INSERT mch_results "
- "(MchCod,UsrCod,StartTime,EndTime,NumQsts,NumQstsNotBlank,Score)"
- " VALUES "
- "(%ld," // MchCod
- "%ld," // UsrCod
- "NOW()," // StartTime
- "NOW()," // EndTime
- "%u," // NumQsts
- "%u," // NumQstsNotBlank
- "'%.15lg')", // Score
- Print->MchCod,Print->UsrCod,
- Print->NumQsts.All,
- Print->NumQsts.NotBlank,
- Print->Score);
- Str_SetDecimalPointToLocal (); // Return to local system
- }
-
/*****************************************************************************/
/*************************** Show my matches results *************************/
/*****************************************************************************/
@@ -974,7 +890,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/* Get match result data */
Print.UsrCod = UsrDat->UsrCod;
- MchRes_GetMatchResultDataByMchCodAndUsrCod (&Print);
+ MchPrn_GetMatchPrintDataByMchCodAndUsrCod (&Print);
/* Get data of match and game */
Match.MchCod = Print.MchCod;
@@ -1276,7 +1192,7 @@ void MchRes_ShowOneMchResult (void)
/***** Get match result data *****/
Print.MchCod = Match.MchCod;
Print.UsrCod = UsrDat->UsrCod;
- MchRes_GetMatchResultDataByMchCodAndUsrCod (&Print);
+ MchPrn_GetMatchPrintDataByMchCodAndUsrCod (&Print);
/***** Check if I can view this match result and score *****/
MchRes_CheckIfICanSeeMatchResult (&Game,&Match,UsrDat->UsrCod,&ICanView);
@@ -1449,62 +1365,6 @@ void MchRes_ShowOneMchResult (void)
Lay_NoPermissionExit ();
}
-/*****************************************************************************/
-/************* Get data of a match result using its match code ***************/
-/*****************************************************************************/
-
-static void MchRes_GetMatchResultDataByMchCodAndUsrCod (struct MchPrn_Print *Print)
- {
- MYSQL_RES *mysql_res;
- MYSQL_ROW row;
- Dat_StartEndTime_t StartEndTime;
-
- /***** Make database query *****/
- if (DB_QuerySELECT (&mysql_res,"can not get data"
- " of a match result of a user",
- "SELECT UNIX_TIMESTAMP(mch_results.StartTime)," // row[1]
- "UNIX_TIMESTAMP(mch_results.EndTime)," // row[2]
- "mch_results.NumQsts," // row[3]
- "mch_results.NumQstsNotBlank," // row[4]
- "mch_results.Score" // row[5]
- " FROM mch_results,mch_matches,gam_games"
- " WHERE mch_results.MchCod=%ld"
- " AND mch_results.UsrCod=%ld"
- " AND mch_results.MchCod=mch_matches.MchCod"
- " AND mch_matches.GamCod=gam_games.GamCod"
- " AND gam_games.CrsCod=%ld", // Extra check
- Print->MchCod,Print->UsrCod,
- Gbl.Hierarchy.Crs.CrsCod) == 1)
- {
- row = mysql_fetch_row (mysql_res);
-
- /* Get start time (row[0] and row[1] hold UTC date-times) */
- for (StartEndTime = (Dat_StartEndTime_t) 0;
- StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
- StartEndTime++)
- Print->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]);
-
- /* Get number of questions (row[2]) */
- if (sscanf (row[2],"%u",&Print->NumQsts.All) != 1)
- Print->NumQsts.All = 0;
-
- /* Get number of questions not blank (row[3]) */
- if (sscanf (row[3],"%u",&Print->NumQsts.NotBlank) != 1)
- Print->NumQsts.NotBlank = 0;
-
- /* Get score (row[4]) */
- Str_SetDecimalPointToUS (); // To get the decimal point as a dot
- if (sscanf (row[4],"%lf",&Print->Score) != 1)
- Print->Score = 0.0;
- Str_SetDecimalPointToLocal (); // Return to local system
- }
- else
- MchPrn_ResetPrint (Print);
-
- /***** Free structure that stores the query result *****/
- DB_FreeMySQLResult (&mysql_res);
- }
-
/*****************************************************************************/
/********************** Get if I can see match result ************************/
/*****************************************************************************/
diff --git a/swad_match_result.h b/swad_match_result.h
index 8d08faaf..a4048d85 100644
--- a/swad_match_result.h
+++ b/swad_match_result.h
@@ -38,8 +38,6 @@
/***************************** Public prototypes *****************************/
/*****************************************************************************/
-void MchRes_ComputeScoreAndUpdateMyMatchResult (long MchCod);
-
void MchRes_ShowMyMchResultsInCrs (void);
void MchRes_ShowMyMchResultsInGam (void);
void MchRes_ShowMyMchResultsInMch (void);
diff --git a/swad_media.h b/swad_media.h
index 095a6594..5dbf3ef3 100644
--- a/swad_media.h
+++ b/swad_media.h
@@ -29,6 +29,8 @@
#include // To access MySQL databases
+#include "swad_cryptography.h"
+
/*****************************************************************************/
/***************************** Public constants ******************************/
/*****************************************************************************/