Version19.127

This commit is contained in:
Antonio Cañas Vargas 2020-02-18 15:40:04 +01:00
parent 1b1316360e
commit eb39b1c58d
12 changed files with 267 additions and 162 deletions

View File

@ -4470,15 +4470,18 @@ int swad__getGames (struct soap *soap,
"MIN(mch_matches.StartTime) AS StartTime," // row[2] "MIN(mch_matches.StartTime) AS StartTime," // row[2]
"MAX(mch_matches.EndTime) AS EndTime," // row[3] "MAX(mch_matches.EndTime) AS EndTime," // row[3]
"gam_games.MaxGrade," // row[4] "gam_games.MaxGrade," // row[4]
"gam_games.Title," // row[5] "gam_games.Visibility," // row[5]
"gam_games.Txt" // row[6] "gam_games.Title," // row[6]
"gam_games.Txt" // row[7]
" FROM gam_games" " FROM gam_games"
" LEFT JOIN mch_matches" " LEFT JOIN mch_matches"
" ON gam_games.GamCod=mch_matches.GamCod" " ON gam_games.GamCod=mch_matches.GamCod"
" WHERE gam_games.CrsCod=%ld" " WHERE gam_games.CrsCod=%ld"
" AND Hidden='N'" " AND Hidden='N'"
" GROUP BY gam_games.GamCod" " GROUP BY gam_games.GamCod"
" ORDER BY StartTime DESC,EndTime DESC,gam_games.Title DESC", " ORDER BY StartTime DESC,"
"EndTime DESC,"
"gam_games.Title DESC",
Gbl.Hierarchy.Crs.CrsCod); Gbl.Hierarchy.Crs.CrsCod);
getGamesOut->gamesArray.__size = getGamesOut->gamesArray.__size =
getGamesOut->numGames = (int) NumRows; getGamesOut->numGames = (int) NumRows;
@ -4560,18 +4563,22 @@ int swad__getGames (struct soap *soap,
if (getGamesOut->gamesArray.__ptr[NumGame].maxGrade < 0.0) // Only positive values allowed if (getGamesOut->gamesArray.__ptr[NumGame].maxGrade < 0.0) // Only positive values allowed
getGamesOut->gamesArray.__ptr[NumGame].maxGrade = 0.0; getGamesOut->gamesArray.__ptr[NumGame].maxGrade = 0.0;
/* Get title of the game (row[5]) */ /* Get visibility (row[5]) */
Length = strlen (row[5]); // TODO: Get visibility
// getGamesOut->gamesArray.__ptr[NumGame].Visibility = TsV_GetVisibilityFromStr (row[5]);
/* Get title of the game (row[6]) */
Length = strlen (row[6]);
getGamesOut->gamesArray.__ptr[NumGame].title = getGamesOut->gamesArray.__ptr[NumGame].title =
(char *) soap_malloc (Gbl.soap,Length + 1); (char *) soap_malloc (Gbl.soap,Length + 1);
Str_Copy (getGamesOut->gamesArray.__ptr[NumGame].title,row[5], Str_Copy (getGamesOut->gamesArray.__ptr[NumGame].title,row[6],
Length); Length);
/* Get Txt (row[6]) */ /* Get Txt (row[7]) */
Length = strlen (row[6]); Length = strlen (row[7]);
getGamesOut->gamesArray.__ptr[NumGame].text = getGamesOut->gamesArray.__ptr[NumGame].text =
(char *) soap_malloc (Gbl.soap,Length + 1); (char *) soap_malloc (Gbl.soap,Length + 1);
Str_Copy (getGamesOut->gamesArray.__ptr[NumGame].text,row[6], Str_Copy (getGamesOut->gamesArray.__ptr[NumGame].text,row[7],
Length); Length);
} }
} }

View File

