Version19.254.1

This commit is contained in:
acanas 2020-06-23 11:48:06 +02:00
parent e6c064c90f
commit b797c3ff17
5 changed files with 86 additions and 92 deletions

View File

@ -556,7 +556,7 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
En OpenSWAD:
ps2pdf source.ps destination.pdf
*/
#define Log_PLATFORM_VERSION "SWAD 19.254 (2020-06-22)"
#define Log_PLATFORM_VERSION "SWAD 19.254.1 (2020-06-23)"
#define CSS_FILE "swad19.253.css"
#define JS_FILE "swad19.254.js"
/*
@ -566,9 +566,9 @@ TODO: Fix bug: Un estudiante recibe una notificaci
TODO: Fix bug: Cuando se pulsa en ver fichas, y luego en una ficha en "Ver trabajos" o "Ver exámenes", o lo que sea, sale dos veces ese estudiante.
TODO: No limitar el número de preguntas en un examen a ExaPrn_MAX_QUESTIONS_PER_EXAM_PRINT, sino asignar PrintedQuestions dinámicamente con malloc
TODO: Que al generar un examen sólo se cojan preguntas válidas. Y si ya está generado, al entrar de nuevo, que se vean en rojo.
TODO: Refactorizar MchRes_CheckIfICanSeeMatchResult y MchRes_CheckIfICanViewScore uniéndolas en una función como ExaRes_CheckIfICanSeePrintResult
Y dentro de las funciones TstPrn_ShowUsrPrints y TstPrn_ShowOnePrint crear y llamar a una función común similar a ExaRes_CheckIfICanSeePrintResult
TODO: Dentro de las funciones TstPrn_ShowUsrPrints y TstPrn_ShowOnePrint crear y llamar a una función común similar a ExaRes_CheckIfICanSeePrintResult
Version 19.254.1: Jun 23, 2020 Code refactoring in matches results. (303646 lines)
Version 19.254: Jun 22, 2020 Fixed bug in Javascript related to quotes. Reported by Laura García Rejón. (303653 lines)
Version 19.253: Jun 22, 2020 More details in listing of exams. (303643 lines)
Version 19.252.1: Jun 19, 2020 Changes in listing of exams and matches results. (303245 lines)

View File

@ -1643,7 +1643,7 @@ static void ExaRes_CheckIfICanSeePrintResult (const struct Exa_Exam *Exam,
{
bool ItsMe;
/***** Check if I can view this print result *****/
/***** Check if I can view print result and score *****/
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_STD:

View File

