Version19.145

This commit is contained in:
Antonio Cañas Vargas 2020-03-07 00:14:35 +01:00
parent 68b1949a42
commit ebf73792a5
6 changed files with 200 additions and 134 deletions

View File

@ -497,7 +497,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.144.3 (2020-03-06)"
#define Log_PLATFORM_VERSION "SWAD 19.145 (2020-03-07)"
#define CSS_FILE "swad19.144.1.css"
#define JS_FILE "swad19.91.1.js"
/*
@ -524,14 +524,10 @@ Param
// TODO: Miguel Damas: al principio de los exámenes tendría que poner cuánto resta cada pregunta
// TODO: Si el alumno ha marcado "Permitir que los profesores...", entonces pedir confirmación al pulsar el botón azul, para evitar que se envíe por error antes de tiempo
// TODO: Oresti Baños: cambiar ojos por candados en descriptores para prohibir/permitir y dejar los ojos para poder elegir descriptores
// TODO: Comprobar los resultados de partidas de juegos con preguntas eliminadas
// TODO: URGENTE: Reportado por Eva Martínez Ortigosa
Sea un juego tiene dos preguntas: 1 y 2
Se elimina la pregunta 1 de los test ==> ahora no sale la pregunta 1 al editar el juego
==> DEBERÍA SALIR el número 1 indicando que la pregunta no existe
Al intentar jugar una partida y pasar por la pregunta 1 ==> Ahora se cuelga
==> DEBERÍA SALIR un mensaje de que la pregunta no existe
Version 19.145: Mar 07, 2020 Fixed bug in log.
Fixed bug in matches, reported by Eva Martínez Ortigosa. (282346 lines)
Version 19.144.3: Mar 06, 2020 New social network: twitch. (282286 lines)
2 changes necessary in database:
ALTER TABLE usr_webs CHANGE Web Web ENUM('www', '500px', 'delicious', 'deviantart', 'diaspora', 'edmodo', 'facebook', 'flickr', 'foursquare', 'github', 'gnusocial', 'googleplus', 'googlescholar', 'identica', 'instagram', 'linkedin', 'orcid', 'paperli', 'pinterest', 'researchgate', 'researcherid', 'scoopit', 'slideshare', 'stackoverflow', 'storify', 'tumblr', 'twitch', 'twitter', 'wikipedia', 'youtube') NOT NULL;

View File

@ -4140,7 +4140,7 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat,
}
else // Not me
{
/* Now he/she doesn't belong to current course */
/* Now he/she does not belong to current course */
UsrDat->Accepted = false;
UsrDat->Roles.InCurrentCrs.Role = Rol_USR;
UsrDat->Roles.InCurrentCrs.Valid = false;

View File

