mirror of https://github.com/acanas/swad-core.git
Version19.207.4
This commit is contained in:
parent
ca5b870c20
commit
1f773a3acc
|
@ -544,10 +544,11 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - *
|
||||||
En OpenSWAD:
|
En OpenSWAD:
|
||||||
ps2pdf source.ps destination.pdf
|
ps2pdf source.ps destination.pdf
|
||||||
*/
|
*/
|
||||||
#define Log_PLATFORM_VERSION "SWAD 19.207.3 (2020-04-30)"
|
#define Log_PLATFORM_VERSION "SWAD 19.207.4 (2020-04-30)"
|
||||||
#define CSS_FILE "swad19.193.1.css"
|
#define CSS_FILE "swad19.193.1.css"
|
||||||
#define JS_FILE "swad19.193.1.js"
|
#define JS_FILE "swad19.193.1.js"
|
||||||
/*
|
/*
|
||||||
|
Version 19.207.4: Apr 30, 2020 Fixed bug in test result, reported by Mancia Anguita López. (300363 lines)
|
||||||
Version 19.207.3: Apr 30, 2020 Fixed bug removing account. (300335 lines)
|
Version 19.207.3: Apr 30, 2020 Fixed bug removing account. (300335 lines)
|
||||||
Version 19.207.2: Apr 30, 2020 Fixed bug creating account, reported by Antonio Becerra. (300334 lines)
|
Version 19.207.2: Apr 30, 2020 Fixed bug creating account, reported by Antonio Becerra. (300334 lines)
|
||||||
Version 19.207.1: Apr 30, 2020 Optimization in table of last prefs on user-course. (300323 lines)
|
Version 19.207.1: Apr 30, 2020 Optimization in table of last prefs on user-course. (300323 lines)
|
||||||
|
|
|
@ -1314,6 +1314,17 @@ mysql> DESCRIBE expanded_folders;
|
||||||
"INDEX(FileBrowser,Cod),"
|
"INDEX(FileBrowser,Cod),"
|
||||||
"INDEX(WorksUsrCod))");
|
"INDEX(WorksUsrCod))");
|
||||||
|
|
||||||
|
/***** Table figures *****/
|
||||||
|
/*
|
||||||
|
mysql> DESCRIBE figures;
|
||||||
|
|
||||||
|
*/
|
||||||
|
DB_CreateTable ("CREATE TABLE IF NOT EXISTS figures ("
|
||||||
|
"Name VARCHAR(32) NOT NULL," // Fig_MAX_BYTES_NAME
|
||||||
|
"Value INT NOT NULL,"
|
||||||
|
"CalcTime DATETIME NOT NULL,"
|
||||||
|
"UNIQUE INDEX(Name))");
|
||||||
|
|
||||||
/***** Table file_browser_last *****/
|
/***** Table file_browser_last *****/
|
||||||
/*
|
/*
|
||||||
mysql> DESCRIBE file_browser_last;
|
mysql> DESCRIBE file_browser_last;
|
||||||
|
|
|
@ -65,6 +65,8 @@ extern struct Globals Gbl;
|
||||||
/***************************** Private constants *****************************/
|
/***************************** Private constants *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#define Fig_MAX_BYTES_NAME 32
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************************* Private types *******************************/
|
/******************************* Private types *******************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -195,6 +197,7 @@ static void Fig_GetAndShowNumUsrsPerMenu (void);
|
||||||
static void Fig_GetAndShowNumUsrsPerTheme (void);
|
static void Fig_GetAndShowNumUsrsPerTheme (void);
|
||||||
static void Fig_GetAndShowNumUsrsPerSideColumns (void);
|
static void Fig_GetAndShowNumUsrsPerSideColumns (void);
|
||||||
unsigned Fig_GetNumUsrsWhoChoseAnOption (const char *SubQuery);
|
unsigned Fig_GetNumUsrsWhoChoseAnOption (const char *SubQuery);
|
||||||
|
bool Fig_GetFigureFromCache (const char *Name);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************************** Show use of the platform *************************/
|
/************************** Show use of the platform *************************/
|
||||||
|
@ -5672,3 +5675,13 @@ unsigned Fig_GetNumUsrsWhoChoseAnOption (const char *SubQuery)
|
||||||
|
|
||||||
return NumUsrs;
|
return NumUsrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************** Get number of users who have chosen an option ****************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
// Return true is figure is valid (if figure is cached and recently calculated)
|
||||||
|
|
||||||
|
bool Fig_GetFigureFromCache (const char *Name)
|
||||||
|
{
|
||||||
|
return Name[0] ? true : false;
|
||||||
|
}
|
||||||
|
|
12
swad_test.c
12
swad_test.c
|
@ -2521,7 +2521,7 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test,
|
||||||
const char *Ptr;
|
const char *Ptr;
|
||||||
char TagText[Tst_MAX_BYTES_TAG + 1];
|
char TagText[Tst_MAX_BYTES_TAG + 1];
|
||||||
char UnsignedStr[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
|
char UnsignedStr[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
|
||||||
Tst_AnswerType_t AnsType;
|
Tst_AnswerType_t AnswerType;
|
||||||
bool Shuffle;
|
bool Shuffle;
|
||||||
char StrNumQsts[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
|
char StrNumQsts[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
|
||||||
unsigned NumQst;
|
unsigned NumQst;
|
||||||
|
@ -2593,15 +2593,15 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test,
|
||||||
while (*Ptr)
|
while (*Ptr)
|
||||||
{
|
{
|
||||||
Par_GetNextStrUntilSeparParamMult (&Ptr,UnsignedStr,Tst_MAX_BYTES_TAG);
|
Par_GetNextStrUntilSeparParamMult (&Ptr,UnsignedStr,Tst_MAX_BYTES_TAG);
|
||||||
AnsType = Tst_ConvertFromUnsignedStrToAnsTyp (UnsignedStr);
|
AnswerType = Tst_ConvertFromUnsignedStrToAnsTyp (UnsignedStr);
|
||||||
LengthQuery = LengthQuery + 35 + strlen (Tst_StrAnswerTypesDB[AnsType]) + 1;
|
LengthQuery = LengthQuery + 35 + strlen (Tst_StrAnswerTypesDB[AnswerType]) + 1;
|
||||||
if (LengthQuery > Tst_MAX_BYTES_QUERY_TEST - 128)
|
if (LengthQuery > Tst_MAX_BYTES_QUERY_TEST - 128)
|
||||||
Lay_ShowErrorAndExit ("Query size exceed.");
|
Lay_ShowErrorAndExit ("Query size exceed.");
|
||||||
Str_Concat (Query,
|
Str_Concat (Query,
|
||||||
NumItemInList ? " OR tst_questions.AnsType='" :
|
NumItemInList ? " OR tst_questions.AnsType='" :
|
||||||
" AND (tst_questions.AnsType='",
|
" AND (tst_questions.AnsType='",
|
||||||
Tst_MAX_BYTES_QUERY_TEST);
|
Tst_MAX_BYTES_QUERY_TEST);
|
||||||
Str_Concat (Query,Tst_StrAnswerTypesDB[AnsType],
|
Str_Concat (Query,Tst_StrAnswerTypesDB[AnswerType],
|
||||||
Tst_MAX_BYTES_QUERY_TEST);
|
Tst_MAX_BYTES_QUERY_TEST);
|
||||||
Str_Concat (Query,"'",
|
Str_Concat (Query,"'",
|
||||||
Tst_MAX_BYTES_QUERY_TEST);
|
Tst_MAX_BYTES_QUERY_TEST);
|
||||||
|
@ -2647,13 +2647,13 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Tst_Test *Test,
|
||||||
Lay_ShowErrorAndExit ("Wrong code of question.");
|
Lay_ShowErrorAndExit ("Wrong code of question.");
|
||||||
|
|
||||||
/* Get answer type (row[1]) */
|
/* Get answer type (row[1]) */
|
||||||
AnsType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
||||||
|
|
||||||
/* Get shuffle (row[2]) */
|
/* Get shuffle (row[2]) */
|
||||||
Shuffle = (row[2][0] == 'Y');
|
Shuffle = (row[2][0] == 'Y');
|
||||||
|
|
||||||
/* Set indexes of answers */
|
/* Set indexes of answers */
|
||||||
switch (AnsType)
|
switch (AnswerType)
|
||||||
{
|
{
|
||||||
case Tst_ANS_INT:
|
case Tst_ANS_INT:
|
||||||
case Tst_ANS_FLOAT:
|
case Tst_ANS_FLOAT:
|
||||||
|
|
|
@ -347,9 +347,9 @@ static void TstRes_WriteQstAndAnsExam (struct UsrData *UsrDat,
|
||||||
HTM_TxtColonNBSP (Txt_Score);
|
HTM_TxtColonNBSP (Txt_Score);
|
||||||
HTM_SPAN_Begin ("class=\"%s\"",
|
HTM_SPAN_Begin ("class=\"%s\"",
|
||||||
Result->Questions[NumQst].StrAnswers[0] ?
|
Result->Questions[NumQst].StrAnswers[0] ?
|
||||||
(Result->Questions[NumQst].Score > 0 ? "ANS_OK" : // Correct/semicorrect
|
(Result->Questions[NumQst].Score > 0 ? "ANS_OK" : // Correct/semicorrect
|
||||||
"ANS_BAD") : // Wrong
|
"ANS_BAD") : // Wrong
|
||||||
"ANS_0"); // Blank answer
|
"ANS_0"); // Blank answer
|
||||||
HTM_Double2Decimals (Result->Questions[NumQst].Score);
|
HTM_Double2Decimals (Result->Questions[NumQst].Score);
|
||||||
HTM_SPAN_End ();
|
HTM_SPAN_End ();
|
||||||
HTM_DIV_End ();
|
HTM_DIV_End ();
|
||||||
|
@ -505,6 +505,7 @@ static void TstRes_ComputeFloatAnsScore (struct TstRes_Result *Result,
|
||||||
if (Result->Questions[NumQst].AnswerIsNotBlank) // If user has answered the answer
|
if (Result->Questions[NumQst].AnswerIsNotBlank) // If user has answered the answer
|
||||||
{
|
{
|
||||||
AnswerUsr = Str_GetDoubleFromStr (Result->Questions[NumQst].StrAnswers);
|
AnswerUsr = Str_GetDoubleFromStr (Result->Questions[NumQst].StrAnswers);
|
||||||
|
|
||||||
// A bad formatted floating point answer will interpreted as 0.0
|
// A bad formatted floating point answer will interpreted as 0.0
|
||||||
Result->Questions[NumQst].Score = (AnswerUsr >= Question->Answer.FloatingPoint[0] &&
|
Result->Questions[NumQst].Score = (AnswerUsr >= Question->Answer.FloatingPoint[0] &&
|
||||||
AnswerUsr <= Question->Answer.FloatingPoint[1]) ? 1.0 : // If correct (inside the interval)
|
AnswerUsr <= Question->Answer.FloatingPoint[1]) ? 1.0 : // If correct (inside the interval)
|
||||||
|
@ -2307,17 +2308,20 @@ void TstRes_GetExamQuestionsFromDB (struct TstRes_Result *Result)
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
unsigned NumQsts;
|
unsigned NumQsts;
|
||||||
unsigned NumQst;
|
unsigned NumQst;
|
||||||
|
Tst_AnswerType_t AnswerType;
|
||||||
|
|
||||||
/***** Get questions of a test exam from database *****/
|
/***** Get questions of a test exam from database *****/
|
||||||
NumQsts =
|
NumQsts =
|
||||||
(unsigned) DB_QuerySELECT (&mysql_res,"can not get questions"
|
(unsigned) DB_QuerySELECT (&mysql_res,"can not get questions"
|
||||||
" of a test exam",
|
" of a test exam",
|
||||||
"SELECT QstCod," // row[0]
|
"SELECT tst_exam_questions.QstCod," // row[0]
|
||||||
"Indexes," // row[1]
|
"tst_questions.AnsType," // row[1]
|
||||||
"Answers" // row[2]
|
"tst_exam_questions.Indexes," // row[2]
|
||||||
" FROM tst_exam_questions"
|
"tst_exam_questions.Answers" // row[3]
|
||||||
" WHERE ExaCod=%ld"
|
" FROM tst_exam_questions,tst_questions"
|
||||||
" ORDER BY QstInd",
|
" WHERE tst_exam_questions.ExaCod=%ld"
|
||||||
|
" AND tst_exam_questions.QstCod=tst_questions.QstCod"
|
||||||
|
" ORDER BY tst_exam_questions.QstInd",
|
||||||
Result->ResCod);
|
Result->ResCod);
|
||||||
|
|
||||||
/***** List questions *****/
|
/***** List questions *****/
|
||||||
|
@ -2330,22 +2334,28 @@ void TstRes_GetExamQuestionsFromDB (struct TstRes_Result *Result)
|
||||||
{
|
{
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
/* Get question code */
|
/* Get question code (row[0]) */
|
||||||
if ((Result->Questions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
if ((Result->Questions[NumQst].QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
|
||||||
Lay_ShowErrorAndExit ("Wrong code of question.");
|
Lay_ShowErrorAndExit ("Wrong code of question.");
|
||||||
|
|
||||||
/* Get indexes for this question (row[1]) */
|
/* Get answer type (row[1]) */
|
||||||
Str_Copy (Result->Questions[NumQst].StrIndexes,row[1],
|
AnswerType = Tst_ConvertFromStrAnsTypDBToAnsTyp (row[1]);
|
||||||
|
|
||||||
|
/* Get indexes for this question (row[2]) */
|
||||||
|
Str_Copy (Result->Questions[NumQst].StrIndexes,row[2],
|
||||||
TstRes_MAX_BYTES_INDEXES_ONE_QST);
|
TstRes_MAX_BYTES_INDEXES_ONE_QST);
|
||||||
|
|
||||||
/* Get answers selected by user for this question (row[2]) */
|
/* Get answers selected by user for this question (row[3]) */
|
||||||
Str_Copy (Result->Questions[NumQst].StrAnswers,row[2],
|
Str_Copy (Result->Questions[NumQst].StrAnswers,row[3],
|
||||||
TstRes_MAX_BYTES_ANSWERS_ONE_QST);
|
TstRes_MAX_BYTES_ANSWERS_ONE_QST);
|
||||||
|
|
||||||
/* Replace each comma by a separator of multiple parameters */
|
/* Replace each comma by a separator of multiple parameters */
|
||||||
/* In database commas are used as separators instead of special chars */
|
/* In database commas are used as separators instead of special chars */
|
||||||
Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrIndexes);
|
Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrIndexes);
|
||||||
Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrAnswers);
|
if (AnswerType == Tst_ANS_MULTIPLE_CHOICE)
|
||||||
|
// Only multiple choice questions have multiple answers separated by commas
|
||||||
|
// Other types of questions have a unique answer, and comma may be part of that answer
|
||||||
|
Par_ReplaceCommaBySeparatorMultiple (Result->Questions[NumQst].StrAnswers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
|
|
Loading…
Reference in New Issue