@ -501,14 +501,32 @@ ps2pdf source.ps destination.pdf
#define CSS_FILE "swad19.118.css" #define CSS_FILE "swad19.118.css"
#define JS_FILE "swad19.91.1.js" #define JS_FILE "swad19.91.1.js"
/* /*
*
// TODO: Geolocalización:
* Función API
sendLocation
Parámetros: string con ubicación (ej. "Aula 0.1")
Poblar base de datos:
En Usuarios > Ubicación aparecería un botón pequeño de "Añadir ubicación". Se preguntaría a SWAD a través de una función de la API
si el usuario tiene permiso para añadir ubicaciones. Si es así, se llamaría a la función:
sendPoint
Paramétros: MAC, string con ubicación (ej. "Aula 0.1")
*
// TODO: Hacer un nuevo rol en los TFG: tutor externo (profesor de áreas no vinculadas con el centro, profesionales de empresas, etc.) // TODO: Hacer un nuevo rol en los TFG: tutor externo (profesor de áreas no vinculadas con el centro, profesionales de empresas, etc.)
// TODO: Impedir la creación y edición de proyectos si no son editables. // TODO: Impedir la creación y edición de proyectos si no son editables.
// TODO: No se puede entrar con DNI '1' suponiendo que no tenga password ¿por qué? // TODO: No se puede entrar con DNI '1' suponiendo que no tenga password ¿por qué?
// TODO: En la lista de conectados central, poner el logo de la institución a la que pertenece el usuario // TODO: En la lista de conectados central, poner el logo de la institución a la que pertenece el usuario
// TODO: Add visibility to API function getTestConfig // TODO: Add visibility to API function getTestConfig
// TODO: Add visibility to games // TODO: Get visibility IN API function getGames
// TODO: Sugerencia de Jesús González Peñalver: añadir un poco más de espacio entre pregunta y pregunta en las opciones de un juego // TODO: Sugerencia de Jesús González Peñalver: añadir un poco más de espacio entre pregunta y pregunta en las opciones de un juego
Version 19.127: Feb 18, 2020 Form to define visibility of match results in games. (279103 lines)
2 changes necessary in database:
ALTER TABLE gam_games ADD COLUMN Visibility INT NOT NULL DEFAULT 0x1f AFTER MaxGrade;
UPDATE gam_games,tst_config SET gam_games.Visibility=tst_config.Visibility WHERE gam_games.CrsCod=tst_config.CrsCod;
Version 19.126: Feb 18, 2020 New module swad_test_visibility for visibility of test results. (279013 lines) Version 19.126: Feb 18, 2020 New module swad_test_visibility for visibility of test results. (279013 lines)
Version 19.125.4: Feb 17, 2020 Changes in visibility of answers. (278930 lines) Version 19.125.4: Feb 17, 2020 Changes in visibility of answers. (278930 lines)
Version 19.125.3: Feb 17, 2020 Changes in visibility of question stem. (278898 lines) Version 19.125.3: Feb 17, 2020 Changes in visibility of question stem. (278898 lines)

View File

@ -1332,6 +1332,7 @@ mysql> DESCRIBE gam_games;
"Hidden ENUM('N','Y') NOT NULL DEFAULT 'N'," "Hidden ENUM('N','Y') NOT NULL DEFAULT 'N',"
"UsrCod INT NOT NULL," "UsrCod INT NOT NULL,"
"MaxGrade DOUBLE PRECISION NOT NULL DEFAULT 1," // Scale from score [0...num.answers] to grade [0...MaxGrade] "MaxGrade DOUBLE PRECISION NOT NULL DEFAULT 1," // Scale from score [0...num.answers] to grade [0...MaxGrade]
"Visibility INT NOT NULL DEFAULT 0x1f,"
"Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE "Title VARCHAR(2047) NOT NULL," // Gam_MAX_BYTES_TITLE
"Txt TEXT NOT NULL," // Cns_MAX_BYTES_TEXT "Txt TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
"UNIQUE INDEX(GamCod)," "UNIQUE INDEX(GamCod),"

View File

@ -43,6 +43,7 @@
#include "swad_pagination.h" #include "swad_pagination.h"
#include "swad_role.h" #include "swad_role.h"
#include "swad_test.h" #include "swad_test.h"
#include "swad_test_visibility.h"
/*****************************************************************************/ /*****************************************************************************/
/************** External global variables from others modules ****************/ /************** External global variables from others modules ****************/
@ -433,8 +434,9 @@ void Gam_ShowOnlyOneGameEnd (void)
static void Gam_ShowOneGame (struct Game *Game,bool ShowOnlyThisGame) static void Gam_ShowOneGame (struct Game *Game,bool ShowOnlyThisGame)
{ {
extern const char *Txt_View_game; extern const char *Txt_View_game;
extern const char *Txt_Maximum_grade;
extern const char *Txt_No_of_questions; extern const char *Txt_No_of_questions;
extern const char *Txt_Maximum_grade;
extern const char *Txt_Result_visibility;
extern const char *Txt_Matches; extern const char *Txt_Matches;
char *Anchor = NULL; char *Anchor = NULL;
static unsigned UniqueId = 0; static unsigned UniqueId = 0;
@ -513,7 +515,7 @@ static void Gam_ShowOneGame (struct Game *Game,bool ShowOnlyThisGame)
Frm_EndForm (); Frm_EndForm ();
HTM_ARTICLE_End (); HTM_ARTICLE_End ();
/* Number of questions and maximum grade */ /* Number of questions, maximum grade, visibility of results */
HTM_DIV_Begin ("class=\"%s\"",Game->Hidden ? "ASG_GRP_LIGHT" : HTM_DIV_Begin ("class=\"%s\"",Game->Hidden ? "ASG_GRP_LIGHT" :
"ASG_GRP"); "ASG_GRP");
HTM_TxtColonNBSP (Txt_No_of_questions); HTM_TxtColonNBSP (Txt_No_of_questions);
@ -521,10 +523,17 @@ static void Gam_ShowOneGame (struct Game *Game,bool ShowOnlyThisGame)
HTM_BR (); HTM_BR ();
HTM_TxtColonNBSP (Txt_Maximum_grade); HTM_TxtColonNBSP (Txt_Maximum_grade);
HTM_Double (Game->MaxGrade); HTM_Double (Game->MaxGrade);
if (ShowOnlyThisGame)
{
HTM_BR ();
HTM_TxtColonNBSP (Txt_Result_visibility);
HTM_BR ();
TsV_ShowVisibility (Game->Visibility,
Game->Hidden ? "ASG_GRP_LIGHT" :
"ASG_GRP");
}
HTM_DIV_End (); HTM_DIV_End ();
HTM_TD_End ();
/***** Number of matches in game *****/ /***** Number of matches in game *****/
if (ShowOnlyThisGame) if (ShowOnlyThisGame)
HTM_TD_Begin ("class=\"RT\""); HTM_TD_Begin ("class=\"RT\"");
@ -899,7 +908,8 @@ void Gam_GetDataOfGameByCod (struct Game *Game)
"gam_games.Hidden," // row[2] "gam_games.Hidden," // row[2]
"gam_games.UsrCod," // row[3] "gam_games.UsrCod," // row[3]
"gam_games.MaxGrade," // row[4] "gam_games.MaxGrade," // row[4]
"gam_games.Title" // row[5] "gam_games.Visibility," // row[5]
"gam_games.Title" // row[6]
" FROM gam_games" " FROM gam_games"
" LEFT JOIN mch_matches" " LEFT JOIN mch_matches"
" ON gam_games.GamCod=mch_matches.GamCod" " ON gam_games.GamCod=mch_matches.GamCod"
@ -927,8 +937,11 @@ void Gam_GetDataOfGameByCod (struct Game *Game)
if (Game->MaxGrade < 0.0) // Only positive values allowed if (Game->MaxGrade < 0.0) // Only positive values allowed
Game->MaxGrade = 0.0; Game->MaxGrade = 0.0;
/* Get the title of the game (row[5]) */ /* Get visibility (row[5]) */
Str_Copy (Game->Title,row[5], Game->Visibility = TsV_GetVisibilityFromStr (row[5]);
/* Get the title of the game (row[6]) */
Str_Copy (Game->Title,row[6],
Gam_MAX_BYTES_TITLE); Gam_MAX_BYTES_TITLE);
/* Get number of questions */ /* Get number of questions */
@ -989,6 +1002,7 @@ static void Gam_ResetGame (struct Game *Game)
Game->CrsCod = -1L; Game->CrsCod = -1L;
Game->UsrCod = -1L; Game->UsrCod = -1L;
Game->MaxGrade = Gam_MAX_GRADE_DEFAULT; Game->MaxGrade = Gam_MAX_GRADE_DEFAULT;
Game->Visibility = TsV_VISIBILITY_DEFAULT;
Game->TimeUTC[Dat_START_TIME] = (time_t) 0; Game->TimeUTC[Dat_START_TIME] = (time_t) 0;
Game->TimeUTC[Dat_END_TIME ] = (time_t) 0; Game->TimeUTC[Dat_END_TIME ] = (time_t) 0;
Game->Title[0] = '\0'; Game->Title[0] = '\0';
@ -1254,6 +1268,7 @@ static void Gam_PutFormsEditionGame (struct Game *Game,bool ItsANewGame)
extern const char *Txt_Edit_game; extern const char *Txt_Edit_game;
extern const char *Txt_Title; extern const char *Txt_Title;
extern const char *Txt_Maximum_grade; extern const char *Txt_Maximum_grade;
extern const char *Txt_Result_visibility;
extern const char *Txt_Description; extern const char *Txt_Description;
extern const char *Txt_Create_game; extern const char *Txt_Create_game;
extern const char *Txt_Save_changes; extern const char *Txt_Save_changes;
@ -1316,6 +1331,19 @@ static void Gam_PutFormsEditionGame (struct Game *Game,bool ItsANewGame)
HTM_TR_End (); HTM_TR_End ();
/***** Visibility of results *****/
HTM_TR_Begin (NULL);
HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
HTM_TxtF ("%s:",Txt_Result_visibility);
HTM_TD_End ();
HTM_TD_Begin ("class=\"LB\"");
TsV_PutVisibilityCheckboxes (Game->Visibility);
HTM_TD_End ();
HTM_TR_End ();
/***** Game text *****/ /***** Game text *****/
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
@ -1378,6 +1406,9 @@ void Gam_RecFormGame (void)
if (Game.MaxGrade < 0.0) // Only positive values allowed if (Game.MaxGrade < 0.0) // Only positive values allowed
Game.MaxGrade = 0.0; Game.MaxGrade = 0.0;
/***** Get visibility from form *****/
Game.Visibility = TsV_GetVisibilityFromForm ();
/***** Get game text and insert links *****/ /***** Get game text and insert links *****/
Par_GetParToHTML ("Txt",Txt,Cns_MAX_BYTES_TEXT); // Store in HTML format (not rigorous) Par_GetParToHTML ("Txt",Txt,Cns_MAX_BYTES_TEXT); // Store in HTML format (not rigorous)
@ -1432,12 +1463,13 @@ static void Gam_CreateGame (struct Game *Game,const char *Txt)
Game->GamCod = Game->GamCod =
DB_QueryINSERTandReturnCode ("can not create new game", DB_QueryINSERTandReturnCode ("can not create new game",
"INSERT INTO gam_games" "INSERT INTO gam_games"
" (CrsCod,Hidden,UsrCod,MaxGrade,Title,Txt)" " (CrsCod,Hidden,UsrCod,MaxGrade,Visibility,Title,Txt)"
" VALUES" " VALUES"
" (%ld,'N',%ld,%.15lg,'%s','%s')", " (%ld,'N',%ld,%.15lg,%u,'%s','%s')",
Gbl.Hierarchy.Crs.CrsCod, Gbl.Hierarchy.Crs.CrsCod,
Gbl.Usrs.Me.UsrDat.UsrCod, Gbl.Usrs.Me.UsrDat.UsrCod,
Game->MaxGrade, Game->MaxGrade,
Game->Visibility,
Game->Title, Game->Title,
Txt); Txt);
Str_SetDecimalPointToLocal (); // Return to local system Str_SetDecimalPointToLocal (); // Return to local system
@ -1461,11 +1493,13 @@ static void Gam_UpdateGame (struct Game *Game,const char *Txt)
"UPDATE gam_games" "UPDATE gam_games"
" SET CrsCod=%ld," " SET CrsCod=%ld,"
"MaxGrade=%.15lg," "MaxGrade=%.15lg,"
"Visibility=%u,"
"Title='%s'," "Title='%s',"
"Txt='%s'" "Txt='%s'"
" WHERE GamCod=%ld", " WHERE GamCod=%ld",
Gbl.Hierarchy.Crs.CrsCod, Gbl.Hierarchy.Crs.CrsCod,
Game->MaxGrade, Game->MaxGrade,
Game->Visibility,
Game->Title, Game->Title,
Txt, Txt,
Game->GamCod); Game->GamCod);