@ -151,6 +151,7 @@ static void Gam_ListGameQuestions (struct Game *Game);
static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
MYSQL_RES *mysql_res,
bool ICanEditQuestions);
static void Gam_ListQuestionForEdition (const char *StrQstInd);
static void Gam_PutIconToAddNewQuestions (void);
static void Gam_PutButtonToAddNewQuestions (void);
@ -1746,7 +1747,7 @@ unsigned Gam_GetNextQuestionIndexInGame (long GamCod,unsigned QstInd)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NextQstInd = 0;
unsigned NextQstInd = Mch_AFTER_LAST_QUESTION; // End of questions has been reached
/***** Get next question index in a game from database *****/
// Although indexes are always continuous...
@ -1784,18 +1785,14 @@ static void Gam_ListGameQuestions (struct Game *Game)
bool ICanEditQuestions = Gam_CheckIfEditable (Game);
/***** Get data of questions from database *****/
NumQsts = (unsigned) DB_QuerySELECT (&mysql_res,"can not get data of a question",
"SELECT gam_questions.QstInd," // row[0]
"gam_questions.QstCod," // row[1]
"tst_questions.AnsType," // row[2]
"tst_questions.Stem," // row[3]
"tst_questions.Feedback," // row[4]
"tst_questions.MedCod" // row[5]
" FROM gam_questions,tst_questions"
" WHERE gam_questions.GamCod=%ld"
" AND gam_questions.QstCod=tst_questions.QstCod"
" ORDER BY gam_questions.QstInd",
Game->GamCod);
NumQsts = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get game questions",
"SELECT QstInd," // row[0]
"QstCod" // row[1]
" FROM gam_questions"
" WHERE GamCod=%ld"
" ORDER BY QstInd",
Game->GamCod);
/***** Begin box *****/
Gam_SetCurrentGamCod (Game->GamCod); // Used to pass parameter
@ -1837,7 +1834,6 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
extern const char *Txt_Move_up_X;
extern const char *Txt_Move_down_X;
extern const char *Txt_Movement_not_allowed;
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
unsigned NumQst;
MYSQL_ROW row;
unsigned QstInd;
@ -1871,10 +1867,6 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
/*
row[0] QstInd
row[1] QstCod
row[2] AnsType
row[3] Stem
row[4] Feedback
row[5] MedCod
*/
/***** Create test question *****/
Tst_QstConstructor ();
@ -1937,52 +1929,9 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
HTM_TD_End ();
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
/***** Question *****/
Gam_ListQuestionForEdition (StrQstInd);
/* Write number of question */
HTM_DIV_Begin ("class=\"BIG_INDEX\"");
HTM_Txt (StrQstInd);
HTM_DIV_End ();
/* Write answer type (row[2]) */
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[2]);
HTM_DIV_Begin ("class=\"DAT_SMALL\"");
HTM_Txt (Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]);
HTM_DIV_End ();
HTM_TD_End ();
/* Write question code */
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
HTM_TxtF ("%ld ",Gbl.Test.QstCod);
HTM_TD_End ();
/* Write the question tags */
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
Tst_GetAndWriteTagsQst (Gbl.Test.QstCod);
HTM_TD_End ();
/* Write stem (row[3]) */
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
Tst_WriteQstStem (row[3],"TEST_EDI",
true); // Visible
/* Get media (row[5]) */
Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
Med_GetMediaDataByCod (&Gbl.Test.Media);
/* Show media */
Med_ShowMedia (&Gbl.Test.Media,
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
"TEST_MED_EDIT_LIST_STEM");
/* Show feedback (row[4]) */
Tst_WriteQstFeedback (row[4],"TEST_EDI_LIGHT");
/* Show answers */
Tst_WriteAnswersEdit (Gbl.Test.QstCod);
HTM_TD_End ();
HTM_TR_End ();
/***** Destroy test question *****/
@ -1993,6 +1942,104 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
HTM_TABLE_End ();
}
/*****************************************************************************/
/********************** List game question for edition ***********************/
/*****************************************************************************/
static void Gam_ListQuestionForEdition (const char *StrQstInd)
{
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
extern const char *Txt_Question_removed;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
bool QstExists;
/***** Get question from database *****/
QstExists = Tst_GetOneQuestionByCod (Gbl.Test.QstCod,&mysql_res); // Question exists?
if (QstExists)
{
/***** Get row of the result of the query *****/
row = mysql_fetch_row (mysql_res);
/*
row[0] QstCod
row[1] UNIX_TIMESTAMP(EditTime)
row[2] AnsType
row[3] Shuffle
row[4] Stem
row[5] Feedback
row[6] MedCod
row[7] NumHits
row[8] NumHitsNotBlank
row[9] Score
*/
}
/***** Number of question and answer type *****/
HTM_TD_Begin ("class=\"RT COLOR%u\"",Gbl.RowEvenOdd);
/* Write number of question */
HTM_DIV_Begin ("class=\"BIG_INDEX\"");
HTM_Txt (StrQstInd);
HTM_DIV_End ();
/* Write answer type (row[2]) */
HTM_DIV_Begin ("class=\"DAT_SMALL\"");
if (QstExists)
{
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[2]);
HTM_Txt (Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]);
}
HTM_DIV_End ();
HTM_TD_End ();
/***** Write question code *****/
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
HTM_TxtF ("%ld ",Gbl.Test.QstCod);
HTM_TD_End ();
/***** Write the question tags *****/
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
if (QstExists)
Tst_GetAndWriteTagsQst (Gbl.Test.QstCod);
HTM_TD_End ();
/***** Write stem and media (row[4]) *****/
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
if (QstExists)
{
/* Write stem */
Tst_WriteQstStem (row[4],"TEST_EDI",
true); // Visible
/* Get media (row[6]) */
Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[6]);
Med_GetMediaDataByCod (&Gbl.Test.Media);
/* Show media */
Med_ShowMedia (&Gbl.Test.Media,
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
"TEST_MED_EDIT_LIST_STEM");
/* Show feedback (row[5]) */
Tst_WriteQstFeedback (row[5],"TEST_EDI_LIGHT");
/* Show answers */
Tst_WriteAnswersEdit (Gbl.Test.QstCod);
}
else
{
HTM_SPAN_Begin ("class=\"DAT_LIGHT\"");
HTM_Txt (Txt_Question_removed);
HTM_SPAN_End ();
}
HTM_TD_End ();
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/***************** Put icon to add a new questions to game *******************/
/*****************************************************************************/

