2019-09-28 02:31:42 +02:00
|
|
|
|
// swad_match_result.c: matches results 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.
|
2020-01-01 14:53:57 +01:00
|
|
|
|
Copyright (C) 1999-2020 Antonio Ca<EFBFBD>as Vargas
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********************************* Headers ***********************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#define _GNU_SOURCE // For asprintf
|
|
|
|
|
#include <linux/limits.h> // For PATH_MAX
|
2019-12-29 12:39:00 +01:00
|
|
|
|
#include <stddef.h> // For NULL
|
2019-09-28 02:31:42 +02:00
|
|
|
|
#include <stdio.h> // For asprintf
|
|
|
|
|
#include <stdlib.h> // For calloc
|
|
|
|
|
#include <string.h> // For string functions
|
|
|
|
|
|
2019-09-30 01:23:24 +02:00
|
|
|
|
#include "swad_action.h"
|
2019-09-28 02:31:42 +02:00
|
|
|
|
#include "swad_database.h"
|
2019-09-30 01:23:24 +02:00
|
|
|
|
#include "swad_date.h"
|
2019-09-28 02:31:42 +02:00
|
|
|
|
#include "swad_form.h"
|
|
|
|
|
#include "swad_global.h"
|
2019-10-23 19:05:05 +02:00
|
|
|
|
#include "swad_HTML.h"
|
2019-09-28 02:31:42 +02:00
|
|
|
|
#include "swad_ID.h"
|
|
|
|
|
#include "swad_match.h"
|
|
|
|
|
#include "swad_match_result.h"
|
|
|
|
|
#include "swad_user.h"
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************** External global variables from others modules ****************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
extern struct Globals Gbl;
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private constants *****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/******************************* Private types *******************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private constants *****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private variables *****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private prototypes ****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
static void McR_ListMyMchResultsInCrs (void);
|
|
|
|
|
static void McR_ListMyMchResultsInGam (long GamCod);
|
|
|
|
|
static void McR_ListMyMchResultsInMch (long MchCod);
|
|
|
|
|
static void McR_ShowAllMchResultsInSelectedGames (void);
|
|
|
|
|
static void McR_ListAllMchResultsInSelectedGames (void);
|
|
|
|
|
static void McR_ListAllMchResultsInGam (long GamCod);
|
|
|
|
|
static void McR_ListAllMchResultsInMch (long MchCod);
|
|
|
|
|
|
|
|
|
|
static void McR_ShowResultsBegin (const char *Title,bool ListGamesToSelect);
|
|
|
|
|
static void McR_ShowResultsEnd (void);
|
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
static void McR_ListGamesToSelect (void);
|
2019-09-30 22:31:07 +02:00
|
|
|
|
static void McR_ShowHeaderMchResults (Usr_MeOrOther_t MeOrOther);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 14:14:29 +01:00
|
|
|
|
static void McR_BuildGamesSelectedCommas (char **GamesSelectedCommas);
|
2019-11-25 23:18:08 +01:00
|
|
|
|
static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
|
2019-12-08 23:19:16 +01:00
|
|
|
|
long MchCod, // <= 0 ==> any
|
|
|
|
|
long GamCod, // <= 0 ==> any
|
|
|
|
|
const char *GamesSelectedCommas);
|
2019-11-28 22:17:00 +01:00
|
|
|
|
static void McR_ShowMchResultsSummaryRow (unsigned NumResults,
|
2019-09-28 02:31:42 +02:00
|
|
|
|
unsigned NumTotalQsts,
|
|
|
|
|
unsigned NumTotalQstsNotBlank,
|
2019-11-28 00:19:42 +01:00
|
|
|
|
double TotalScoreOfAllResults,
|
2019-11-29 17:42:05 +01:00
|
|
|
|
double TotalGrade);
|
2019-09-30 01:26:19 +02:00
|
|
|
|
static void McR_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
|
2019-09-28 02:31:42 +02:00
|
|
|
|
time_t TimeUTC[Dat_NUM_START_END_TIME],
|
|
|
|
|
unsigned *NumQsts,
|
|
|
|
|
unsigned *NumQstsNotBlank,
|
|
|
|
|
double *Score);
|
|
|
|
|
|
2019-09-30 01:26:19 +02:00
|
|
|
|
static bool McR_CheckIfICanSeeMatchResult (long MchCod,long UsrCod);
|
|
|
|
|
static bool McR_GetVisibilityMchResultFromDB (long MchCod);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/*********** Select users and dates to show their matches results ************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
void McR_SelUsrsToViewMchResults (void)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Hlp_ASSESSMENT_Games_results;
|
|
|
|
|
extern const char *Txt_Results;
|
|
|
|
|
extern const char *Txt_View_matches_results;
|
2019-12-09 12:56:21 +01:00
|
|
|
|
|
|
|
|
|
Usr_PutFormToSelectUsrsToGoToAct (&Gbl.Usrs.Selected,
|
2019-12-10 14:22:09 +01:00
|
|
|
|
ActSeeAllMchResCrs,NULL,
|
2019-12-09 12:56:21 +01:00
|
|
|
|
Txt_Results,
|
|
|
|
|
Hlp_ASSESSMENT_Games_results,
|
|
|
|
|
Txt_View_matches_results,
|
|
|
|
|
false); // Do not put form with date range
|
2019-09-28 02:31:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-08 13:34:12 +01:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/*************************** Show my matches results *************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
void McR_ShowMyMchResultsInCrs (void)
|
2019-12-08 13:34:12 +01:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Results;
|
|
|
|
|
|
|
|
|
|
/***** Get list of games *****/
|
|
|
|
|
Gam_GetListGames (Gam_ORDER_BY_TITLE);
|
|
|
|
|
Gam_GetListSelectedGamCods ();
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** List my matches results in the current course *****/
|
|
|
|
|
McR_ShowResultsBegin (Txt_Results,true); // List games to select
|
|
|
|
|
McR_ListMyMchResultsInCrs ();
|
|
|
|
|
McR_ShowResultsEnd ();
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** Free list of games *****/
|
|
|
|
|
free (Gbl.Games.GamCodsSelected);
|
|
|
|
|
Gam_FreeListGames ();
|
|
|
|
|
}
|
2019-12-08 15:03:40 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
static void McR_ListMyMchResultsInCrs (void)
|
|
|
|
|
{
|
|
|
|
|
char *GamesSelectedCommas = NULL; // Initialized to avoid warning
|
|
|
|
|
|
|
|
|
|
/***** Table header *****/
|
2019-12-08 15:03:40 +01:00
|
|
|
|
McR_ShowHeaderMchResults (Usr_ME);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** List my matches results in the current course *****/
|
2019-12-08 15:03:40 +01:00
|
|
|
|
Tst_GetConfigTstFromDB (); // Get feedback type
|
2019-12-08 23:19:16 +01:00
|
|
|
|
McR_BuildGamesSelectedCommas (&GamesSelectedCommas);
|
|
|
|
|
McR_ShowMchResults (Usr_ME,-1L,-1L,GamesSelectedCommas);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
free (GamesSelectedCommas);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************** Show my matches results in a given game *******************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
void McR_ShowMyMchResultsInGam (void)
|
2019-12-08 13:34:12 +01:00
|
|
|
|
{
|
2019-12-08 23:19:16 +01:00
|
|
|
|
extern const char *Txt_Results_of_game_X;
|
2019-12-08 14:14:29 +01:00
|
|
|
|
struct Game Game;
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 14:14:29 +01:00
|
|
|
|
/***** Get parameters *****/
|
|
|
|
|
if ((Game.GamCod = Gam_GetParams ()) == -1L)
|
2019-12-08 13:34:12 +01:00
|
|
|
|
Lay_ShowErrorAndExit ("Code of game is missing.");
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Gam_GetDataOfGameByCod (&Game);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 17:08:15 +01:00
|
|
|
|
/***** Game begin *****/
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Gam_ShowOnlyOneGameBegin (&Game,
|
2019-12-08 17:08:15 +01:00
|
|
|
|
false, // Do not list game questions
|
|
|
|
|
false); // Do not put form to start new match
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** List my matches results in game *****/
|
2019-12-30 21:47:07 +01:00
|
|
|
|
McR_ShowResultsBegin (Str_BuildStringStr (Txt_Results_of_game_X,Game.Title),
|
2019-12-30 18:08:31 +01:00
|
|
|
|
false); // Do not list games to select
|
2019-12-30 21:47:07 +01:00
|
|
|
|
Str_FreeString ();
|
2019-12-08 23:19:16 +01:00
|
|
|
|
McR_ListMyMchResultsInGam (Game.GamCod);
|
|
|
|
|
McR_ShowResultsEnd ();
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** Game end *****/
|
|
|
|
|
Gam_ShowOnlyOneGameEnd ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void McR_ListMyMchResultsInGam (long GamCod)
|
|
|
|
|
{
|
|
|
|
|
/***** Table header *****/
|
2019-12-08 13:34:12 +01:00
|
|
|
|
McR_ShowHeaderMchResults (Usr_ME);
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** List my matches results in game *****/
|
2019-12-08 14:14:29 +01:00
|
|
|
|
Tst_GetConfigTstFromDB (); // Get feedback type
|
2019-12-08 23:19:16 +01:00
|
|
|
|
McR_ShowMchResults (Usr_ME,-1L,GamCod,NULL);
|
|
|
|
|
}
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************** Show my matches results in a given match ******************/
|
|
|
|
|
/*****************************************************************************/
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
void McR_ShowMyMchResultsInMch (void)
|
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Results_of_match_X;
|
|
|
|
|
struct Game Game;
|
|
|
|
|
struct Match Match;
|
|
|
|
|
|
|
|
|
|
/***** Get parameters *****/
|
|
|
|
|
if ((Game.GamCod = Gam_GetParams ()) == -1L)
|
|
|
|
|
Lay_ShowErrorAndExit ("Code of game is missing.");
|
|
|
|
|
if ((Match.MchCod = Mch_GetParamMchCod ()) == -1L)
|
|
|
|
|
Lay_ShowErrorAndExit ("Code of match is missing.");
|
|
|
|
|
Gam_GetDataOfGameByCod (&Game);
|
|
|
|
|
Mch_GetDataOfMatchByCod (&Match);
|
|
|
|
|
|
|
|
|
|
/***** Game begin *****/
|
|
|
|
|
Gam_ShowOnlyOneGameBegin (&Game,
|
|
|
|
|
false, // Do not list game questions
|
|
|
|
|
false); // Do not put form to start new match
|
|
|
|
|
|
|
|
|
|
/***** List my matches results in match *****/
|
2019-12-30 21:47:07 +01:00
|
|
|
|
McR_ShowResultsBegin (Str_BuildStringStr (Txt_Results_of_match_X,Match.Title),
|
2019-12-30 18:08:31 +01:00
|
|
|
|
false); // Do not list games to select
|
2019-12-30 21:47:07 +01:00
|
|
|
|
Str_FreeString ();
|
2019-12-08 23:19:16 +01:00
|
|
|
|
McR_ListMyMchResultsInMch (Match.MchCod);
|
|
|
|
|
McR_ShowResultsEnd ();
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 17:08:15 +01:00
|
|
|
|
/***** Game end *****/
|
|
|
|
|
Gam_ShowOnlyOneGameEnd ();
|
2019-12-08 23:19:16 +01:00
|
|
|
|
}
|
2019-12-08 17:08:15 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
static void McR_ListMyMchResultsInMch (long MchCod)
|
|
|
|
|
{
|
|
|
|
|
/***** Table header *****/
|
|
|
|
|
McR_ShowHeaderMchResults (Usr_ME);
|
|
|
|
|
|
|
|
|
|
/***** List my matches results in game *****/
|
|
|
|
|
Tst_GetConfigTstFromDB (); // Get feedback type
|
|
|
|
|
McR_ShowMchResults (Usr_ME,MchCod,-1L,NULL);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-11-14 14:34:34 +01:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/****************** Get users and show their matches results *****************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
void McR_ShowAllMchResultsInCrs (void)
|
2019-11-14 14:34:34 +01:00
|
|
|
|
{
|
2019-11-15 03:34:48 +01:00
|
|
|
|
Usr_GetSelectedUsrsAndGoToAct (&Gbl.Usrs.Selected,
|
2019-12-08 23:19:16 +01:00
|
|
|
|
McR_ShowAllMchResultsInSelectedGames,
|
|
|
|
|
McR_SelUsrsToViewMchResults);
|
2019-12-07 02:12:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 02:31:42 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/****************** Show matches results for several users *******************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
static void McR_ShowAllMchResultsInSelectedGames (void)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Results;
|
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/***** Get list of games *****/
|
|
|
|
|
Gam_GetListGames (Gam_ORDER_BY_TITLE);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
Gam_GetListSelectedGamCods ();
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** List the matches results of the selected users *****/
|
|
|
|
|
McR_ShowResultsBegin (Txt_Results,true); // List games to select
|
|
|
|
|
McR_ListAllMchResultsInSelectedGames ();
|
|
|
|
|
McR_ShowResultsEnd ();
|
2019-11-25 23:18:08 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** Free list of games *****/
|
|
|
|
|
free (Gbl.Games.GamCodsSelected);
|
|
|
|
|
Gam_FreeListGames ();
|
|
|
|
|
}
|
2019-11-25 23:18:08 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
static void McR_ListAllMchResultsInSelectedGames (void)
|
|
|
|
|
{
|
|
|
|
|
char *GamesSelectedCommas = NULL; // Initialized to avoid warning
|
|
|
|
|
const char *Ptr;
|
|
|
|
|
|
|
|
|
|
/***** Table head *****/
|
2019-12-08 13:34:12 +01:00
|
|
|
|
McR_ShowHeaderMchResults (Usr_OTHER);
|
|
|
|
|
|
|
|
|
|
/***** List the matches results of the selected users *****/
|
2019-12-08 23:19:16 +01:00
|
|
|
|
McR_BuildGamesSelectedCommas (&GamesSelectedCommas);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
Ptr = Gbl.Usrs.Selected.List[Rol_UNK];
|
|
|
|
|
while (*Ptr)
|
2019-11-25 23:18:08 +01:00
|
|
|
|
{
|
2019-12-08 13:34:12 +01:00
|
|
|
|
Par_GetNextStrUntilSeparParamMult (&Ptr,Gbl.Usrs.Other.UsrDat.EncryptedUsrCod,
|
|
|
|
|
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
|
|
|
|
|
Usr_GetUsrCodFromEncryptedUsrCod (&Gbl.Usrs.Other.UsrDat);
|
|
|
|
|
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat,Usr_DONT_GET_PREFS))
|
|
|
|
|
if (Usr_CheckIfICanViewMch (&Gbl.Usrs.Other.UsrDat))
|
|
|
|
|
{
|
|
|
|
|
/***** Show matches results *****/
|
|
|
|
|
Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat);
|
2019-12-08 23:19:16 +01:00
|
|
|
|
McR_ShowMchResults (Usr_OTHER,-1L,-1L,GamesSelectedCommas);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
free (GamesSelectedCommas);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/*** Show matches results of a game for the users who answered in that game **/
|
2019-12-08 13:34:12 +01:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
void McR_ShowAllMchResultsInGam (void)
|
2019-12-08 13:34:12 +01:00
|
|
|
|
{
|
2019-12-08 23:19:16 +01:00
|
|
|
|
extern const char *Txt_Results_of_game_X;
|
2019-12-08 14:14:29 +01:00
|
|
|
|
struct Game Game;
|
2019-12-08 23:19:16 +01:00
|
|
|
|
|
|
|
|
|
/***** Get parameters *****/
|
|
|
|
|
if ((Game.GamCod = Gam_GetParams ()) == -1L)
|
|
|
|
|
Lay_ShowErrorAndExit ("Code of game is missing.");
|
|
|
|
|
Gam_GetDataOfGameByCod (&Game);
|
|
|
|
|
|
|
|
|
|
/***** Game begin *****/
|
|
|
|
|
Gam_ShowOnlyOneGameBegin (&Game,
|
|
|
|
|
false, // Do not list game questions
|
|
|
|
|
false); // Do not put form to start new match
|
|
|
|
|
|
|
|
|
|
/***** List matches results in game *****/
|
2019-12-30 21:47:07 +01:00
|
|
|
|
McR_ShowResultsBegin (Str_BuildStringStr (Txt_Results_of_game_X,Game.Title),
|
2019-12-30 18:08:31 +01:00
|
|
|
|
false); // Do not list games to select
|
2019-12-30 21:47:07 +01:00
|
|
|
|
Str_FreeString ();
|
2019-12-08 23:19:16 +01:00
|
|
|
|
McR_ListAllMchResultsInGam (Game.GamCod);
|
|
|
|
|
McR_ShowResultsEnd ();
|
|
|
|
|
|
|
|
|
|
/***** Game end *****/
|
|
|
|
|
Gam_ShowOnlyOneGameEnd ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void McR_ListAllMchResultsInGam (long GamCod)
|
|
|
|
|
{
|
2019-12-08 13:34:12 +01:00
|
|
|
|
MYSQL_RES *mysql_res;
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
unsigned long NumUsrs;
|
|
|
|
|
unsigned long NumUsr;
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** Table head *****/
|
|
|
|
|
McR_ShowHeaderMchResults (Usr_OTHER);
|
|
|
|
|
|
|
|
|
|
/***** Get all users who have answered any match question in this game *****/
|
2019-12-10 14:22:09 +01:00
|
|
|
|
NumUsrs = DB_QuerySELECT (&mysql_res,"can not get users in game",
|
2019-12-09 21:21:11 +01:00
|
|
|
|
"SELECT users.UsrCod FROM"
|
|
|
|
|
" (SELECT DISTINCT mch_results.UsrCod AS UsrCod" // row[0]
|
2019-12-08 23:19:16 +01:00
|
|
|
|
" FROM mch_results,mch_matches,gam_games"
|
|
|
|
|
" WHERE mch_matches.GamCod=%ld"
|
|
|
|
|
" AND mch_matches.MchCod=mch_results.MchCod"
|
|
|
|
|
" AND mch_matches.GamCod=gam_games.GamCod"
|
2019-12-09 21:21:11 +01:00
|
|
|
|
" AND gam_games.CrsCod=%ld)" // Extra check
|
|
|
|
|
" AS users,usr_data"
|
|
|
|
|
" WHERE users.UsrCod=usr_data.UsrCod"
|
|
|
|
|
" ORDER BY usr_data.Surname1,"
|
|
|
|
|
"usr_data.Surname2,"
|
|
|
|
|
"usr_data.FirstName",
|
2019-12-08 23:19:16 +01:00
|
|
|
|
GamCod,
|
|
|
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
|
|
|
|
if (NumUsrs)
|
|
|
|
|
{
|
|
|
|
|
/***** List matches results for each user *****/
|
|
|
|
|
for (NumUsr = 0;
|
|
|
|
|
NumUsr < NumUsrs;
|
|
|
|
|
NumUsr++)
|
|
|
|
|
{
|
|
|
|
|
row = mysql_fetch_row (mysql_res);
|
|
|
|
|
|
|
|
|
|
/* Get match code (row[0]) */
|
|
|
|
|
if ((Gbl.Usrs.Other.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0])) > 0)
|
|
|
|
|
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat,Usr_DONT_GET_PREFS))
|
|
|
|
|
if (Usr_CheckIfICanViewMch (&Gbl.Usrs.Other.UsrDat))
|
|
|
|
|
{
|
|
|
|
|
/***** Show matches results *****/
|
|
|
|
|
Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat);
|
|
|
|
|
McR_ShowMchResults (Usr_OTHER,-1L,GamCod,NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/** Show matches results of a match for the users who answered in that match */
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void McR_ShowAllMchResultsInMch (void)
|
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Results_of_match_X;
|
|
|
|
|
struct Game Game;
|
|
|
|
|
struct Match Match;
|
|
|
|
|
|
2019-12-08 14:14:29 +01:00
|
|
|
|
/***** Get parameters *****/
|
|
|
|
|
if ((Game.GamCod = Gam_GetParams ()) == -1L)
|
2019-12-08 13:34:12 +01:00
|
|
|
|
Lay_ShowErrorAndExit ("Code of game is missing.");
|
2019-12-08 23:19:16 +01:00
|
|
|
|
if ((Match.MchCod = Mch_GetParamMchCod ()) == -1L)
|
|
|
|
|
Lay_ShowErrorAndExit ("Code of match is missing.");
|
|
|
|
|
Gam_GetDataOfGameByCod (&Game);
|
|
|
|
|
Mch_GetDataOfMatchByCod (&Match);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 17:08:15 +01:00
|
|
|
|
/***** Game begin *****/
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Gam_ShowOnlyOneGameBegin (&Game,
|
2019-12-08 17:08:15 +01:00
|
|
|
|
false, // Do not list game questions
|
|
|
|
|
false); // Do not put form to start new match
|
2019-12-08 14:14:29 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** List matches results in match *****/
|
2019-12-30 21:47:07 +01:00
|
|
|
|
McR_ShowResultsBegin (Str_BuildStringStr (Txt_Results_of_match_X,Match.Title),
|
2019-12-30 18:08:31 +01:00
|
|
|
|
false); // Do not list games to select
|
2019-12-30 21:47:07 +01:00
|
|
|
|
Str_FreeString ();
|
2019-12-08 23:19:16 +01:00
|
|
|
|
McR_ListAllMchResultsInMch (Match.MchCod);
|
|
|
|
|
McR_ShowResultsEnd ();
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** Game end *****/
|
|
|
|
|
Gam_ShowOnlyOneGameEnd ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void McR_ListAllMchResultsInMch (long MchCod)
|
|
|
|
|
{
|
|
|
|
|
MYSQL_RES *mysql_res;
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
unsigned long NumUsrs;
|
|
|
|
|
unsigned long NumUsr;
|
|
|
|
|
|
|
|
|
|
/***** Table head *****/
|
|
|
|
|
McR_ShowHeaderMchResults (Usr_OTHER);
|
|
|
|
|
|
|
|
|
|
/***** Get all users who have answered any match question in this game *****/
|
2019-12-10 14:22:09 +01:00
|
|
|
|
NumUsrs = DB_QuerySELECT (&mysql_res,"can not get users in match",
|
2019-12-09 21:21:11 +01:00
|
|
|
|
"SELECT users.UsrCod FROM"
|
|
|
|
|
" (SELECT mch_results.UsrCod AS UsrCod" // row[0]
|
2019-12-08 23:19:16 +01:00
|
|
|
|
" FROM mch_results,mch_matches,gam_games"
|
|
|
|
|
" WHERE mch_results.MchCod=%ld"
|
|
|
|
|
" AND mch_results.MchCod=mch_matches.MchCod"
|
|
|
|
|
" AND mch_matches.GamCod=gam_games.GamCod"
|
2019-12-09 21:21:11 +01:00
|
|
|
|
" AND gam_games.CrsCod=%ld)" // Extra check
|
|
|
|
|
" AS users,usr_data"
|
|
|
|
|
" WHERE users.UsrCod=usr_data.UsrCod"
|
|
|
|
|
" ORDER BY usr_data.Surname1,"
|
|
|
|
|
"usr_data.Surname2,"
|
|
|
|
|
"usr_data.FirstName",
|
2019-12-08 23:19:16 +01:00
|
|
|
|
MchCod,
|
|
|
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
if (NumUsrs)
|
|
|
|
|
{
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** List matches results for each user *****/
|
2019-12-08 13:34:12 +01:00
|
|
|
|
for (NumUsr = 0;
|
|
|
|
|
NumUsr < NumUsrs;
|
|
|
|
|
NumUsr++)
|
2019-11-25 23:18:08 +01:00
|
|
|
|
{
|
2019-12-08 13:34:12 +01:00
|
|
|
|
row = mysql_fetch_row (mysql_res);
|
2019-11-25 23:18:08 +01:00
|
|
|
|
|
2019-12-08 13:34:12 +01:00
|
|
|
|
/* Get match code (row[0]) */
|
|
|
|
|
if ((Gbl.Usrs.Other.UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0])) > 0)
|
|
|
|
|
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat,Usr_DONT_GET_PREFS))
|
|
|
|
|
if (Usr_CheckIfICanViewMch (&Gbl.Usrs.Other.UsrDat))
|
|
|
|
|
{
|
|
|
|
|
/***** Show matches results *****/
|
|
|
|
|
Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat);
|
2019-12-08 23:19:16 +01:00
|
|
|
|
McR_ShowMchResults (Usr_OTHER,MchCod,-1L,NULL);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-11-25 23:18:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-08 13:34:12 +01:00
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
2019-12-08 23:19:16 +01:00
|
|
|
|
}
|
2019-11-25 23:18:08 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************************ Show results (begin / end) *************************/
|
|
|
|
|
/*****************************************************************************/
|
2019-12-08 13:34:12 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
static void McR_ShowResultsBegin (const char *Title,bool ListGamesToSelect)
|
|
|
|
|
{
|
|
|
|
|
extern const char *Hlp_ASSESSMENT_Games_results;
|
2019-12-08 17:08:15 +01:00
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** Begin box *****/
|
2019-12-09 11:09:12 +01:00
|
|
|
|
HTM_SECTION_Begin (McR_RESULTS_BOX_ID);
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Box_BoxBegin ("100%",Title,NULL,
|
|
|
|
|
Hlp_ASSESSMENT_Games_results,Box_NOT_CLOSABLE);
|
|
|
|
|
|
|
|
|
|
/***** List games to select *****/
|
|
|
|
|
if (ListGamesToSelect)
|
|
|
|
|
McR_ListGamesToSelect ();
|
|
|
|
|
|
2019-12-09 11:09:12 +01:00
|
|
|
|
/***** Begin match results table *****/
|
2019-12-08 23:19:16 +01:00
|
|
|
|
HTM_SECTION_Begin (McR_RESULTS_TABLE_ID);
|
|
|
|
|
HTM_TABLE_BeginWidePadding (2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void McR_ShowResultsEnd (void)
|
|
|
|
|
{
|
2019-12-09 11:09:12 +01:00
|
|
|
|
/***** End match results table *****/
|
2019-12-08 23:19:16 +01:00
|
|
|
|
HTM_TABLE_End ();
|
|
|
|
|
HTM_SECTION_End ();
|
|
|
|
|
|
|
|
|
|
/***** End box *****/
|
|
|
|
|
Box_BoxEnd ();
|
2019-12-09 11:09:12 +01:00
|
|
|
|
HTM_SECTION_End ();
|
2019-11-25 23:18:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********** Write list of those attendance events that have students *********/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static void McR_ListGamesToSelect (void)
|
|
|
|
|
{
|
2019-12-09 11:09:12 +01:00
|
|
|
|
extern const char *Hlp_ASSESSMENT_Games_results;
|
2019-11-25 23:18:08 +01:00
|
|
|
|
extern const char *The_ClassFormLinkInBoxBold[The_NUM_THEMES];
|
|
|
|
|
extern const char *Txt_Games;
|
|
|
|
|
extern const char *Txt_Game;
|
|
|
|
|
extern const char *Txt_Update_results;
|
|
|
|
|
unsigned UniqueId;
|
|
|
|
|
unsigned NumGame;
|
|
|
|
|
struct Game Game;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/***** Begin box *****/
|
2019-12-09 11:09:12 +01:00
|
|
|
|
Box_BoxBegin (NULL,Txt_Games,NULL,Hlp_ASSESSMENT_Games_results,Box_CLOSABLE);
|
2019-11-25 23:18:08 +01:00
|
|
|
|
|
|
|
|
|
/***** Begin form to update the results
|
|
|
|
|
depending on the games selected *****/
|
|
|
|
|
Frm_StartFormAnchor (Gbl.Action.Act,McR_RESULTS_TABLE_ID);
|
|
|
|
|
Grp_PutParamsCodGrps ();
|
|
|
|
|
Usr_PutHiddenParSelectedUsrsCods (&Gbl.Usrs.Selected);
|
2019-11-14 14:34:34 +01:00
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/***** Begin table *****/
|
|
|
|
|
HTM_TABLE_BeginWidePadding (2);
|
|
|
|
|
|
|
|
|
|
/***** Heading row *****/
|
|
|
|
|
HTM_TR_Begin (NULL);
|
2019-11-14 14:34:34 +01:00
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
HTM_TH (1,2,NULL,NULL);
|
|
|
|
|
HTM_TH (1,1,"LM",Txt_Game);
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
|
|
|
|
|
/***** List the events *****/
|
|
|
|
|
for (NumGame = 0, UniqueId = 1, Gbl.RowEvenOdd = 0;
|
|
|
|
|
NumGame < Gbl.Games.Num;
|
|
|
|
|
NumGame++, UniqueId++, Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
{
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/* Get data of this game */
|
|
|
|
|
Game.GamCod = Gbl.Games.Lst[NumGame].GamCod;
|
|
|
|
|
Gam_GetDataOfGameByCod (&Game);
|
|
|
|
|
|
|
|
|
|
/* Write a row for this event */
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"DAT CT COLOR%u\"",Gbl.RowEvenOdd);
|
2019-12-07 18:44:13 +01:00
|
|
|
|
HTM_INPUT_CHECKBOX ("GamCod",false,
|
2019-11-25 23:18:08 +01:00
|
|
|
|
"id=\"Gam%u\" value=\"%ld\"%s",
|
|
|
|
|
NumGame,Gbl.Games.Lst[NumGame].GamCod,
|
|
|
|
|
Gbl.Games.Lst[NumGame].Selected ? " checked=\"checked\"" : "");
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
|
|
|
|
|
HTM_LABEL_Begin ("for=\"Gam%u\"",NumGame);
|
|
|
|
|
HTM_TxtF ("%u:",NumGame + 1);
|
|
|
|
|
HTM_LABEL_End ();
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"DAT LT COLOR%u\"",Gbl.RowEvenOdd);
|
|
|
|
|
HTM_Txt (Game.Title);
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/***** Put button to refresh *****/
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("colspan=\"3\" class=\"CM\"");
|
|
|
|
|
HTM_BUTTON_Animated_Begin (Txt_Update_results,
|
|
|
|
|
The_ClassFormLinkInBoxBold[Gbl.Prefs.Theme],
|
|
|
|
|
NULL);
|
|
|
|
|
Ico_PutCalculateIconWithText (Txt_Update_results);
|
|
|
|
|
HTM_BUTTON_End ();
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
|
|
|
|
|
/***** End table *****/
|
|
|
|
|
HTM_TABLE_End ();
|
|
|
|
|
|
|
|
|
|
/***** End form *****/
|
|
|
|
|
Frm_EndForm ();
|
|
|
|
|
|
|
|
|
|
/***** End box *****/
|
|
|
|
|
Box_BoxEnd ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********************* Show header of my matches results *********************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-09-30 22:31:07 +02:00
|
|
|
|
static void McR_ShowHeaderMchResults (Usr_MeOrOther_t MeOrOther)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_User[Usr_NUM_SEXS];
|
2019-09-30 20:13:08 +02:00
|
|
|
|
extern const char *Txt_Match;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME];
|
|
|
|
|
extern const char *Txt_Questions;
|
|
|
|
|
extern const char *Txt_Non_blank_BR_questions;
|
2019-11-28 22:17:00 +01:00
|
|
|
|
extern const char *Txt_Score;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
extern const char *Txt_Average_BR_score_BR_per_question_BR_from_0_to_1;
|
2019-11-28 00:19:42 +01:00
|
|
|
|
extern const char *Txt_Grade;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_Begin (NULL);
|
2019-10-12 00:07:52 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TH (1,2,"CT",Txt_User[MeOrOther == Usr_ME ? Gbl.Usrs.Me.UsrDat.Sex :
|
2019-10-13 16:21:05 +02:00
|
|
|
|
Usr_SEX_UNKNOWN]);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TH (1,1,"LT",Txt_START_END_TIME[Dat_START_TIME]);
|
|
|
|
|
HTM_TH (1,1,"LT",Txt_START_END_TIME[Dat_END_TIME]);
|
|
|
|
|
HTM_TH (1,1,"LT",Txt_Match);
|
|
|
|
|
HTM_TH (1,1,"RT",Txt_Questions);
|
|
|
|
|
HTM_TH (1,1,"RT",Txt_Non_blank_BR_questions);
|
2019-11-28 22:17:00 +01:00
|
|
|
|
HTM_TH (1,1,"RT",Txt_Score);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TH (1,1,"RT",Txt_Average_BR_score_BR_per_question_BR_from_0_to_1);
|
2019-11-28 22:49:05 +01:00
|
|
|
|
HTM_TH (1,1,"RT",Txt_Grade);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TH_Empty (1);
|
2019-10-12 00:07:52 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-12-08 13:34:12 +01:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/******* Build string with list of selected games separated by commas ********/
|
|
|
|
|
/******* from list of selected games ********/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-12-08 14:14:29 +01:00
|
|
|
|
static void McR_BuildGamesSelectedCommas (char **GamesSelectedCommas)
|
2019-12-08 13:34:12 +01:00
|
|
|
|
{
|
|
|
|
|
size_t MaxLength;
|
|
|
|
|
unsigned NumGame;
|
|
|
|
|
char LongStr[Cns_MAX_DECIMAL_DIGITS_LONG + 1];
|
|
|
|
|
|
|
|
|
|
/***** Allocate memory for subquery of games selected *****/
|
|
|
|
|
MaxLength = (size_t) Gbl.Games.NumSelected * (Cns_MAX_DECIMAL_DIGITS_LONG + 1);
|
2019-12-08 14:14:29 +01:00
|
|
|
|
if ((*GamesSelectedCommas = (char *) malloc (MaxLength + 1)) == NULL)
|
2019-12-08 13:34:12 +01:00
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
|
|
|
|
|
/***** Build subquery with list of selected games *****/
|
2019-12-08 14:14:29 +01:00
|
|
|
|
(*GamesSelectedCommas)[0] = '\0';
|
2019-12-08 13:34:12 +01:00
|
|
|
|
for (NumGame = 0;
|
|
|
|
|
NumGame < Gbl.Games.Num;
|
|
|
|
|
NumGame++)
|
|
|
|
|
if (Gbl.Games.Lst[NumGame].Selected)
|
|
|
|
|
{
|
|
|
|
|
sprintf (LongStr,"%ld",Gbl.Games.Lst[NumGame].GamCod);
|
2019-12-08 14:14:29 +01:00
|
|
|
|
if ((*GamesSelectedCommas)[0])
|
|
|
|
|
Str_Concat (*GamesSelectedCommas,",",MaxLength);
|
|
|
|
|
Str_Concat (*GamesSelectedCommas,LongStr,MaxLength);
|
2019-12-08 13:34:12 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 02:31:42 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********* Show the matches results of a user in the current course **********/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
|
2019-12-08 23:19:16 +01:00
|
|
|
|
long MchCod, // <= 0 ==> any
|
|
|
|
|
long GamCod, // <= 0 ==> any
|
2019-12-08 13:34:12 +01:00
|
|
|
|
const char *GamesSelectedCommas)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Match_result;
|
2019-12-08 23:19:16 +01:00
|
|
|
|
extern const char *Txt_Hidden_results;
|
|
|
|
|
char *MchSubQuery;
|
|
|
|
|
char *GamSubQuery;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
MYSQL_RES *mysql_res;
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
struct UsrData *UsrDat;
|
|
|
|
|
bool ShowResultThisMatch;
|
|
|
|
|
bool ShowSummaryResults = true;
|
|
|
|
|
unsigned NumResults;
|
|
|
|
|
unsigned NumResult;
|
|
|
|
|
static unsigned UniqueId = 0;
|
2019-11-01 22:53:39 +01:00
|
|
|
|
char *Id;
|
2019-09-30 01:10:57 +02:00
|
|
|
|
struct Match Match;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
Dat_StartEndTime_t StartEndTime;
|
|
|
|
|
unsigned NumQstsInThisResult;
|
|
|
|
|
unsigned NumQstsNotBlankInThisResult;
|
|
|
|
|
unsigned NumTotalQsts = 0;
|
|
|
|
|
unsigned NumTotalQstsNotBlank = 0;
|
|
|
|
|
double ScoreInThisResult;
|
|
|
|
|
double TotalScoreOfAllResults = 0.0;
|
2019-11-28 00:19:42 +01:00
|
|
|
|
double MaxGrade;
|
|
|
|
|
double Grade;
|
|
|
|
|
double TotalGrade = 0.0;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
time_t TimeUTC[Dat_NUM_START_END_TIME];
|
|
|
|
|
|
|
|
|
|
/***** Set user *****/
|
|
|
|
|
UsrDat = (MeOrOther == Usr_ME) ? &Gbl.Usrs.Me.UsrDat :
|
2019-11-25 23:18:08 +01:00
|
|
|
|
&Gbl.Usrs.Other.UsrDat;
|
|
|
|
|
|
2019-12-08 23:19:16 +01:00
|
|
|
|
/***** Build matches subquery *****/
|
|
|
|
|
if (MchCod > 0)
|
|
|
|
|
{
|
|
|
|
|
if (asprintf (&MchSubQuery," AND mch_results.MchCod=%ld",MchCod) < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (asprintf (&MchSubQuery,"%s","") < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Build games subquery *****/
|
|
|
|
|
if (GamCod > 0)
|
|
|
|
|
{
|
|
|
|
|
if (asprintf (&GamSubQuery," AND mch_matches.GamCod=%ld",GamCod) < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
}
|
|
|
|
|
else if (GamesSelectedCommas)
|
|
|
|
|
{
|
2019-12-10 14:22:09 +01:00
|
|
|
|
if (GamesSelectedCommas[0])
|
|
|
|
|
{
|
|
|
|
|
if (asprintf (&GamSubQuery," AND mch_matches.GamCod IN (%s)",
|
|
|
|
|
GamesSelectedCommas) < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (asprintf (&GamSubQuery,"%s","") < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
}
|
2019-12-08 23:19:16 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (asprintf (&GamSubQuery,"%s","") < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 02:31:42 +02:00
|
|
|
|
/***** Make database query *****/
|
|
|
|
|
NumResults =
|
2019-12-10 14:22:09 +01:00
|
|
|
|
(unsigned) DB_QuerySELECT (&mysql_res,"can not get matches results",
|
2019-09-28 02:31:42 +02:00
|
|
|
|
"SELECT mch_results.MchCod," // row[0]
|
2019-11-25 23:18:08 +01:00
|
|
|
|
"UNIX_TIMESTAMP(mch_results.StartTime)," // row[1]
|
|
|
|
|
"UNIX_TIMESTAMP(mch_results.EndTime)," // row[2]
|
|
|
|
|
"mch_results.NumQsts," // row[3]
|
|
|
|
|
"mch_results.NumQstsNotBlank," // row[4]
|
2019-11-28 00:19:42 +01:00
|
|
|
|
"mch_results.Score," // row[5]
|
|
|
|
|
"gam_games.MaxGrade" // row[6]
|
2019-09-28 02:31:42 +02:00
|
|
|
|
" FROM mch_results,mch_matches,gam_games"
|
|
|
|
|
" WHERE mch_results.UsrCod=%ld"
|
2019-12-08 23:19:16 +01:00
|
|
|
|
"%s" // Match subquery
|
2019-09-28 02:31:42 +02:00
|
|
|
|
" AND mch_results.MchCod=mch_matches.MchCod"
|
2019-12-08 23:19:16 +01:00
|
|
|
|
"%s" // Games subquery
|
2019-09-28 02:31:42 +02:00
|
|
|
|
" AND mch_matches.GamCod=gam_games.GamCod"
|
|
|
|
|
" AND gam_games.CrsCod=%ld" // Extra check
|
2019-12-08 13:34:12 +01:00
|
|
|
|
" ORDER BY mch_matches.Title",
|
2019-09-28 02:31:42 +02:00
|
|
|
|
UsrDat->UsrCod,
|
2019-12-08 23:19:16 +01:00
|
|
|
|
MchSubQuery,
|
|
|
|
|
GamSubQuery,
|
|
|
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
|
|
|
|
free (GamSubQuery);
|
|
|
|
|
free (MchSubQuery);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Show user's data *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_Begin (NULL);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
Usr_ShowTableCellWithUsrData (UsrDat,NumResults);
|
|
|
|
|
|
|
|
|
|
/***** Get and print matches results *****/
|
|
|
|
|
if (NumResults)
|
|
|
|
|
{
|
|
|
|
|
for (NumResult = 0;
|
2019-11-25 23:18:08 +01:00
|
|
|
|
NumResult < NumResults;
|
|
|
|
|
NumResult++)
|
|
|
|
|
{
|
|
|
|
|
row = mysql_fetch_row (mysql_res);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/* Get match code (row[0]) */
|
2019-09-30 01:10:57 +02:00
|
|
|
|
if ((Match.MchCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
Lay_ShowErrorAndExit ("Wrong code of match.");
|
2019-11-25 23:18:08 +01:00
|
|
|
|
Mch_GetDataOfMatchByCod (&Match);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/* Show match result? */
|
2019-09-30 01:26:19 +02:00
|
|
|
|
ShowResultThisMatch = McR_CheckIfICanSeeMatchResult (Match.MchCod,UsrDat->UsrCod);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
ShowSummaryResults = ShowSummaryResults && ShowResultThisMatch;
|
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
if (NumResult)
|
|
|
|
|
HTM_TR_Begin (NULL);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/* Write start/end times (row[1], row[2] hold UTC start/end times) */
|
2019-12-15 20:02:34 +01:00
|
|
|
|
for (StartEndTime = (Dat_StartEndTime_t) 0;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
|
|
|
|
|
StartEndTime++)
|
2019-11-25 23:18:08 +01:00
|
|
|
|
{
|
2019-09-28 02:31:42 +02:00
|
|
|
|
TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[1 + StartEndTime]);
|
|
|
|
|
UniqueId++;
|
2019-12-09 16:59:19 +01:00
|
|
|
|
if (asprintf (&Id,"mch_res_time_%u_%u",(unsigned) StartEndTime,UniqueId) < 0)
|
2019-11-01 22:53:39 +01:00
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
HTM_TD_Begin ("id =\"%s\" class=\"DAT LT COLOR%u\"",
|
|
|
|
|
Id,Gbl.RowEvenOdd);
|
2019-11-01 23:35:55 +01:00
|
|
|
|
Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC[StartEndTime],
|
2019-11-02 12:10:58 +01:00
|
|
|
|
Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK,
|
2019-11-02 11:45:41 +01:00
|
|
|
|
true,true,false,0x7);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-11-25 23:18:08 +01:00
|
|
|
|
free (Id);
|
|
|
|
|
}
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/* Write match title */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT LT COLOR%u\"",Gbl.RowEvenOdd);
|
2019-11-10 12:36:37 +01:00
|
|
|
|
HTM_Txt (Match.Title);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-30 22:31:07 +02:00
|
|
|
|
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (ShowResultThisMatch)
|
|
|
|
|
{
|
2019-11-28 22:17:00 +01:00
|
|
|
|
/* Get number of questions (row[3]) */
|
|
|
|
|
if (sscanf (row[3],"%u",&NumQstsInThisResult) != 1)
|
|
|
|
|
NumQstsInThisResult = 0;
|
|
|
|
|
NumTotalQsts += NumQstsInThisResult;
|
|
|
|
|
|
|
|
|
|
/* Get number of questions not blank (row[4]) */
|
|
|
|
|
if (sscanf (row[4],"%u",&NumQstsNotBlankInThisResult) != 1)
|
|
|
|
|
NumQstsNotBlankInThisResult = 0;
|
|
|
|
|
NumTotalQstsNotBlank += NumQstsNotBlankInThisResult;
|
|
|
|
|
|
2019-09-28 02:31:42 +02:00
|
|
|
|
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
|
2019-11-28 00:19:42 +01:00
|
|
|
|
|
|
|
|
|
/* Get score (row[5]) */
|
|
|
|
|
if (sscanf (row[5],"%lg",&ScoreInThisResult) != 1)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
ScoreInThisResult = 0.0;
|
|
|
|
|
TotalScoreOfAllResults += ScoreInThisResult;
|
2019-11-28 00:19:42 +01:00
|
|
|
|
|
|
|
|
|
/* Get maximum grade (row[6]) */
|
|
|
|
|
if (sscanf (row[6],"%lg",&MaxGrade) != 1)
|
|
|
|
|
MaxGrade = 0.0;
|
|
|
|
|
|
|
|
|
|
Str_SetDecimalPointToLocal (); // Return to local system
|
2019-09-28 02:31:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/* Write number of questions */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
|
2019-11-28 22:17:00 +01:00
|
|
|
|
if (ShowResultThisMatch)
|
|
|
|
|
HTM_Unsigned (NumQstsInThisResult);
|
|
|
|
|
else
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/* Write number of questions not blank */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
|
2019-11-28 22:17:00 +01:00
|
|
|
|
if (ShowResultThisMatch)
|
|
|
|
|
HTM_Unsigned (NumQstsNotBlankInThisResult);
|
|
|
|
|
else
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/* Write score */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (ShowResultThisMatch)
|
2019-12-14 13:35:35 +01:00
|
|
|
|
HTM_Double2Decimals (ScoreInThisResult);
|
2019-11-28 22:17:00 +01:00
|
|
|
|
else
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
/* Write average score per question */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (ShowResultThisMatch)
|
2019-12-14 13:35:35 +01:00
|
|
|
|
HTM_Double2Decimals (NumQstsInThisResult ? ScoreInThisResult /
|
2019-11-25 23:18:08 +01:00
|
|
|
|
(double) NumQstsInThisResult :
|
|
|
|
|
0.0);
|
2019-11-28 22:17:00 +01:00
|
|
|
|
else
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
2019-11-28 00:19:42 +01:00
|
|
|
|
/* Write grade over maximum grade */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (ShowResultThisMatch)
|
2019-11-28 00:19:42 +01:00
|
|
|
|
{
|
2019-11-28 09:12:34 +01:00
|
|
|
|
Grade = Tst_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,MaxGrade);
|
|
|
|
|
Tst_ShowGrade (Grade,MaxGrade);
|
2019-11-28 00:19:42 +01:00
|
|
|
|
TotalGrade += Grade;
|
|
|
|
|
}
|
2019-11-28 22:17:00 +01:00
|
|
|
|
else
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/* Link to show this result */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (ShowResultThisMatch)
|
|
|
|
|
{
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Gam_SetCurrentGamCod (Match.GamCod); // Used to pass parameter
|
|
|
|
|
Mch_SetCurrentMchCod (Match.MchCod); // Used to pass parameter
|
2019-09-28 02:31:42 +02:00
|
|
|
|
switch (MeOrOther)
|
|
|
|
|
{
|
|
|
|
|
case Usr_ME:
|
|
|
|
|
Frm_StartForm (ActSeeOneMchResMe);
|
2019-09-30 01:10:57 +02:00
|
|
|
|
Mch_PutParamsEdit ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
break;
|
|
|
|
|
case Usr_OTHER:
|
|
|
|
|
Frm_StartForm (ActSeeOneMchResOth);
|
2019-09-30 01:10:57 +02:00
|
|
|
|
Mch_PutParamsEdit ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
Usr_PutParamOtherUsrCodEncrypted ();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
Ico_PutIconLink ("tasks.svg",Txt_Match_result);
|
|
|
|
|
Frm_EndForm ();
|
|
|
|
|
}
|
|
|
|
|
else
|
2019-12-08 23:19:16 +01:00
|
|
|
|
Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
2019-11-25 23:18:08 +01:00
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
}
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Write totals for this user *****/
|
2019-11-28 22:17:00 +01:00
|
|
|
|
McR_ShowMchResultsSummaryRow (NumResults,
|
2019-11-25 23:18:08 +01:00
|
|
|
|
NumTotalQsts,NumTotalQstsNotBlank,
|
2019-11-28 00:19:42 +01:00
|
|
|
|
TotalScoreOfAllResults,
|
2019-11-29 17:42:05 +01:00
|
|
|
|
TotalGrade);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-11-25 23:18:08 +01:00
|
|
|
|
HTM_TD_ColouredEmpty (9);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
|
|
|
|
|
|
Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************** Show row with summary of user's matches results **************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-11-28 22:17:00 +01:00
|
|
|
|
static void McR_ShowMchResultsSummaryRow (unsigned NumResults,
|
2019-09-28 02:31:42 +02:00
|
|
|
|
unsigned NumTotalQsts,
|
|
|
|
|
unsigned NumTotalQstsNotBlank,
|
2019-11-28 00:19:42 +01:00
|
|
|
|
double TotalScoreOfAllResults,
|
2019-11-29 17:42:05 +01:00
|
|
|
|
double TotalGrade)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Matches;
|
|
|
|
|
|
|
|
|
|
/***** Start row *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_Begin (NULL);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Row title *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("colspan=\"3\" class=\"DAT_N_LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd);
|
2019-11-11 10:59:24 +01:00
|
|
|
|
HTM_TxtF ("%s: ",Txt_Matches);
|
2019-11-11 00:15:44 +01:00
|
|
|
|
HTM_Unsigned (NumResults);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Write total number of questions *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N_LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (NumResults)
|
2019-11-10 13:31:47 +01:00
|
|
|
|
HTM_Unsigned (NumTotalQsts);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Write total number of questions not blank *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N_LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (NumResults)
|
2019-11-10 13:31:47 +01:00
|
|
|
|
HTM_Unsigned (NumTotalQstsNotBlank);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Write total score *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N_LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd);
|
2019-12-14 13:35:35 +01:00
|
|
|
|
HTM_Double2Decimals (TotalScoreOfAllResults);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Write average score per question *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N_LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd);
|
2019-12-14 13:35:35 +01:00
|
|
|
|
HTM_Double2Decimals (NumTotalQsts ? TotalScoreOfAllResults / (double) NumTotalQsts :
|
2019-11-28 22:17:00 +01:00
|
|
|
|
0.0);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
2019-11-28 00:19:42 +01:00
|
|
|
|
/***** Write total grade *****/
|
2019-11-29 17:42:05 +01:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N_LINE_TOP RM COLOR%u\"",Gbl.RowEvenOdd);
|
2019-12-14 13:35:35 +01:00
|
|
|
|
HTM_Double2Decimals (TotalGrade);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Last cell *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N_LINE_TOP COLOR%u\"",Gbl.RowEvenOdd);
|
|
|
|
|
HTM_TD_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** End row *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/******************* Show one match result of another user *******************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-09-30 01:26:19 +02:00
|
|
|
|
void McR_ShowOneMchResult (void)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Hlp_ASSESSMENT_Games_results;
|
2019-09-30 01:10:57 +02:00
|
|
|
|
extern const char *Txt_The_user_does_not_exist;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
|
|
|
|
extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME];
|
|
|
|
|
extern const char *Txt_Questions;
|
|
|
|
|
extern const char *Txt_non_blank_QUESTIONS;
|
|
|
|
|
extern const char *Txt_Score;
|
2019-11-28 09:45:32 +01:00
|
|
|
|
extern const char *Txt_Grade;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
extern const char *Txt_Tags;
|
2019-09-29 22:38:32 +02:00
|
|
|
|
struct Game Game;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
struct Match Match;
|
|
|
|
|
Usr_MeOrOther_t MeOrOther;
|
|
|
|
|
struct UsrData *UsrDat;
|
|
|
|
|
time_t TimeUTC[Dat_NUM_START_END_TIME]; // Match result UTC date-time
|
|
|
|
|
Dat_StartEndTime_t StartEndTime;
|
2019-11-01 22:53:39 +01:00
|
|
|
|
char *Id;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
unsigned NumQsts;
|
|
|
|
|
unsigned NumQstsNotBlank;
|
|
|
|
|
double TotalScore;
|
|
|
|
|
bool ShowPhoto;
|
|
|
|
|
char PhotoURL[PATH_MAX + 1];
|
|
|
|
|
bool ItsMe;
|
2019-09-29 19:36:32 +02:00
|
|
|
|
bool ICanPlayThisMatchBasedOnGrps;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
bool ICanViewResult;
|
|
|
|
|
bool ICanViewScore;
|
|
|
|
|
|
2019-09-29 22:38:32 +02:00
|
|
|
|
/***** Get and check parameters *****/
|
|
|
|
|
Mch_GetAndCheckParameters (&Game,&Match);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Pointer to user's data *****/
|
|
|
|
|
MeOrOther = (Gbl.Action.Act == ActSeeOneMchResMe) ? Usr_ME :
|
|
|
|
|
Usr_OTHER;
|
|
|
|
|
switch (MeOrOther)
|
|
|
|
|
{
|
|
|
|
|
case Usr_ME:
|
|
|
|
|
UsrDat = &Gbl.Usrs.Me.UsrDat;
|
|
|
|
|
break;
|
|
|
|
|
case Usr_OTHER:
|
|
|
|
|
default:
|
|
|
|
|
UsrDat = &Gbl.Usrs.Other.UsrDat;
|
|
|
|
|
Usr_GetParamOtherUsrCodEncrypted (UsrDat);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Get match result data *****/
|
2019-09-30 01:26:19 +02:00
|
|
|
|
McR_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod,
|
2019-09-28 02:31:42 +02:00
|
|
|
|
TimeUTC,
|
|
|
|
|
&NumQsts,
|
|
|
|
|
&NumQstsNotBlank,
|
|
|
|
|
&TotalScore);
|
|
|
|
|
Gbl.Test.Config.Feedback = Tst_FEEDBACK_FULL_FEEDBACK; // Initialize feedback to maximum
|
|
|
|
|
|
|
|
|
|
/***** Check if I can view this match result *****/
|
|
|
|
|
ItsMe = Usr_ItsMe (UsrDat->UsrCod);
|
|
|
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
|
|
|
{
|
|
|
|
|
case Rol_STD:
|
|
|
|
|
switch (MeOrOther)
|
|
|
|
|
{
|
|
|
|
|
case Usr_ME:
|
2019-12-05 19:54:28 +01:00
|
|
|
|
ICanPlayThisMatchBasedOnGrps = Mch_CheckIfICanPlayThisMatchBasedOnGrps (&Match);
|
2019-09-29 19:36:32 +02:00
|
|
|
|
ICanViewResult = ItsMe && ICanPlayThisMatchBasedOnGrps &&
|
|
|
|
|
Match.Status.ShowUsrResults;
|
|
|
|
|
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (ICanViewResult)
|
|
|
|
|
{
|
|
|
|
|
Tst_GetConfigTstFromDB (); // To get feedback type
|
|
|
|
|
ICanViewScore = Gbl.Test.Config.Feedback != Tst_FEEDBACK_NOTHING;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
ICanViewScore = false;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ICanViewResult =
|
|
|
|
|
ICanViewScore = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Rol_NET:
|
|
|
|
|
case Rol_TCH:
|
|
|
|
|
case Rol_DEG_ADM:
|
|
|
|
|
case Rol_CTR_ADM:
|
|
|
|
|
case Rol_INS_ADM:
|
|
|
|
|
switch (MeOrOther)
|
|
|
|
|
{
|
|
|
|
|
case Usr_ME:
|
|
|
|
|
ICanViewResult =
|
|
|
|
|
ICanViewScore = ItsMe;
|
|
|
|
|
break;
|
|
|
|
|
case Usr_OTHER:
|
|
|
|
|
ICanViewResult =
|
|
|
|
|
ICanViewScore = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ICanViewResult =
|
|
|
|
|
ICanViewScore = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Rol_SYS_ADM:
|
|
|
|
|
ICanViewResult =
|
|
|
|
|
ICanViewScore = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ICanViewResult =
|
|
|
|
|
ICanViewScore = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ICanViewResult) // I am allowed to view this match result
|
|
|
|
|
{
|
|
|
|
|
/***** Get questions and user's answers of the match result from database *****/
|
2019-09-30 01:26:19 +02:00
|
|
|
|
McR_GetMatchResultQuestionsFromDB (Match.MchCod,UsrDat->UsrCod,
|
2019-09-28 02:31:42 +02:00
|
|
|
|
&NumQsts,&NumQstsNotBlank);
|
|
|
|
|
|
2019-10-26 02:19:42 +02:00
|
|
|
|
/***** Begin box *****/
|
2019-12-08 15:03:40 +01:00
|
|
|
|
Box_BoxBegin (NULL,Match.Title,NULL,
|
2019-09-28 02:31:42 +02:00
|
|
|
|
Hlp_ASSESSMENT_Games_results,Box_NOT_CLOSABLE);
|
|
|
|
|
Lay_WriteHeaderClassPhoto (false,false,
|
|
|
|
|
Gbl.Hierarchy.Ins.InsCod,
|
|
|
|
|
Gbl.Hierarchy.Deg.DegCod,
|
|
|
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
|
|
|
|
|
2019-10-20 22:00:28 +02:00
|
|
|
|
/***** Begin table *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TABLE_BeginWideMarginPadding (10);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Header row *****/
|
|
|
|
|
/* Get data of the user who answer the match */
|
|
|
|
|
if (!Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (UsrDat,Usr_DONT_GET_PREFS))
|
2019-09-30 01:10:57 +02:00
|
|
|
|
Lay_ShowErrorAndExit (Txt_The_user_does_not_exist);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (!Usr_CheckIfICanViewTst (UsrDat))
|
2019-10-26 01:56:36 +02:00
|
|
|
|
Lay_NoPermissionExit ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/* User */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_Begin (NULL);
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N RT\"");
|
2019-11-11 10:59:24 +01:00
|
|
|
|
HTM_TxtF ("%s:",Txt_ROLES_SINGUL_Abc[UsrDat->Roles.InCurrentCrs.Role][UsrDat->Sex]);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT LT\"");
|
2019-09-28 02:31:42 +02:00
|
|
|
|
ID_WriteUsrIDs (UsrDat,NULL);
|
2019-11-11 10:59:24 +01:00
|
|
|
|
HTM_TxtF (" %s",UsrDat->Surname1);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (UsrDat->Surname2[0])
|
2019-11-11 10:59:24 +01:00
|
|
|
|
HTM_TxtF (" %s",UsrDat->Surname2);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (UsrDat->FirstName[0])
|
2019-11-11 00:15:44 +01:00
|
|
|
|
HTM_TxtF (", %s",UsrDat->FirstName);
|
2019-11-09 21:08:20 +01:00
|
|
|
|
HTM_BR ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (UsrDat,PhotoURL);
|
|
|
|
|
Pho_ShowUsrPhoto (UsrDat,ShowPhoto ? PhotoURL :
|
|
|
|
|
NULL,
|
|
|
|
|
"PHOTO45x60",Pho_ZOOM,false);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/* Start/end time (for user in this match) */
|
2019-12-15 20:02:34 +01:00
|
|
|
|
for (StartEndTime = (Dat_StartEndTime_t) 0;
|
2019-09-28 02:31:42 +02:00
|
|
|
|
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
|
|
|
|
|
StartEndTime++)
|
2019-10-04 14:42:59 +02:00
|
|
|
|
{
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_Begin (NULL);
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N RT\"");
|
2019-11-11 10:59:24 +01:00
|
|
|
|
HTM_TxtF ("%s:",Txt_START_END_TIME[StartEndTime]);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-11-01 22:53:39 +01:00
|
|
|
|
if (asprintf (&Id,"match_%u",(unsigned) StartEndTime) < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
HTM_TD_Begin ("id=\"%s\" class=\"DAT LT\"",Id);
|
2019-11-01 23:35:55 +01:00
|
|
|
|
Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC[StartEndTime],
|
2019-11-02 12:10:58 +01:00
|
|
|
|
Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA,
|
2019-11-02 11:45:41 +01:00
|
|
|
|
true,true,true,0x7);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-11-06 19:45:20 +01:00
|
|
|
|
free (Id);
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_End ();
|
2019-10-04 14:42:59 +02:00
|
|
|
|
}
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/* Number of questions */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_Begin (NULL);
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N RT\"");
|
2019-11-11 10:59:24 +01:00
|
|
|
|
HTM_TxtF ("%s:",Txt_Questions);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT LT\"");
|
2019-11-11 00:15:44 +01:00
|
|
|
|
HTM_TxtF ("%u (%u %s)",NumQsts,NumQstsNotBlank,Txt_non_blank_QUESTIONS);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/* Score */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_Begin (NULL);
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N RT\"");
|
2019-11-11 10:59:24 +01:00
|
|
|
|
HTM_TxtF ("%s:",Txt_Score);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT LT\"");
|
2019-09-28 02:31:42 +02:00
|
|
|
|
if (ICanViewScore)
|
2019-12-14 13:35:35 +01:00
|
|
|
|
HTM_Double2Decimals (TotalScore);
|
2019-11-28 09:45:32 +01:00
|
|
|
|
else
|
|
|
|
|
HTM_Txt ("?"); // No feedback
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
|
|
|
|
|
/* Grade */
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N RT\"");
|
|
|
|
|
HTM_TxtF ("%s:",Txt_Grade);
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"DAT LT\"");
|
|
|
|
|
if (ICanViewScore)
|
|
|
|
|
Tst_ComputeAndShowGrade (NumQsts,TotalScore,Game.MaxGrade);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
else
|
2019-11-28 09:12:34 +01:00
|
|
|
|
HTM_Txt ("?"); // No feedback
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/* Tags present in this result */
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_Begin (NULL);
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT_N RT\"");
|
2019-11-11 10:59:24 +01:00
|
|
|
|
HTM_TxtF ("%s:",Txt_Tags);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"DAT LT\"");
|
2019-09-28 02:31:42 +02:00
|
|
|
|
Gam_ShowTstTagsPresentInAGame (Match.GamCod);
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TD_End ();
|
2019-10-07 17:36:41 +02:00
|
|
|
|
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TR_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Write answers and solutions *****/
|
|
|
|
|
Tst_ShowTestResult (UsrDat,NumQsts,TimeUTC[Dat_START_TIME]);
|
|
|
|
|
|
|
|
|
|
/***** End table *****/
|
2019-10-23 19:05:05 +02:00
|
|
|
|
HTM_TABLE_End ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** Write total mark of match result *****/
|
|
|
|
|
if (ICanViewScore)
|
2019-11-28 09:12:34 +01:00
|
|
|
|
{
|
2019-11-28 09:45:32 +01:00
|
|
|
|
HTM_DIV_Begin ("class=\"DAT_N_BOLD CM\"");
|
2019-11-28 09:12:34 +01:00
|
|
|
|
HTM_TxtF ("%s: ",Txt_Score);
|
2019-12-14 13:35:35 +01:00
|
|
|
|
HTM_Double2Decimals (TotalScore);
|
2019-11-28 09:45:32 +01:00
|
|
|
|
HTM_BR ();
|
|
|
|
|
HTM_TxtF ("%s: ",Txt_Grade);
|
|
|
|
|
Tst_ComputeAndShowGrade (NumQsts,TotalScore,Game.MaxGrade);
|
2019-11-28 09:12:34 +01:00
|
|
|
|
HTM_DIV_End ();
|
|
|
|
|
}
|
2019-09-28 02:31:42 +02:00
|
|
|
|
|
|
|
|
|
/***** End box *****/
|
2019-10-25 22:48:34 +02:00
|
|
|
|
Box_BoxEnd ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
}
|
|
|
|
|
else // I am not allowed to view this match result
|
2019-10-26 01:56:36 +02:00
|
|
|
|
Lay_NoPermissionExit ();
|
2019-09-28 02:31:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************ Get the questions of a match result from database **************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-09-30 01:26:19 +02:00
|
|
|
|
void McR_GetMatchResultQuestionsFromDB (long MchCod,long UsrCod,
|
2019-09-28 02:31:42 +02:00
|
|
|
|
unsigned *NumQsts,unsigned *NumQstsNotBlank)
|
|
|
|
|
{
|
|
|
|
|
MYSQL_RES *mysql_res;
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
unsigned NumQst;
|
|
|
|
|
long LongNum;
|
|
|
|
|
unsigned QstInd;
|
|
|
|
|
struct Mch_UsrAnswer UsrAnswer;
|
|
|
|
|
|
|
|
|
|
/***** Get questions and answers of a match result *****/
|
|
|
|
|
*NumQsts = (unsigned)
|
|
|
|
|
DB_QuerySELECT (&mysql_res,"can not get questions and answers"
|
|
|
|
|
" of a match result",
|
|
|
|
|
"SELECT gam_questions.QstCod," // row[0]
|
|
|
|
|
"gam_questions.QstInd," // row[1]
|
|
|
|
|
"mch_indexes.Indexes" // row[2]
|
|
|
|
|
" FROM mch_matches,gam_questions,mch_indexes"
|
|
|
|
|
" WHERE mch_matches.MchCod=%ld"
|
|
|
|
|
" AND mch_matches.GamCod=gam_questions.GamCod"
|
|
|
|
|
" AND mch_matches.MchCod=mch_indexes.MchCod"
|
|
|
|
|
" AND gam_questions.QstInd=mch_indexes.QstInd"
|
|
|
|
|
" ORDER BY gam_questions.QstInd",
|
|
|
|
|
MchCod);
|
|
|
|
|
for (NumQst = 0, *NumQstsNotBlank = 0;
|
|
|
|
|
NumQst < *NumQsts;
|
|
|
|
|
NumQst++)
|
|
|
|
|
{
|
|
|
|
|
row = mysql_fetch_row (mysql_res);
|
|
|
|
|
|
|
|
|
|
/* Get question code (row[0]) */
|
|
|
|
|
if ((Gbl.Test.QstCodes[NumQst] = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
|
|
|
|
Lay_ShowErrorAndExit ("Wrong code of question.");
|
|
|
|
|
|
|
|
|
|
/* Get question index (row[1]) */
|
|
|
|
|
if ((LongNum = Str_ConvertStrCodToLongCod (row[1])) < 0)
|
|
|
|
|
Lay_ShowErrorAndExit ("Wrong code of question.");
|
|
|
|
|
QstInd = (unsigned) LongNum;
|
|
|
|
|
|
|
|
|
|
/* Get indexes for this question (row[2]) */
|
|
|
|
|
Str_Copy (Gbl.Test.StrIndexesOneQst[NumQst],row[2],
|
|
|
|
|
Tst_MAX_BYTES_INDEXES_ONE_QST);
|
|
|
|
|
|
|
|
|
|
/* Get answers selected by user for this question */
|
|
|
|
|
Mch_GetQstAnsFromDB (MchCod,UsrCod,QstInd,&UsrAnswer);
|
|
|
|
|
if (UsrAnswer.AnsInd >= 0) // UsrAnswer.AnsInd >= 0 ==> answer selected
|
|
|
|
|
{
|
|
|
|
|
snprintf (Gbl.Test.StrAnswersOneQst[NumQst],Tst_MAX_BYTES_ANSWERS_ONE_QST + 1,
|
|
|
|
|
"%d",UsrAnswer.AnsInd);
|
|
|
|
|
(*NumQstsNotBlank)++;
|
|
|
|
|
}
|
|
|
|
|
else // UsrAnswer.AnsInd < 0 ==> no answer selected
|
|
|
|
|
Gbl.Test.StrAnswersOneQst[NumQst][0] = '\0'; // Empty answer
|
|
|
|
|
|
|
|
|
|
/* Replace each comma by a separator of multiple parameters */
|
|
|
|
|
/* In database commas are used as separators instead of special chars */
|
|
|
|
|
Par_ReplaceCommaBySeparatorMultiple (Gbl.Test.StrIndexesOneQst[NumQst]);
|
|
|
|
|
Par_ReplaceCommaBySeparatorMultiple (Gbl.Test.StrAnswersOneQst[NumQst]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************* Get data of a match result using its match code ***************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-09-30 01:26:19 +02:00
|
|
|
|
static void McR_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
|
2019-09-28 02:31:42 +02:00
|
|
|
|
time_t TimeUTC[Dat_NUM_START_END_TIME],
|
|
|
|
|
unsigned *NumQsts,
|
|
|
|
|
unsigned *NumQstsNotBlank,
|
|
|
|
|
double *Score)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
MchCod,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++)
|
|
|
|
|
TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[StartEndTime]);
|
|
|
|
|
|
|
|
|
|
/* Get number of questions (row[2]) */
|
|
|
|
|
if (sscanf (row[2],"%u",NumQsts) != 1)
|
|
|
|
|
*NumQsts = 0;
|
|
|
|
|
|
|
|
|
|
/* Get number of questions not blank (row[3]) */
|
|
|
|
|
if (sscanf (row[3],"%u",NumQstsNotBlank) != 1)
|
|
|
|
|
*NumQstsNotBlank = 0;
|
|
|
|
|
|
|
|
|
|
/* Get score (row[4]) */
|
|
|
|
|
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
|
2019-11-28 00:19:42 +01:00
|
|
|
|
if (sscanf (row[4],"%lg",Score) != 1)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
*Score = 0.0;
|
|
|
|
|
Str_SetDecimalPointToLocal (); // Return to local system
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********************* Get if I can see match result ************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-09-30 01:26:19 +02:00
|
|
|
|
static bool McR_CheckIfICanSeeMatchResult (long MchCod,long UsrCod)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
{
|
|
|
|
|
bool ItsMe;
|
|
|
|
|
bool ShowResultThisMatch;
|
|
|
|
|
|
|
|
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
|
|
|
{
|
|
|
|
|
case Rol_STD:
|
|
|
|
|
ItsMe = Usr_ItsMe (UsrCod);
|
|
|
|
|
if (ItsMe && Gbl.Test.Config.Feedback != Tst_FEEDBACK_NOTHING)
|
2019-09-30 01:26:19 +02:00
|
|
|
|
ShowResultThisMatch = McR_GetVisibilityMchResultFromDB (MchCod);
|
2019-09-28 02:31:42 +02:00
|
|
|
|
else
|
|
|
|
|
ShowResultThisMatch = false;
|
|
|
|
|
break;
|
|
|
|
|
case Rol_NET:
|
|
|
|
|
case Rol_TCH:
|
|
|
|
|
case Rol_DEG_ADM:
|
|
|
|
|
case Rol_CTR_ADM:
|
|
|
|
|
case Rol_INS_ADM:
|
|
|
|
|
case Rol_SYS_ADM:
|
|
|
|
|
ShowResultThisMatch = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ShowResultThisMatch = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ShowResultThisMatch;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********************* Get visibility of match result ************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-09-30 01:26:19 +02:00
|
|
|
|
static bool McR_GetVisibilityMchResultFromDB (long MchCod)
|
2019-09-28 02:31:42 +02:00
|
|
|
|
{
|
|
|
|
|
MYSQL_RES *mysql_res;
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
unsigned long NumRows;
|
|
|
|
|
bool ShowUsrResults;
|
|
|
|
|
|
|
|
|
|
/***** Get visibility of match result from database *****/
|
|
|
|
|
NumRows = (unsigned) DB_QuerySELECT (&mysql_res,"can not get if show result",
|
|
|
|
|
"SELECT ShowUsrResults" // row[0]
|
|
|
|
|
" FROM mch_matches"
|
|
|
|
|
" WHERE MchCod=%ld"
|
|
|
|
|
" AND GamCod IN" // Extra check
|
|
|
|
|
" (SELECT GamCod FROM gam_games"
|
|
|
|
|
" WHERE CrsCod='%ld')",
|
|
|
|
|
MchCod,
|
|
|
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
|
|
|
|
if (NumRows) // Match found...
|
|
|
|
|
{
|
|
|
|
|
/* Get whether to show user results or not (row(0)) */
|
|
|
|
|
row = mysql_fetch_row (mysql_res);
|
|
|
|
|
ShowUsrResults = (row[0][0] == 'Y');
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
ShowUsrResults = false;
|
|
|
|
|
|
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
|
|
|
|
|
|
return ShowUsrResults;
|
|
|
|
|
}
|