mirror of https://github.com/acanas/swad-core.git
Version 21.46: Oct 26, 2021 New module swad_test_database for database queries related to self-assessment tests.
This commit is contained in:
parent
352de7c69d
commit
4120cb75b7
9
Makefile
9
Makefile
|
@ -83,10 +83,11 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \
|
||||||
swad_statistic_database.o swad_string.o swad_survey.o \
|
swad_statistic_database.o swad_string.o swad_survey.o \
|
||||||
swad_survey_database.o swad_syllabus.o swad_system_config.o \
|
swad_survey_database.o swad_syllabus.o swad_system_config.o \
|
||||||
swad_tab.o swad_tag.o swad_tag_database.o swad_test.o \
|
swad_tab.o swad_tag.o swad_tag_database.o swad_test.o \
|
||||||
swad_test_config.o swad_test_print.o swad_test_visibility.o \
|
swad_test_database.o swad_test_config.o swad_test_print.o \
|
||||||
swad_theme.o swad_timeline.o swad_timeline_comment.o \
|
swad_test_visibility.o swad_theme.o swad_timeline.o \
|
||||||
swad_timeline_database.o swad_timeline_favourite.o swad_timeline_form.o \
|
swad_timeline_comment.o swad_timeline_database.o \
|
||||||
swad_timeline_note.o swad_timeline_notification.o swad_timeline_post.o \
|
swad_timeline_favourite.o swad_timeline_form.o swad_timeline_note.o \
|
||||||
|
swad_timeline_notification.o swad_timeline_post.o \
|
||||||
swad_timeline_publication.o swad_timeline_share.o swad_timeline_user.o \
|
swad_timeline_publication.o swad_timeline_share.o swad_timeline_user.o \
|
||||||
swad_timeline_who.o swad_timetable.o \
|
swad_timeline_who.o swad_timetable.o \
|
||||||
swad_user.o \
|
swad_user.o \
|
||||||
|
|
|
@ -688,7 +688,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] =
|
||||||
[ActReqAssTst ] = {1837,-1,TabUnk,ActReqTst ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_ReceiveTestDraft ,NULL},
|
[ActReqAssTst ] = {1837,-1,TabUnk,ActReqTst ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_ReceiveTestDraft ,NULL},
|
||||||
[ActAssTst ] = { 98,-1,TabUnk,ActReqTst ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_AssessTest ,NULL},
|
[ActAssTst ] = { 98,-1,TabUnk,ActReqTst ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_AssessTest ,NULL},
|
||||||
|
|
||||||
[ActCfgTst ] = { 451,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Tst_ShowFormConfig ,NULL},
|
[ActCfgTst ] = { 451,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstCfg_CheckAndShowFormConfig ,NULL},
|
||||||
[ActRcvCfgTst ] = { 454,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstCfg_ReceiveConfigTst ,NULL},
|
[ActRcvCfgTst ] = { 454,-1,TabUnk,ActReqTst ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,TstCfg_ReceiveConfigTst ,NULL},
|
||||||
|
|
||||||
[ActReqSeeMyTstRes ] = {1083,-1,TabUnk,ActReqTst ,0x208,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,TstPrn_SelDatesToSeeMyPrints ,NULL},
|
[ActReqSeeMyTstRes ] = {1083,-1,TabUnk,ActReqTst ,0x208,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,Dat_SetIniEndDates ,TstPrn_SelDatesToSeeMyPrints ,NULL},
|
||||||
|
@ -4152,7 +4152,7 @@ void Act_AdjustCurrentAction (void)
|
||||||
-------------
|
-------------
|
||||||
If current course has tests and pluggable is unknown,
|
If current course has tests and pluggable is unknown,
|
||||||
the only action possible is configure tests *****/
|
the only action possible is configure tests *****/
|
||||||
if (Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown ())
|
if (TstCfg_CheckIfPluggableIsUnknownAndCrsHasTests ())
|
||||||
{
|
{
|
||||||
Gbl.Action.Act = ActCfgTst;
|
Gbl.Action.Act = ActCfgTst;
|
||||||
Tab_SetCurrentTab ();
|
Tab_SetCurrentTab ();
|
||||||
|
|
|
@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par
|
||||||
|
|
||||||
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
|
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
|
||||||
*/
|
*/
|
||||||
#define Log_PLATFORM_VERSION "SWAD 21.45.1 (2021-10-25)"
|
#define Log_PLATFORM_VERSION "SWAD 21.46 (2021-10-26)"
|
||||||
#define CSS_FILE "swad20.45.css"
|
#define CSS_FILE "swad20.45.css"
|
||||||
#define JS_FILE "swad20.69.1.js"
|
#define JS_FILE "swad20.69.1.js"
|
||||||
/*
|
/*
|
||||||
TODO: Rename CENTRE to CENTER in help wiki.
|
TODO: Rename CENTRE to CENTER in help wiki.
|
||||||
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
|
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
|
||||||
|
|
||||||
|
Version 21.46: Oct 26, 2021 New module swad_test_database for database queries related to self-assessment tests. (321036 lines)
|
||||||
Version 21.45.1: Oct 25, 2021 Code refactoring in test questions. (320932 lines)
|
Version 21.45.1: Oct 25, 2021 Code refactoring in test questions. (320932 lines)
|
||||||
Version 21.45: Oct 25, 2021 Functions moved to module swad_question. (320930 lines)
|
Version 21.45: Oct 25, 2021 Functions moved to module swad_question. (320930 lines)
|
||||||
Version 21.44: Oct 25, 2021 Functions moved to module swad_question. (320928 lines)
|
Version 21.44: Oct 25, 2021 Functions moved to module swad_question. (320928 lines)
|
||||||
|
|
|
@ -1928,7 +1928,7 @@ void Exa_DB_RemoveAllPrintsFromCrs (long CrsCod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************* Store user's answers of an test exam into database ************/
|
/*************** Store user's answers of a test into database ****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Exa_DB_StoreOneQstOfPrint (const struct ExaPrn_Print *Print,
|
void Exa_DB_StoreOneQstOfPrint (const struct ExaPrn_Print *Print,
|
||||||
|
|
|
@ -230,7 +230,7 @@ void ExaPrn_ShowExamPrint (void)
|
||||||
ExaLog_SetIfCanAnswer (true);
|
ExaLog_SetIfCanAnswer (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Show test exam to be answered *****/
|
/***** Show test to be answered *****/
|
||||||
ExaPrn_ShowExamPrintToFillIt (&Exams,&Exam,&Print);
|
ExaPrn_ShowExamPrintToFillIt (&Exams,&Exam,&Print);
|
||||||
}
|
}
|
||||||
else // Session not open or accessible
|
else // Session not open or accessible
|
||||||
|
@ -1111,7 +1111,7 @@ static void ExaPrn_ComputeScoreAndStoreQuestionOfPrint (struct ExaPrn_Print *Pri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Store test exam question in database *****/
|
/***** Store test question in database *****/
|
||||||
Exa_DB_StoreOneQstOfPrint (Print,
|
Exa_DB_StoreOneQstOfPrint (Print,
|
||||||
QstInd); // 0, 1, 2, 3...
|
QstInd); // 0, 1, 2, 3...
|
||||||
}
|
}
|
||||||
|
|
|
@ -1755,7 +1755,7 @@ static void ExaRes_ShowExamResultGrade (const struct Exa_Exam *Exam,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************** Show user's and correct answers of a test exam ***************/
|
/**************** Show user's and correct answers of a test ******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void ExaRes_ShowExamAnswers (struct UsrData *UsrDat,
|
static void ExaRes_ShowExamAnswers (struct UsrData *UsrDat,
|
||||||
|
|
|
@ -26,42 +26,19 @@
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define _GNU_SOURCE // For asprintf
|
#define _GNU_SOURCE // For asprintf
|
||||||
// #include <limits.h> // For UINT_MAX
|
|
||||||
// #include <linux/limits.h> // For PATH_MAX
|
|
||||||
// #include <mysql/mysql.h> // To access MySQL databases
|
|
||||||
// #include <stdbool.h> // For boolean type
|
|
||||||
// #include <stddef.h> // For NULL
|
|
||||||
#include <stdio.h> // For asprintf
|
#include <stdio.h> // For asprintf
|
||||||
// #include <stdlib.h> // For exit, system, malloc, free, etc
|
|
||||||
#include <string.h> // For string functions
|
#include <string.h> // For string functions
|
||||||
// #include <sys/stat.h> // For mkdir
|
|
||||||
// #include <sys/types.h> // For mkdir
|
|
||||||
|
|
||||||
// #include "swad_action.h"
|
|
||||||
// #include "swad_box.h"
|
|
||||||
#include "swad_database.h"
|
#include "swad_database.h"
|
||||||
#include "swad_error.h"
|
#include "swad_error.h"
|
||||||
#include "swad_exam_set.h"
|
#include "swad_exam_set.h"
|
||||||
#include "swad_figure.h"
|
#include "swad_figure.h"
|
||||||
#include "swad_form.h"
|
#include "swad_form.h"
|
||||||
#include "swad_global.h"
|
#include "swad_global.h"
|
||||||
// #include "swad_hierarchy_level.h"
|
|
||||||
// #include "swad_HTML.h"
|
|
||||||
// #include "swad_ID.h"
|
|
||||||
// #include "swad_language.h"
|
|
||||||
// #include "swad_match.h"
|
|
||||||
// #include "swad_media.h"
|
|
||||||
// #include "swad_parameter.h"
|
|
||||||
#include "swad_question.h"
|
#include "swad_question.h"
|
||||||
#include "swad_question_import.h"
|
#include "swad_question_import.h"
|
||||||
#include "swad_tag_database.h"
|
#include "swad_tag_database.h"
|
||||||
#include "swad_test.h"
|
#include "swad_test.h"
|
||||||
// #include "swad_test_config.h"
|
|
||||||
// #include "swad_test_print.h"
|
|
||||||
// #include "swad_test_visibility.h"
|
|
||||||
// #include "swad_theme.h"
|
|
||||||
// #include "swad_user.h"
|
|
||||||
// #include "swad_xml.h"
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***************************** Public constants ******************************/
|
/***************************** Public constants ******************************/
|
||||||
|
|
|
@ -36,10 +36,6 @@
|
||||||
#include "swad_media.h"
|
#include "swad_media.h"
|
||||||
#include "swad_string.h"
|
#include "swad_string.h"
|
||||||
#include "swad_tag.h"
|
#include "swad_tag.h"
|
||||||
// #include "swad_test.h"
|
|
||||||
// #include "swad_test_config.h"
|
|
||||||
// #include "swad_test_visibility.h"
|
|
||||||
// #include "swad_user.h"
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***************************** Public constants ******************************/
|
/***************************** Public constants ******************************/
|
||||||
|
|
|
@ -25,19 +25,10 @@
|
||||||
/*********************************** Headers *********************************/
|
/*********************************** Headers *********************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
// #include <mysql/mysql.h> // To access MySQL databases
|
|
||||||
// #include <stdbool.h> // For boolean type
|
|
||||||
// #include <stdlib.h> // For free
|
|
||||||
// #include <string.h> // For string functions
|
|
||||||
|
|
||||||
// #include "swad_action.h"
|
|
||||||
#include "swad_database.h"
|
#include "swad_database.h"
|
||||||
// #include "swad_error.h"
|
|
||||||
// #include "swad_form.h"
|
|
||||||
#include "swad_global.h"
|
#include "swad_global.h"
|
||||||
#include "swad_tag.h"
|
#include "swad_tag.h"
|
||||||
#include "swad_tag_database.h"
|
#include "swad_tag_database.h"
|
||||||
// #include "swad_theme.h"
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***************************** Public constants ******************************/
|
/***************************** Public constants ******************************/
|
||||||
|
|
387
swad_test.c
387
swad_test.c
|
@ -57,6 +57,7 @@
|
||||||
#include "swad_tag_database.h"
|
#include "swad_tag_database.h"
|
||||||
#include "swad_test.h"
|
#include "swad_test.h"
|
||||||
#include "swad_test_config.h"
|
#include "swad_test_config.h"
|
||||||
|
#include "swad_test_database.h"
|
||||||
#include "swad_test_print.h"
|
#include "swad_test_print.h"
|
||||||
#include "swad_test_visibility.h"
|
#include "swad_test_visibility.h"
|
||||||
#include "swad_theme.h"
|
#include "swad_theme.h"
|
||||||
|
@ -94,17 +95,6 @@ static void Tst_ShowFormRequestTest (struct Qst_Questions *Questions);
|
||||||
static void TstPrn_GetAnswersFromForm (struct TstPrn_Print *Print);
|
static void TstPrn_GetAnswersFromForm (struct TstPrn_Print *Print);
|
||||||
|
|
||||||
static bool Tst_CheckIfNextTstAllowed (void);
|
static bool Tst_CheckIfNextTstAllowed (void);
|
||||||
static unsigned Tst_GetNumTstExamsGeneratedByMe (void);
|
|
||||||
|
|
||||||
static void Tst_DB_IncreaseMyNumTstExams (void);
|
|
||||||
static void Tst_DB_UpdateLastAccTst (unsigned NumQsts);
|
|
||||||
|
|
||||||
static void Tst_PutIconsTests (__attribute__((unused)) void *Args);
|
|
||||||
|
|
||||||
static void Tst_ShowFormConfigTst (void);
|
|
||||||
|
|
||||||
static void Tst_PutInputFieldNumQst (const char *Field,const char *Label,
|
|
||||||
unsigned Value);
|
|
||||||
|
|
||||||
static void Tst_GetQuestionsForNewTestFromDB (struct Qst_Questions *Questions,
|
static void Tst_GetQuestionsForNewTestFromDB (struct Qst_Questions *Questions,
|
||||||
struct TstPrn_Print *Print);
|
struct TstPrn_Print *Print);
|
||||||
|
@ -223,7 +213,7 @@ void Tst_ShowNewTest (void)
|
||||||
extern const char *Txt_No_questions_found_matching_your_search_criteria;
|
extern const char *Txt_No_questions_found_matching_your_search_criteria;
|
||||||
struct Qst_Questions Questions;
|
struct Qst_Questions Questions;
|
||||||
struct TstPrn_Print Print;
|
struct TstPrn_Print Print;
|
||||||
unsigned NumTstExamsGeneratedByMe;
|
unsigned NumPrintsGeneratedByMe;
|
||||||
|
|
||||||
/***** Create test *****/
|
/***** Create test *****/
|
||||||
Qst_Constructor (&Questions);
|
Qst_Constructor (&Questions);
|
||||||
|
@ -242,16 +232,16 @@ void Tst_ShowNewTest (void)
|
||||||
if (Print.NumQsts.All)
|
if (Print.NumQsts.All)
|
||||||
{
|
{
|
||||||
/***** Increase number of exams generated (answered or not) by me *****/
|
/***** Increase number of exams generated (answered or not) by me *****/
|
||||||
Tst_DB_IncreaseMyNumTstExams ();
|
Tst_DB_IncreaseNumMyPrints ();
|
||||||
NumTstExamsGeneratedByMe = Tst_GetNumTstExamsGeneratedByMe ();
|
NumPrintsGeneratedByMe = TstPrn_GetNumPrintsGeneratedByMe ();
|
||||||
|
|
||||||
/***** Create new test exam in database *****/
|
/***** Create new test print in database *****/
|
||||||
TstPrn_CreatePrintInDB (&Print);
|
TstPrn_CreatePrintInDB (&Print);
|
||||||
TstPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print,
|
TstPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print,
|
||||||
false); // Don't update question score
|
false); // Don't update question score
|
||||||
|
|
||||||
/***** Show test exam to be answered *****/
|
/***** Show test print to be answered *****/
|
||||||
TstPrn_ShowTestPrintToFillIt (&Print,NumTstExamsGeneratedByMe,TstPrn_REQUEST);
|
TstPrn_ShowTestPrintToFillIt (&Print,NumPrintsGeneratedByMe,TstPrn_REQUEST);
|
||||||
|
|
||||||
/***** Update date-time of my next allowed access to test *****/
|
/***** Update date-time of my next allowed access to test *****/
|
||||||
if (Gbl.Usrs.Me.Role.Logged == Rol_STD)
|
if (Gbl.Usrs.Me.Role.Logged == Rol_STD)
|
||||||
|
@ -272,7 +262,7 @@ void Tst_ShowNewTest (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/** Receive the draft of a test exam already (total or partially) answered ***/
|
/** Receive the draft of a test print already (total or partially) answered **/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Tst_ReceiveTestDraft (void)
|
void Tst_ReceiveTestDraft (void)
|
||||||
|
@ -286,7 +276,7 @@ void Tst_ReceiveTestDraft (void)
|
||||||
TstCfg_GetConfigFromDB ();
|
TstCfg_GetConfigFromDB ();
|
||||||
|
|
||||||
/***** Get basic parameters of the exam *****/
|
/***** Get basic parameters of the exam *****/
|
||||||
/* Get test exam code from form */
|
/* Get test print code from form */
|
||||||
TstPrn_ResetPrint (&Print);
|
TstPrn_ResetPrint (&Print);
|
||||||
if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0)
|
if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0)
|
||||||
Err_WrongTestExit ();
|
Err_WrongTestExit ();
|
||||||
|
@ -294,7 +284,7 @@ void Tst_ReceiveTestDraft (void)
|
||||||
/* Get number of this test from form */
|
/* Get number of this test from form */
|
||||||
NumTst = Tst_GetParamNumTst ();
|
NumTst = Tst_GetParamNumTst ();
|
||||||
|
|
||||||
/***** Get test exam print from database *****/
|
/***** Get test print from database *****/
|
||||||
TstPrn_GetPrintDataByPrnCod (&Print);
|
TstPrn_GetPrintDataByPrnCod (&Print);
|
||||||
|
|
||||||
/****** Get test status in database for this session-course-num.test *****/
|
/****** Get test status in database for this session-course-num.test *****/
|
||||||
|
@ -303,13 +293,13 @@ void Tst_ReceiveTestDraft (void)
|
||||||
NumTst);
|
NumTst);
|
||||||
else // Print not yet sent
|
else // Print not yet sent
|
||||||
{
|
{
|
||||||
/***** Get test exam print questions from database *****/
|
/***** Get test print questions from database *****/
|
||||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
TstPrn_GetPrintQuestionsFromDB (&Print);
|
||||||
|
|
||||||
/***** Get answers from form to assess a test *****/
|
/***** Get answers from form to assess a test *****/
|
||||||
TstPrn_GetAnswersFromForm (&Print);
|
TstPrn_GetAnswersFromForm (&Print);
|
||||||
|
|
||||||
/***** Update test exam in database *****/
|
/***** Update test print in database *****/
|
||||||
TstPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print,
|
TstPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print,
|
||||||
false); // Don't update question score
|
false); // Don't update question score
|
||||||
TstPrn_UpdatePrintInDB (&Print);
|
TstPrn_UpdatePrintInDB (&Print);
|
||||||
|
@ -318,7 +308,7 @@ void Tst_ReceiveTestDraft (void)
|
||||||
/* Begin alert */
|
/* Begin alert */
|
||||||
Ale_ShowAlert (Ale_WARNING,Txt_Please_review_your_answers_before_submitting_the_exam);
|
Ale_ShowAlert (Ale_WARNING,Txt_Please_review_your_answers_before_submitting_the_exam);
|
||||||
|
|
||||||
/* Show the same test exam to be answered */
|
/* Show the same test print to be answered */
|
||||||
TstPrn_ShowTestPrintToFillIt (&Print,NumTst,TstPrn_CONFIRM);
|
TstPrn_ShowTestPrintToFillIt (&Print,NumTst,TstPrn_CONFIRM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,7 +332,7 @@ void Tst_AssessTest (void)
|
||||||
TstCfg_GetConfigFromDB ();
|
TstCfg_GetConfigFromDB ();
|
||||||
|
|
||||||
/***** Get basic parameters of the exam *****/
|
/***** Get basic parameters of the exam *****/
|
||||||
/* Get test exam code from form */
|
/* Get test print code from form */
|
||||||
TstPrn_ResetPrint (&Print);
|
TstPrn_ResetPrint (&Print);
|
||||||
if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0)
|
if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0)
|
||||||
Err_WrongTestExit ();
|
Err_WrongTestExit ();
|
||||||
|
@ -350,7 +340,7 @@ void Tst_AssessTest (void)
|
||||||
/* Get number of this test from form */
|
/* Get number of this test from form */
|
||||||
NumTst = Tst_GetParamNumTst ();
|
NumTst = Tst_GetParamNumTst ();
|
||||||
|
|
||||||
/***** Get test exam from database *****/
|
/***** Get test print from database *****/
|
||||||
TstPrn_GetPrintDataByPrnCod (&Print);
|
TstPrn_GetPrintDataByPrnCod (&Print);
|
||||||
|
|
||||||
/****** Get test status in database for this session-course-num.test *****/
|
/****** Get test status in database for this session-course-num.test *****/
|
||||||
|
@ -359,17 +349,17 @@ void Tst_AssessTest (void)
|
||||||
NumTst);
|
NumTst);
|
||||||
else // Print not yet sent
|
else // Print not yet sent
|
||||||
{
|
{
|
||||||
/***** Get test exam questions from database *****/
|
/***** Get test print questions from database *****/
|
||||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
TstPrn_GetPrintQuestionsFromDB (&Print);
|
||||||
|
|
||||||
/***** Get answers from form to assess a test *****/
|
/***** Get answers from form to assess a test *****/
|
||||||
TstPrn_GetAnswersFromForm (&Print);
|
TstPrn_GetAnswersFromForm (&Print);
|
||||||
|
|
||||||
/***** Get if test exam will be visible by teachers *****/
|
/***** Get if test print will be visible by teachers *****/
|
||||||
Print.Sent = true; // The exam has been finished and sent by student
|
Print.Sent = true; // The exam has been finished and sent by student
|
||||||
Print.AllowTeachers = Par_GetParToBool ("AllowTchs");
|
Print.AllowTeachers = Par_GetParToBool ("AllowTchs");
|
||||||
|
|
||||||
/***** Update test exam in database *****/
|
/***** Update test print in database *****/
|
||||||
TstPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print,
|
TstPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print,
|
||||||
Gbl.Usrs.Me.Role.Logged == Rol_STD); // Update question score?
|
Gbl.Usrs.Me.Role.Logged == Rol_STD); // Update question score?
|
||||||
TstPrn_UpdatePrintInDB (&Print);
|
TstPrn_UpdatePrintInDB (&Print);
|
||||||
|
@ -412,7 +402,7 @@ void Tst_AssessTest (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/****** Get questions and answers from form to assess a test exam print ******/
|
/******** Get questions and answers from form to assess a test print *********/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void TstPrn_GetAnswersFromForm (struct TstPrn_Print *Print)
|
static void TstPrn_GetAnswersFromForm (struct TstPrn_Print *Print)
|
||||||
|
@ -453,19 +443,9 @@ static bool Tst_CheckIfNextTstAllowed (void)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/***** Get date of next allowed access to test from database *****/
|
/***** Get date of next allowed access to test from database *****/
|
||||||
if (DB_QuerySELECT (&mysql_res,"can not get last access to test",
|
if (Tst_DB_GetDateNextTstAllowed (&mysql_res))
|
||||||
"SELECT UNIX_TIMESTAMP(LastAccTst+INTERVAL (NumQstsLastTst*%lu) SECOND)-"
|
|
||||||
"UNIX_TIMESTAMP()," // row[0]
|
|
||||||
"UNIX_TIMESTAMP(LastAccTst+INTERVAL (NumQstsLastTst*%lu) SECOND)" // row[1]
|
|
||||||
" FROM crs_user_settings"
|
|
||||||
" WHERE UsrCod=%ld"
|
|
||||||
" AND CrsCod=%ld",
|
|
||||||
TstCfg_GetConfigMinTimeNxtTstPerQst (),
|
|
||||||
TstCfg_GetConfigMinTimeNxtTstPerQst (),
|
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod) == 1)
|
|
||||||
{
|
{
|
||||||
/* Get seconds from now to next access to test */
|
/* Get seconds from now to next access to test (row[0]) */
|
||||||
row = mysql_fetch_row (mysql_res);
|
row = mysql_fetch_row (mysql_res);
|
||||||
if (row[0])
|
if (row[0])
|
||||||
if (sscanf (row[0],"%ld",&NumSecondsFromNowToNextAccTst) == 1)
|
if (sscanf (row[0],"%ld",&NumSecondsFromNowToNextAccTst) == 1)
|
||||||
|
@ -473,7 +453,7 @@ static bool Tst_CheckIfNextTstAllowed (void)
|
||||||
TimeNextTestUTC = Dat_GetUNIXTimeFromStr (row[1]);
|
TimeNextTestUTC = Dat_GetUNIXTimeFromStr (row[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Err_ShowErrorAndExit ("Error when reading date of next allowed access to test.");
|
Err_WrongDateExit ();
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
/***** Free structure that stores the query result *****/
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
@ -482,107 +462,26 @@ static bool Tst_CheckIfNextTstAllowed (void)
|
||||||
if (NumSecondsFromNowToNextAccTst > 0)
|
if (NumSecondsFromNowToNextAccTst > 0)
|
||||||
{
|
{
|
||||||
/***** Write warning *****/
|
/***** Write warning *****/
|
||||||
Ale_ShowAlert (Ale_WARNING,"%s:<br /><span id=\"date_next_test\"></span>."
|
Ale_ShowAlert (Ale_WARNING,"%s:<br />"
|
||||||
"<script type=\"text/javascript\">"
|
"<span id=\"date_next_test\"></span>."
|
||||||
"writeLocalDateHMSFromUTC('date_next_test',%ld,"
|
"<script type=\"text/javascript\">"
|
||||||
"%u,', ',%u,true,true,true,0x7);"
|
"writeLocalDateHMSFromUTC('date_next_test',%ld,"
|
||||||
"</script>",
|
"%u,', ',%u,true,true,true,0x7);"
|
||||||
|
"</script>",
|
||||||
Txt_You_can_not_take_a_new_test_until,
|
Txt_You_can_not_take_a_new_test_until,
|
||||||
(long) TimeNextTestUTC,
|
(long) TimeNextTestUTC,
|
||||||
(unsigned) Gbl.Prefs.DateFormat,
|
(unsigned) Gbl.Prefs.DateFormat,
|
||||||
(unsigned) Gbl.Prefs.Language);
|
(unsigned) Gbl.Prefs.Language);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/***************** Get number of test exams generated by me ******************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
static unsigned Tst_GetNumTstExamsGeneratedByMe (void)
|
|
||||||
{
|
|
||||||
MYSQL_RES *mysql_res;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
unsigned long NumRows;
|
|
||||||
unsigned NumTstExamsGeneratedByMe = 0;
|
|
||||||
|
|
||||||
if (Gbl.Usrs.Me.IBelongToCurrentCrs)
|
|
||||||
{
|
|
||||||
/***** Get number of test exams generated by me from database *****/
|
|
||||||
NumRows = DB_QuerySELECT (&mysql_res,"can not get number of test exams generated",
|
|
||||||
"SELECT NumAccTst" // row[0]
|
|
||||||
" FROM crs_user_settings"
|
|
||||||
" WHERE UsrCod=%ld"
|
|
||||||
" AND CrsCod=%ld",
|
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod);
|
|
||||||
|
|
||||||
if (NumRows == 0)
|
|
||||||
NumTstExamsGeneratedByMe = 0;
|
|
||||||
else if (NumRows == 1)
|
|
||||||
{
|
|
||||||
/* Get number of hits */
|
|
||||||
row = mysql_fetch_row (mysql_res);
|
|
||||||
if (row[0] == NULL)
|
|
||||||
NumTstExamsGeneratedByMe = 0;
|
|
||||||
else if (sscanf (row[0],"%u",&NumTstExamsGeneratedByMe) != 1)
|
|
||||||
NumTstExamsGeneratedByMe = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Err_ShowErrorAndExit ("Error when getting number of hits to test.");
|
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NumTstExamsGeneratedByMe;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*********** Update my number of accesses to test in this course *************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
static void Tst_DB_IncreaseMyNumTstExams (void)
|
|
||||||
{
|
|
||||||
/***** Trivial check *****/
|
|
||||||
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/***** Update my number of accesses to test in this course *****/
|
|
||||||
DB_QueryUPDATE ("can not update the number of accesses to test",
|
|
||||||
"UPDATE crs_user_settings"
|
|
||||||
" SET NumAccTst=NumAccTst+1"
|
|
||||||
" WHERE UsrCod=%ld"
|
|
||||||
" AND CrsCod=%ld",
|
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/************ Update date-time of my next allowed access to test *************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
static void Tst_DB_UpdateLastAccTst (unsigned NumQsts)
|
|
||||||
{
|
|
||||||
/***** Update date-time and number of questions of this test *****/
|
|
||||||
DB_QueryUPDATE ("can not update time and number of questions of this test",
|
|
||||||
"UPDATE crs_user_settings"
|
|
||||||
" SET LastAccTst=NOW(),"
|
|
||||||
"NumQstsLastTst=%u"
|
|
||||||
" WHERE UsrCod=%ld"
|
|
||||||
" AND CrsCod=%ld",
|
|
||||||
NumQsts,
|
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********************* Put contextual icons in tests *************************/
|
/********************* Put contextual icons in tests *************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Tst_PutIconsTests (__attribute__((unused)) void *Args)
|
void Tst_PutIconsTests (__attribute__((unused)) void *Args)
|
||||||
{
|
{
|
||||||
switch (Gbl.Usrs.Me.Role.Logged)
|
switch (Gbl.Usrs.Me.Role.Logged)
|
||||||
{
|
{
|
||||||
|
@ -613,228 +512,6 @@ static void Tst_PutIconsTests (__attribute__((unused)) void *Args)
|
||||||
Fig_PutIconToShowFigure (Fig_TESTS);
|
Fig_PutIconToShowFigure (Fig_TESTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/***************************** Form to rename tags ***************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
void Tst_ShowFormConfig (void)
|
|
||||||
{
|
|
||||||
extern const char *Txt_Please_specify_if_you_allow_downloading_the_question_bank_from_other_applications;
|
|
||||||
|
|
||||||
/***** If current course has tests and pluggable is unknown... *****/
|
|
||||||
if (Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown ())
|
|
||||||
Ale_ShowAlert (Ale_WARNING,Txt_Please_specify_if_you_allow_downloading_the_question_bank_from_other_applications);
|
|
||||||
|
|
||||||
/***** Form to configure test *****/
|
|
||||||
Tst_ShowFormConfigTst ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*************** Get configuration of test for current course ****************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
// Returns true if course has test tags and pluggable is unknown
|
|
||||||
// Return false if course has no test tags or pluggable is known
|
|
||||||
|
|
||||||
bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void)
|
|
||||||
{
|
|
||||||
extern const char *TstCfg_PluggableDB[TstCfg_NUM_OPTIONS_PLUGGABLE];
|
|
||||||
MYSQL_RES *mysql_res;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
unsigned NumRows;
|
|
||||||
TstCfg_Pluggable_t Pluggable;
|
|
||||||
|
|
||||||
/***** Get pluggability of tests for current course from database *****/
|
|
||||||
NumRows = (unsigned)
|
|
||||||
DB_QuerySELECT (&mysql_res,"can not get configuration of test",
|
|
||||||
"SELECT Pluggable" // row[0]
|
|
||||||
" FROM tst_config"
|
|
||||||
" WHERE CrsCod=%ld",
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod);
|
|
||||||
|
|
||||||
if (NumRows == 0)
|
|
||||||
TstCfg_SetConfigPluggable (TstCfg_PLUGGABLE_UNKNOWN);
|
|
||||||
else // NumRows == 1
|
|
||||||
{
|
|
||||||
/***** Get whether test are visible via plugins or not *****/
|
|
||||||
row = mysql_fetch_row (mysql_res);
|
|
||||||
|
|
||||||
TstCfg_SetConfigPluggable (TstCfg_PLUGGABLE_UNKNOWN);
|
|
||||||
for (Pluggable = TstCfg_PLUGGABLE_NO;
|
|
||||||
Pluggable <= TstCfg_PLUGGABLE_YES;
|
|
||||||
Pluggable++)
|
|
||||||
if (!strcmp (row[0],TstCfg_PluggableDB[Pluggable]))
|
|
||||||
{
|
|
||||||
TstCfg_SetConfigPluggable (Pluggable);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
|
||||||
|
|
||||||
/***** Get if current course has tests from database *****/
|
|
||||||
if (TstCfg_GetConfigPluggable () == TstCfg_PLUGGABLE_UNKNOWN)
|
|
||||||
return Tag_DB_CheckIfCurrentCrsHasTestTags (); // Return true if course has tests
|
|
||||||
|
|
||||||
return false; // Pluggable is not unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/********************* Show a form to to configure test **********************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
static void Tst_ShowFormConfigTst (void)
|
|
||||||
{
|
|
||||||
extern const char *Hlp_ASSESSMENT_Tests_configuring_tests;
|
|
||||||
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
|
||||||
extern const char *Txt_Configure_tests;
|
|
||||||
extern const char *Txt_Plugins;
|
|
||||||
extern const char *Txt_TST_PLUGGABLE[TstCfg_NUM_OPTIONS_PLUGGABLE];
|
|
||||||
extern const char *Txt_Number_of_questions;
|
|
||||||
extern const char *Txt_minimum;
|
|
||||||
extern const char *Txt_default;
|
|
||||||
extern const char *Txt_maximum;
|
|
||||||
extern const char *Txt_Minimum_time_seconds_per_question_between_two_tests;
|
|
||||||
extern const char *Txt_Result_visibility;
|
|
||||||
extern const char *Txt_Save_changes;
|
|
||||||
struct Qst_Questions Questions;
|
|
||||||
TstCfg_Pluggable_t Pluggable;
|
|
||||||
char StrMinTimeNxtTstPerQst[Cns_MAX_DECIMAL_DIGITS_ULONG + 1];
|
|
||||||
|
|
||||||
/***** Create test *****/
|
|
||||||
Qst_Constructor (&Questions);
|
|
||||||
|
|
||||||
/***** Read test configuration from database *****/
|
|
||||||
TstCfg_GetConfigFromDB ();
|
|
||||||
|
|
||||||
/***** Begin box *****/
|
|
||||||
Box_BoxBegin (NULL,Txt_Configure_tests,
|
|
||||||
Tst_PutIconsTests,NULL,
|
|
||||||
Hlp_ASSESSMENT_Tests_configuring_tests,Box_NOT_CLOSABLE);
|
|
||||||
|
|
||||||
/***** Begin form *****/
|
|
||||||
Frm_BeginForm (ActRcvCfgTst);
|
|
||||||
|
|
||||||
/***** Tests are visible from plugins? *****/
|
|
||||||
HTM_TABLE_BeginCenterPadding (2);
|
|
||||||
HTM_TR_Begin (NULL);
|
|
||||||
|
|
||||||
HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
|
||||||
HTM_TxtColon (Txt_Plugins);
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
HTM_TD_Begin ("class=\"LB\"");
|
|
||||||
for (Pluggable = TstCfg_PLUGGABLE_NO;
|
|
||||||
Pluggable <= TstCfg_PLUGGABLE_YES;
|
|
||||||
Pluggable++)
|
|
||||||
{
|
|
||||||
HTM_LABEL_Begin ("class=\"DAT\"");
|
|
||||||
HTM_INPUT_RADIO ("Pluggable",false,
|
|
||||||
"value=\"%u\"%s",
|
|
||||||
(unsigned) Pluggable,
|
|
||||||
Pluggable == TstCfg_GetConfigPluggable () ? " checked=\"checked\"" :
|
|
||||||
"");
|
|
||||||
HTM_Txt (Txt_TST_PLUGGABLE[Pluggable]);
|
|
||||||
HTM_LABEL_End ();
|
|
||||||
HTM_BR ();
|
|
||||||
}
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
HTM_TR_End ();
|
|
||||||
|
|
||||||
/***** Number of questions *****/
|
|
||||||
HTM_TR_Begin (NULL);
|
|
||||||
|
|
||||||
HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
|
||||||
HTM_TxtColon (Txt_Number_of_questions);
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
HTM_TD_Begin ("class=\"LB\"");
|
|
||||||
HTM_TABLE_BeginPadding (2);
|
|
||||||
Tst_PutInputFieldNumQst ("NumQstMin",Txt_minimum,
|
|
||||||
TstCfg_GetConfigMin ()); // Minimum number of questions
|
|
||||||
Tst_PutInputFieldNumQst ("NumQstDef",Txt_default,
|
|
||||||
TstCfg_GetConfigDef ()); // Default number of questions
|
|
||||||
Tst_PutInputFieldNumQst ("NumQstMax",Txt_maximum,
|
|
||||||
TstCfg_GetConfigMax ()); // Maximum number of questions
|
|
||||||
HTM_TABLE_End ();
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
HTM_TR_End ();
|
|
||||||
|
|
||||||
/***** Minimum time between consecutive tests, per question *****/
|
|
||||||
HTM_TR_Begin (NULL);
|
|
||||||
|
|
||||||
/* Label */
|
|
||||||
Frm_LabelColumn ("RT","MinTimeNxtTstPerQst",
|
|
||||||
Txt_Minimum_time_seconds_per_question_between_two_tests);
|
|
||||||
|
|
||||||
/* Data */
|
|
||||||
HTM_TD_Begin ("class=\"LB\"");
|
|
||||||
snprintf (StrMinTimeNxtTstPerQst,sizeof (StrMinTimeNxtTstPerQst),"%lu",
|
|
||||||
TstCfg_GetConfigMinTimeNxtTstPerQst ());
|
|
||||||
HTM_INPUT_TEXT ("MinTimeNxtTstPerQst",Cns_MAX_DECIMAL_DIGITS_ULONG,StrMinTimeNxtTstPerQst,
|
|
||||||
HTM_DONT_SUBMIT_ON_CHANGE,
|
|
||||||
"id=\"MinTimeNxtTstPerQst\" size=\"7\" required=\"required\"");
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
HTM_TR_End ();
|
|
||||||
|
|
||||||
/***** Visibility of test exams *****/
|
|
||||||
HTM_TR_Begin (NULL);
|
|
||||||
|
|
||||||
HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
|
||||||
HTM_TxtColon (Txt_Result_visibility);
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
HTM_TD_Begin ("class=\"LB\"");
|
|
||||||
TstVis_PutVisibilityCheckboxes (TstCfg_GetConfigVisibility ());
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
HTM_TR_End ();
|
|
||||||
|
|
||||||
HTM_TABLE_End ();
|
|
||||||
|
|
||||||
/***** Send button *****/
|
|
||||||
Btn_PutConfirmButton (Txt_Save_changes);
|
|
||||||
|
|
||||||
/***** End form *****/
|
|
||||||
Frm_EndForm ();
|
|
||||||
|
|
||||||
/***** End box *****/
|
|
||||||
Box_BoxEnd ();
|
|
||||||
|
|
||||||
/***** Destroy test *****/
|
|
||||||
Qst_Destructor (&Questions);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*************** Get configuration of test for current course ****************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
static void Tst_PutInputFieldNumQst (const char *Field,const char *Label,
|
|
||||||
unsigned Value)
|
|
||||||
{
|
|
||||||
char StrValue[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
|
|
||||||
|
|
||||||
HTM_TR_Begin (NULL);
|
|
||||||
|
|
||||||
HTM_TD_Begin ("class=\"RM\"");
|
|
||||||
HTM_LABEL_Begin ("for=\"%s\" class=\"DAT\"",Field);
|
|
||||||
HTM_Txt (Label);
|
|
||||||
HTM_LABEL_End ();
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
HTM_TD_Begin ("class=\"LM\"");
|
|
||||||
snprintf (StrValue,sizeof (StrValue),"%u",Value);
|
|
||||||
HTM_INPUT_TEXT (Field,Cns_MAX_DECIMAL_DIGITS_UINT,StrValue,
|
|
||||||
HTM_DONT_SUBMIT_ON_CHANGE,
|
|
||||||
"id=\"%s\" size=\"3\" required=\"required\"",Field);
|
|
||||||
HTM_TD_End ();
|
|
||||||
|
|
||||||
HTM_TR_End ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************** Get questions for a new test from the database ***************/
|
/************** Get questions for a new test from the database ***************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -1001,7 +678,7 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Qst_Questions *Questions,
|
||||||
Print->PrintedQuestions[QstInd].StrAnswers[0] = '\0';
|
Print->PrintedQuestions[QstInd].StrAnswers[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Get if test exam will be visible by teachers *****/
|
/***** Get if test print will be visible by teachers *****/
|
||||||
Print->AllowTeachers = Par_GetParToBool ("AllowTchs");
|
Print->AllowTeachers = Par_GetParToBool ("AllowTchs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1170,7 +847,7 @@ bool Tst_GetParamsTst (struct Qst_Questions *Questions,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******** Get parameter with the number of test exam generated by me *********/
|
/******** Get parameter with the number of test prints generated by me *******/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static unsigned Tst_GetParamNumTst (void)
|
static unsigned Tst_GetParamNumTst (void)
|
||||||
|
@ -1264,7 +941,7 @@ unsigned Tst_CountNumQuestionsInList (const char *ListQuestions)
|
||||||
|
|
||||||
void Tst_RemoveCrsTests (long CrsCod)
|
void Tst_RemoveCrsTests (long CrsCod)
|
||||||
{
|
{
|
||||||
/***** Remove all test exam prints made in the course *****/
|
/***** Remove all test prints made in the course *****/
|
||||||
TstPrn_RemoveCrsPrints (CrsCod);
|
TstPrn_RemoveCrsPrints (CrsCod);
|
||||||
|
|
||||||
/***** Remove test configuration of the course *****/
|
/***** Remove test configuration of the course *****/
|
||||||
|
|
|
@ -64,11 +64,10 @@ void Tst_ShowNewTest (void);
|
||||||
void Tst_ReceiveTestDraft (void);
|
void Tst_ReceiveTestDraft (void);
|
||||||
void Tst_AssessTest (void);
|
void Tst_AssessTest (void);
|
||||||
|
|
||||||
|
void Tst_PutIconsTests (__attribute__((unused)) void *Args);
|
||||||
|
|
||||||
bool Tst_GetParamsTst (struct Qst_Questions *Questions,
|
bool Tst_GetParamsTst (struct Qst_Questions *Questions,
|
||||||
Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions);
|
Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions);
|
||||||
void Tst_ShowFormConfig (void);
|
|
||||||
|
|
||||||
bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void);
|
|
||||||
|
|
||||||
unsigned Tst_CountNumQuestionsInList (const char *ListQuestions);
|
unsigned Tst_CountNumQuestionsInList (const char *ListQuestions);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
#include <string.h> // For string functions
|
#include <string.h> // For string functions
|
||||||
|
|
||||||
#include "swad_database.h"
|
#include "swad_database.h"
|
||||||
|
#include "swad_form.h"
|
||||||
#include "swad_global.h"
|
#include "swad_global.h"
|
||||||
|
#include "swad_tag_database.h"
|
||||||
#include "swad_test.h"
|
#include "swad_test.h"
|
||||||
#include "swad_test_config.h"
|
#include "swad_test_config.h"
|
||||||
#include "swad_test_visibility.h"
|
#include "swad_test_visibility.h"
|
||||||
|
@ -78,9 +80,235 @@ struct TstCfg_Config TstCfg_Config;
|
||||||
/***************************** Private prototypes ****************************/
|
/***************************** Private prototypes ****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void TstCfg_ShowFormConfig (void);
|
||||||
|
static void TstCfg_PutInputFieldNumQsts (const char *Field,const char *Label,
|
||||||
|
unsigned Value);
|
||||||
|
|
||||||
static TstCfg_Pluggable_t TstCfg_GetPluggableFromForm (void);
|
static TstCfg_Pluggable_t TstCfg_GetPluggableFromForm (void);
|
||||||
static void TstCfg_CheckAndCorrectMinDefMax (void);
|
static void TstCfg_CheckAndCorrectMinDefMax (void);
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***************************** Form to rename tags ***************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void TstCfg_CheckAndShowFormConfig (void)
|
||||||
|
{
|
||||||
|
extern const char *Txt_Please_specify_if_you_allow_downloading_the_question_bank_from_other_applications;
|
||||||
|
|
||||||
|
/***** If current course has tests and pluggable is unknown... *****/
|
||||||
|
if (TstCfg_CheckIfPluggableIsUnknownAndCrsHasTests ())
|
||||||
|
Ale_ShowAlert (Ale_WARNING,Txt_Please_specify_if_you_allow_downloading_the_question_bank_from_other_applications);
|
||||||
|
|
||||||
|
/***** Form to configure test *****/
|
||||||
|
TstCfg_ShowFormConfig ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/*************** Get configuration of test for current course ****************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
// Returns true if course has test tags and pluggable is unknown
|
||||||
|
// Return false if course has no test tags or pluggable is known
|
||||||
|
|
||||||
|
bool TstCfg_CheckIfPluggableIsUnknownAndCrsHasTests (void)
|
||||||
|
{
|
||||||
|
extern const char *TstCfg_PluggableDB[TstCfg_NUM_OPTIONS_PLUGGABLE];
|
||||||
|
MYSQL_RES *mysql_res;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
unsigned NumRows;
|
||||||
|
TstCfg_Pluggable_t Pluggable;
|
||||||
|
|
||||||
|
/***** Get pluggability of tests for current course from database *****/
|
||||||
|
NumRows = (unsigned)
|
||||||
|
DB_QuerySELECT (&mysql_res,"can not get configuration of test",
|
||||||
|
"SELECT Pluggable" // row[0]
|
||||||
|
" FROM tst_config"
|
||||||
|
" WHERE CrsCod=%ld",
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod);
|
||||||
|
|
||||||
|
if (NumRows == 0)
|
||||||
|
TstCfg_SetConfigPluggable (TstCfg_PLUGGABLE_UNKNOWN);
|
||||||
|
else // NumRows == 1
|
||||||
|
{
|
||||||
|
/***** Get whether test are visible via plugins or not *****/
|
||||||
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
|
||||||
|
TstCfg_SetConfigPluggable (TstCfg_PLUGGABLE_UNKNOWN);
|
||||||
|
for (Pluggable = TstCfg_PLUGGABLE_NO;
|
||||||
|
Pluggable <= TstCfg_PLUGGABLE_YES;
|
||||||
|
Pluggable++)
|
||||||
|
if (!strcmp (row[0],TstCfg_PluggableDB[Pluggable]))
|
||||||
|
{
|
||||||
|
TstCfg_SetConfigPluggable (Pluggable);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Free structure that stores the query result *****/
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
|
||||||
|
/***** Get if current course has tests from database *****/
|
||||||
|
if (TstCfg_GetConfigPluggable () == TstCfg_PLUGGABLE_UNKNOWN)
|
||||||
|
return Tag_DB_CheckIfCurrentCrsHasTestTags (); // Return true if course has test tags
|
||||||
|
|
||||||
|
return false; // Pluggable is not unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/********************* Show a form to to configure test **********************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void TstCfg_ShowFormConfig (void)
|
||||||
|
{
|
||||||
|
extern const char *Hlp_ASSESSMENT_Tests_configuring_tests;
|
||||||
|
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
||||||
|
extern const char *Txt_Configure_tests;
|
||||||
|
extern const char *Txt_Plugins;
|
||||||
|
extern const char *Txt_TST_PLUGGABLE[TstCfg_NUM_OPTIONS_PLUGGABLE];
|
||||||
|
extern const char *Txt_Number_of_questions;
|
||||||
|
extern const char *Txt_minimum;
|
||||||
|
extern const char *Txt_default;
|
||||||
|
extern const char *Txt_maximum;
|
||||||
|
extern const char *Txt_Minimum_time_seconds_per_question_between_two_tests;
|
||||||
|
extern const char *Txt_Result_visibility;
|
||||||
|
extern const char *Txt_Save_changes;
|
||||||
|
struct Qst_Questions Questions;
|
||||||
|
TstCfg_Pluggable_t Pluggable;
|
||||||
|
char StrMinTimeNxtTstPerQst[Cns_MAX_DECIMAL_DIGITS_ULONG + 1];
|
||||||
|
|
||||||
|
/***** Create test *****/
|
||||||
|
Qst_Constructor (&Questions);
|
||||||
|
|
||||||
|
/***** Read test configuration from database *****/
|
||||||
|
TstCfg_GetConfigFromDB ();
|
||||||
|
|
||||||
|
/***** Begin box *****/
|
||||||
|
Box_BoxBegin (NULL,Txt_Configure_tests,
|
||||||
|
Tst_PutIconsTests,NULL,
|
||||||
|
Hlp_ASSESSMENT_Tests_configuring_tests,Box_NOT_CLOSABLE);
|
||||||
|
|
||||||
|
/***** Begin form *****/
|
||||||
|
Frm_BeginForm (ActRcvCfgTst);
|
||||||
|
|
||||||
|
/***** Tests are visible from plugins? *****/
|
||||||
|
HTM_TABLE_BeginCenterPadding (2);
|
||||||
|
HTM_TR_Begin (NULL);
|
||||||
|
|
||||||
|
HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
||||||
|
HTM_TxtColon (Txt_Plugins);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TD_Begin ("class=\"LB\"");
|
||||||
|
for (Pluggable = TstCfg_PLUGGABLE_NO;
|
||||||
|
Pluggable <= TstCfg_PLUGGABLE_YES;
|
||||||
|
Pluggable++)
|
||||||
|
{
|
||||||
|
HTM_LABEL_Begin ("class=\"DAT\"");
|
||||||
|
HTM_INPUT_RADIO ("Pluggable",false,
|
||||||
|
"value=\"%u\"%s",
|
||||||
|
(unsigned) Pluggable,
|
||||||
|
Pluggable == TstCfg_GetConfigPluggable () ? " checked=\"checked\"" :
|
||||||
|
"");
|
||||||
|
HTM_Txt (Txt_TST_PLUGGABLE[Pluggable]);
|
||||||
|
HTM_LABEL_End ();
|
||||||
|
HTM_BR ();
|
||||||
|
}
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TR_End ();
|
||||||
|
|
||||||
|
/***** Number of questions *****/
|
||||||
|
HTM_TR_Begin (NULL);
|
||||||
|
|
||||||
|
HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
||||||
|
HTM_TxtColon (Txt_Number_of_questions);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TD_Begin ("class=\"LB\"");
|
||||||
|
HTM_TABLE_BeginPadding (2);
|
||||||
|
TstCfg_PutInputFieldNumQsts ("NumQstMin",Txt_minimum,
|
||||||
|
TstCfg_GetConfigMin ()); // Minimum number of questions
|
||||||
|
TstCfg_PutInputFieldNumQsts ("NumQstDef",Txt_default,
|
||||||
|
TstCfg_GetConfigDef ()); // Default number of questions
|
||||||
|
TstCfg_PutInputFieldNumQsts ("NumQstMax",Txt_maximum,
|
||||||
|
TstCfg_GetConfigMax ()); // Maximum number of questions
|
||||||
|
HTM_TABLE_End ();
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TR_End ();
|
||||||
|
|
||||||
|
/***** Minimum time between consecutive tests, per question *****/
|
||||||
|
HTM_TR_Begin (NULL);
|
||||||
|
|
||||||
|
/* Label */
|
||||||
|
Frm_LabelColumn ("RT","MinTimeNxtTstPerQst",
|
||||||
|
Txt_Minimum_time_seconds_per_question_between_two_tests);
|
||||||
|
|
||||||
|
/* Data */
|
||||||
|
HTM_TD_Begin ("class=\"LB\"");
|
||||||
|
snprintf (StrMinTimeNxtTstPerQst,sizeof (StrMinTimeNxtTstPerQst),"%lu",
|
||||||
|
TstCfg_GetConfigMinTimeNxtTstPerQst ());
|
||||||
|
HTM_INPUT_TEXT ("MinTimeNxtTstPerQst",Cns_MAX_DECIMAL_DIGITS_ULONG,StrMinTimeNxtTstPerQst,
|
||||||
|
HTM_DONT_SUBMIT_ON_CHANGE,
|
||||||
|
"id=\"MinTimeNxtTstPerQst\" size=\"7\" required=\"required\"");
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TR_End ();
|
||||||
|
|
||||||
|
/***** Visibility of test prints *****/
|
||||||
|
HTM_TR_Begin (NULL);
|
||||||
|
|
||||||
|
HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
||||||
|
HTM_TxtColon (Txt_Result_visibility);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TD_Begin ("class=\"LB\"");
|
||||||
|
TstVis_PutVisibilityCheckboxes (TstCfg_GetConfigVisibility ());
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TR_End ();
|
||||||
|
|
||||||
|
HTM_TABLE_End ();
|
||||||
|
|
||||||
|
/***** Send button *****/
|
||||||
|
Btn_PutConfirmButton (Txt_Save_changes);
|
||||||
|
|
||||||
|
/***** End form *****/
|
||||||
|
Frm_EndForm ();
|
||||||
|
|
||||||
|
/***** End box *****/
|
||||||
|
Box_BoxEnd ();
|
||||||
|
|
||||||
|
/***** Destroy test *****/
|
||||||
|
Qst_Destructor (&Questions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/*************** Get configuration of test for current course ****************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void TstCfg_PutInputFieldNumQsts (const char *Field,const char *Label,
|
||||||
|
unsigned Value)
|
||||||
|
{
|
||||||
|
char StrValue[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
|
||||||
|
|
||||||
|
HTM_TR_Begin (NULL);
|
||||||
|
|
||||||
|
HTM_TD_Begin ("class=\"RM\"");
|
||||||
|
HTM_LABEL_Begin ("for=\"%s\" class=\"DAT\"",Field);
|
||||||
|
HTM_Txt (Label);
|
||||||
|
HTM_LABEL_End ();
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TD_Begin ("class=\"LM\"");
|
||||||
|
snprintf (StrValue,sizeof (StrValue),"%u",Value);
|
||||||
|
HTM_INPUT_TEXT (Field,Cns_MAX_DECIMAL_DIGITS_UINT,StrValue,
|
||||||
|
HTM_DONT_SUBMIT_ON_CHANGE,
|
||||||
|
"id=\"%s\" size=\"3\" required=\"required\"",Field);
|
||||||
|
HTM_TD_End ();
|
||||||
|
|
||||||
|
HTM_TR_End ();
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*************** Get configuration of test for current course ****************/
|
/*************** Get configuration of test for current course ****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -242,7 +470,7 @@ void TstCfg_ReceiveConfigTst (void)
|
||||||
Ale_ShowAlert (Ale_SUCCESS,Txt_The_test_configuration_has_been_updated);
|
Ale_ShowAlert (Ale_SUCCESS,Txt_The_test_configuration_has_been_updated);
|
||||||
|
|
||||||
/***** Show again the form to configure test *****/
|
/***** Show again the form to configure test *****/
|
||||||
Tst_ShowFormConfig ();
|
TstCfg_CheckAndShowFormConfig ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -56,6 +56,9 @@ typedef enum
|
||||||
/***************************** Public prototypes *****************************/
|
/***************************** Public prototypes *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void TstCfg_CheckAndShowFormConfig (void);
|
||||||
|
bool TstCfg_CheckIfPluggableIsUnknownAndCrsHasTests (void);
|
||||||
|
|
||||||
void TstCfg_GetConfigFromDB (void);
|
void TstCfg_GetConfigFromDB (void);
|
||||||
|
|
||||||
void TstCfg_GetConfigFromRow (MYSQL_ROW row);
|
void TstCfg_GetConfigFromRow (MYSQL_ROW row);
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
// swad_test_database.c: self-assessment tests, operations with database
|
||||||
|
|
||||||
|
/*
|
||||||
|
SWAD (Shared Workspace At a Distance),
|
||||||
|
is a web platform developed at the University of Granada (Spain),
|
||||||
|
and used to support university teaching.
|
||||||
|
|
||||||
|
This file is part of SWAD core.
|
||||||
|
Copyright (C) 1999-2021 Antonio Cañas Vargas
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/*****************************************************************************/
|
||||||
|
/*********************************** Headers *********************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
// #define _GNU_SOURCE // For asprintf
|
||||||
|
// #include <limits.h> // For UINT_MAX
|
||||||
|
// #include <linux/limits.h> // For PATH_MAX
|
||||||
|
// #include <mysql/mysql.h> // To access MySQL databases
|
||||||
|
// #include <stdbool.h> // For boolean type
|
||||||
|
// #include <stddef.h> // For NULL
|
||||||
|
// #include <stdio.h> // For asprintf
|
||||||
|
// #include <stdlib.h> // For exit, system, malloc, free, etc
|
||||||
|
// #include <string.h> // For string functions
|
||||||
|
// #include <sys/stat.h> // For mkdir
|
||||||
|
// #include <sys/types.h> // For mkdir
|
||||||
|
|
||||||
|
// #include "swad_action.h"
|
||||||
|
// #include "swad_box.h"
|
||||||
|
#include "swad_database.h"
|
||||||
|
// #include "swad_error.h"
|
||||||
|
// #include "swad_exam_set.h"
|
||||||
|
// #include "swad_figure.h"
|
||||||
|
// #include "swad_form.h"
|
||||||
|
#include "swad_global.h"
|
||||||
|
// #include "swad_hierarchy_level.h"
|
||||||
|
// #include "swad_HTML.h"
|
||||||
|
// #include "swad_ID.h"
|
||||||
|
// #include "swad_language.h"
|
||||||
|
// #include "swad_match.h"
|
||||||
|
// #include "swad_media.h"
|
||||||
|
// #include "swad_parameter.h"
|
||||||
|
// #include "swad_question.h"
|
||||||
|
// #include "swad_question_import.h"
|
||||||
|
// #include "swad_tag_database.h"
|
||||||
|
// #include "swad_test.h"
|
||||||
|
#include "swad_test_config.h"
|
||||||
|
// #include "swad_test_print.h"
|
||||||
|
// #include "swad_test_visibility.h"
|
||||||
|
// #include "swad_theme.h"
|
||||||
|
// #include "swad_user.h"
|
||||||
|
// #include "swad_xml.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***************************** Public constants ******************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**************************** Private constants ******************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/******************************* Private types *******************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************** External global variables from others modules ****************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
extern struct Globals Gbl;
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************************* Private global variables **************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***************************** Private prototypes ****************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************** Update my number of test prints in this course ***************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Tst_DB_IncreaseNumMyPrints (void)
|
||||||
|
{
|
||||||
|
/***** Trivial check *****/
|
||||||
|
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/***** Update my number of accesses to test in this course *****/
|
||||||
|
DB_QueryUPDATE ("can not update the number of accesses to test",
|
||||||
|
"UPDATE crs_user_settings"
|
||||||
|
" SET NumAccTst=NumAccTst+1"
|
||||||
|
" WHERE UsrCod=%ld"
|
||||||
|
" AND CrsCod=%ld",
|
||||||
|
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/******** Update date-time and number of questions of this test print ********/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Tst_DB_UpdateLastAccTst (unsigned NumQsts)
|
||||||
|
{
|
||||||
|
DB_QueryUPDATE ("can not update time and number of questions of this test",
|
||||||
|
"UPDATE crs_user_settings"
|
||||||
|
" SET LastAccTst=NOW(),"
|
||||||
|
"NumQstsLastTst=%u"
|
||||||
|
" WHERE UsrCod=%ld"
|
||||||
|
" AND CrsCod=%ld",
|
||||||
|
NumQsts,
|
||||||
|
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/********** Get date of next allowed access to test from database ************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned Tst_DB_GetDateNextTstAllowed (MYSQL_RES **mysql_res)
|
||||||
|
{
|
||||||
|
return (unsigned)
|
||||||
|
DB_QuerySELECT (mysql_res,"can not get date of last test print",
|
||||||
|
"SELECT UNIX_TIMESTAMP(LastAccTst+INTERVAL (NumQstsLastTst*%lu) SECOND)-"
|
||||||
|
"UNIX_TIMESTAMP()," // row[0]
|
||||||
|
"UNIX_TIMESTAMP(LastAccTst+INTERVAL (NumQstsLastTst*%lu) SECOND)" // row[1]
|
||||||
|
" FROM crs_user_settings"
|
||||||
|
" WHERE UsrCod=%ld"
|
||||||
|
" AND CrsCod=%ld",
|
||||||
|
TstCfg_GetConfigMinTimeNxtTstPerQst (),
|
||||||
|
TstCfg_GetConfigMinTimeNxtTstPerQst (),
|
||||||
|
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**************** Get number of test prints generated by me ******************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned Tst_DB_GetNumPrintsGeneratedByMe (MYSQL_RES **mysql_res)
|
||||||
|
{
|
||||||
|
return (unsigned)
|
||||||
|
DB_QuerySELECT (mysql_res,"can not get number of test prints generated",
|
||||||
|
"SELECT NumAccTst" // row[0]
|
||||||
|
" FROM crs_user_settings"
|
||||||
|
" WHERE UsrCod=%ld"
|
||||||
|
" AND CrsCod=%ld",
|
||||||
|
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod);
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
// swad_test_database.h: self-assessment tests, operations with database
|
||||||
|
|
||||||
|
#ifndef _SWAD_TST_DB
|
||||||
|
#define _SWAD_TST_DB
|
||||||
|
/*
|
||||||
|
SWAD (Shared Workspace At a Distance in Spanish),
|
||||||
|
is a web platform developed at the University of Granada (Spain),
|
||||||
|
and used to support university teaching.
|
||||||
|
|
||||||
|
This file is part of SWAD core.
|
||||||
|
Copyright (C) 1999-2021 Antonio Cañas Vargas
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/*****************************************************************************/
|
||||||
|
/********************************* Headers ***********************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mysql/mysql.h> // To access MySQL databases
|
||||||
|
|
||||||
|
// #include "swad_exam.h"
|
||||||
|
// #include "swad_game.h"
|
||||||
|
// #include "swad_media.h"
|
||||||
|
// #include "swad_question.h"
|
||||||
|
// #include "swad_question_type.h"
|
||||||
|
// #include "swad_test_config.h"
|
||||||
|
// #include "swad_test_print.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***************************** Public constants ******************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/******************************* Public types ********************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***************************** Public prototypes *****************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Tst_DB_IncreaseNumMyPrints (void);
|
||||||
|
void Tst_DB_UpdateLastAccTst (unsigned NumQsts);
|
||||||
|
unsigned Tst_DB_GetDateNextTstAllowed (MYSQL_RES **mysql_res);
|
||||||
|
unsigned Tst_DB_GetNumPrintsGeneratedByMe (MYSQL_RES **mysql_res);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,4 +1,4 @@
|
||||||
// swad_test_print.c: test exam prints made by users
|
// swad_test_print.c: test prints made by users
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SWAD (Shared Workspace At a Distance),
|
SWAD (Shared Workspace At a Distance),
|
||||||
|
@ -42,6 +42,7 @@
|
||||||
#include "swad_photo.h"
|
#include "swad_photo.h"
|
||||||
#include "swad_question.h"
|
#include "swad_question.h"
|
||||||
#include "swad_test.h"
|
#include "swad_test.h"
|
||||||
|
#include "swad_test_database.h"
|
||||||
#include "swad_test_print.h"
|
#include "swad_test_print.h"
|
||||||
#include "swad_test_visibility.h"
|
#include "swad_test_visibility.h"
|
||||||
#include "swad_user.h"
|
#include "swad_user.h"
|
||||||
|
@ -210,14 +211,14 @@ static void TstPrn_ResetPrintExceptPrnCod (struct TstPrn_Print *Print)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************** Create new blank test exam print in database *****************/
|
/**************** Create new blank test print in database ********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_CreatePrintInDB (struct TstPrn_Print *Print)
|
void TstPrn_CreatePrintInDB (struct TstPrn_Print *Print)
|
||||||
{
|
{
|
||||||
/***** Insert new test exam print into table *****/
|
/***** Insert new test print into table *****/
|
||||||
Print->PrnCod =
|
Print->PrnCod =
|
||||||
DB_QueryINSERTandReturnCode ("can not create new test exam print",
|
DB_QueryINSERTandReturnCode ("can not create new test print",
|
||||||
"INSERT INTO tst_exams"
|
"INSERT INTO tst_exams"
|
||||||
" (CrsCod,UsrCod,StartTime,EndTime,"
|
" (CrsCod,UsrCod,StartTime,EndTime,"
|
||||||
"NumQsts,NumQstsNotBlank,"
|
"NumQsts,NumQstsNotBlank,"
|
||||||
|
@ -232,14 +233,14 @@ void TstPrn_CreatePrintInDB (struct TstPrn_Print *Print)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************** Update test exam print in database *********************/
|
/*********************** Update test print in database ***********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_UpdatePrintInDB (const struct TstPrn_Print *Print)
|
void TstPrn_UpdatePrintInDB (const struct TstPrn_Print *Print)
|
||||||
{
|
{
|
||||||
/***** Update test exam print in database *****/
|
/***** Update test print in database *****/
|
||||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||||
DB_QueryUPDATE ("can not update test exam",
|
DB_QueryUPDATE ("can not update test",
|
||||||
"UPDATE tst_exams"
|
"UPDATE tst_exams"
|
||||||
" SET EndTime=NOW(),"
|
" SET EndTime=NOW(),"
|
||||||
"NumQstsNotBlank=%u,"
|
"NumQstsNotBlank=%u,"
|
||||||
|
@ -262,11 +263,11 @@ void TstPrn_UpdatePrintInDB (const struct TstPrn_Print *Print)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/****************** Show a test exam print to be answered ********************/
|
/********************* Show a test print to be answered **********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
void TstPrn_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
||||||
unsigned NumTstExamsGeneratedByMe,
|
unsigned NumPrintsGeneratedByMe,
|
||||||
TstPrn_RequestOrConfirm_t RequestOrConfirm)
|
TstPrn_RequestOrConfirm_t RequestOrConfirm)
|
||||||
{
|
{
|
||||||
extern const char *Hlp_ASSESSMENT_Tests;
|
extern const char *Hlp_ASSESSMENT_Tests;
|
||||||
|
@ -295,7 +296,7 @@ void TstPrn_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
||||||
/***** Begin form *****/
|
/***** Begin form *****/
|
||||||
Frm_BeginForm (Action[RequestOrConfirm]);
|
Frm_BeginForm (Action[RequestOrConfirm]);
|
||||||
TstPrn_PutParamPrnCod (Print->PrnCod);
|
TstPrn_PutParamPrnCod (Print->PrnCod);
|
||||||
Par_PutHiddenParamUnsigned (NULL,"NumTst",NumTstExamsGeneratedByMe);
|
Par_PutHiddenParamUnsigned (NULL,"NumTst",NumPrintsGeneratedByMe);
|
||||||
|
|
||||||
/***** Begin table *****/
|
/***** Begin table *****/
|
||||||
HTM_TABLE_BeginWideMarginPadding (10);
|
HTM_TABLE_BeginWideMarginPadding (10);
|
||||||
|
@ -333,7 +334,7 @@ void TstPrn_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
||||||
Btn_PutConfirmButton (Txt_Continue);
|
Btn_PutConfirmButton (Txt_Continue);
|
||||||
break;
|
break;
|
||||||
case TstPrn_CONFIRM:
|
case TstPrn_CONFIRM:
|
||||||
/* Will the test exam be visible by teachers? */
|
/* Will the test be visible by teachers? */
|
||||||
TstPrn_PutCheckBoxAllowTeachers (true);
|
TstPrn_PutCheckBoxAllowTeachers (true);
|
||||||
|
|
||||||
/* Send button */
|
/* Send button */
|
||||||
|
@ -569,7 +570,7 @@ static void TstPrn_WriteTxtAnsToFill (const struct TstPrn_PrintedQuestion *Print
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************* Put checkbox to allow teachers to see test exam ***************/
|
/**************** Put checkbox to allow teachers to see test *****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void TstPrn_PutCheckBoxAllowTeachers (bool AllowTeachers)
|
static void TstPrn_PutCheckBoxAllowTeachers (bool AllowTeachers)
|
||||||
|
@ -590,7 +591,7 @@ static void TstPrn_PutCheckBoxAllowTeachers (bool AllowTeachers)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********************* Show test exam after assessing it *********************/
|
/************************ Show test after assessing it ***********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print)
|
void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print)
|
||||||
|
@ -626,7 +627,7 @@ void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print)
|
||||||
&Question,QuestionExists,
|
&Question,QuestionExists,
|
||||||
TstCfg_GetConfigVisibility ());
|
TstCfg_GetConfigVisibility ());
|
||||||
|
|
||||||
/***** Store test exam question in database *****/
|
/***** Store test question in database *****/
|
||||||
TstPrn_StoreOneQstOfPrintInDB (Print,QstInd);
|
TstPrn_StoreOneQstOfPrintInDB (Print,QstInd);
|
||||||
|
|
||||||
/***** Compute total score *****/
|
/***** Compute total score *****/
|
||||||
|
@ -787,7 +788,7 @@ void TstPrn_ComputeScoresAndStoreQuestionsOfPrint (struct TstPrn_Print *Print,
|
||||||
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[QstInd],&Question);
|
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[QstInd],&Question);
|
||||||
Qst_QstDestructor (&Question);
|
Qst_QstDestructor (&Question);
|
||||||
|
|
||||||
/* Store test exam question in database */
|
/* Store test question in database */
|
||||||
TstPrn_StoreOneQstOfPrintInDB (Print,
|
TstPrn_StoreOneQstOfPrintInDB (Print,
|
||||||
QstInd); // 0, 1, 2, 3...
|
QstInd); // 0, 1, 2, 3...
|
||||||
|
|
||||||
|
@ -1865,7 +1866,7 @@ static void TstPrn_StoreOneQstOfPrintInDB (const struct TstPrn_Print *Print,
|
||||||
{
|
{
|
||||||
/***** Insert question and user's answers into database *****/
|
/***** Insert question and user's answers into database *****/
|
||||||
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
Str_SetDecimalPointToUS (); // To print the floating point as a dot
|
||||||
DB_QueryREPLACE ("can not update a question of a test exam",
|
DB_QueryREPLACE ("can not update a question of a test",
|
||||||
"REPLACE INTO tst_exam_questions"
|
"REPLACE INTO tst_exam_questions"
|
||||||
" (ExaCod,QstCod,QstInd,Score,Indexes,Answers)"
|
" (ExaCod,QstCod,QstInd,Score,Indexes,Answers)"
|
||||||
" VALUES"
|
" VALUES"
|
||||||
|
@ -1880,7 +1881,7 @@ static void TstPrn_StoreOneQstOfPrintInDB (const struct TstPrn_Print *Print,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************* Select users and dates to show their test exams ***************/
|
/*************** Select users and dates to show their tests ******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_SelUsrsToViewUsrsPrints (void)
|
void TstPrn_SelUsrsToViewUsrsPrints (void)
|
||||||
|
@ -1904,7 +1905,7 @@ static void TstPrn_PutFormToSelectUsrsToViewUsrsPrints (__attribute__((unused))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************** Select dates to show my test exams *********************/
|
/*********************** Select dates to show my tests ***********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_SelDatesToSeeMyPrints (void)
|
void TstPrn_SelDatesToSeeMyPrints (void)
|
||||||
|
@ -1935,7 +1936,7 @@ void TstPrn_SelDatesToSeeMyPrints (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***************************** Show my test exams ****************************/
|
/******************************* Show my tests *******************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_ShowMyPrints (void)
|
void TstPrn_ShowMyPrints (void)
|
||||||
|
@ -1954,7 +1955,7 @@ void TstPrn_ShowMyPrints (void)
|
||||||
/***** Header of the table with the list of users *****/
|
/***** Header of the table with the list of users *****/
|
||||||
TstPrn_ShowHeaderPrints (Usr_ME);
|
TstPrn_ShowHeaderPrints (Usr_ME);
|
||||||
|
|
||||||
/***** List my test exams *****/
|
/***** List my tests *****/
|
||||||
TstCfg_GetConfigFromDB (); // To get visibility
|
TstCfg_GetConfigFromDB (); // To get visibility
|
||||||
TstPrn_ShowUsrPrints (&Gbl.Usrs.Me.UsrDat);
|
TstPrn_ShowUsrPrints (&Gbl.Usrs.Me.UsrDat);
|
||||||
|
|
||||||
|
@ -1963,7 +1964,7 @@ void TstPrn_ShowMyPrints (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************** Get users and show their test exams ********************/
|
/********************** Get users and show their test ************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_GetUsrsAndShowPrints (void)
|
void TstPrn_GetUsrsAndShowPrints (void)
|
||||||
|
@ -1994,7 +1995,7 @@ static void TstPrn_ShowUsrsPrints (__attribute__((unused)) void *Args)
|
||||||
/***** Header of the table with the list of users *****/
|
/***** Header of the table with the list of users *****/
|
||||||
TstPrn_ShowHeaderPrints (Usr_OTHER);
|
TstPrn_ShowHeaderPrints (Usr_OTHER);
|
||||||
|
|
||||||
/***** List the test exams of the selected users *****/
|
/***** List the tests of the selected users *****/
|
||||||
Ptr = Gbl.Usrs.Selected.List[Rol_UNK];
|
Ptr = Gbl.Usrs.Selected.List[Rol_UNK];
|
||||||
while (*Ptr)
|
while (*Ptr)
|
||||||
{
|
{
|
||||||
|
@ -2006,7 +2007,7 @@ static void TstPrn_ShowUsrsPrints (__attribute__((unused)) void *Args)
|
||||||
Usr_DONT_GET_ROLE_IN_CURRENT_CRS))
|
Usr_DONT_GET_ROLE_IN_CURRENT_CRS))
|
||||||
if (Usr_CheckIfICanViewTstExaMchResult (&Gbl.Usrs.Other.UsrDat))
|
if (Usr_CheckIfICanViewTstExaMchResult (&Gbl.Usrs.Other.UsrDat))
|
||||||
{
|
{
|
||||||
/***** Show test exams *****/
|
/***** Show tests *****/
|
||||||
Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat);
|
Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat);
|
||||||
TstPrn_ShowUsrPrints (&Gbl.Usrs.Other.UsrDat);
|
TstPrn_ShowUsrPrints (&Gbl.Usrs.Other.UsrDat);
|
||||||
}
|
}
|
||||||
|
@ -2017,7 +2018,7 @@ static void TstPrn_ShowUsrsPrints (__attribute__((unused)) void *Args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************************ Show header of my test exams ***********************/
|
/************************** Show header of my tests **************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void TstPrn_ShowHeaderPrints (Usr_MeOrOther_t MeOrOther)
|
static void TstPrn_ShowHeaderPrints (Usr_MeOrOther_t MeOrOther)
|
||||||
|
@ -2104,7 +2105,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
|
||||||
Start | End Start | End
|
Start | End Start | End
|
||||||
*/
|
*/
|
||||||
NumPrints = (unsigned)
|
NumPrints = (unsigned)
|
||||||
DB_QuerySELECT (&mysql_res,"can not get test exams of a user",
|
DB_QuerySELECT (&mysql_res,"can not get tests of a user",
|
||||||
"SELECT ExaCod" // row[0]
|
"SELECT ExaCod" // row[0]
|
||||||
" FROM tst_exams"
|
" FROM tst_exams"
|
||||||
" WHERE CrsCod=%ld"
|
" WHERE CrsCod=%ld"
|
||||||
|
@ -2121,7 +2122,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
|
||||||
HTM_TR_Begin (NULL);
|
HTM_TR_Begin (NULL);
|
||||||
Usr_ShowTableCellWithUsrData (UsrDat,NumPrints);
|
Usr_ShowTableCellWithUsrData (UsrDat,NumPrints);
|
||||||
|
|
||||||
/***** Get and print test exams *****/
|
/***** Get and print tests *****/
|
||||||
if (NumPrints)
|
if (NumPrints)
|
||||||
{
|
{
|
||||||
for (NumPrint = 0;
|
for (NumPrint = 0;
|
||||||
|
@ -2235,7 +2236,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
|
||||||
Ico_PutIconNotVisible ();
|
Ico_PutIconNotVisible ();
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
|
|
||||||
/* Link to show this test exam */
|
/* Link to show this test */
|
||||||
HTM_TD_Begin ("class=\"RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"RT LINE_LEFT COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
if (ICanView.Result)
|
if (ICanView.Result)
|
||||||
{
|
{
|
||||||
|
@ -2294,7 +2295,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*************** Write parameter with code of test exam print ****************/
|
/***************** Write parameter with code of test print ******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_PutParamPrnCod (long ExaCod)
|
void TstPrn_PutParamPrnCod (long ExaCod)
|
||||||
|
@ -2303,17 +2304,17 @@ void TstPrn_PutParamPrnCod (long ExaCod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*************** Get parameter with code of test exam print ******************/
|
/***************** Get parameter with code of test print *********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
long TstPrn_GetParamPrnCod (void)
|
long TstPrn_GetParamPrnCod (void)
|
||||||
{
|
{
|
||||||
/***** Get code of test exam print *****/
|
/***** Get code of test print *****/
|
||||||
return Par_GetParToLong ("PrnCod");
|
return Par_GetParToLong ("PrnCod");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/**************** Show row with summary of user's test exams *****************/
|
/****************** Show row with summary of user's tess *********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void TstPrn_ShowPrintsSummaryRow (bool ItsMe,
|
static void TstPrn_ShowPrintsSummaryRow (bool ItsMe,
|
||||||
|
@ -2405,7 +2406,7 @@ static void TstPrn_ShowPrintsSummaryRow (bool ItsMe,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************** Show one test exam of another user *********************/
|
/*********************** Show one test of another user ***********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_ShowOnePrint (void)
|
void TstPrn_ShowOnePrint (void)
|
||||||
|
@ -2429,7 +2430,7 @@ void TstPrn_ShowOnePrint (void)
|
||||||
if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0)
|
if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0)
|
||||||
Err_WrongTestExit ();
|
Err_WrongTestExit ();
|
||||||
|
|
||||||
/***** Get test exam data *****/
|
/***** Get test data *****/
|
||||||
TstPrn_GetPrintDataByPrnCod (&Print);
|
TstPrn_GetPrintDataByPrnCod (&Print);
|
||||||
|
|
||||||
/***** Get if I can see print result and score *****/
|
/***** Get if I can see print result and score *****/
|
||||||
|
@ -2439,7 +2440,7 @@ void TstPrn_ShowOnePrint (void)
|
||||||
|
|
||||||
if (ICanView.Result) // I am allowed to view this test print result
|
if (ICanView.Result) // I am allowed to view this test print result
|
||||||
{
|
{
|
||||||
/***** Get questions and user's answers of the test exam from database *****/
|
/***** Get questions and user's answers of the test from database *****/
|
||||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
TstPrn_GetPrintQuestionsFromDB (&Print);
|
||||||
|
|
||||||
/***** Begin box *****/
|
/***** Begin box *****/
|
||||||
|
@ -2600,7 +2601,7 @@ void TstPrn_ShowOnePrint (void)
|
||||||
/***** End box *****/
|
/***** End box *****/
|
||||||
Box_BoxEnd ();
|
Box_BoxEnd ();
|
||||||
}
|
}
|
||||||
else // I am not allowed to view this test exam
|
else // I am not allowed to view this test
|
||||||
Err_NoPermissionExit ();
|
Err_NoPermissionExit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2649,7 +2650,7 @@ static void TstRes_CheckIfICanSeePrintResult (const struct TstPrn_Print *Print,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********************* Show test tags in this test exam **********************/
|
/************************ Show test tags in this test ************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void TstPrn_ShowTagsPresentInAPrint (long ResCod)
|
static void TstPrn_ShowTagsPresentInAPrint (long ResCod)
|
||||||
|
@ -2659,8 +2660,7 @@ static void TstPrn_ShowTagsPresentInAPrint (long ResCod)
|
||||||
|
|
||||||
/***** Get all tags of questions in this test *****/
|
/***** Get all tags of questions in this test *****/
|
||||||
NumTags = (unsigned)
|
NumTags = (unsigned)
|
||||||
DB_QuerySELECT (&mysql_res,"can not get tags"
|
DB_QuerySELECT (&mysql_res,"can not get tags present in a test",
|
||||||
" present in a test exam",
|
|
||||||
"SELECT tst_tags.TagTxt" // row[0]
|
"SELECT tst_tags.TagTxt" // row[0]
|
||||||
" FROM (SELECT DISTINCT(tst_question_tags.TagCod)"
|
" FROM (SELECT DISTINCT(tst_question_tags.TagCod)"
|
||||||
" FROM tst_question_tags,"
|
" FROM tst_question_tags,"
|
||||||
|
@ -2678,7 +2678,7 @@ static void TstPrn_ShowTagsPresentInAPrint (long ResCod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************** Show user's and correct answers of a test exam ***************/
|
/**************** Show user's and correct answers of a test ******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_ShowPrintAnswers (struct UsrData *UsrDat,
|
void TstPrn_ShowPrintAnswers (struct UsrData *UsrDat,
|
||||||
|
@ -2717,7 +2717,7 @@ void TstPrn_ShowPrintAnswers (struct UsrData *UsrDat,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************ Get data of a test exam using its test exam code ***************/
|
/**************** Get data of a test using its test code *********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print)
|
void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print)
|
||||||
|
@ -2726,7 +2726,7 @@ void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print)
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
|
|
||||||
/***** Make database query *****/
|
/***** Make database query *****/
|
||||||
if (DB_QuerySELECT (&mysql_res,"can not get data of a test exam",
|
if (DB_QuerySELECT (&mysql_res,"can not get data of a test",
|
||||||
"SELECT UsrCod," // row[0]
|
"SELECT UsrCod," // row[0]
|
||||||
"UNIX_TIMESTAMP(StartTime)," // row[1]
|
"UNIX_TIMESTAMP(StartTime)," // row[1]
|
||||||
"UNIX_TIMESTAMP(EndTime)," // row[2]
|
"UNIX_TIMESTAMP(EndTime)," // row[2]
|
||||||
|
@ -2761,7 +2761,7 @@ void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print)
|
||||||
/* Get if exam has been sent (row[5]) */
|
/* Get if exam has been sent (row[5]) */
|
||||||
Print->Sent = (row[5][0] == 'Y');
|
Print->Sent = (row[5][0] == 'Y');
|
||||||
|
|
||||||
/* Get if teachers are allowed to see this test exam (row[6]) */
|
/* Get if teachers are allowed to see this test (row[6]) */
|
||||||
Print->AllowTeachers = (row[6][0] == 'Y');
|
Print->AllowTeachers = (row[6][0] == 'Y');
|
||||||
|
|
||||||
/* Get score (row[7]) */
|
/* Get score (row[7]) */
|
||||||
|
@ -2778,7 +2778,7 @@ void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*********** Get the questions of a test exam print from database ************/
|
/************* Get the questions of a test print from database ***************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
||||||
|
@ -2788,9 +2788,9 @@ void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
||||||
unsigned NumQsts;
|
unsigned NumQsts;
|
||||||
unsigned QstInd;
|
unsigned QstInd;
|
||||||
|
|
||||||
/***** Get questions of a test exam print from database *****/
|
/***** Get questions of a test print from database *****/
|
||||||
NumQsts = (unsigned)
|
NumQsts = (unsigned)
|
||||||
DB_QuerySELECT (&mysql_res,"can not get questions of a test exam",
|
DB_QuerySELECT (&mysql_res,"can not get questions of a test",
|
||||||
"SELECT QstCod," // row[0]
|
"SELECT QstCod," // row[0]
|
||||||
"Score," // row[1]
|
"Score," // row[1]
|
||||||
"Indexes," // row[2]
|
"Indexes," // row[2]
|
||||||
|
@ -2835,13 +2835,13 @@ void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************* Remove test exam prints made by a user ******************/
|
/********************** Remove test prints made by a user ********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_RemovePrintsMadeByUsrInAllCrss (long UsrCod)
|
void TstPrn_RemovePrintsMadeByUsrInAllCrss (long UsrCod)
|
||||||
{
|
{
|
||||||
/***** Remove test prints questions for the given user *****/
|
/***** Remove test prints questions for the given user *****/
|
||||||
DB_QueryDELETE ("can not remove test exams made by a user",
|
DB_QueryDELETE ("can not remove tests made by a user",
|
||||||
"DELETE FROM tst_exam_questions"
|
"DELETE FROM tst_exam_questions"
|
||||||
" USING tst_exams,"
|
" USING tst_exams,"
|
||||||
"tst_exam_questions"
|
"tst_exam_questions"
|
||||||
|
@ -2850,20 +2850,20 @@ void TstPrn_RemovePrintsMadeByUsrInAllCrss (long UsrCod)
|
||||||
UsrCod);
|
UsrCod);
|
||||||
|
|
||||||
/***** Remove test prints made by the given user *****/
|
/***** Remove test prints made by the given user *****/
|
||||||
DB_QueryDELETE ("can not remove test exams made by a user",
|
DB_QueryDELETE ("can not remove tests made by a user",
|
||||||
"DELETE FROM tst_exams"
|
"DELETE FROM tst_exams"
|
||||||
" WHERE UsrCod=%ld",
|
" WHERE UsrCod=%ld",
|
||||||
UsrCod);
|
UsrCod);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************ Remove test exam prints made by a user in a course *************/
|
/************** Remove test prints made by a user in a course ****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_RemovePrintsMadeByUsrInCrs (long UsrCod,long CrsCod)
|
void TstPrn_RemovePrintsMadeByUsrInCrs (long UsrCod,long CrsCod)
|
||||||
{
|
{
|
||||||
/***** Remove test exams made by the given user *****/
|
/***** Remove tests made by the given user *****/
|
||||||
DB_QueryDELETE ("can not remove test exams made by a user in a course",
|
DB_QueryDELETE ("can not remove tests made by a user in a course",
|
||||||
"DELETE FROM tst_exam_questions"
|
"DELETE FROM tst_exam_questions"
|
||||||
" USING tst_exams,"
|
" USING tst_exams,"
|
||||||
"tst_exam_questions"
|
"tst_exam_questions"
|
||||||
|
@ -2873,7 +2873,7 @@ void TstPrn_RemovePrintsMadeByUsrInCrs (long UsrCod,long CrsCod)
|
||||||
CrsCod,
|
CrsCod,
|
||||||
UsrCod);
|
UsrCod);
|
||||||
|
|
||||||
DB_QueryDELETE ("can not remove test exams made by a user in a course",
|
DB_QueryDELETE ("can not remove tests made by a user in a course",
|
||||||
"DELETE FROM tst_exams"
|
"DELETE FROM tst_exams"
|
||||||
" WHERE CrsCod=%ld"
|
" WHERE CrsCod=%ld"
|
||||||
" AND UsrCod=%ld",
|
" AND UsrCod=%ld",
|
||||||
|
@ -2882,13 +2882,13 @@ void TstPrn_RemovePrintsMadeByUsrInCrs (long UsrCod,long CrsCod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/**************** Remove all test exam prints made in a course ***************/
|
/****************** Remove all test prints made in a course ******************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void TstPrn_RemoveCrsPrints (long CrsCod)
|
void TstPrn_RemoveCrsPrints (long CrsCod)
|
||||||
{
|
{
|
||||||
/***** Remove questions of test exams made in the course *****/
|
/***** Remove questions of tests made in the course *****/
|
||||||
DB_QueryDELETE ("can not remove test exams made in a course",
|
DB_QueryDELETE ("can not remove tests made in a course",
|
||||||
"DELETE FROM tst_exam_questions"
|
"DELETE FROM tst_exam_questions"
|
||||||
" USING tst_exams,"
|
" USING tst_exams,"
|
||||||
"tst_exam_questions"
|
"tst_exam_questions"
|
||||||
|
@ -2896,9 +2896,46 @@ void TstPrn_RemoveCrsPrints (long CrsCod)
|
||||||
" AND tst_exams.ExaCod=tst_exam_questions.ExaCod",
|
" AND tst_exams.ExaCod=tst_exam_questions.ExaCod",
|
||||||
CrsCod);
|
CrsCod);
|
||||||
|
|
||||||
/***** Remove test exams made in the course *****/
|
/***** Remove tests made in the course *****/
|
||||||
DB_QueryDELETE ("can not remove test exams made in a course",
|
DB_QueryDELETE ("can not remove tests made in a course",
|
||||||
"DELETE FROM tst_exams"
|
"DELETE FROM tst_exams"
|
||||||
" WHERE CrsCod=%ld",
|
" WHERE CrsCod=%ld",
|
||||||
CrsCod);
|
CrsCod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***************** Get number of test prints generated by me *****************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned TstPrn_GetNumPrintsGeneratedByMe (void)
|
||||||
|
{
|
||||||
|
MYSQL_RES *mysql_res;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
unsigned NumRows;
|
||||||
|
unsigned NumPrintsGeneratedByMe = 0;
|
||||||
|
|
||||||
|
if (Gbl.Usrs.Me.IBelongToCurrentCrs)
|
||||||
|
{
|
||||||
|
/***** Get number of test prints generated by me from database *****/
|
||||||
|
NumRows = Tst_DB_GetNumPrintsGeneratedByMe (&mysql_res);
|
||||||
|
|
||||||
|
if (NumRows == 0)
|
||||||
|
NumPrintsGeneratedByMe = 0;
|
||||||
|
else if (NumRows == 1)
|
||||||
|
{
|
||||||
|
/* Get number of hits */
|
||||||
|
row = mysql_fetch_row (mysql_res);
|
||||||
|
if (row[0] == NULL)
|
||||||
|
NumPrintsGeneratedByMe = 0;
|
||||||
|
else if (sscanf (row[0],"%u",&NumPrintsGeneratedByMe) != 1)
|
||||||
|
NumPrintsGeneratedByMe = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Err_ShowErrorAndExit ("Error when getting number of tests.");
|
||||||
|
|
||||||
|
/***** Free structure that stores the query result *****/
|
||||||
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NumPrintsGeneratedByMe;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// swad_test_print.h: test exam prints made by users
|
// swad_test_print.h: test prints made by users
|
||||||
|
|
||||||
#ifndef _SWAD_TST_PRN
|
#ifndef _SWAD_TST_PRN
|
||||||
#define _SWAD_TST_PRN
|
#define _SWAD_TST_PRN
|
||||||
|
@ -95,7 +95,7 @@ void TstPrn_CreatePrintInDB (struct TstPrn_Print *Print);
|
||||||
void TstPrn_UpdatePrintInDB (const struct TstPrn_Print *Print);
|
void TstPrn_UpdatePrintInDB (const struct TstPrn_Print *Print);
|
||||||
|
|
||||||
void TstPrn_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
void TstPrn_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
||||||
unsigned NumTstExamsGeneratedByMe,
|
unsigned NumPrintsGeneratedByMe,
|
||||||
TstPrn_RequestOrConfirm_t RequestOrConfirm);
|
TstPrn_RequestOrConfirm_t RequestOrConfirm);
|
||||||
|
|
||||||
void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print);
|
void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print);
|
||||||
|
@ -160,4 +160,6 @@ void TstPrn_RemovePrintsMadeByUsrInAllCrss (long UsrCod);
|
||||||
void TstPrn_RemovePrintsMadeByUsrInCrs (long UsrCod,long CrsCod);
|
void TstPrn_RemovePrintsMadeByUsrInCrs (long UsrCod,long CrsCod);
|
||||||
void TstPrn_RemoveCrsPrints (long CrsCod);
|
void TstPrn_RemoveCrsPrints (long CrsCod);
|
||||||
|
|
||||||
|
unsigned TstPrn_GetNumPrintsGeneratedByMe (void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// swad_test_visibility.c: visibility of test exams
|
// swad_test_visibility.c: visibility of test prints
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SWAD (Shared Workspace At a Distance),
|
SWAD (Shared Workspace At a Distance),
|
||||||
|
|
Loading…
Reference in New Issue