mirror of https://github.com/acanas/swad-core.git
Version19.154
This commit is contained in:
parent
01f4e74c7f
commit
07ebc6aef4
|
@ -497,13 +497,13 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
|
|||
En OpenSWAD:
|
||||
ps2pdf source.ps destination.pdf
|
||||
*/
|
||||
#define Log_PLATFORM_VERSION "SWAD 19.153 (2020-03-24)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 19.154 (2020-03-25)"
|
||||
#define CSS_FILE "swad19.146.css"
|
||||
#define JS_FILE "swad19.153.js"
|
||||
/*
|
||||
*
|
||||
// TODO: Geolocalización:
|
||||
Función API sendLocation...
|
||||
Función API sendCurrentLocation...
|
||||
Parámetros: string con ubicación (ej. "Aula 0.1")
|
||||
|
||||
Poblar base de datos:
|
||||
|
@ -524,6 +524,7 @@ Param
|
|||
// TODO: Oresti Baños: cambiar ojos por candados en descriptores para prohibir/permitir y dejar los ojos para poder elegir descriptores
|
||||
// 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
|
||||
|
||||
Version 19.154: Mar 25, 2020 Code refactoring in tests. (283385 lines)
|
||||
Version 19.153: Mar 24, 2020 Code refactoring in tests. (283432 lines)
|
||||
Version 19.152.4: Mar 24, 2020 Code refactoring in tests. (283459 lines)
|
||||
Version 19.152.3: Mar 23, 2020 Code refactoring in tests. (283512 lines)
|
||||
|
|
27
swad_game.c
27
swad_game.c
|
@ -156,7 +156,8 @@ 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 (long QstCod,unsigned QstInd);
|
||||
static void Gam_ListQuestionForEdition (struct Tst_Question *Question,
|
||||
unsigned QstInd);
|
||||
static void Gam_PutIconToAddNewQuestions (void);
|
||||
static void Gam_PutButtonToAddNewQuestions (void);
|
||||
|
||||
|
@ -1873,7 +1874,6 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
|
|||
extern const char *Txt_Movement_not_allowed;
|
||||
unsigned NumQst;
|
||||
MYSQL_ROW row;
|
||||
long QstCod;
|
||||
struct Tst_Question Question;
|
||||
unsigned QstInd;
|
||||
unsigned MaxQstInd;
|
||||
|
@ -1902,13 +1902,15 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
|
|||
{
|
||||
Gbl.RowEvenOdd = NumQst % 2;
|
||||
|
||||
/***** Create test question *****/
|
||||
Tst_QstConstructor (&Question);
|
||||
|
||||
/***** Get question data *****/
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
/*
|
||||
row[0] QstInd
|
||||
row[1] QstCod
|
||||
*/
|
||||
/***** Create test question *****/
|
||||
Tst_QstConstructor (&Question);
|
||||
|
||||
/* Get question index (row[0]) */
|
||||
QstInd = Str_ConvertStrToUnsigned (row[0]);
|
||||
|
@ -1917,7 +1919,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
|
|||
QstInd);
|
||||
|
||||
/* Get question code (row[1]) */
|
||||
QstCod = Str_ConvertStrCodToLongCod (row[1]);
|
||||
Question.QstCod = Str_ConvertStrCodToLongCod (row[1]);
|
||||
|
||||
/***** Icons *****/
|
||||
Gam_SetCurrentGamCod (GamCod); // Used to pass parameter
|
||||
|
@ -1965,14 +1967,14 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
|
|||
/* Put icon to edit the question */
|
||||
if (ICanEditQuestions)
|
||||
{
|
||||
Tst_SetParamGblQstCod (QstCod);
|
||||
Tst_SetParamGblQstCod (Question.QstCod);
|
||||
Ico_PutContextualIconToEdit (ActEdiOneTstQst,NULL,Tst_PutParamGblQstCod);
|
||||
}
|
||||
|
||||
HTM_TD_End ();
|
||||
|
||||
/***** Question *****/
|
||||
Gam_ListQuestionForEdition (QstCod,QstInd);
|
||||
Gam_ListQuestionForEdition (&Question,QstInd);
|
||||
|
||||
HTM_TR_End ();
|
||||
|
||||
|
@ -1988,7 +1990,8 @@ static void Gam_ListOneOrMoreQuestionsForEdition (long GamCod,unsigned NumQsts,
|
|||
/********************** List game question for edition ***********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Gam_ListQuestionForEdition (long QstCod,unsigned QstInd)
|
||||
static void Gam_ListQuestionForEdition (struct Tst_Question *Question,
|
||||
unsigned QstInd)
|
||||
{
|
||||
extern const char *Txt_Question_removed;
|
||||
MYSQL_RES *mysql_res;
|
||||
|
@ -1998,7 +2001,7 @@ static void Gam_ListQuestionForEdition (long QstCod,unsigned QstInd)
|
|||
struct Media Media;
|
||||
|
||||
/***** Get question from database *****/
|
||||
QstExists = Tst_GetOneQuestionByCod (QstCod,&mysql_res); // Question exists?
|
||||
QstExists = Tst_GetOneQuestionByCod (Question->QstCod,&mysql_res); // Question exists?
|
||||
|
||||
if (QstExists)
|
||||
{
|
||||
|
@ -2029,13 +2032,13 @@ static void Gam_ListQuestionForEdition (long QstCod,unsigned QstInd)
|
|||
|
||||
/***** Write question code *****/
|
||||
HTM_TD_Begin ("class=\"DAT_SMALL CT COLOR%u\"",Gbl.RowEvenOdd);
|
||||
HTM_TxtF ("%ld ",QstCod);
|
||||
HTM_TxtF ("%ld ",Question->QstCod);
|
||||
HTM_TD_End ();
|
||||
|
||||
/***** Write the question tags *****/
|
||||
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||
if (QstExists)
|
||||
Tst_GetAndWriteTagsQst (QstCod);
|
||||
Tst_GetAndWriteTagsQst (Question->QstCod);
|
||||
HTM_TD_End ();
|
||||
|
||||
/***** Write stem (row[3]) and media *****/
|
||||
|
@ -2059,7 +2062,7 @@ static void Gam_ListQuestionForEdition (long QstCod,unsigned QstInd)
|
|||
Tst_WriteQstFeedback (row[4],"TEST_EDI_LIGHT");
|
||||
|
||||
/* Show answers */
|
||||
Tst_WriteAnswersEdit (QstCod,AnswerType);
|
||||
Tst_WriteAnswersEdit (Question);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
64
swad_match.c
64
swad_match.c
|
@ -140,7 +140,7 @@ static void Mch_ShowLstGrpsToCreateMatch (void);
|
|||
static long Mch_CreateMatch (long GamCod,char Title[Gam_MAX_BYTES_TITLE + 1]);
|
||||
static void Mch_CreateIndexes (long GamCod,long MchCod);
|
||||
static void Mch_ReorderAnswer (long MchCod,unsigned QstInd,
|
||||
long QstCod,bool Shuffle);
|
||||
const struct Tst_Question *Question);
|
||||
static void Mch_CreateGrps (long MchCod);
|
||||
static void Mch_UpdateMatchStatusInDB (const struct Match *Match);
|
||||
|
||||
|
@ -1448,11 +1448,9 @@ static void Mch_CreateIndexes (long GamCod,long MchCod)
|
|||
MYSQL_ROW row;
|
||||
unsigned NumQsts;
|
||||
unsigned NumQst;
|
||||
long QstCod;
|
||||
struct Tst_Question Question;
|
||||
long LongNum;
|
||||
unsigned QstInd;
|
||||
Tst_AnswerType_t AnswerType;
|
||||
bool Shuffle;
|
||||
|
||||
/***** Get questions of the game *****/
|
||||
NumQsts = (unsigned)
|
||||
|
@ -1472,11 +1470,20 @@ static void Mch_CreateIndexes (long GamCod,long MchCod)
|
|||
NumQst < NumQsts;
|
||||
NumQst++)
|
||||
{
|
||||
/***** Create test question *****/
|
||||
Tst_QstConstructor (&Question);
|
||||
|
||||
/***** Get question data *****/
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
/*
|
||||
gam_questions.QstCod row[0]
|
||||
gam_questions.QstInd row[1]
|
||||
tst_questions.AnsType row[2]
|
||||
tst_questions.Shuffle row[3]
|
||||
*/
|
||||
|
||||
/* Get question code (row[0]) */
|
||||
if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
||||
if ((Question.QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
||||
Lay_ShowErrorAndExit ("Wrong code of question.");
|
||||
|
||||
/* Get question index (row[1]) */
|
||||
|
@ -1485,15 +1492,18 @@ static void Mch_CreateIndexes (long GamCod,long MchCod)
|
|||
QstInd = (unsigned) LongNum;
|
||||
|
||||
/* Get answer type (row[2]) */
|
||||
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[2]);
|
||||
if (AnswerType != Tst_ANS_UNIQUE_CHOICE)
|
||||
Question.Answer.Type = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[2]);
|
||||
if (Question.Answer.Type != Tst_ANS_UNIQUE_CHOICE)
|
||||
Lay_ShowErrorAndExit ("Wrong answer type.");
|
||||
|
||||
/* Get shuffle (row[3]) */
|
||||
Shuffle = (row[3][0] == 'Y');
|
||||
Question.Shuffle = (row[3][0] == 'Y');
|
||||
|
||||
/***** Reorder answer *****/
|
||||
Mch_ReorderAnswer (MchCod,QstInd,QstCod,Shuffle);
|
||||
Mch_ReorderAnswer (MchCod,QstInd,&Question);
|
||||
|
||||
/***** Destroy test question *****/
|
||||
Tst_QstDestructor (&Question);
|
||||
}
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
|
@ -1505,7 +1515,7 @@ static void Mch_CreateIndexes (long GamCod,long MchCod)
|
|||
/*****************************************************************************/
|
||||
|
||||
static void Mch_ReorderAnswer (long MchCod,unsigned QstInd,
|
||||
long QstCod,bool Shuffle)
|
||||
const struct Tst_Question *Question)
|
||||
{
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
|
@ -1526,9 +1536,9 @@ static void Mch_ReorderAnswer (long MchCod,unsigned QstInd,
|
|||
" FROM tst_answers"
|
||||
" WHERE QstCod=%ld"
|
||||
" ORDER BY %s",
|
||||
QstCod,
|
||||
Shuffle ? "RAND()" : // Use RAND() because is really random; RAND(NOW()) repeats order
|
||||
"AnsInd");
|
||||
Question->QstCod,
|
||||
Question->Shuffle ? "RAND()" : // Use RAND() because is really random; RAND(NOW()) repeats order
|
||||
"AnsInd");
|
||||
|
||||
/***** For each answer in question... *****/
|
||||
for (NumAns = 0;
|
||||
|
@ -3799,34 +3809,30 @@ static void Mch_ComputeScore (struct TsR_Result *Result)
|
|||
unsigned Indexes[Tst_MAX_OPTIONS_PER_QUESTION]; // Indexes of all answers of this question
|
||||
bool AnswersUsr[Tst_MAX_OPTIONS_PER_QUESTION];
|
||||
|
||||
/***** Create test question *****/
|
||||
Tst_QstConstructor (&Question);
|
||||
Question.Answer.Type = Tst_ANS_UNIQUE_CHOICE;
|
||||
Result->Score = 0.0;
|
||||
|
||||
for (NumQst = 0;
|
||||
for (NumQst = 0, Result->Score = 0.0;
|
||||
NumQst < Result->NumQsts;
|
||||
NumQst++)
|
||||
{
|
||||
/***** Get indexes for this question from string *****/
|
||||
Tst_GetIndexesFromStr (Result->StrIndexes[NumQst],Indexes);
|
||||
|
||||
/***** Get the user's answers for this question from string *****/
|
||||
Tst_GetAnswersFromStr (Result->StrAnswers[NumQst],AnswersUsr);
|
||||
/***** Create test question *****/
|
||||
Tst_QstConstructor (&Question);
|
||||
Question.QstCod = Result->QstCodes[NumQst];
|
||||
Question.Answer.Type = Tst_ANS_UNIQUE_CHOICE;
|
||||
|
||||
/***** Get correct answers of test question from database *****/
|
||||
Tst_GetCorrectAnswersFromDB (Result->QstCodes[NumQst],&Question);
|
||||
Tst_GetCorrectAnswersFromDB (&Question);
|
||||
|
||||
/***** Compute the total score of this question *****/
|
||||
/***** Compute the score of this question *****/
|
||||
Tst_GetIndexesFromStr (Result->StrIndexes[NumQst],Indexes);
|
||||
Tst_GetAnswersFromStr (Result->StrAnswers[NumQst],AnswersUsr);
|
||||
Tst_ComputeScoreQst (&Question,
|
||||
Indexes,AnswersUsr,&ScoreThisQst,&AnswerIsNotBlank);
|
||||
|
||||
/***** Update total score *****/
|
||||
Result->Score += ScoreThisQst;
|
||||
}
|
||||
|
||||
/***** Destroy test question *****/
|
||||
Tst_QstDestructor (&Question);
|
||||
/***** Destroy test question *****/
|
||||
Tst_QstDestructor (&Question);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
681
swad_test.c
681
swad_test.c
File diff suppressed because it is too large
Load Diff
26
swad_test.h
26
swad_test.h
|
@ -98,6 +98,8 @@ struct Tst_Test
|
|||
|
||||
struct Tst_Question
|
||||
{
|
||||
long QstCod;
|
||||
struct Tst_Tags Tags;
|
||||
struct
|
||||
{
|
||||
char *Text;
|
||||
|
@ -176,15 +178,14 @@ void Tst_ListQuestionsToSelect (void);
|
|||
bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res);
|
||||
void Tst_WriteParamEditQst (void);
|
||||
|
||||
void Tst_SetParamGblTags (const struct Tst_Tags *TagsSrc);
|
||||
void Tst_SetParamGblAnswerTypes (const struct Tst_AnswerTypes *AnswerTypesSrc);
|
||||
void Tst_SetParamGblSelectedOrder (Tst_QuestionsOrder_t SelectedOrder);
|
||||
Tst_QuestionsOrder_t Tst_GetParamGblSelectedOrder (void);
|
||||
void Tst_SetParamGblTest (const struct Tst_Test *TestSrc);
|
||||
void Tst_GetParamGblTest (struct Tst_Test *TestDst);
|
||||
|
||||
unsigned Tst_GetNumAnswersQst (long QstCod);
|
||||
unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle);
|
||||
void Tst_GetCorrectAnswersFromDB (long QstCod,struct Tst_Question *Question);
|
||||
void Tst_WriteAnswersEdit (long QstCod,Tst_AnswerType_t AnswerType);
|
||||
void Tst_GetAnswersQst (struct Tst_Question *Question,MYSQL_RES **mysql_res,
|
||||
bool Shuffle);
|
||||
void Tst_GetCorrectAnswersFromDB (struct Tst_Question *Question);
|
||||
void Tst_WriteAnswersEdit (struct Tst_Question *Question);
|
||||
bool Tst_CheckIfQuestionIsValidForGame (long QstCod);
|
||||
void Tst_WriteAnsTF (char AnsTF);
|
||||
void Tst_GetIndexesFromStr (const char StrIndexesOneQst[Tst_MAX_BYTES_INDEXES_ONE_QST + 1], // 0 1 2 3, 3 0 2 1, etc.
|
||||
|
@ -214,14 +215,13 @@ void Tst_ShowFormEditOneQst (void);
|
|||
void Tst_QstConstructor (struct Tst_Question *Question);
|
||||
void Tst_QstDestructor (struct Tst_Question *Question);
|
||||
|
||||
int Tst_AllocateTextChoiceAnswer (struct Tst_Question *Question,unsigned NumOpt);
|
||||
bool Tst_AllocateTextChoiceAnswer (struct Tst_Question *Question,unsigned NumOpt);
|
||||
|
||||
Tst_AnswerType_t Tst_ConvertFromStrAnsTypDBToAnsTyp (const char *StrAnsTypeBD);
|
||||
void Tst_ReceiveQst (void);
|
||||
bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (struct Tst_Question *Question,
|
||||
const struct Tst_Tags *Tags);
|
||||
bool Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (struct Tst_Question *Question);
|
||||
|
||||
bool Tst_CheckIfQuestionExistsInDB (const struct Tst_Question *Question);
|
||||
bool Tst_CheckIfQuestionExistsInDB (struct Tst_Question *Question);
|
||||
|
||||
long Tst_GetIntAnsFromStr (char *Str);
|
||||
|
||||
|
@ -237,9 +237,7 @@ long Tst_GetParamGblQstCod (void);
|
|||
void Tst_PutParamGblQstCod (void);
|
||||
void Tst_PutParamQstCod (long QstCod);
|
||||
|
||||
long Tst_InsertOrUpdateQstTagsAnsIntoDB (long QstCod,
|
||||
struct Tst_Question *Question,
|
||||
const struct Tst_Tags *Tags);
|
||||
void Tst_InsertOrUpdateQstTagsAnsIntoDB (struct Tst_Question *Question);
|
||||
|
||||
void Tst_RemoveCrsTests (long CrsCod);
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ static void TsI_PutCreateXMLParam (void);
|
|||
static void TsI_ExportQuestion (long QstCod,FILE *FileXML);
|
||||
|
||||
static void TsI_GetAndWriteTagsXML (long QstCod,FILE *FileXML);
|
||||
static void TsI_WriteAnswersOfAQstXML (long QstCod,Tst_AnswerType_t AnswerType,
|
||||
static void TsI_WriteAnswersOfAQstXML (struct Tst_Question *Question,
|
||||
FILE *FileXML);
|
||||
static void TsI_ReadQuestionsFromXMLFileAndStoreInDB (const char *FileNameXML);
|
||||
static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer);
|
||||
|
@ -81,7 +81,6 @@ static void TsI_GetAnswerFromXML (struct XMLElement *AnswerElem,
|
|||
static void TsI_WriteHeadingListImportedQst (void);
|
||||
static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
||||
struct XMLElement *FeedbackElem,
|
||||
const struct Tst_Tags *Tags,
|
||||
const struct Tst_Question *Question,
|
||||
bool QuestionExists);
|
||||
|
||||
|
@ -94,9 +93,7 @@ void TsI_PutFormToExportQuestions (const struct Tst_Test *Test)
|
|||
extern const char *Txt_Export_questions;
|
||||
|
||||
/***** Put a link to create a file with questions *****/
|
||||
Tst_SetParamGblTags (&Test->Tags);
|
||||
Tst_SetParamGblAnswerTypes (&Test->AnswerTypes);
|
||||
Tst_SetParamGblSelectedOrder (Test->SelectedOrder);
|
||||
Tst_SetParamGblTest (Test);
|
||||
Lay_PutContextualLinkIconText (ActLstTstQst,NULL,TsI_PutParamsExportQsts,
|
||||
"file-import.svg",
|
||||
Txt_Export_questions);
|
||||
|
@ -108,11 +105,13 @@ void TsI_PutFormToExportQuestions (const struct Tst_Test *Test)
|
|||
|
||||
static void TsI_PutParamsExportQsts (void)
|
||||
{
|
||||
struct Tst_Test Test;
|
||||
|
||||
Tst_GetParamGblTest (&Test);
|
||||
Dat_WriteParamsIniEndDates ();
|
||||
Tst_WriteParamEditQst ();
|
||||
Par_PutHiddenParamChar ("OnlyThisQst",'N');
|
||||
Par_PutHiddenParamUnsigned (NULL,"Order",
|
||||
(unsigned) Tst_GetParamGblSelectedOrder ());
|
||||
Par_PutHiddenParamUnsigned (NULL,"Order",(unsigned) Test.SelectedOrder);
|
||||
TsI_PutCreateXMLParam ();
|
||||
}
|
||||
|
||||
|
@ -250,7 +249,10 @@ static void TsI_ExportQuestion (long QstCod,FILE *FileXML)
|
|||
extern const char *Txt_NEW_LINE;
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
Tst_AnswerType_t AnswerType;
|
||||
struct Tst_Question Question;
|
||||
|
||||
/***** Create test question *****/
|
||||
Tst_QstConstructor (&Question);
|
||||
|
||||
if (Tst_GetOneQuestionByCod (QstCod,&mysql_res))
|
||||
{
|
||||
|
@ -269,9 +271,9 @@ static void TsI_ExportQuestion (long QstCod,FILE *FileXML)
|
|||
*/
|
||||
|
||||
/***** Write the answer type (row[1]) *****/
|
||||
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
||||
Question.Answer.Type = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
||||
fprintf (FileXML,"<question type=\"%s\">%s",
|
||||
Tst_StrAnswerTypesXML[AnswerType],Txt_NEW_LINE);
|
||||
Tst_StrAnswerTypesXML[Question.Answer.Type],Txt_NEW_LINE);
|
||||
|
||||
/***** Write the question tags *****/
|
||||
fprintf (FileXML,"<tags>%s",Txt_NEW_LINE);
|
||||
|
@ -291,19 +293,22 @@ static void TsI_ExportQuestion (long QstCod,FILE *FileXML)
|
|||
/***** Write the answers of this question.
|
||||
Shuffle can be enabled or disabled (row[2]) *****/
|
||||
fprintf (FileXML,"<answer");
|
||||
if (AnswerType == Tst_ANS_UNIQUE_CHOICE ||
|
||||
AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
||||
if (Question.Answer.Type == Tst_ANS_UNIQUE_CHOICE ||
|
||||
Question.Answer.Type == Tst_ANS_MULTIPLE_CHOICE)
|
||||
fprintf (FileXML," shuffle=\"%s\"",
|
||||
(row[2][0] == 'Y') ? "yes" :
|
||||
"no");
|
||||
fprintf (FileXML,">");
|
||||
TsI_WriteAnswersOfAQstXML (QstCod,AnswerType,FileXML);
|
||||
TsI_WriteAnswersOfAQstXML (&Question,FileXML);
|
||||
fprintf (FileXML,"</answer>%s",Txt_NEW_LINE);
|
||||
|
||||
/***** End question *****/
|
||||
fprintf (FileXML,"</question>%s%s",
|
||||
Txt_NEW_LINE,Txt_NEW_LINE);
|
||||
}
|
||||
|
||||
/***** Destroy test question *****/
|
||||
Tst_QstDestructor (&Question);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -337,21 +342,19 @@ static void TsI_GetAndWriteTagsXML (long QstCod,FILE *FileXML)
|
|||
/**************** Get and write the answers of a test question ***************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void TsI_WriteAnswersOfAQstXML (long QstCod,Tst_AnswerType_t AnswerType,
|
||||
static void TsI_WriteAnswersOfAQstXML (struct Tst_Question *Question,
|
||||
FILE *FileXML)
|
||||
{
|
||||
extern const char *Txt_NEW_LINE;
|
||||
struct Tst_Question Question;
|
||||
unsigned NumOpt;
|
||||
unsigned i;
|
||||
MYSQL_RES *mysql_res;
|
||||
MYSQL_ROW row;
|
||||
double FloatNum[2];
|
||||
|
||||
Question.Answer.Type = AnswerType;
|
||||
|
||||
/***** Get answers *****/
|
||||
Question.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false); // Result: AnsInd,Answer,Correct
|
||||
Tst_GetAnswersQst (Question,&mysql_res,
|
||||
false); // Don't shuffle
|
||||
/*
|
||||
row[0] AnsInd
|
||||
row[1] Answer
|
||||
|
@ -361,16 +364,16 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod,Tst_AnswerType_t AnswerType,
|
|||
*/
|
||||
|
||||
/***** Write answers *****/
|
||||
switch (Question.Answer.Type)
|
||||
switch (Question->Answer.Type)
|
||||
{
|
||||
case Tst_ANS_INT:
|
||||
Tst_CheckIfNumberOfAnswersIsOne (&Question);
|
||||
Tst_CheckIfNumberOfAnswersIsOne (Question);
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
fprintf (FileXML,"%ld",
|
||||
Tst_GetIntAnsFromStr (row[1]));
|
||||
break;
|
||||
case Tst_ANS_FLOAT:
|
||||
if (Question.Answer.NumOptions != 2)
|
||||
if (Question->Answer.NumOptions != 2)
|
||||
Lay_ShowErrorAndExit ("Wrong float range.");
|
||||
|
||||
for (i = 0;
|
||||
|
@ -388,7 +391,7 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod,Tst_AnswerType_t AnswerType,
|
|||
FloatNum[1],Txt_NEW_LINE);
|
||||
break;
|
||||
case Tst_ANS_TRUE_FALSE:
|
||||
Tst_CheckIfNumberOfAnswersIsOne (&Question);
|
||||
Tst_CheckIfNumberOfAnswersIsOne (Question);
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
fprintf (FileXML,"%s",
|
||||
row[1][0] == 'T' ? "true" :
|
||||
|
@ -399,7 +402,7 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod,Tst_AnswerType_t AnswerType,
|
|||
case Tst_ANS_TEXT:
|
||||
fprintf (FileXML,"%s",Txt_NEW_LINE);
|
||||
for (NumOpt = 0;
|
||||
NumOpt < Question.Answer.NumOptions;
|
||||
NumOpt < Question->Answer.NumOptions;
|
||||
NumOpt++)
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
@ -408,7 +411,7 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod,Tst_AnswerType_t AnswerType,
|
|||
fprintf (FileXML,"<option");
|
||||
|
||||
/* Write whether the answer is correct or not (row[4]) */
|
||||
if (Question.Answer.Type != Tst_ANS_TEXT)
|
||||
if (Question->Answer.Type != Tst_ANS_TEXT)
|
||||
fprintf (FileXML," correct=\"%s\"",
|
||||
(row[4][0] == 'Y') ? "yes" :
|
||||
"no");
|
||||
|
@ -541,10 +544,9 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
|||
struct XMLElement *FeedbackElem;
|
||||
struct XMLElement *AnswerElem;
|
||||
struct XMLAttribute *Attribute;
|
||||
struct Tst_Tags Tags;
|
||||
bool AnswerTypeFound;
|
||||
bool QuestionExists;
|
||||
struct Tst_Question Question;
|
||||
bool QuestionExists;
|
||||
bool AnswerTypeFound;
|
||||
char Stem[Cns_MAX_BYTES_TEXT + 1];
|
||||
char Feedback[Cns_MAX_BYTES_TEXT + 1];
|
||||
|
||||
|
@ -605,22 +607,22 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
|||
if (AnswerTypeFound)
|
||||
{
|
||||
/* Get tags */
|
||||
for (TagsElem = QuestionElem->FirstChild, Tags.Num = 0;
|
||||
for (TagsElem = QuestionElem->FirstChild, Question.Tags.Num = 0;
|
||||
TagsElem != NULL;
|
||||
TagsElem = TagsElem->NextBrother)
|
||||
if (!strcmp (TagsElem->TagName,"tags"))
|
||||
{
|
||||
for (TagElem = TagsElem->FirstChild;
|
||||
TagElem != NULL && Tags.Num < Tst_MAX_TAGS_PER_QUESTION;
|
||||
TagElem != NULL && Question.Tags.Num < Tst_MAX_TAGS_PER_QUESTION;
|
||||
TagElem = TagElem->NextBrother)
|
||||
if (!strcmp (TagElem->TagName,"tag"))
|
||||
{
|
||||
if (TagElem->Content)
|
||||
{
|
||||
Str_Copy (Tags.Txt[Tags.Num],
|
||||
Str_Copy (Question.Tags.Txt[Question.Tags.Num],
|
||||
TagElem->Content,
|
||||
Tst_MAX_BYTES_TAG);
|
||||
Tags.Num++;
|
||||
Question.Tags.Num++;
|
||||
}
|
||||
}
|
||||
break; // Only first element "tags"
|
||||
|
@ -691,19 +693,23 @@ static void TsI_ImportQuestionsFromXMLBuffer (const char *XMLBuffer)
|
|||
TsI_GetAnswerFromXML (AnswerElem,&Question);
|
||||
|
||||
/* Make sure that tags, text and answer are not empty */
|
||||
if (Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (&Question,&Tags))
|
||||
if (Tst_CheckIfQstFormatIsCorrectAndCountNumOptions (&Question))
|
||||
{
|
||||
/* Check if question already exists in database */
|
||||
QuestionExists = Tst_CheckIfQuestionExistsInDB (&Question);
|
||||
|
||||
/* Write row with this imported question */
|
||||
TsI_WriteRowImportedQst (StemElem,FeedbackElem,
|
||||
&Tags,&Question,QuestionExists);
|
||||
&Question,QuestionExists);
|
||||
|
||||
/***** If a new question ==> insert question, tags and answer in the database *****/
|
||||
if (!QuestionExists)
|
||||
if (Tst_InsertOrUpdateQstTagsAnsIntoDB (-1L,&Question,&Tags) <= 0)
|
||||
{
|
||||
Question.QstCod = -1L;
|
||||
Tst_InsertOrUpdateQstTagsAnsIntoDB (&Question);
|
||||
if (Question.QstCod <= 0)
|
||||
Lay_ShowErrorAndExit ("Can not create question.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Answer type not found
|
||||
|
@ -923,7 +929,6 @@ static void TsI_WriteHeadingListImportedQst (void)
|
|||
|
||||
static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
||||
struct XMLElement *FeedbackElem,
|
||||
const struct Tst_Tags *Tags,
|
||||
const struct Tst_Question *Question,
|
||||
bool QuestionExists)
|
||||
{
|
||||
|
@ -971,12 +976,12 @@ static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
|||
|
||||
/***** Write the question tags *****/
|
||||
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
||||
if (Tags->Num)
|
||||
if (Question->Tags.Num)
|
||||
{
|
||||
/***** Write the tags *****/
|
||||
HTM_TABLE_Begin (NULL);
|
||||
for (NumTag = 0;
|
||||
NumTag < Tags->Num;
|
||||
NumTag < Question->Tags.Num;
|
||||
NumTag++)
|
||||
{
|
||||
HTM_TR_Begin (NULL);
|
||||
|
@ -986,7 +991,7 @@ static void TsI_WriteRowImportedQst (struct XMLElement *StemElem,
|
|||
HTM_TD_End ();
|
||||
|
||||
HTM_TD_Begin ("class=\"%s LT\"",ClassData);
|
||||
HTM_Txt (Tags->Txt[NumTag]);
|
||||
HTM_Txt (Question->Tags.Txt[NumTag]);
|
||||
HTM_TD_End ();
|
||||
|
||||
HTM_TR_End ();
|
||||
|
|
Loading…
Reference in New Issue