View File

@ -51,6 +51,7 @@ struct Game
double MaxGrade; // Score range [0...max.score] double MaxGrade; // Score range [0...max.score]
// will be converted to // will be converted to
// grade range [0...max.grade] // grade range [0...max.grade]
unsigned Visibility; // Visibility of results
char Title[Gam_MAX_BYTES_TITLE + 1]; char Title[Gam_MAX_BYTES_TITLE + 1];
time_t TimeUTC[Dat_NUM_START_END_TIME]; time_t TimeUTC[Dat_NUM_START_END_TIME];
bool Hidden; // Game is hidden bool Hidden; // Game is hidden

View File

@ -100,8 +100,8 @@ static void McR_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
unsigned *NumQstsNotBlank, unsigned *NumQstsNotBlank,
double *Score); double *Score);
static bool McR_CheckIfICanSeeMatchResult (long MchCod,long UsrCod); static bool McR_CheckIfICanSeeMatchResult (struct Match *Match,long UsrCod);
static bool McR_GetVisibilityMchResultFromDB (long MchCod); static bool McR_CheckIfICanViewScore (bool ICanViewResult,unsigned Visibility);
/*****************************************************************************/ /*****************************************************************************/
/*********** Select users and dates to show their matches results ************/ /*********** Select users and dates to show their matches results ************/
@ -668,8 +668,8 @@ static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
struct UsrData *UsrDat; struct UsrData *UsrDat;
bool ShowResultThisMatch; bool ICanViewResult;
bool ShowSummaryResults = true; bool ICanViewScore;
unsigned NumResults; unsigned NumResults;
unsigned NumResult; unsigned NumResult;
static unsigned UniqueId = 0; static unsigned UniqueId = 0;
@ -685,6 +685,7 @@ static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
double MaxGrade; double MaxGrade;
double Grade; double Grade;
double TotalGrade = 0.0; double TotalGrade = 0.0;
unsigned Visibility;
time_t TimeUTC[Dat_NUM_START_END_TIME]; time_t TimeUTC[Dat_NUM_START_END_TIME];
/***** Set user *****/ /***** Set user *****/
@ -738,7 +739,8 @@ static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
"mch_results.NumQsts," // row[3] "mch_results.NumQsts," // row[3]
"mch_results.NumQstsNotBlank," // row[4] "mch_results.NumQstsNotBlank," // row[4]
"mch_results.Score," // row[5] "mch_results.Score," // row[5]
"gam_games.MaxGrade" // row[6] "gam_games.MaxGrade," // row[6]
"gam_games.Visibility" // row[7]
" FROM mch_results,mch_matches,gam_games" " FROM mch_results,mch_matches,gam_games"
" WHERE mch_results.UsrCod=%ld" " WHERE mch_results.UsrCod=%ld"
"%s" // Match subquery "%s" // Match subquery
@ -772,9 +774,12 @@ static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
Lay_ShowErrorAndExit ("Wrong code of match."); Lay_ShowErrorAndExit ("Wrong code of match.");
Mch_GetDataOfMatchByCod (&Match); Mch_GetDataOfMatchByCod (&Match);
/* Get visibility (row[7]) */
Visibility = TsV_GetVisibilityFromStr (row[7]);
/* Show match result? */ /* Show match result? */
ShowResultThisMatch = McR_CheckIfICanSeeMatchResult (Match.MchCod,UsrDat->UsrCod); ICanViewResult = McR_CheckIfICanSeeMatchResult (&Match,UsrDat->UsrCod);
ShowSummaryResults = ShowSummaryResults && ShowResultThisMatch; ICanViewScore = McR_CheckIfICanViewScore (ICanViewResult,Visibility);
if (NumResult) if (NumResult)
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
@ -802,7 +807,7 @@ static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
HTM_Txt (Match.Title); HTM_Txt (Match.Title);
HTM_TD_End (); HTM_TD_End ();
if (ShowResultThisMatch) if (ICanViewResult)
{ {
/* Get number of questions (row[3]) */ /* Get number of questions (row[3]) */
if (sscanf (row[3],"%u",&NumQstsInThisResult) != 1) if (sscanf (row[3],"%u",&NumQstsInThisResult) != 1)
@ -830,7 +835,7 @@ static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
/* Write number of questions */ /* Write number of questions */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ShowResultThisMatch) if (ICanViewResult)
HTM_Unsigned (NumQstsInThisResult); HTM_Unsigned (NumQstsInThisResult);
else else
Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results); Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results);
@ -838,7 +843,7 @@ static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
/* Write number of questions not blank */ /* Write number of questions not blank */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ShowResultThisMatch) if (ICanViewResult)
HTM_Unsigned (NumQstsNotBlankInThisResult); HTM_Unsigned (NumQstsNotBlankInThisResult);
else else
Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results); Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results);
@ -846,7 +851,7 @@ static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
/* Write score */ /* Write score */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ShowResultThisMatch) if (ICanViewScore)
HTM_Double2Decimals (ScoreInThisResult); HTM_Double2Decimals (ScoreInThisResult);
else else
Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results); Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results);
@ -854,17 +859,17 @@ static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
/* Write average score per question */ /* Write average score per question */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ShowResultThisMatch) if (ICanViewScore)
HTM_Double2Decimals (NumQstsInThisResult ? ScoreInThisResult / HTM_Double2Decimals (NumQstsInThisResult ? ScoreInThisResult /
(double) NumQstsInThisResult : (double) NumQstsInThisResult :
0.0); 0.0);
else else
Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results); Ico_PutIconOff ("eye-slash.svg",Txt_Hidden_results);
HTM_TD_End (); HTM_TD_End ();
/* Write grade over maximum grade */ /* Write grade over maximum grade */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ShowResultThisMatch) if (ICanViewScore)
{ {
Grade = Tst_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,MaxGrade); Grade = Tst_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,MaxGrade);
Tst_ShowGrade (Grade,MaxGrade); Tst_ShowGrade (Grade,MaxGrade);
@ -876,7 +881,7 @@ static void McR_ShowMchResults (Usr_MeOrOther_t MeOrOther,
/* Link to show this result */ /* Link to show this result */
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd); HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
if (ShowResultThisMatch) if (ICanViewResult)
{ {
Gam_SetCurrentGamCod (Match.GamCod); // Used to pass parameter Gam_SetCurrentGamCod (Match.GamCod); // Used to pass parameter
Mch_SetCurrentMchCod (Match.MchCod); // Used to pass parameter Mch_SetCurrentMchCod (Match.MchCod); // Used to pass parameter
@ -1004,8 +1009,6 @@ void McR_ShowOneMchResult (void)
double TotalScore; double TotalScore;
bool ShowPhoto; bool ShowPhoto;
char PhotoURL[PATH_MAX + 1]; char PhotoURL[PATH_MAX + 1];
bool ItsMe;
bool ICanPlayThisMatchBasedOnGrps;
bool ICanViewResult; bool ICanViewResult;
bool ICanViewScore; bool ICanViewScore;
@ -1033,55 +1036,22 @@ void McR_ShowOneMchResult (void)
&NumQsts, &NumQsts,
&NumQstsNotBlank, &NumQstsNotBlank,
&TotalScore); &TotalScore);
Gbl.Test.Config.Visibility = TsV_MAX_VISIBILITY; // Initialize visibility to maximum
/***** Check if I can view this match result *****/ /***** Check if I can view this match result *****/
ItsMe = Usr_ItsMe (UsrDat->UsrCod);
switch (Gbl.Usrs.Me.Role.Logged) switch (Gbl.Usrs.Me.Role.Logged)
{ {
case Rol_STD: case Rol_STD:
switch (MeOrOther) ICanViewResult = McR_CheckIfICanSeeMatchResult (&Match,UsrDat->UsrCod);
{ if (ICanViewResult)
case Usr_ME: ICanViewScore = TsV_IsVisibleTotalScore (Game.Visibility);
ICanPlayThisMatchBasedOnGrps = Mch_CheckIfICanPlayThisMatchBasedOnGrps (&Match); else
ICanViewResult = ItsMe && ICanPlayThisMatchBasedOnGrps && ICanViewScore = false;
Match.Status.ShowUsrResults;
if (ICanViewResult)
{
Tst_GetConfigTstFromDB (); // To get feedback type
ICanViewScore = TsV_IsVisibleTotalScore (Gbl.Test.Config.Visibility);
}
else
ICanViewScore = false;
break;
default:
ICanViewResult =
ICanViewScore = false;
break;
}
break; break;
case Rol_NET: case Rol_NET:
case Rol_TCH: case Rol_TCH:
case Rol_DEG_ADM: case Rol_DEG_ADM:
case Rol_CTR_ADM: case Rol_CTR_ADM:
case Rol_INS_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: case Rol_SYS_ADM:
ICanViewResult = ICanViewResult =
ICanViewScore = true; ICanViewScore = true;
@ -1202,7 +1172,7 @@ void McR_ShowOneMchResult (void)
if (ICanViewScore) if (ICanViewScore)
Tst_ComputeAndShowGrade (NumQsts,TotalScore,Game.MaxGrade); Tst_ComputeAndShowGrade (NumQsts,TotalScore,Game.MaxGrade);
else else
HTM_Txt ("?"); // No feedback HTM_Txt ("?"); // Not visible
HTM_TD_End (); HTM_TD_End ();
HTM_TR_End (); HTM_TR_End ();
@ -1221,7 +1191,8 @@ void McR_ShowOneMchResult (void)
HTM_TR_End (); HTM_TR_End ();
/***** Write answers and solutions *****/ /***** Write answers and solutions *****/
TsR_ShowTestResult (UsrDat,NumQsts,TimeUTC[Dat_START_TIME]); TsR_ShowTestResult (UsrDat,NumQsts,TimeUTC[Dat_START_TIME],
Game.Visibility);
/***** End table *****/ /***** End table *****/
HTM_TABLE_End (); HTM_TABLE_End ();
@ -1372,22 +1343,44 @@ static void McR_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
} }
/*****************************************************************************/ /*****************************************************************************/
/********************* Get if I can see match result ************************/ /********************** Get if I can see match result ************************/
/*****************************************************************************/ /*****************************************************************************/
static bool McR_CheckIfICanSeeMatchResult (long MchCod,long UsrCod) static bool McR_CheckIfICanSeeMatchResult (struct Match *Match,long UsrCod)
{ {
bool ItsMe; bool ItsMe;
bool ShowResultThisMatch;
switch (Gbl.Usrs.Me.Role.Logged) switch (Gbl.Usrs.Me.Role.Logged)
{ {
case Rol_STD: case Rol_STD:
ItsMe = Usr_ItsMe (UsrCod); ItsMe = Usr_ItsMe (UsrCod);
if (ItsMe && Gbl.Test.Config.Visibility != 0) if (ItsMe && Match->Status.ShowUsrResults)
ShowResultThisMatch = McR_GetVisibilityMchResultFromDB (MchCod); return Mch_CheckIfICanPlayThisMatchBasedOnGrps (Match);
else return false;
ShowResultThisMatch = false; case Rol_NET:
case Rol_TCH:
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
return true;
default:
return false;
}
}
/*****************************************************************************/
/********************** Get if I can see match result ************************/
/*****************************************************************************/
static bool McR_CheckIfICanViewScore (bool ICanViewResult,unsigned Visibility)
{
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_STD:
if (ICanViewResult)
return TsV_IsVisibleTotalScore (Visibility);
return false;
break; break;
case Rol_NET: case Rol_NET:
case Rol_TCH: case Rol_TCH:
@ -1395,48 +1388,9 @@ static bool McR_CheckIfICanSeeMatchResult (long MchCod,long UsrCod)
case Rol_CTR_ADM: case Rol_CTR_ADM:
case Rol_INS_ADM: case Rol_INS_ADM:
case Rol_SYS_ADM: case Rol_SYS_ADM:
ShowResultThisMatch = true; return true;
break;
default: default:
ShowResultThisMatch = false; return false;
break;
} }
return ShowResultThisMatch;
} }
/*****************************************************************************/
/********************* Get visibility of match result ************************/
/*****************************************************************************/
static bool McR_GetVisibilityMchResultFromDB (long MchCod)
{
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;
}