View File

@ -25,6 +25,8 @@
/*********************************** Headers *********************************/
/*****************************************************************************/
#include <string.h> // For strlen
#include "swad_action.h"
#include "swad_config.h"
#include "swad_database.h"
@ -71,6 +73,8 @@ void Log_LogAccess (const char *Comments)
{
long LogCod;
long ActCod = Act_GetActCod (Gbl.Action.Act);
size_t MaxLength;
char *CommentsDB;
Rol_Role_t RoleToStore = (Gbl.Action.Act == ActLogOut) ? Gbl.Usrs.Me.Role.LoggedBeforeCloseSession :
Gbl.Usrs.Me.Role.Logged;
@ -118,12 +122,23 @@ void Log_LogAccess (const char *Comments)
/* Log comments */
if (Comments)
DB_QueryINSERT ("can not log access (comments)",
"INSERT INTO log_comments"
" (LogCod,Comments)"
" VALUES"
" (%ld,'%s')",
LogCod,Comments);
{
MaxLength = strlen (Comments) * Str_MAX_BYTES_PER_CHAR;
if ((CommentsDB = (char *) malloc (MaxLength + 1)) != NULL)
{
Str_Copy (CommentsDB,Comments,
MaxLength);
Str_ChangeFormat (Str_FROM_TEXT,Str_TO_TEXT,
CommentsDB,MaxLength,true); // Avoid SQL injection
DB_QueryINSERT ("can not log access (comments)",
"INSERT INTO log_comments"
" (LogCod,Comments)"
" VALUES"
" (%ld,'%s')",
LogCod,CommentsDB);
free (CommentsDB);
}
}
/* Log search string */
if (Gbl.Search.LogSearch && Gbl.Search.Str[0])

View File

@ -2852,6 +2852,7 @@ static void Mch_ShowMatchTitle (const struct Match *Match)
static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match)
{
extern const char *Txt_MATCH_Paused;
extern const char *Txt_Question_removed;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
@ -2866,64 +2867,69 @@ static void Mch_ShowQuestionAndAnswersTch (const struct Match *Match)
}
/***** Get data of question from database *****/
if (!DB_QuerySELECT (&mysql_res,"can not get data of a question",
"SELECT AnsType," // row[0]
"Stem," // row[1]
"MedCod" // row[2]
" FROM tst_questions"
" WHERE QstCod=%ld",
Match->Status.QstCod))
Ale_ShowAlert (Ale_ERROR,"Question doesn't exist.");
row = mysql_fetch_row (mysql_res);
/***** Show question *****/
/* Get answer type (row[0]) */
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
if (Gbl.Test.AnswerType != Tst_ANS_UNIQUE_CHOICE)
Lay_ShowErrorAndExit ("Wrong answer type.");
HTM_DIV_Begin ("class=\"MCH_BOTTOM\""); // Bottom
/* Write stem (row[1]) */
Tst_WriteQstStem (row[1],"MCH_TCH_STEM",
true); // Visible
/* Get media (row[2]) */
Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[2]);
Med_GetMediaDataByCod (&Gbl.Test.Media);
/* Show media */
Med_ShowMedia (&Gbl.Test.Media,
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
"TEST_MED_EDIT_LIST_STEM");
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
/***** Write answers? *****/
switch (Match->Status.Showing)
if (DB_QuerySELECT (&mysql_res,"can not get data of a question",
"SELECT AnsType," // row[0]
"Stem," // row[1]
"MedCod" // row[2]
" FROM tst_questions"
" WHERE QstCod=%ld",
Match->Status.QstCod))
{
case Mch_ANSWERS:
if (Match->Status.Playing) // Match is being played
/* Write answers */
row = mysql_fetch_row (mysql_res);
/***** Show question *****/
/* Get answer type (row[0]) */
Gbl.Test.AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[0]);
if (Gbl.Test.AnswerType != Tst_ANS_UNIQUE_CHOICE)
Lay_ShowErrorAndExit ("Wrong answer type.");
/* Begin container */
HTM_DIV_Begin ("class=\"MCH_BOTTOM\""); // Bottom
/* Write stem (row[1]) */
Tst_WriteQstStem (row[1],"MCH_TCH_STEM",
true); // Visible
/* Get media (row[2]) */
Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[2]);
Med_GetMediaDataByCod (&Gbl.Test.Media);
/* Show media */
Med_ShowMedia (&Gbl.Test.Media,
"TEST_MED_EDIT_LIST_STEM_CONTAINER",
"TEST_MED_EDIT_LIST_STEM");
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
/***** Write answers? *****/
switch (Match->Status.Showing)
{
case Mch_ANSWERS:
if (Match->Status.Playing) // Match is being played
/* Write answers */
Mch_WriteAnswersMatchResult (Match,
"MCH_TCH_ANS",
false); // Don't show result
else // Match is paused, not being played
Mch_ShowWaitImage (Txt_MATCH_Paused);
break;
case Mch_RESULTS:
/* Write answers with results */
Mch_WriteAnswersMatchResult (Match,
"MCH_TCH_ANS",
false); // Don't show result
else // Match is paused, not being played
Mch_ShowWaitImage (Txt_MATCH_Paused);
break;
case Mch_RESULTS:
/* Write answers with results */
Mch_WriteAnswersMatchResult (Match,
"MCH_TCH_ANS",
true); // Show result
break;
default:
/* Don't write anything */
break;
}
true); // Show result
break;
default:
/* Don't write anything */
break;
}
HTM_DIV_End (); // Bottom
/* End container */
HTM_DIV_End (); // Bottom
}
else
Ale_ShowAlert (Ale_WARNING,Txt_Question_removed);
}
/*****************************************************************************/

View File

@ -1616,7 +1616,9 @@ static unsigned long Tst_GetEnabledTagsFromThisCrs (MYSQL_RES **mysql_res)
{
/***** Get available not hidden tags from database *****/
return DB_QuerySELECT (mysql_res,"can not get available enabled tags",
"SELECT TagCod,TagTxt FROM tst_tags"
"SELECT TagCod," // row[0]
"TagTxt" // row[1]
" FROM tst_tags"
" WHERE CrsCod=%ld AND TagHidden='N'"
" ORDER BY TagTxt",
Gbl.Hierarchy.Crs.CrsCod);
@ -6552,7 +6554,7 @@ void Tst_RemoveQst (void)
Gbl.Test.QstCod,Gbl.Hierarchy.Crs.CrsCod);
if (!mysql_affected_rows (&Gbl.mysql))
Lay_ShowErrorAndExit ("The question to be removed does not exist or belongs to another course.");
Lay_ShowErrorAndExit ("Wrong question.");
/***** Write message *****/
Ale_ShowAlert (Ale_SUCCESS,Txt_Question_removed);