@ -925,6 +925,13 @@ void Gam_GetListSelectedGamCods (struct Gam_Games *Games)
long GamCod;
char LongStr[Cns_MAX_DECIMAL_DIGITS_LONG + 1];
/***** Default selected *****/
Games->NumSelected = 0;
/***** Trivial check: there are games visibles by me *****/
if (!Games->Num)
return;
/***** Allocate memory for list of games selected *****/
MaxSizeListGamCodsSelected = Games->Num * (Cns_MAX_DECIMAL_DIGITS_LONG + 1);
if ((Games->GamCodsSelected = (char *) malloc (MaxSizeListGamCodsSelected + 1)) == NULL)
@ -941,7 +948,6 @@ void Gam_GetListSelectedGamCods (struct Gam_Games *Games)
NumGame < Games->Num;
NumGame++)
Games->Lst[NumGame].Selected = false;
Games->NumSelected = 0;
/* Set some games as selected */
for (Ptr = Games->GamCodsSelected;

View File

@ -59,6 +59,12 @@ extern struct Globals Gbl;
/******************************* Private types *******************************/
/*****************************************************************************/
struct MchRes_ICanView
{
bool Result;
bool Score;
};
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
@ -105,8 +111,10 @@ static void MchRes_ShowMchResultsSummaryRow (unsigned NumResults,
static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
struct TstPrn_Print *Print);
static bool MchRes_CheckIfICanSeeMatchResult (struct Mch_Match *Match,long UsrCod);
static bool MchRes_CheckIfICanViewScore (bool ICanViewResult,unsigned Visibility);
static void MchRes_CheckIfICanSeeMatchResult (const struct Gam_Game *Game,
const struct Mch_Match *Match,
long UsrCod,
struct MchRes_ICanView *ICanView);
/*****************************************************************************/
/*********** Compute score and create/update my result in a match ************/
@ -799,16 +807,17 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
extern const char *Txt_Result;
char *MchSubQuery;
char *GamSubQuery;
char *HidGamSubQuery;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
struct UsrData *UsrDat;
bool ICanViewResult;
bool ICanViewScore;
struct MchRes_ICanView ICanView;
unsigned NumResults;
unsigned NumResult;
static unsigned UniqueId = 0;
char *Id;
struct Mch_Match Match;
struct Gam_Game Game;
Dat_StartEndTime_t StartEndTime;
unsigned NumQstsInThisResult;
unsigned NumQstsNotBlankInThisResult;
@ -816,10 +825,8 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
unsigned NumTotalQstsNotBlank = 0;
double ScoreInThisResult;
double TotalScoreOfAllResults = 0.0;
double MaxGrade;
double Grade;
double TotalGrade = 0.0;
unsigned Visibility;
time_t TimeUTC[Dat_NUM_START_END_TIME];
/***** Reset match *****/
@ -867,6 +874,22 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
Lay_NotEnoughMemoryExit ();
}
/***** Subquery: get hidden games?
· A student will not be able to see their results in hidden games
· A teacher will be able to see results from other users even in hidden games
*****/
switch (MeOrOther)
{
case Usr_ME: // A student watching her/his results
if (asprintf (&HidGamSubQuery," AND gam_games.Hidden='N'") < 0)
Lay_NotEnoughMemoryExit ();
break;
default: // A teacher/admin watching the results of other users
if (asprintf (&HidGamSubQuery,"%s","") < 0)
Lay_NotEnoughMemoryExit ();
break;
}
/***** Make database query *****/
NumResults =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get matches results",
@ -875,21 +898,22 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
"UNIX_TIMESTAMP(mch_results.EndTime)," // row[2]
"mch_results.NumQsts," // row[3]
"mch_results.NumQstsNotBlank," // row[4]
"mch_results.Score," // row[5]
"gam_games.MaxGrade," // row[6]
"gam_games.Visibility" // row[7]
"mch_results.Score" // row[5]
" FROM mch_results,mch_matches,gam_games"
" WHERE mch_results.UsrCod=%ld"
"%s" // Match subquery
" AND mch_results.MchCod=mch_matches.MchCod"
"%s" // Games subquery
" AND mch_matches.GamCod=gam_games.GamCod"
"%s" // Hidden games subquery
" AND gam_games.CrsCod=%ld" // Extra check
" ORDER BY mch_matches.Title",
UsrDat->UsrCod,
MchSubQuery,
GamSubQuery,
HidGamSubQuery,
Gbl.Hierarchy.Crs.CrsCod);
free (HidGamSubQuery);
free (GamSubQuery);
free (MchSubQuery);
@ -911,12 +935,13 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
Lay_ShowErrorAndExit ("Wrong code of match.");
Mch_GetDataOfMatchByCod (&Match);
/* Get visibility (row[7]) */
Visibility = TstVis_GetVisibilityFromStr (row[7]);
/* Get data of match and game */
Mch_GetDataOfMatchByCod (&Match);
Game.GamCod = Match.GamCod;
Gam_GetDataOfGameByCod (&Game);
/* Show match result? */
ICanViewResult = MchRes_CheckIfICanSeeMatchResult (&Match,UsrDat->UsrCod);
ICanViewScore = MchRes_CheckIfICanViewScore (ICanViewResult,Visibility);
/* Check if I can view this match result and score */
MchRes_CheckIfICanSeeMatchResult (&Game,&Match,UsrDat->UsrCod,&ICanView);
if (NumResult)
HTM_TR_Begin (NULL);
@ -944,7 +969,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
HTM_Txt (Match.Title);
HTM_TD_End ();
if (ICanViewScore)
if (ICanView.Score)
{
/* Get number of questions (row[3]) */
if (sscanf (row[3],"%u",&NumQstsInThisResult) != 1)
@ -963,16 +988,12 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
ScoreInThisResult = 0.0;
TotalScoreOfAllResults += ScoreInThisResult;
/* Get maximum grade (row[6]) */
if (sscanf (row[6],"%lf",&MaxGrade) != 1)
MaxGrade = 0.0;
Str_SetDecimalPointToLocal (); // Return to local system
}
/* Write number of questions */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanViewScore)
if (ICanView.Score)
HTM_Unsigned (NumQstsInThisResult);
else
Ico_PutIconNotVisible ();
@ -980,7 +1001,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/* Write number of questions not blank */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanViewScore)
if (ICanView.Score)
HTM_Unsigned (NumQstsNotBlankInThisResult);
else
Ico_PutIconNotVisible ();
@ -988,7 +1009,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/* Write score */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanViewScore)
if (ICanView.Score)
{
HTM_Double2Decimals (ScoreInThisResult);
HTM_Txt ("/");
@ -1000,7 +1021,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/* Write average score per question */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanViewScore)
if (ICanView.Score)
HTM_Double2Decimals (NumQstsInThisResult ? ScoreInThisResult /
(double) NumQstsInThisResult :
0.0);
@ -1010,10 +1031,10 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/* Write grade over maximum grade */
HTM_TD_Begin ("class=\"DAT RT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanViewScore)
if (ICanView.Score)
{
Grade = TstPrn_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,MaxGrade);
TstPrn_ShowGrade (Grade,MaxGrade);
Grade = TstPrn_ComputeGrade (NumQstsInThisResult,ScoreInThisResult,Game.MaxGrade);
TstPrn_ShowGrade (Grade,Game.MaxGrade);
TotalGrade += Grade;
}
else
@ -1022,7 +1043,7 @@ static void MchRes_ShowMchResults (struct Gam_Games *Games,
/* Link to show this result */
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
if (ICanViewResult)
if (ICanView.Result)
{
Games->GamCod = Match.GamCod;
Games->MchCod = Match.MchCod;
@ -1151,8 +1172,7 @@ void MchRes_ShowOneMchResult (void)
struct TstPrn_Print Print;
bool ShowPhoto;
char PhotoURL[PATH_MAX + 1];
bool ICanViewResult;
bool ICanViewScore;
struct MchRes_ICanView ICanView;
/***** Reset games context *****/
Gam_ResetGames (&Games);
@ -1183,35 +1203,10 @@ void MchRes_ShowOneMchResult (void)
TstPrn_ResetPrint (&Print);
MchRes_GetMatchResultDataByMchCod (Match.MchCod,UsrDat->UsrCod,&Print);
/***** Check if I can view this match result *****/
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_STD:
// Depends on visibility of result for this match (eye icon)
ICanViewResult = MchRes_CheckIfICanSeeMatchResult (&Match,UsrDat->UsrCod);
/***** Check if I can view this match result and score *****/
MchRes_CheckIfICanSeeMatchResult (&Game,&Match,UsrDat->UsrCod,&ICanView);
if (ICanViewResult)
// Depends on 5 visibility icons
ICanViewScore = TstVis_IsVisibleTotalScore (Game.Visibility);
else
ICanViewScore = false;
break;
case Rol_NET:
case Rol_TCH:
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
ICanViewResult =
ICanViewScore = true;
break;
default:
ICanViewResult =
ICanViewScore = false;
break;
}
if (ICanViewResult) // I am allowed to view this match result
if (ICanView.Result) // I am allowed to view this match result
{
/***** Get questions and user's answers of the match result from database *****/
Mch_GetMatchQuestionsFromDB (Match.MchCod,UsrDat->UsrCod,&Print);
@ -1315,7 +1310,7 @@ void MchRes_ShowOneMchResult (void)
HTM_TD_End ();
HTM_TD_Begin ("class=\"DAT LB\"");
if (ICanViewScore)
if (ICanView.Score)
{
HTM_STRONG_Begin ();
HTM_Double2Decimals (Print.Score);
@ -1337,7 +1332,7 @@ void MchRes_ShowOneMchResult (void)
HTM_TD_End ();
HTM_TD_Begin ("class=\"DAT LB\"");
if (ICanViewScore)
if (ICanView.Score)
{
HTM_STRONG_Begin ();
TstPrn_ComputeAndShowGrade (Print.NumQsts,Print.Score,Game.MaxGrade);
@ -1440,41 +1435,30 @@ static void MchRes_GetMatchResultDataByMchCod (long MchCod,long UsrCod,
/********************** Get if I can see match result ************************/
/*****************************************************************************/
static bool MchRes_CheckIfICanSeeMatchResult (struct Mch_Match *Match,long UsrCod)
static void MchRes_CheckIfICanSeeMatchResult (const struct Gam_Game *Game,
const struct Mch_Match *Match,
long UsrCod,
struct MchRes_ICanView *ICanView)
{
bool ItsMe;
/***** Check if I can view print result and score *****/
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_STD:
// Depends on visibility of game and result (eye icons)
ItsMe = Usr_ItsMe (UsrCod);
return ItsMe && Match->Status.ShowUsrResults;
ICanView->Result = (ItsMe && // The result is mine
!Game->Hidden && // The game is visible
Match->Status.ShowUsrResults); // The results of the match are visible to users
// Whether I belong or not to groups of match is not checked here...
// ...because I should be able to see old matches made in old groups to which I belonged
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 MchRes_CheckIfICanViewScore (bool ICanViewResult,unsigned Visibility)
{
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_STD:
if (ICanViewResult)
return TstVis_IsVisibleTotalScore (Visibility);
return false;
if (ICanView->Result)
// Depends on 5 visibility icons associated to game
ICanView->Score = TstVis_IsVisibleTotalScore (Game->Visibility);
else
ICanView->Score = false;
break;
case Rol_NET:
case Rol_TCH:
@ -1482,8 +1466,12 @@ static bool MchRes_CheckIfICanViewScore (bool ICanViewResult,unsigned Visibility
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
return true;
ICanView->Result =
ICanView->Score = true;
break;
default:
return false;
ICanView->Result =
ICanView->Score = false;
break;
}
}

View File

@ -30889,7 +30889,7 @@ const char *Txt_Please_check_your_email_address =
#elif L==4 // es
"Por favor, compruebe su direcci&oacute;n de correo.";
#elif L==5 // fr
"S'il vous pla&iacute;t, v&eaxcute;rifiez votre adresse email.";
"S'il vous pla&iacute;t, v&eacute;rifiez votre adresse email.";
#elif L==6 // gn
"Por favor, compruebe su direcci&oacute;n de correo."; // Okoteve traducción
#elif L==7 // it