View File

@ -1674,12 +1674,10 @@ static void Tst_ShowFormSelTags (unsigned long NumRows,MYSQL_RES *mysql_res,
{ {
TagHidden = (row[2][0] == 'Y'); TagHidden = (row[2][0] == 'Y');
HTM_TD_Begin ("class=\"LM\""); HTM_TD_Begin ("class=\"LM\"");
if (TagHidden) Ico_PutIconOff (TagHidden ? "eye-slash.svg" :
HTM_IMG (Cfg_URL_ICON_PUBLIC,"eye-slash.svg",Txt_Tag_not_allowed, "eye.svg",
"class=\"ICO_HIDDEN ICO16x16\""); TagHidden ? Txt_Tag_not_allowed :
else Txt_Tag_allowed);
HTM_IMG (Cfg_URL_ICON_PUBLIC,"eye.svg",Txt_Tag_allowed,
"class=\"ICO_HIDDEN ICO16x16\"");
HTM_TD_End (); HTM_TD_End ();
} }
@ -2018,7 +2016,6 @@ void Tst_GetConfigFromRow (MYSQL_ROW row)
{ {
int IntNum; int IntNum;
long LongNum; long LongNum;
unsigned UnsignedNum;
Tst_Pluggable_t Pluggable; Tst_Pluggable_t Pluggable;
/***** Get whether test are visible via plugins or not *****/ /***** Get whether test are visible via plugins or not *****/
@ -2060,8 +2057,7 @@ void Tst_GetConfigFromRow (MYSQL_ROW row)
(unsigned long) LongNum; (unsigned long) LongNum;
/***** Get visibility (row[5]) *****/ /***** Get visibility (row[5]) *****/
if (sscanf (row[5],"%u",&UnsignedNum) == 1) Gbl.Test.Config.Visibility = TsV_GetVisibilityFromStr (row[5]);
Gbl.Test.Config.Visibility = UnsignedNum & TsV_MAX_VISIBILITY;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -2154,7 +2150,7 @@ void Tst_ReceiveConfigTst (void)
ULONG_MAX, ULONG_MAX,
0); 0);
/***** Get type of feedback from form *****/ /***** Get visibility from form *****/
Gbl.Test.Config.Visibility = TsV_GetVisibilityFromForm (); Gbl.Test.Config.Visibility = TsV_GetVisibilityFromForm ();
/***** Update database *****/ /***** Update database *****/

View File

@ -774,7 +774,8 @@ void TsR_ShowOneTstResult (void)
/***** Write answers and solutions *****/ /***** Write answers and solutions *****/
TsR_ShowTestResult (&Gbl.Usrs.Other.UsrDat, TsR_ShowTestResult (&Gbl.Usrs.Other.UsrDat,
Gbl.Test.NumQsts,TstTimeUTC); Gbl.Test.NumQsts,TstTimeUTC,
Gbl.Test.Config.Visibility);
/***** End table *****/ /***** End table *****/
HTM_TABLE_End (); HTM_TABLE_End ();
@ -832,7 +833,8 @@ static void TsR_ShowTstTagsPresentInATestResult (long TstCod)
/*****************************************************************************/ /*****************************************************************************/
void TsR_ShowTestResult (struct UsrData *UsrDat, void TsR_ShowTestResult (struct UsrData *UsrDat,
unsigned NumQsts,time_t TstTimeUTC) unsigned NumQsts,time_t TstTimeUTC,
unsigned Visibility)
{ {
extern const char *Txt_Question_modified; extern const char *Txt_Question_modified;
extern const char *Txt_Question_removed; extern const char *Txt_Question_removed;
@ -900,7 +902,7 @@ void TsR_ShowTestResult (struct UsrData *UsrDat,
Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_RESULT, Tst_WriteQstAndAnsTest (Tst_SHOW_TEST_RESULT,
UsrDat, UsrDat,
NumQst,QstCod,row, NumQst,QstCod,row,
Gbl.Test.Config.Visibility, Visibility,
&ScoreThisQst, // Not used here &ScoreThisQst, // Not used here
&AnswerIsNotBlank); // Not used here &AnswerIsNotBlank); // Not used here
} }

View File

@ -52,7 +52,8 @@ void TsR_StoreScoreOfTestResultInDB (long TstCod,
void TsR_GetUsrsAndShowTstResults (void); void TsR_GetUsrsAndShowTstResults (void);
void TsR_ShowOneTstResult (void); void TsR_ShowOneTstResult (void);
void TsR_ShowTestResult (struct UsrData *UsrDat, void TsR_ShowTestResult (struct UsrData *UsrDat,
unsigned NumQsts,time_t TstTimeUTC); unsigned NumQsts,time_t TstTimeUTC,
unsigned Visibility);
void TsR_StoreOneTestResultQstInDB (long TstCod,long QstCod,unsigned NumQst,double Score); void TsR_StoreOneTestResultQstInDB (long TstCod,long QstCod,unsigned NumQst,double Score);
void TsR_RemoveTestResultsMadeByUsrInAllCrss (long UsrCod); void TsR_RemoveTestResultsMadeByUsrInAllCrss (long UsrCod);
void TsR_RemoveTestResultsMadeByUsrInCrs (long UsrCod,long CrsCod); void TsR_RemoveTestResultsMadeByUsrInCrs (long UsrCod,long CrsCod);

View File

@ -56,7 +56,60 @@ extern struct Globals Gbl;
/*****************************************************************************/ /*****************************************************************************/
/*****************************************************************************/ /*****************************************************************************/
/*********************** Get type of feedback from form **********************/ /************ Put checkboxes in form to select result visibility *************/
/*****************************************************************************/
void TsV_ShowVisibility (unsigned SelectedVisibility,const char *Class)
{
extern const char *Txt_Visible;
extern const char *Txt_Hidden;
extern const char *Txt_TST_STR_VISIBILITY[TsV_NUM_ITEMS_VISIBILITY];
TsV_Visibility_t Visibility;
bool ItemVisible;
for (Visibility = (TsV_Visibility_t) 0;
Visibility <= (TsV_Visibility_t) (TsV_NUM_ITEMS_VISIBILITY - 1);
Visibility++)
{
HTM_LABEL_Begin ("class=\"%s\"",Class);
ItemVisible = (SelectedVisibility & (1 << Visibility)) != 0;
Ico_PutIconOff (ItemVisible ? "eye.svg" :
"eye-slash.svg",
ItemVisible ? Txt_Visible :
Txt_Hidden);
HTM_Txt (Txt_TST_STR_VISIBILITY[Visibility]);
HTM_LABEL_End ();
HTM_BR ();
}
}
/*****************************************************************************/
/************ Put checkboxes in form to select result visibility *************/
/*****************************************************************************/
void TsV_PutVisibilityCheckboxes (unsigned SelectedVisibility)
{
extern const char *Txt_TST_STR_VISIBILITY[TsV_NUM_ITEMS_VISIBILITY];
TsV_Visibility_t Visibility;
for (Visibility = (TsV_Visibility_t) 0;
Visibility <= (TsV_Visibility_t) (TsV_NUM_ITEMS_VISIBILITY - 1);
Visibility++)
{
HTM_LABEL_Begin ("class=\"DAT\"");
HTM_INPUT_CHECKBOX ("Visibility",false,
"value=\"%u\"%s",
(unsigned) Visibility,
(SelectedVisibility & (1 << Visibility)) != 0 ? " checked=\"checked\"" :
"");
HTM_Txt (Txt_TST_STR_VISIBILITY[Visibility]);
HTM_LABEL_End ();
HTM_BR ();
}
}
/*****************************************************************************/
/************************** Get visibility from form *************************/
/*****************************************************************************/ /*****************************************************************************/
unsigned TsV_GetVisibilityFromForm (void) unsigned TsV_GetVisibilityFromForm (void)
@ -66,7 +119,7 @@ unsigned TsV_GetVisibilityFromForm (void)
const char *Ptr; const char *Ptr;
char UnsignedStr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char UnsignedStr[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
unsigned UnsignedNum; unsigned UnsignedNum;
TsV_ResultVisibility_t VisibilityItem; TsV_Visibility_t VisibilityItem;
unsigned Visibility = 0; // Nothing selected unsigned Visibility = 0; // Nothing selected
/***** Allocate memory for list of attendance events selected *****/ /***** Allocate memory for list of attendance events selected *****/
@ -88,7 +141,7 @@ unsigned TsV_GetVisibilityFromForm (void)
if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1) if (sscanf (UnsignedStr,"%u",&UnsignedNum) == 1)
if (UnsignedNum < TsV_NUM_ITEMS_VISIBILITY) if (UnsignedNum < TsV_NUM_ITEMS_VISIBILITY)
{ {
VisibilityItem = (TsV_ResultVisibility_t) UnsignedNum; VisibilityItem = (TsV_Visibility_t) UnsignedNum;
Visibility |= (1 << VisibilityItem); Visibility |= (1 << VisibilityItem);
} }
} }
@ -97,28 +150,21 @@ unsigned TsV_GetVisibilityFromForm (void)
} }
/*****************************************************************************/ /*****************************************************************************/
/************ Put checkboxes in form to select result visibility *************/ /************************** Get visibility from string *************************/
/*****************************************************************************/ /*****************************************************************************/
void TsV_PutVisibilityCheckboxes (unsigned SelectedVisibility) unsigned TsV_GetVisibilityFromStr (const char *Str)
{ {
extern const char *Txt_TST_STR_VISIBILITY[TsV_NUM_ITEMS_VISIBILITY]; unsigned UnsignedNum;
TsV_ResultVisibility_t Visibility; unsigned Visibility = TsV_MIN_VISIBILITY; // In nothing is read, return minimum visibility
for (Visibility = (TsV_ResultVisibility_t) 0; /***** Get visibility from string *****/
Visibility <= (TsV_ResultVisibility_t) (TsV_NUM_ITEMS_VISIBILITY - 1); if (Str)
Visibility++) if (Str[0])
{ if (sscanf (Str,"%u",&UnsignedNum) == 1)
HTM_LABEL_Begin ("class=\"DAT\""); Visibility = UnsignedNum & TsV_MAX_VISIBILITY;
HTM_INPUT_CHECKBOX ("Visibility",false,
"value=\"%u\"%s", return Visibility;
(unsigned) Visibility,
(SelectedVisibility & (1 << Visibility)) != 0 ? " checked=\"checked\"" :
"");
HTM_Txt (Txt_TST_STR_VISIBILITY[Visibility]);
HTM_LABEL_End ();
HTM_BR ();
}
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -45,7 +45,8 @@ typedef enum
TsV_VISIBLE_CORRECT_ANSWER = 2, // Correct answers TsV_VISIBLE_CORRECT_ANSWER = 2, // Correct answers
TsV_VISIBLE_EACH_QST_SCORE = 3, // Score of each question TsV_VISIBLE_EACH_QST_SCORE = 3, // Score of each question
TsV_VISIBLE_TOTAL_SCORE = 4, // Total score TsV_VISIBLE_TOTAL_SCORE = 4, // Total score
} TsV_ResultVisibility_t; } TsV_Visibility_t;
#define TsV_MIN_VISIBILITY 0 // Nothing visible
#define TsV_MAX_VISIBILITY ((1 << TsV_NUM_ITEMS_VISIBILITY) - 1) // All visible #define TsV_MAX_VISIBILITY ((1 << TsV_NUM_ITEMS_VISIBILITY) - 1) // All visible
#define TsV_VISIBILITY_DEFAULT TsV_MAX_VISIBILITY #define TsV_VISIBILITY_DEFAULT TsV_MAX_VISIBILITY
@ -53,8 +54,10 @@ typedef enum
/***************************** Public prototypes *****************************/ /***************************** Public prototypes *****************************/
/*****************************************************************************/ /*****************************************************************************/
unsigned TsV_GetVisibilityFromForm (void); void TsV_ShowVisibility (unsigned SelectedVisibility,const char *Class);
void TsV_PutVisibilityCheckboxes (unsigned SelectedVisibility); void TsV_PutVisibilityCheckboxes (unsigned SelectedVisibility);
unsigned TsV_GetVisibilityFromForm (void);
unsigned TsV_GetVisibilityFromStr (const char *Str);
bool TsV_IsVisibleQstAndAnsTxt (unsigned Visibility); bool TsV_IsVisibleQstAndAnsTxt (unsigned Visibility);
bool TsV_IsVisibleFeedbackTxt (unsigned Visibility); bool TsV_IsVisibleFeedbackTxt (unsigned Visibility);

