diff --git a/swad_changelog.h b/swad_changelog.h index 8dd1cff57..bf5482410 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -548,10 +548,11 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.229.2 (2020-05-14)" +#define Log_PLATFORM_VERSION "SWAD 19.230 (2020-05-15)" #define CSS_FILE "swad19.217.css" #define JS_FILE "swad19.223.js" /* + Version 19.230: May 15, 2020 Code refactoring and bug fixing in exams. (300984 lines) Version 19.229.2: May 14, 2020 Some messages translated in exam results. (301070 lines) Version 19.229.1: May 14, 2020 Removed unused database tables in exams. Fixed bugs in exam prints. (301009 lines) diff --git a/swad_exam.c b/swad_exam.c index 3eb216eea..5f3f0d9e7 100644 --- a/swad_exam.c +++ b/swad_exam.c @@ -535,7 +535,7 @@ static void Exa_ShowOneExam (struct Exa_Exams *Exams, if (Exam->TimeUTC[Dat_START_TIME]) Dat_WriteLocalDateHMSFromUTC (Id,Exam->TimeUTC[StartEndTime], Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, - true,true,true,0x7); + true,true,true,0x6); HTM_TD_End (); free (Id); } diff --git a/swad_exam_event.c b/swad_exam_event.c index 04bcd8911..d98443266 100644 --- a/swad_exam_event.c +++ b/swad_exam_event.c @@ -224,17 +224,26 @@ void ExaEvt_ListEvents (struct Exa_Exams *Exams, Hlp_ASSESSMENT_Exams_events,Box_NOT_CLOSABLE); /***** Select whether show only my groups or all groups *****/ - if (Gbl.Crs.Grps.NumGrps) + switch (Gbl.Usrs.Me.Role.Logged) { - Set_StartSettingsHead (); - Grp_ShowFormToSelWhichGrps (ActSeeExa, - Exa_PutParams,Exams); - Set_EndSettingsHead (); + case Rol_NET: + case Rol_TCH: + case Rol_SYS_ADM: + if (Gbl.Crs.Grps.NumGrps) + { + Set_StartSettingsHead (); + Grp_ShowFormToSelWhichGrps (ActSeeExa, + Exa_PutParams,Exams); + Set_EndSettingsHead (); + } + break; + default: + break; } + /***** Show the table with the events *****/ if (NumEvents) { - /***** Show the table with the events *****/ EvtCodToBeEdited = PutFormEvent && Event->EvtCod > 0 ? Event->EvtCod : -1L; ExaEvt_ListOneOrMoreEvents (Exams,Exam,EvtCodToBeEdited,NumEvents,mysql_res); @@ -321,6 +330,25 @@ void ExaEvt_GetDataOfEventByCod (struct ExaEvt_Event *Event) DB_FreeMySQLResult (&mysql_res); } +/*****************************************************************************/ +/***************** Check if exam event is visible and open *******************/ +/*****************************************************************************/ + +bool ExaEvt_CheckIfEventIsVisibleAndOpen (long EvtCod) + { + /***** Trivial check *****/ + if (EvtCod < 0) // A non-existing event... + return false; // ...is not visible or open + + /***** Check if exam event is visible and open from database *****/ + return (DB_QueryCOUNT ("can not check if event is visible and open", + "SELECT COUNT(*) FROM exa_events" + " WHERE EvtCod=%ld" + " AND Hidden='N'" // Visible + " AND NOW() BETWEEN StartTime AND EndTime", // Open + EvtCod) != 0); + } + /*****************************************************************************/ /****************** Put icons in list of events of an exam *******************/ /*****************************************************************************/ @@ -389,7 +417,7 @@ static void ExaEvt_ListOneOrMoreEvents (struct Exa_Exams *Exams, /***** Get exam event data from row *****/ ExaEvt_GetEventDataFromRow (mysql_res,&Event); - if (ExaEvt_CheckIfICanPlayThisEventBasedOnGrps (&Event)) + if (ExaEvt_CheckIfICanListThisEventBasedOnGrps (&Event)) { /***** Build anchor string *****/ if (asprintf (&Anchor,"evt_%ld_%ld",Exam->ExaCod,Event.EvtCod) < 0) @@ -574,7 +602,7 @@ static void ExaEvt_ListOneOrMoreEventsTimes (const struct ExaEvt_Event *Event,un Id,Color,Gbl.RowEvenOdd); Dat_WriteLocalDateHMSFromUTC (Id,Event->TimeUTC[StartEndTime], Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, - true,true,true,0x7); + true,true,true,0x6); HTM_TD_End (); free (Id); } @@ -595,17 +623,27 @@ static void ExaEvt_ListOneOrMoreEventsTitleGrps (struct Exa_Exams *Exams, /***** Event title *****/ HTM_ARTICLE_Begin (Anchor); - Frm_StartForm (ActSeeExaPrn); - Exa_PutParams (Exams); - ExaEvt_PutParamEvtCod (Event->EvtCod); - HTM_BUTTON_SUBMIT_Begin (Gbl.Usrs.Me.Role.Logged == Rol_STD ? Txt_Play : - Txt_Resume, - Event->Hidden ? "BT_LINK LT ASG_TITLE_LIGHT": - "BT_LINK LT ASG_TITLE", - NULL); - HTM_Txt (Event->Title); - HTM_BUTTON_End (); - Frm_EndForm (); + if (ExaEvt_CheckIfICanAnswerThisEvent (Event)) + { + Frm_StartForm (ActSeeExaPrn); + Exa_PutParams (Exams); + ExaEvt_PutParamEvtCod (Event->EvtCod); + HTM_BUTTON_SUBMIT_Begin (Gbl.Usrs.Me.Role.Logged == Rol_STD ? Txt_Play : + Txt_Resume, + Event->Hidden ? "BT_LINK LT ASG_TITLE_LIGHT": + "BT_LINK LT ASG_TITLE", + NULL); + HTM_Txt (Event->Title); + HTM_BUTTON_End (); + Frm_EndForm (); + } + else + { + HTM_SPAN_Begin ("class=\"%s\"",Event->Hidden ? "LT ASG_TITLE_LIGHT": + "LT ASG_TITLE"); + HTM_Txt (Event->Title); + HTM_SPAN_End (); + } HTM_ARTICLE_End (); /***** Groups whose students can answer this exam event *****/ @@ -1152,17 +1190,17 @@ void ExaEvt_GetAndCheckParameters (struct Exa_Exams *Exams, if ((Event->EvtCod = ExaEvt_GetParamEvtCod ()) <= 0) Lay_WrongEventExit (); - /***** Get exam data and event from database *****/ + /***** Get exam data from database *****/ Exa_GetDataOfExamByCod (Exam); if (Exam->CrsCod != Gbl.Hierarchy.Crs.CrsCod) Lay_WrongExamExit (); Exams->ExaCod = Exam->ExaCod; - ExaEvt_GetDataOfEventByCod (Event); - /***** Ensure parameters are correct *****/ - if (Exam->ExaCod != Event->ExaCod || - Exam->CrsCod != Gbl.Hierarchy.Crs.CrsCod) - Lay_WrongExamExit (); + /***** Get set data from database *****/ + ExaEvt_GetDataOfEventByCod (Event); + if (Event->ExaCod != Exam->ExaCod) + Lay_WrongSetExit (); + Exams->EvtCod = Event->EvtCod; } /*****************************************************************************/ @@ -1203,8 +1241,6 @@ static void ExaEvt_PutFormEvent (const struct ExaEvt_Event *Event) if (!ItsANewEvent) // Existing event ExaEvt_PutParamEvtCod (Event->EvtCod); - // Exa_PutParamQstInd (0); // Start by first question in exam - /***** Begin box and table *****/ Box_BoxTableBegin (NULL,ItsANewEvent ? Txt_New_event : Event->Title, @@ -1228,7 +1264,7 @@ static void ExaEvt_PutFormEvent (const struct ExaEvt_Event *Event) /***** Start and end dates *****/ Dat_PutFormStartEndClientLocalDateTimes (Event->TimeUTC, - Dat_FORM_SECONDS_ON, + Dat_FORM_SECONDS_OFF, SetHMS); /***** Groups *****/ @@ -1625,7 +1661,16 @@ unsigned ExaEvt_GetNumOpenEventsInExam (long ExaCod) /********* Check if I belong to any of the groups of an exam event ***********/ /*****************************************************************************/ -bool ExaEvt_CheckIfICanPlayThisEventBasedOnGrps (const struct ExaEvt_Event *Event) +bool ExaEvt_CheckIfICanAnswerThisEvent (const struct ExaEvt_Event *Event) + { + /***** Hidden or closed events are not accesible *****/ + if (Event->Hidden || !Event->Open) + return false; + + return ExaEvt_CheckIfICanListThisEventBasedOnGrps (Event); + } + +bool ExaEvt_CheckIfICanListThisEventBasedOnGrps (const struct ExaEvt_Event *Event) { switch (Gbl.Usrs.Me.Role.Logged) { @@ -1647,8 +1692,6 @@ bool ExaEvt_CheckIfICanPlayThisEventBasedOnGrps (const struct ExaEvt_Event *Even Event->EvtCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0); break; case Rol_NET: - /***** Only if I am the creator *****/ - return (Event->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod); case Rol_TCH: case Rol_SYS_ADM: return true; diff --git a/swad_exam_event.h b/swad_exam_event.h index ea9f7794c..a4d642a36 100644 --- a/swad_exam_event.h +++ b/swad_exam_event.h @@ -55,6 +55,7 @@ void ExaEvt_ListEvents (struct Exa_Exams *Exams, struct ExaEvt_Event *Event, bool PutFormEvent); void ExaEvt_GetDataOfEventByCod (struct ExaEvt_Event *Event); +bool ExaEvt_CheckIfEventIsVisibleAndOpen (long EvtCod); void ExaEvt_ToggleVisibilResultsEvtUsr (void); @@ -84,7 +85,8 @@ void ExaEvt_RemoveGroupsOfType (long GrpTypCod); unsigned ExaEvt_GetNumEventsInExam (long ExaCod); unsigned ExaEvt_GetNumOpenEventsInExam (long ExaCod); -bool ExaEvt_CheckIfICanPlayThisEventBasedOnGrps (const struct ExaEvt_Event *Event); +bool ExaEvt_CheckIfICanAnswerThisEvent (const struct ExaEvt_Event *Event); +bool ExaEvt_CheckIfICanListThisEventBasedOnGrps (const struct ExaEvt_Event *Event); void ExaEvt_GetQstAnsFromDB (long EvtCod,long UsrCod,unsigned QstInd, struct ExaEvt_UsrAnswer *UsrAnswer); diff --git a/swad_exam_print.c b/swad_exam_print.c index 90ce1d333..c0d35316f 100644 --- a/swad_exam_print.c +++ b/swad_exam_print.c @@ -62,7 +62,7 @@ extern struct Globals Gbl; struct ExaPrn_Print { long PrnCod; // Exam print code - long ExaCod; // Exam code + // long ExaCod; // Exam code long EvtCod; // Event code associated to this print long UsrCod; // User who answered the exam print time_t TimeUTC[Dat_NUM_START_END_TIME]; @@ -90,7 +90,7 @@ static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print); static void ExaPrn_ResetPrintExceptEvtCodAndUsrCod (struct ExaPrn_Print *Print); static void ExaPrn_GetPrintDataByEvtCodAndUsrCod (struct ExaPrn_Print *Print); -static void ExaPrn_GetQuestionsForNewPrintFromDB (struct ExaPrn_Print *Print); +static void ExaPrn_GetQuestionsForNewPrintFromDB (struct ExaPrn_Print *Print,long ExaCod); static unsigned ExaPrn_GetSomeQstsFromSetToPrint (struct ExaPrn_Print *Print, struct ExaSet_Set *Set, unsigned *NumQstInPrint); @@ -174,7 +174,7 @@ static void ExaPrn_ResetPrint (struct ExaPrn_Print *Print) static void ExaPrn_ResetPrintExceptEvtCodAndUsrCod (struct ExaPrn_Print *Print) { Print->PrnCod = -1L; - Print->ExaCod = -1L; + // Print->ExaCod = -1L; Print->TimeUTC[Dat_START_TIME] = Print->TimeUTC[Dat_END_TIME ] = (time_t) 0; Print->NumQsts = @@ -203,37 +203,35 @@ void ExaPrn_ShowExamPrint (void) /***** Get and check parameters *****/ ExaEvt_GetAndCheckParameters (&Exams,&Exam,&Event); - /***** Get print data from database *****/ - Print.EvtCod = Event.EvtCod; - Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod; - ExaPrn_GetPrintDataByEvtCodAndUsrCod (&Print); - - if (Print.PrnCod > 0) // Print exists + /***** Check if I can access to this event *****/ + if (ExaEvt_CheckIfICanAnswerThisEvent (&Event)) { - Ale_ShowAlert (Ale_INFO,"Examen existente."); + /***** Get print data from database *****/ + Print.EvtCod = Event.EvtCod; + Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod; + ExaPrn_GetPrintDataByEvtCodAndUsrCod (&Print); - /***** Get questions and answers from database *****/ - ExaPrn_GetPrintQuestionsFromDB (&Print); + if (Print.PrnCod > 0) // Print exists and I can access to it + /***** Get questions and answers from database *****/ + ExaPrn_GetPrintQuestionsFromDB (&Print); + else + { + /***** Get questions from database *****/ + ExaPrn_GetQuestionsForNewPrintFromDB (&Print,Exam.ExaCod); + + if (Print.NumQsts) + { + /***** Create/update new exam print in database *****/ + ExaPrn_CreatePrintInDB (&Print); + ExaPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print); + } + } + + /***** Show test exam to be answered *****/ + ExaPrn_ShowExamPrintToFillIt (Exam.Title,&Print); } else - { - Ale_ShowAlert (Ale_INFO,"Examen nuevo."); - - /***** Get questions from database *****/ - // Print doesn't exists ==> exam code is -1 ==> so initialize it - Print.ExaCod = Exam.ExaCod; - ExaPrn_GetQuestionsForNewPrintFromDB (&Print); - - if (Print.NumQsts) - { - /***** Create/update new exam print in database *****/ - ExaPrn_CreatePrintInDB (&Print); - ExaPrn_ComputeScoresAndStoreQuestionsOfPrint (&Print); - } - } - - /***** Show test exam to be answered *****/ - ExaPrn_ShowExamPrintToFillIt (Exam.Title,&Print); + Ale_ShowAlert (Ale_INFO,"Usted no tiene acceso al examen."); // TODO: Need translation!!!! } /*****************************************************************************/ @@ -247,51 +245,42 @@ static void ExaPrn_GetPrintDataByEvtCodAndUsrCod (struct ExaPrn_Print *Print) /***** Make database query *****/ if (DB_QuerySELECT (&mysql_res,"can not get data of an exam print", - "SELECT exa_prints.PrnCod," // row[0] - "exa_exams.ExaCod," // row[1] - "UNIX_TIMESTAMP(exa_prints.StartTime)," // row[2] - "UNIX_TIMESTAMP(exa_prints.EndTime)," // row[3] - "exa_prints.NumQsts," // row[4] - "exa_prints.NumQstsNotBlank," // row[5] - "exa_prints.Sent," // row[6] - "exa_prints.Score" // row[7] - " FROM exa_prints,exa_events,exa_exams" - " WHERE exa_prints.EvtCod=%ld" - " AND exa_prints.UsrCod=%ld" // Extra check: it belong to user - " AND exa_prints.EvtCod=exa_events.EvtCod" - " AND (NOW() BETWEEN exa_events.StartTime AND exa_events.EndTime)" // Extra check: event is open - " AND exa_events.ExaCod=exa_exams.ExaCod" - " AND exa_exams.CrsCod=%ld", // Extra check: it belong to current course + "SELECT PrnCod," // row[0] + "UNIX_TIMESTAMP(StartTime)," // row[1] + "UNIX_TIMESTAMP(EndTime)," // row[2] + "NumQsts," // row[3] + "NumQstsNotBlank," // row[4] + "Sent," // row[5] + "Score" // row[6] + " FROM exa_prints" + " WHERE EvtCod=%ld" + " AND UsrCod=%ld", Print->EvtCod, - Print->UsrCod, - Gbl.Hierarchy.Crs.CrsCod) == 1) + Print->UsrCod) == 1) { row = mysql_fetch_row (mysql_res); /* Get print code (row[0]) */ Print->PrnCod = Str_ConvertStrCodToLongCod (row[0]); - /* Get exam code (row[1]) */ - Print->ExaCod = Str_ConvertStrCodToLongCod (row[1]); + /* Get date-time (row[1] and row[2] hold UTC date-time) */ + Print->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[1]); + Print->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[2]); - /* Get date-time (row[2] and row[3] hold UTC date-time) */ - Print->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[2]); - Print->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[3]); - - /* Get number of questions (row[4]) */ - if (sscanf (row[4],"%u",&Print->NumQsts) != 1) + /* Get number of questions (row[3]) */ + if (sscanf (row[3],"%u",&Print->NumQsts) != 1) Print->NumQsts = 0; - /* Get number of questions not blank (row[5]) */ - if (sscanf (row[5],"%u",&Print->NumQstsNotBlank) != 1) + /* Get number of questions not blank (row[4]) */ + if (sscanf (row[4],"%u",&Print->NumQstsNotBlank) != 1) Print->NumQstsNotBlank = 0; - /* Get if exam has been sent (row[6]) */ - Print->Sent = (row[6][0] == 'Y'); + /* Get if exam has been sent (row[5]) */ + Print->Sent = (row[5][0] == 'Y'); - /* Get score (row[7]) */ + /* Get score (row[6]) */ Str_SetDecimalPointToUS (); // To get the decimal point as a dot - if (sscanf (row[7],"%lf",&Print->Score) != 1) + if (sscanf (row[6],"%lf",&Print->Score) != 1) Print->Score = 0.0; Str_SetDecimalPointToLocal (); // Return to local system } @@ -306,7 +295,7 @@ static void ExaPrn_GetPrintDataByEvtCodAndUsrCod (struct ExaPrn_Print *Print) /*********** Get questions for a new exam print from the database ************/ /*****************************************************************************/ -static void ExaPrn_GetQuestionsForNewPrintFromDB (struct ExaPrn_Print *Print) +static void ExaPrn_GetQuestionsForNewPrintFromDB (struct ExaPrn_Print *Print,long ExaCod) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -325,7 +314,7 @@ static void ExaPrn_GetQuestionsForNewPrintFromDB (struct ExaPrn_Print *Print) " FROM exa_sets" " WHERE ExaCod=%ld" " ORDER BY SetInd", - Print->ExaCod); + ExaCod); /***** Get questions from all sets *****/ Print->NumQsts = 0; @@ -658,7 +647,7 @@ static void ExaPrn_ShowTableWithQstsToFill (struct ExaPrn_Print *Print) Question.QstCod = Print->PrintedQuestions[NumQst].QstCod; /* Show question */ - ExaSet_GetQstDataFromDB (&Question,Print->ExaCod); + ExaSet_GetQstDataFromDB (&Question); /* Write question and answers */ ExaPrn_WriteQstAndAnsToFill (Print,NumQst,&Question); @@ -691,9 +680,7 @@ static void ExaPrn_WriteQstAndAnsToFill (struct ExaPrn_Print *Print, if (Print->PrintedQuestions[NumQst].SetCod != CurrentSet.SetCod) { /***** Get data of this set *****/ - CurrentSet.ExaCod = Print->ExaCod; CurrentSet.SetCod = Print->PrintedQuestions[NumQst].SetCod; - ExaSet_GetDataOfSetByCod (&CurrentSet); /***** Title for this set *****/ @@ -956,30 +943,38 @@ void ExaPrn_ReceivePrintAnswer (void) /***** Reset print *****/ ExaPrn_ResetPrint (&Print); - /***** Get and check parameters *****/ + /***** Get event code *****/ Print.EvtCod = ExaEvt_GetParamEvtCod (); - Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod; - ExaPrn_GetPrintDataByEvtCodAndUsrCod (&Print); - if (Print.PrnCod <= 0) - Lay_WrongExamExit (); - /***** Get questions and answers from database *****/ - ExaPrn_GetPrintQuestionsFromDB (&Print); + /***** Check if event if visible and open *****/ + if (ExaEvt_CheckIfEventIsVisibleAndOpen (Print.EvtCod)) + { + /***** Get print data *****/ + Print.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod; + ExaPrn_GetPrintDataByEvtCodAndUsrCod (&Print); + if (Print.PrnCod <= 0) + Lay_WrongExamExit (); - /***** Get answers from form to assess a test *****/ - NumQst = ExaPrn_GetAnswerFromForm (&Print); + /***** Get questions and answers from database *****/ + ExaPrn_GetPrintQuestionsFromDB (&Print); - /***** Update answer in database *****/ - /* Compute question score and store in database */ - ExaPrn_ComputeScoreAndStoreQuestionOfPrint (&Print,NumQst); + /***** Get answers from form to assess a test *****/ + NumQst = ExaPrn_GetAnswerFromForm (&Print); - /* Update exam print in database */ - ExaPrn_GetNumQstsNotBlank (&Print); - ExaPrn_ComputeTotalScoreOfPrint (&Print); - ExaPrn_UpdatePrintInDB (&Print); + /***** Update answer in database *****/ + /* Compute question score and store in database */ + ExaPrn_ComputeScoreAndStoreQuestionOfPrint (&Print,NumQst); - /***** Show table with questions to answer *****/ - ExaPrn_ShowTableWithQstsToFill (&Print); + /* Update exam print in database */ + ExaPrn_GetNumQstsNotBlank (&Print); + ExaPrn_ComputeTotalScoreOfPrint (&Print); + ExaPrn_UpdatePrintInDB (&Print); + + /***** Show table with questions to answer *****/ + ExaPrn_ShowTableWithQstsToFill (&Print); + } + else + Ale_ShowAlert (Ale_INFO,"Usted no tiene acceso al examen."); // TODO: Need translation!!!! } /*****************************************************************************/ diff --git a/swad_exam_result.c b/swad_exam_result.c index 81169d7e8..fa82fb9e4 100644 --- a/swad_exam_result.c +++ b/swad_exam_result.c @@ -1444,7 +1444,7 @@ static bool ExaRes_CheckIfICanSeeEventResult (struct ExaEvt_Event *Event,long Us case Rol_STD: ItsMe = Usr_ItsMe (UsrCod); if (ItsMe && Event->ShowUsrResults) - return ExaEvt_CheckIfICanPlayThisEventBasedOnGrps (Event); + return ExaEvt_CheckIfICanListThisEventBasedOnGrps (Event); return false; case Rol_NET: case Rol_TCH: diff --git a/swad_exam_set.c b/swad_exam_set.c index 326c2030f..71347f50d 100644 --- a/swad_exam_set.c +++ b/swad_exam_set.c @@ -131,6 +131,10 @@ static void ExaSet_FreeListsSelectedQuestions (struct Exa_Exams *Exams); static void ExaSet_CopyQstFromBankToExamSet (struct ExaSet_Set *Set,long QstCod); +static void ExaSet_GetAndCheckParameters (struct Exa_Exams *Exams, + struct Exa_Exam *Exam, + struct ExaSet_Set *Set); + static long ExaSet_GetParamQstCod (void); static void ExaSet_PutParamQstCod (void *QstCod); // Should be a pointer to long @@ -208,36 +212,40 @@ void ExaSet_GetDataOfSetByCod (struct ExaSet_Set *Set) /***** Get data of set of questions from database *****/ if (DB_QuerySELECT (&mysql_res,"can not get set data", "SELECT SetCod," // row[0] - "SetInd," // row[1] - "NumQstsToPrint," // row[2] - "Title" // row[3] + "ExaCod," // row[1] + "SetInd," // row[2] + "NumQstsToPrint," // row[3] + "Title" // row[4] " FROM exa_sets" - " WHERE SetCod=%ld" - " AND ExaCod=%ld", // Extra check - Set->SetCod,Set->ExaCod)) // Set found... + " WHERE SetCod=%ld", + Set->SetCod)) // Set found... { /* Get row */ row = mysql_fetch_row (mysql_res); /* row[0] SetCod - row[1] SetInd - row[2] NumQstsToPrint - row[3] Title + row[1] ExaCod + row[2] SetInd + row[3] NumQstsToPrint + row[4] Title */ /* Get set code (row[0]) */ Set->SetCod = Str_ConvertStrCodToLongCod (row[0]); - /* Get set index (row[1]) */ - Set->SetInd = Str_ConvertStrToUnsigned (row[1]); + /* Get exam code (row[0]) */ + Set->ExaCod = Str_ConvertStrCodToLongCod (row[1]); + + /* Get set index (row[2]) */ + Set->SetInd = Str_ConvertStrToUnsigned (row[2]); snprintf (StrSetInd,sizeof (Set->SetInd), "%u", Set->SetInd); - /* Get set index (row[2]) */ - Set->NumQstsToPrint = Str_ConvertStrToUnsigned (row[2]); + /* Get set index (row[3]) */ + Set->NumQstsToPrint = Str_ConvertStrToUnsigned (row[3]); - /* Get the title of the set (row[3]) */ - Str_Copy (Set->Title,row[3], + /* Get the title of the set (row[4]) */ + Str_Copy (Set->Title,row[4], ExaSet_MAX_BYTES_TITLE); } else @@ -447,21 +455,8 @@ void ExaSet_ChangeSetTitle (void) Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - Exams.SetCod = Set.SetCod; - - /***** Get exam and set data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - ExaSet_GetDataOfSetByCod (&Set); - Exams.SetCod = Set.SetCod; + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Receive new title from form *****/ Par_GetParToText ("Title",NewTitle,ExaSet_MAX_BYTES_TITLE); @@ -501,21 +496,8 @@ void ExaSet_ChangeNumQstsToExam (void) Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - Exams.SetCod = Set.SetCod; - - /***** Get exam and set data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - ExaSet_GetDataOfSetByCod (&Set); - Exams.SetCod = Set.SetCod; + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Get number of questions in set to appear in exam print *****/ NumQstsToPrint = (unsigned) Par_GetParToUnsignedLong ("NumQstsToPrint", @@ -726,38 +708,14 @@ void ExaSet_ReqSelectQstsToAddToSet (void) struct Exa_Exams Exams; struct Exa_Exam Exam; struct ExaSet_Set Set; - char Txt[Cns_MAX_BYTES_TEXT + 1]; /***** Reset exams context *****/ Exa_ResetExams (&Exams); Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Exam.ExaCod = Exams.ExaCod; - - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Exams.SetCod = Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - Exa_GetExamTxtFromDB (Exam.ExaCod,Txt); - if (!Exa_CheckIfEditable (&Exam)) - Lay_NoPermissionExit (); - - /***** Get set data from database *****/ - ExaSet_GetDataOfSetByCod (&Set); - Exams.SetCod = Set.SetCod; + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Show form to select questions for set *****/ Tst_RequestSelectTestsForSet (&Exams); @@ -776,34 +734,14 @@ void ExaSet_ListQstsToAddToSet (void) struct Exa_Exams Exams; struct Exa_Exam Exam; struct ExaSet_Set Set; - char Txt[Cns_MAX_BYTES_TEXT + 1]; /***** Reset exams context *****/ Exa_ResetExams (&Exams); Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Exam.ExaCod = Exams.ExaCod; - - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Exams.SetCod = Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - Exa_GetExamTxtFromDB (Exam.ExaCod,Txt); - if (!Exa_CheckIfEditable (&Exam)) - Lay_NoPermissionExit (); + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Get set data from database *****/ ExaSet_GetDataOfSetByCod (&Set); @@ -1368,7 +1306,7 @@ static void ExaSet_ListOneOrMoreQuestionsForEdition (struct Exa_Exams *Exams, HTM_TD_End (); /***** Question *****/ - ExaSet_GetQstDataFromDB (&Question,Exams->ExaCod); + ExaSet_GetQstDataFromDB (&Question); ExaSet_ListQuestionForEdition (&Question,NumQst + 1,Anchor); /***** End row *****/ @@ -1417,7 +1355,7 @@ Tst_AnswerType_t ExaSet_GetQstAnswerTypeFromDB (long QstCod) /*************** Get data of a question in a set from database ***************/ /*****************************************************************************/ -void ExaSet_GetQstDataFromDB (struct Tst_Question *Question,long ExaCod) +void ExaSet_GetQstDataFromDB (struct Tst_Question *Question) { MYSQL_RES *mysql_res; MYSQL_ROW row; @@ -1432,11 +1370,8 @@ void ExaSet_GetQstDataFromDB (struct Tst_Question *Question,long ExaCod) "Feedback," // row[3] "MedCod" // row[4] " FROM exa_set_questions" - " WHERE QstCod=%ld" - " AND SetCod IN" - " (SELECT SetCod FROM exa_sets WHERE ExaCod=%ld)", // Extra check - Question->QstCod, - ExaCod) != 0); + " WHERE QstCod=%ld", + Question->QstCod) != 0); if (QuestionExists) { @@ -1622,7 +1557,6 @@ void ExaSet_AddQstsToSet (void) struct Exa_Exams Exams; struct Exa_Exam Exam; struct ExaSet_Set Set; - char Txt[Cns_MAX_BYTES_TEXT + 1]; const char *Ptr; char LongStr[Cns_MAX_DECIMAL_DIGITS_LONG + 1]; long QstCod; @@ -1632,27 +1566,8 @@ void ExaSet_AddQstsToSet (void) Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Exam.ExaCod = Exams.ExaCod; - - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Exams.SetCod = Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - Exa_GetExamTxtFromDB (Exam.ExaCod,Txt); - if (!Exa_CheckIfEditable (&Exam)) - Lay_NoPermissionExit (); + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Get set data from database *****/ ExaSet_GetDataOfSetByCod (&Set); @@ -1822,24 +1737,8 @@ void ExaSet_RequestRemoveSet (void) Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Exams.SetCod = Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - if (!Exa_CheckIfEditable (&Exam)) - Lay_NoPermissionExit (); - - /***** Get set data from database *****/ - ExaSet_GetDataOfSetByCod (&Set); - Exams.SetCod = Set.SetCod; + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Show question and button to remove question *****/ Ale_ShowAlertAndButton (ActRemExaSet,NULL,NULL, @@ -1869,24 +1768,8 @@ void ExaSet_RemoveSet (void) Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - if (!Exa_CheckIfEditable (&Exam)) - Lay_NoPermissionExit (); - - /***** Get set data from database *****/ - ExaSet_GetDataOfSetByCod (&Set); - Exams.SetCod = Set.SetCod; + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Remove the set from all the tables *****/ /* Remove questions associated to set */ @@ -1939,24 +1822,8 @@ void ExaSet_MoveUpSet (void) Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - if (!Exa_CheckIfEditable (&Exam)) - Lay_NoPermissionExit (); - - /***** Get set data from database *****/ - ExaSet_GetDataOfSetByCod (&Set); - Exams.SetCod = Set.SetCod; + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Get set index *****/ SetIndBottom = ExaSet_GetSetIndFromSetCod (Exam.ExaCod,Set.SetCod); @@ -1999,24 +1866,8 @@ void ExaSet_MoveDownSet (void) Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - if (!Exa_CheckIfEditable (&Exam)) - Lay_NoPermissionExit (); - - /***** Get set data from database *****/ - ExaSet_GetDataOfSetByCod (&Set); - Exams.SetCod = Set.SetCod; + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Get set index *****/ SetIndTop = ExaSet_GetSetIndFromSetCod (Exam.ExaCod,Set.SetCod); @@ -2061,24 +1912,8 @@ void ExaSet_RequestRemoveQstFromSet (void) Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - if (!Exa_CheckIfEditable (&Exam)) - Lay_NoPermissionExit (); - - /***** Get set data from database *****/ - ExaSet_GetDataOfSetByCod (&Set); - Exams.SetCod = Set.SetCod; + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Get question index *****/ Exams.QstCod = ExaSet_GetParamQstCod (); @@ -2118,24 +1953,8 @@ void ExaSet_RemoveQstFromSet (void) Exa_ResetExam (&Exam); ExaSet_ResetSet (&Set); - /***** Get parameters *****/ - Exa_GetParams (&Exams); - if (Exams.ExaCod <= 0) - Lay_WrongExamExit (); - Set.ExaCod = Exam.ExaCod = Exams.ExaCod; - Set.SetCod = ExaSet_GetParamSetCod (); - if (Set.SetCod <= 0) - Lay_WrongSetExit (); - - /***** Get exam data from database *****/ - Exa_GetDataOfExamByCod (&Exam); - Exams.ExaCod = Exam.ExaCod; - if (!Exa_CheckIfEditable (&Exam)) - Lay_NoPermissionExit (); - - /***** Get set data from database *****/ - ExaSet_GetDataOfSetByCod (&Set); - Exams.SetCod = Set.SetCod; + /***** Get and check parameters *****/ + ExaSet_GetAndCheckParameters (&Exams,&Exam,&Set); /***** Get question index *****/ QstCod = ExaSet_GetParamQstCod (); @@ -2158,6 +1977,36 @@ void ExaSet_RemoveQstFromSet (void) false); // It's not a new exam } +/*****************************************************************************/ +/************************** Get and check parameters *************************/ +/*****************************************************************************/ + +static void ExaSet_GetAndCheckParameters (struct Exa_Exams *Exams, + struct Exa_Exam *Exam, + struct ExaSet_Set *Set) + { + /***** Get parameters *****/ + Exa_GetParams (Exams); + if (Exams->ExaCod <= 0) + Lay_WrongExamExit (); + Exam->ExaCod = Exams->ExaCod; + Grp_GetParamWhichGroups (); + if ((Set->SetCod = ExaSet_GetParamSetCod ()) <= 0) + Lay_WrongSetExit (); + + /***** Get exam data from database *****/ + Exa_GetDataOfExamByCod (Exam); + if (Exam->CrsCod != Gbl.Hierarchy.Crs.CrsCod) + Lay_WrongExamExit (); + Exams->ExaCod = Exam->ExaCod; + + /***** Get set data from database *****/ + ExaSet_GetDataOfSetByCod (Set); + if (Set->ExaCod != Exam->ExaCod) + Lay_WrongSetExit (); + Exams->SetCod = Set->SetCod; + } + /*****************************************************************************/ /************ Get the parameter with the code of a test question *************/ /*****************************************************************************/ diff --git a/swad_exam_set.h b/swad_exam_set.h index c20c0bd1b..831b82464 100644 --- a/swad_exam_set.h +++ b/swad_exam_set.h @@ -62,7 +62,7 @@ void ExaSet_ListExamSets (struct Exa_Exams *Exams, void ExaSet_ResetSet (struct ExaSet_Set *Set); Tst_AnswerType_t ExaSet_GetQstAnswerTypeFromDB (long QstCod); -void ExaSet_GetQstDataFromDB (struct Tst_Question *Question,long ExaCod); +void ExaSet_GetQstDataFromDB (struct Tst_Question *Question); void ExaSet_GetAnswersQst (struct Tst_Question *Question,MYSQL_RES **mysql_res, bool Shuffle); diff --git a/swad_group.c b/swad_group.c index cdf72ae8d..355b56591 100644 --- a/swad_group.c +++ b/swad_group.c @@ -5070,6 +5070,7 @@ Grp_WhichGroups_t Grp_GetParamWhichGroups (void) case ActPrnCrsTT: // Print course timetable case ActChgCrsTT1stDay:// Change first day of week in course timetable case ActSeeAsg: // List assignments + case ActSeeAllExa: // List exams case ActSeeAllGam: // List games case ActSeeAllSvy: // List surveys case ActSeeAtt: // List attendance diff --git a/swad_match.c b/swad_match.c index 877c18dae..500a65854 100644 --- a/swad_match.c +++ b/swad_match.c @@ -341,16 +341,25 @@ void Mch_ListMatches (struct Gam_Games *Games, Hlp_ASSESSMENT_Games_matches,Box_NOT_CLOSABLE); /***** Select whether show only my groups or all groups *****/ - if (Gbl.Crs.Grps.NumGrps) + switch (Gbl.Usrs.Me.Role.Logged) { - Set_StartSettingsHead (); - Grp_ShowFormToSelWhichGrps (ActSeeGam, - Gam_PutParams,Games); - Set_EndSettingsHead (); + case Rol_NET: + case Rol_TCH: + case Rol_SYS_ADM: + if (Gbl.Crs.Grps.NumGrps) + { + Set_StartSettingsHead (); + Grp_ShowFormToSelWhichGrps (ActSeeGam, + Gam_PutParams,Games); + Set_EndSettingsHead (); + } + break; + default: + break; } + /***** Show the table with the matches *****/ if (NumMatches) - /***** Show the table with the matches *****/ Mch_ListOneOrMoreMatches (Games,Game,NumMatches,mysql_res); /***** Free structure that stores the query result *****/