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_survey_database.o swad_syllabus.o swad_system_config.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_theme.o swad_timeline.o swad_timeline_comment.o \
|
||||
swad_timeline_database.o swad_timeline_favourite.o swad_timeline_form.o \
|
||||
swad_timeline_note.o swad_timeline_notification.o swad_timeline_post.o \
|
||||
swad_test_database.o swad_test_config.o swad_test_print.o \
|
||||
swad_test_visibility.o swad_theme.o swad_timeline.o \
|
||||
swad_timeline_comment.o swad_timeline_database.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_who.o swad_timetable.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},
|
||||
[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},
|
||||
|
||||
[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,
|
||||
the only action possible is configure tests *****/
|
||||
if (Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown ())
|
||||
if (TstCfg_CheckIfPluggableIsUnknownAndCrsHasTests ())
|
||||
{
|
||||
Gbl.Action.Act = ActCfgTst;
|
||||
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.
|
||||
*/
|
||||
#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 JS_FILE "swad20.69.1.js"
|
||||
/*
|
||||
TODO: Rename CENTRE to CENTER in help wiki.
|
||||
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: 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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -230,7 +230,7 @@ void ExaPrn_ShowExamPrint (void)
|
|||
ExaLog_SetIfCanAnswer (true);
|
||||
}
|
||||
|
||||
/***** Show test exam to be answered *****/
|
||||
/***** Show test to be answered *****/
|
||||
ExaPrn_ShowExamPrintToFillIt (&Exams,&Exam,&Print);
|
||||
}
|
||||
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,
|
||||
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,
|
||||
|
|
|
@ -26,42 +26,19 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#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 ******************************/
|
||||
|
|
|
@ -36,10 +36,6 @@
|
|||
#include "swad_media.h"
|
||||
#include "swad_string.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 ******************************/
|
||||
|
|
|
@ -25,19 +25,10 @@
|
|||
/*********************************** 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_error.h"
|
||||
// #include "swad_form.h"
|
||||
#include "swad_global.h"
|
||||
#include "swad_tag.h"
|
||||
#include "swad_tag_database.h"
|
||||
// #include "swad_theme.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Public constants ******************************/
|
||||
|
|
387
swad_test.c
387
swad_test.c
|
@ -57,6 +57,7 @@
|
|||
#include "swad_tag_database.h"
|
||||
#include "swad_test.h"
|
||||
#include "swad_test_config.h"
|
||||
#include "swad_test_database.h"
|
||||
#include "swad_test_print.h"
|
||||
#include "swad_test_visibility.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 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,
|
||||
struct TstPrn_Print *Print);
|
||||
|
@ -223,7 +213,7 @@ void Tst_ShowNewTest (void)
|
|||
extern const char *Txt_No_questions_found_matching_your_search_criteria;
|
||||
struct Qst_Questions Questions;
|
||||
struct TstPrn_Print Print;
|
||||
unsigned NumTstExamsGeneratedByMe;
|
||||
unsigned NumPrintsGeneratedByMe;
|
||||
|
||||
/***** Create test *****/
|
||||
Qst_Constructor (&Questions);
|
||||
|
@ -242,16 +232,16 @@ void Tst_ShowNewTest (void)
|
|||
if (Print.NumQsts.All)
|
||||
{
|
||||
/***** Increase number of exams generated (answered or not) by me *****/
|
||||
Tst_DB_IncreaseMyNumTstExams ();
|
||||
NumTstExamsGeneratedByMe = Tst_GetNumTstExamsGeneratedByMe ();
|
||||
Tst_DB_IncreaseNumMyPrints ();
|
||||
NumPrintsGeneratedByMe = TstPrn_GetNumPrintsGeneratedByMe ();
|
||||
|
||||
/***** Create new test exam in database *****/
|
||||
/***** Create new test print in database *****/
|
||||
TstPrn_CreatePrintInDB (&Print);
|
||||
TstPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print,
|
||||
false); // Don't update question score
|
||||
|
||||
/***** Show test exam to be answered *****/
|
||||
TstPrn_ShowTestPrintToFillIt (&Print,NumTstExamsGeneratedByMe,TstPrn_REQUEST);
|
||||
/***** Show test print to be answered *****/
|
||||
TstPrn_ShowTestPrintToFillIt (&Print,NumPrintsGeneratedByMe,TstPrn_REQUEST);
|
||||
|
||||
/***** Update date-time of my next allowed access to test *****/
|
||||
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)
|
||||
|
@ -286,7 +276,7 @@ void Tst_ReceiveTestDraft (void)
|
|||
TstCfg_GetConfigFromDB ();
|
||||
|
||||
/***** Get basic parameters of the exam *****/
|
||||
/* Get test exam code from form */
|
||||
/* Get test print code from form */
|
||||
TstPrn_ResetPrint (&Print);
|
||||
if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0)
|
||||
Err_WrongTestExit ();
|
||||
|
@ -294,7 +284,7 @@ void Tst_ReceiveTestDraft (void)
|
|||
/* Get number of this test from form */
|
||||
NumTst = Tst_GetParamNumTst ();
|
||||
|
||||
/***** Get test exam print from database *****/
|
||||
/***** Get test print from database *****/
|
||||
TstPrn_GetPrintDataByPrnCod (&Print);
|
||||
|
||||
/****** Get test status in database for this session-course-num.test *****/
|
||||
|
@ -303,13 +293,13 @@ void Tst_ReceiveTestDraft (void)
|
|||
NumTst);
|
||||
else // Print not yet sent
|
||||
{
|
||||
/***** Get test exam print questions from database *****/
|
||||
/***** Get test print questions from database *****/
|
||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
||||
|
||||
/***** Get answers from form to assess a test *****/
|
||||
TstPrn_GetAnswersFromForm (&Print);
|
||||
|
||||
/***** Update test exam in database *****/
|
||||
/***** Update test print in database *****/
|
||||
TstPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print,
|
||||
false); // Don't update question score
|
||||
TstPrn_UpdatePrintInDB (&Print);
|
||||
|
@ -318,7 +308,7 @@ void Tst_ReceiveTestDraft (void)
|
|||
/* Begin alert */
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -342,7 +332,7 @@ void Tst_AssessTest (void)
|
|||
TstCfg_GetConfigFromDB ();
|
||||
|
||||
/***** Get basic parameters of the exam *****/
|
||||
/* Get test exam code from form */
|
||||
/* Get test print code from form */
|
||||
TstPrn_ResetPrint (&Print);
|
||||
if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0)
|
||||
Err_WrongTestExit ();
|
||||
|
@ -350,7 +340,7 @@ void Tst_AssessTest (void)
|
|||
/* Get number of this test from form */
|
||||
NumTst = Tst_GetParamNumTst ();
|
||||
|
||||
/***** Get test exam from database *****/
|
||||
/***** Get test print from database *****/
|
||||
TstPrn_GetPrintDataByPrnCod (&Print);
|
||||
|
||||
/****** Get test status in database for this session-course-num.test *****/
|
||||
|
@ -359,17 +349,17 @@ void Tst_AssessTest (void)
|
|||
NumTst);
|
||||
else // Print not yet sent
|
||||
{
|
||||
/***** Get test exam questions from database *****/
|
||||
/***** Get test print questions from database *****/
|
||||
TstPrn_GetPrintQuestionsFromDB (&Print);
|
||||
|
||||
/***** Get answers from form to assess a test *****/
|
||||
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.AllowTeachers = Par_GetParToBool ("AllowTchs");
|
||||
|
||||
/***** Update test exam in database *****/
|
||||
/***** Update test print in database *****/
|
||||
TstPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print,
|
||||
Gbl.Usrs.Me.Role.Logged == Rol_STD); // Update question score?
|
||||
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)
|
||||
|
@ -453,19 +443,9 @@ static bool Tst_CheckIfNextTstAllowed (void)
|
|||
return true;
|
||||
|
||||
/***** Get date of next allowed access to test from database *****/
|
||||
if (DB_QuerySELECT (&mysql_res,"can not get last access to test",
|
||||
"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)
|
||||
if (Tst_DB_GetDateNextTstAllowed (&mysql_res))
|
||||
{
|
||||
/* 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);
|
||||
if (row[0])
|
||||
if (sscanf (row[0],"%ld",&NumSecondsFromNowToNextAccTst) == 1)
|
||||
|
@ -473,7 +453,7 @@ static bool Tst_CheckIfNextTstAllowed (void)
|
|||
TimeNextTestUTC = Dat_GetUNIXTimeFromStr (row[1]);
|
||||
}
|
||||
else
|
||||
Err_ShowErrorAndExit ("Error when reading date of next allowed access to test.");
|
||||
Err_WrongDateExit ();
|
||||
|
||||
/***** Free structure that stores the query result *****/
|
||||
DB_FreeMySQLResult (&mysql_res);
|
||||
|
@ -482,107 +462,26 @@ static bool Tst_CheckIfNextTstAllowed (void)
|
|||
if (NumSecondsFromNowToNextAccTst > 0)
|
||||
{
|
||||
/***** Write warning *****/
|
||||
Ale_ShowAlert (Ale_WARNING,"%s:<br /><span id=\"date_next_test\"></span>."
|
||||
"<script type=\"text/javascript\">"
|
||||
"writeLocalDateHMSFromUTC('date_next_test',%ld,"
|
||||
"%u,', ',%u,true,true,true,0x7);"
|
||||
"</script>",
|
||||
Ale_ShowAlert (Ale_WARNING,"%s:<br />"
|
||||
"<span id=\"date_next_test\"></span>."
|
||||
"<script type=\"text/javascript\">"
|
||||
"writeLocalDateHMSFromUTC('date_next_test',%ld,"
|
||||
"%u,', ',%u,true,true,true,0x7);"
|
||||
"</script>",
|
||||
Txt_You_can_not_take_a_new_test_until,
|
||||
(long) TimeNextTestUTC,
|
||||
(unsigned) Gbl.Prefs.DateFormat,
|
||||
(unsigned) Gbl.Prefs.Language);
|
||||
|
||||
return false;
|
||||
}
|
||||
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 *************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Tst_PutIconsTests (__attribute__((unused)) void *Args)
|
||||
void Tst_PutIconsTests (__attribute__((unused)) void *Args)
|
||||
{
|
||||
switch (Gbl.Usrs.Me.Role.Logged)
|
||||
{
|
||||
|
@ -613,228 +512,6 @@ static void Tst_PutIconsTests (__attribute__((unused)) void *Args)
|
|||
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 ***************/
|
||||
/*****************************************************************************/
|
||||
|
@ -1001,7 +678,7 @@ static void Tst_GetQuestionsForNewTestFromDB (struct Qst_Questions *Questions,
|
|||
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");
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -1264,7 +941,7 @@ unsigned Tst_CountNumQuestionsInList (const char *ListQuestions)
|
|||
|
||||
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);
|
||||
|
||||
/***** Remove test configuration of the course *****/
|
||||
|
|
|
@ -64,11 +64,10 @@ void Tst_ShowNewTest (void);
|
|||
void Tst_ReceiveTestDraft (void);
|
||||
void Tst_AssessTest (void);
|
||||
|
||||
void Tst_PutIconsTests (__attribute__((unused)) void *Args);
|
||||
|
||||
bool Tst_GetParamsTst (struct Qst_Questions *Questions,
|
||||
Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions);
|
||||
void Tst_ShowFormConfig (void);
|
||||
|
||||
bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void);
|
||||
|
||||
unsigned Tst_CountNumQuestionsInList (const char *ListQuestions);
|
||||
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
#include <string.h> // For string functions
|
||||
|
||||
#include "swad_database.h"
|
||||
#include "swad_form.h"
|
||||
#include "swad_global.h"
|
||||
#include "swad_tag_database.h"
|
||||
#include "swad_test.h"
|
||||
#include "swad_test_config.h"
|
||||
#include "swad_test_visibility.h"
|
||||
|
@ -78,9 +80,235 @@ struct TstCfg_Config TstCfg_Config;
|
|||
/***************************** 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 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 ****************/
|
||||
/*****************************************************************************/
|
||||
|
@ -242,7 +470,7 @@ void TstCfg_ReceiveConfigTst (void)
|
|||
Ale_ShowAlert (Ale_SUCCESS,Txt_The_test_configuration_has_been_updated);
|
||||
|
||||
/***** Show again the form to configure test *****/
|
||||
Tst_ShowFormConfig ();
|
||||
TstCfg_CheckAndShowFormConfig ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -56,6 +56,9 @@ typedef enum
|
|||
/***************************** Public prototypes *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TstCfg_CheckAndShowFormConfig (void);
|
||||
bool TstCfg_CheckIfPluggableIsUnknownAndCrsHasTests (void);
|
||||
|
||||
void TstCfg_GetConfigFromDB (void);
|
||||
|
||||
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),
|
||||
|
@ -42,6 +42,7 @@
|
|||
#include "swad_photo.h"
|
||||
#include "swad_question.h"
|
||||
#include "swad_test.h"
|
||||
#include "swad_test_database.h"
|
||||
#include "swad_test_print.h"
|
||||
#include "swad_test_visibility.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)
|
||||
{
|
||||
/***** Insert new test exam print into table *****/
|
||||
/***** Insert new test print into table *****/
|
||||
Print->PrnCod =
|
||||
DB_QueryINSERTandReturnCode ("can not create new test exam print",
|
||||
DB_QueryINSERTandReturnCode ("can not create new test print",
|
||||
"INSERT INTO tst_exams"
|
||||
" (CrsCod,UsrCod,StartTime,EndTime,"
|
||||
"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)
|
||||
{
|
||||
/***** Update test exam print in database *****/
|
||||
/***** Update test print in database *****/
|
||||
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"
|
||||
" SET EndTime=NOW(),"
|
||||
"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,
|
||||
unsigned NumTstExamsGeneratedByMe,
|
||||
unsigned NumPrintsGeneratedByMe,
|
||||
TstPrn_RequestOrConfirm_t RequestOrConfirm)
|
||||
{
|
||||
extern const char *Hlp_ASSESSMENT_Tests;
|
||||
|
@ -295,7 +296,7 @@ void TstPrn_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
|||
/***** Begin form *****/
|
||||
Frm_BeginForm (Action[RequestOrConfirm]);
|
||||
TstPrn_PutParamPrnCod (Print->PrnCod);
|
||||
Par_PutHiddenParamUnsigned (NULL,"NumTst",NumTstExamsGeneratedByMe);
|
||||
Par_PutHiddenParamUnsigned (NULL,"NumTst",NumPrintsGeneratedByMe);
|
||||
|
||||
/***** Begin table *****/
|
||||
HTM_TABLE_BeginWideMarginPadding (10);
|
||||
|
@ -333,7 +334,7 @@ void TstPrn_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
|||
Btn_PutConfirmButton (Txt_Continue);
|
||||
break;
|
||||
case TstPrn_CONFIRM:
|
||||
/* Will the test exam be visible by teachers? */
|
||||
/* Will the test be visible by teachers? */
|
||||
TstPrn_PutCheckBoxAllowTeachers (true);
|
||||
|
||||
/* 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)
|
||||
|
@ -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)
|
||||
|
@ -626,7 +627,7 @@ void TstPrn_ShowPrintAfterAssess (struct TstPrn_Print *Print)
|
|||
&Question,QuestionExists,
|
||||
TstCfg_GetConfigVisibility ());
|
||||
|
||||
/***** Store test exam question in database *****/
|
||||
/***** Store test question in database *****/
|
||||
TstPrn_StoreOneQstOfPrintInDB (Print,QstInd);
|
||||
|
||||
/***** Compute total score *****/
|
||||
|
@ -787,7 +788,7 @@ void TstPrn_ComputeScoresAndStoreQuestionsOfPrint (struct TstPrn_Print *Print,
|
|||
TstPrn_ComputeAnswerScore (&Print->PrintedQuestions[QstInd],&Question);
|
||||
Qst_QstDestructor (&Question);
|
||||
|
||||
/* Store test exam question in database */
|
||||
/* Store test question in database */
|
||||
TstPrn_StoreOneQstOfPrintInDB (Print,
|
||||
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 *****/
|
||||
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"
|
||||
" (ExaCod,QstCod,QstInd,Score,Indexes,Answers)"
|
||||
" 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)
|
||||
|
@ -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)
|
||||
|
@ -1935,7 +1936,7 @@ void TstPrn_SelDatesToSeeMyPrints (void)
|
|||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Show my test exams ****************************/
|
||||
/******************************* Show my tests *******************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void TstPrn_ShowMyPrints (void)
|
||||
|
@ -1954,7 +1955,7 @@ void TstPrn_ShowMyPrints (void)
|
|||
/***** Header of the table with the list of users *****/
|
||||
TstPrn_ShowHeaderPrints (Usr_ME);
|
||||
|
||||
/***** List my test exams *****/
|
||||
/***** List my tests *****/
|
||||
TstCfg_GetConfigFromDB (); // To get visibility
|
||||
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)
|
||||
|
@ -1994,7 +1995,7 @@ static void TstPrn_ShowUsrsPrints (__attribute__((unused)) void *Args)
|
|||
/***** Header of the table with the list of users *****/
|
||||
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];
|
||||
while (*Ptr)
|
||||
{
|
||||
|
@ -2006,7 +2007,7 @@ static void TstPrn_ShowUsrsPrints (__attribute__((unused)) void *Args)
|
|||
Usr_DONT_GET_ROLE_IN_CURRENT_CRS))
|
||||
if (Usr_CheckIfICanViewTstExaMchResult (&Gbl.Usrs.Other.UsrDat))
|
||||
{
|
||||
/***** Show test exams *****/
|
||||
/***** Show tests *****/
|
||||
Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&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)
|
||||
|
@ -2104,7 +2105,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
|
|||
Start | End Start | End
|
||||
*/
|
||||
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]
|
||||
" FROM tst_exams"
|
||||
" WHERE CrsCod=%ld"
|
||||
|
@ -2121,7 +2122,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
|
|||
HTM_TR_Begin (NULL);
|
||||
Usr_ShowTableCellWithUsrData (UsrDat,NumPrints);
|
||||
|
||||
/***** Get and print test exams *****/
|
||||
/***** Get and print tests *****/
|
||||
if (NumPrints)
|
||||
{
|
||||
for (NumPrint = 0;
|
||||
|
@ -2235,7 +2236,7 @@ static void TstPrn_ShowUsrPrints (struct UsrData *UsrDat)
|
|||
Ico_PutIconNotVisible ();
|
||||
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);
|
||||
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)
|
||||
|
@ -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)
|
||||
{
|
||||
/***** Get code of test exam print *****/
|
||||
/***** Get code of test print *****/
|
||||
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,
|
||||
|
@ -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)
|
||||
|
@ -2429,7 +2430,7 @@ void TstPrn_ShowOnePrint (void)
|
|||
if ((Print.PrnCod = TstPrn_GetParamPrnCod ()) <= 0)
|
||||
Err_WrongTestExit ();
|
||||
|
||||
/***** Get test exam data *****/
|
||||
/***** Get test data *****/
|
||||
TstPrn_GetPrintDataByPrnCod (&Print);
|
||||
|
||||
/***** 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
|
||||
{
|
||||
/***** 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);
|
||||
|
||||
/***** Begin box *****/
|
||||
|
@ -2600,7 +2601,7 @@ void TstPrn_ShowOnePrint (void)
|
|||
/***** End box *****/
|
||||
Box_BoxEnd ();
|
||||
}
|
||||
else // I am not allowed to view this test exam
|
||||
else // I am not allowed to view this test
|
||||
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)
|
||||
|
@ -2659,8 +2660,7 @@ static void TstPrn_ShowTagsPresentInAPrint (long ResCod)
|
|||
|
||||
/***** Get all tags of questions in this test *****/
|
||||
NumTags = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get tags"
|
||||
" present in a test exam",
|
||||
DB_QuerySELECT (&mysql_res,"can not get tags present in a test",
|
||||
"SELECT tst_tags.TagTxt" // row[0]
|
||||
" FROM (SELECT DISTINCT(tst_question_tags.TagCod)"
|
||||
" 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,
|
||||
|
@ -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)
|
||||
|
@ -2726,7 +2726,7 @@ void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print)
|
|||
MYSQL_ROW row;
|
||||
|
||||
/***** 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]
|
||||
"UNIX_TIMESTAMP(StartTime)," // row[1]
|
||||
"UNIX_TIMESTAMP(EndTime)," // row[2]
|
||||
|
@ -2761,7 +2761,7 @@ void TstPrn_GetPrintDataByPrnCod (struct TstPrn_Print *Print)
|
|||
/* Get if exam has been sent (row[5]) */
|
||||
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');
|
||||
|
||||
/* 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)
|
||||
|
@ -2788,9 +2788,9 @@ void TstPrn_GetPrintQuestionsFromDB (struct TstPrn_Print *Print)
|
|||
unsigned NumQsts;
|
||||
unsigned QstInd;
|
||||
|
||||
/***** Get questions of a test exam print from database *****/
|
||||
/***** Get questions of a test print from database *****/
|
||||
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]
|
||||
"Score," // row[1]
|
||||
"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)
|
||||
{
|
||||
/***** 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"
|
||||
" USING tst_exams,"
|
||||
"tst_exam_questions"
|
||||
|
@ -2850,20 +2850,20 @@ void TstPrn_RemovePrintsMadeByUsrInAllCrss (long UsrCod)
|
|||
UsrCod);
|
||||
|
||||
/***** 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"
|
||||
" WHERE UsrCod=%ld",
|
||||
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)
|
||||
{
|
||||
/***** Remove test exams made by the given user *****/
|
||||
DB_QueryDELETE ("can not remove test exams made by a user in a course",
|
||||
/***** Remove tests made by the given user *****/
|
||||
DB_QueryDELETE ("can not remove tests made by a user in a course",
|
||||
"DELETE FROM tst_exam_questions"
|
||||
" USING tst_exams,"
|
||||
"tst_exam_questions"
|
||||
|
@ -2873,7 +2873,7 @@ void TstPrn_RemovePrintsMadeByUsrInCrs (long UsrCod,long CrsCod)
|
|||
CrsCod,
|
||||
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"
|
||||
" WHERE CrsCod=%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)
|
||||
{
|
||||
/***** Remove questions of test exams made in the course *****/
|
||||
DB_QueryDELETE ("can not remove test exams made in a course",
|
||||
/***** Remove questions of tests made in the course *****/
|
||||
DB_QueryDELETE ("can not remove tests made in a course",
|
||||
"DELETE FROM tst_exam_questions"
|
||||
" USING tst_exams,"
|
||||
"tst_exam_questions"
|
||||
|
@ -2896,9 +2896,46 @@ void TstPrn_RemoveCrsPrints (long CrsCod)
|
|||
" AND tst_exams.ExaCod=tst_exam_questions.ExaCod",
|
||||
CrsCod);
|
||||
|
||||
/***** Remove test exams made in the course *****/
|
||||
DB_QueryDELETE ("can not remove test exams made in a course",
|
||||
/***** Remove tests made in the course *****/
|
||||
DB_QueryDELETE ("can not remove tests made in a course",
|
||||
"DELETE FROM tst_exams"
|
||||
" WHERE CrsCod=%ld",
|
||||
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
|
||||
#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_ShowTestPrintToFillIt (struct TstPrn_Print *Print,
|
||||
unsigned NumTstExamsGeneratedByMe,
|
||||
unsigned NumPrintsGeneratedByMe,
|
||||
TstPrn_RequestOrConfirm_t RequestOrConfirm);
|
||||
|
||||
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_RemoveCrsPrints (long CrsCod);
|
||||
|
||||
unsigned TstPrn_GetNumPrintsGeneratedByMe (void);
|
||||
|
||||
#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),
|
||||
|
|
Loading…
Reference in New Issue