View File

@ -14600,6 +14600,27 @@ const char *Txt_HELP_password =
"8 ou mais caracteres"; "8 ou mais caracteres";
#endif #endif
const char *Txt_Hidden =
#if L==1 // ca
"Ocult";
#elif L==2 // de
"Verborgen";
#elif L==3 // en
"Hidden";
#elif L==4 // es
"Oculto";
#elif L==5 // fr
"Cach&eacute;";
#elif L==6 // gn
"Oculto"; // Okoteve traducción
#elif L==7 // it
"Nascosto";
#elif L==8 // pl
"Ukryty";
#elif L==9 // pt
"Oculto";
#endif
const char *Txt_Hidden_MALE_PLURAL = const char *Txt_Hidden_MALE_PLURAL =
#if L==1 // ca #if L==1 // ca
"Ocultos"; // Necessita traduccio "Ocultos"; // Necessita traduccio
@ -53734,6 +53755,27 @@ const char *Txt_Result_visibility =
"Visibilidade dos resultados"; "Visibilidade dos resultados";
#endif #endif
const char *Txt_Visible =
#if L==1 // ca
"Visible";
#elif L==2 // de
"Sichtbare";
#elif L==3 // en
"Visible";
#elif L==4 // es
"Visible";
#elif L==5 // fr
"Visible";
#elif L==6 // gn
"Visible"; // Okoteve traducción
#elif L==7 // it
"Visibile";
#elif L==8 // pl
"Widoczny";
#elif L==9 // pt
"Vis&iacute;vel";
#endif
const char *Txt_Visible_by_BR_the_student = const char *Txt_Visible_by_BR_the_student =
#if L==1 // ca #if L==1 // ca
"&iquest;Visible por<br />el estudiante?"; // Necessita traduccio "&iquest;Visible por<br />el estudiante?"; // Necessita traduccio