2020-05-17 02:28:30 +02:00
|
|
|
|
// swad_exam_session.c: exam sessions (each ocurrence of an exam)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
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-2020 Antonio Ca<EFBFBD>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 <linux/limits.h> // For PATH_MAX
|
|
|
|
|
#include <stddef.h> // For NULL
|
|
|
|
|
#include <stdio.h> // For asprintf
|
|
|
|
|
#include <stdlib.h> // For calloc
|
|
|
|
|
#include <string.h> // For string functions
|
|
|
|
|
|
|
|
|
|
#include "swad_database.h"
|
|
|
|
|
#include "swad_date.h"
|
|
|
|
|
#include "swad_exam.h"
|
2020-05-13 12:53:27 +02:00
|
|
|
|
#include "swad_exam_print.h"
|
2020-04-20 01:26:46 +02:00
|
|
|
|
#include "swad_exam_result.h"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
#include "swad_exam_session.h"
|
2020-05-07 02:22:57 +02:00
|
|
|
|
#include "swad_exam_set.h"
|
2020-05-05 21:49:00 +02:00
|
|
|
|
#include "swad_exam_type.h"
|
2020-04-20 01:26:46 +02:00
|
|
|
|
#include "swad_form.h"
|
|
|
|
|
#include "swad_global.h"
|
|
|
|
|
#include "swad_HTML.h"
|
|
|
|
|
#include "swad_role.h"
|
|
|
|
|
#include "swad_setting.h"
|
|
|
|
|
#include "swad_test.h"
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************** External global variables from others modules ****************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
extern struct Globals Gbl;
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private constants *****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/******************************* Private types *******************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private constants *****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private variables *****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/***************************** Private prototypes ****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_PutIconsInListOfSessions (void *Exams);
|
|
|
|
|
static void ExaSes_PutIconToCreateNewSession (struct Exa_Exams *Exams);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessions (struct Exa_Exams *Exams,
|
|
|
|
|
const struct Exa_Exam *Exam,
|
|
|
|
|
long EvtCodToBeEdited,
|
|
|
|
|
unsigned NumSessions,
|
|
|
|
|
MYSQL_RES *mysql_res);
|
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsHeading (bool ICanEditSessions);
|
|
|
|
|
static bool ExaSes_CheckIfICanEditSessions (void);
|
|
|
|
|
static bool ExaSes_CheckIfICanEditThisSession (const struct ExaSes_Session *Session);
|
2020-05-30 19:33:55 +02:00
|
|
|
|
static bool ExaSes_CheckIfVisibilityOfResultsCanBeChanged (const struct ExaSes_Session *Session);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsIcons (struct Exa_Exams *Exams,
|
|
|
|
|
const struct ExaSes_Session *Session,
|
|
|
|
|
const char *Anchor);
|
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsAuthor (const struct ExaSes_Session *Session);
|
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsTimes (const struct ExaSes_Session *Session,
|
|
|
|
|
unsigned UniqueId);
|
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsTitleGrps (struct Exa_Exams *Exams,
|
2020-05-21 16:59:14 +02:00
|
|
|
|
const struct Exa_Exam *Exam,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
const struct ExaSes_Session *Session,
|
|
|
|
|
const char *Anchor);
|
|
|
|
|
static void ExaSes_GetAndWriteNamesOfGrpsAssociatedToSession (const struct ExaSes_Session *Session);
|
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsResult (struct Exa_Exams *Exams,
|
|
|
|
|
const struct ExaSes_Session *Session);
|
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsResultStd (struct Exa_Exams *Exams,
|
|
|
|
|
const struct ExaSes_Session *Session);
|
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsResultTch (struct Exa_Exams *Exams,
|
|
|
|
|
const struct ExaSes_Session *Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_GetSessionDataFromRow (MYSQL_RES *mysql_res,
|
|
|
|
|
struct ExaSes_Session *Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_RemoveSessionFromAllTables (long SesCod);
|
|
|
|
|
static void ExaSes_RemoveUsrSesResultsInCrs (long UsrCod,long CrsCod,const char *TableName);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_PutFormSession (const struct ExaSes_Session *Session);
|
|
|
|
|
static void ExaSes_ShowLstGrpsToCreateSession (long SesCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_CreateSession (struct ExaSes_Session *Session);
|
|
|
|
|
static void ExaSes_UpdateSession (struct ExaSes_Session *Session);
|
2020-05-06 01:43:48 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_CreateGrps (long SesCod);
|
|
|
|
|
static void ExaSes_RemoveGroups (long SesCod);
|
2020-05-06 01:43:48 +02:00
|
|
|
|
|
2020-04-23 23:09:28 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***************************** Reset exam session ****************************/
|
2020-04-23 23:09:28 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_ResetSession (struct ExaSes_Session *Session)
|
2020-04-23 23:09:28 +02:00
|
|
|
|
{
|
2020-05-05 20:09:28 +02:00
|
|
|
|
Dat_StartEndTime_t StartEndTime;
|
|
|
|
|
|
2020-04-23 23:09:28 +02:00
|
|
|
|
/***** Initialize to empty match *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->SesCod = -1L;
|
|
|
|
|
Session->ExaCod = -1L;
|
|
|
|
|
Session->UsrCod = -1L;
|
2020-05-05 20:09:28 +02:00
|
|
|
|
for (StartEndTime = (Dat_StartEndTime_t) 0;
|
|
|
|
|
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
|
|
|
|
|
StartEndTime++)
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->TimeUTC[StartEndTime] = (time_t) 0;
|
|
|
|
|
Session->Title[0] = '\0';
|
|
|
|
|
Session->Hidden = false;
|
|
|
|
|
Session->Open = false;
|
|
|
|
|
Session->ShowUsrResults = false;
|
2020-04-23 23:09:28 +02:00
|
|
|
|
};
|
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/************************ List the sessions of an exam ***********************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_ListSessions (struct Exa_Exams *Exams,
|
2020-05-21 16:59:14 +02:00
|
|
|
|
struct Exa_Exam *Exam,
|
|
|
|
|
struct ExaSes_Session *Session,
|
|
|
|
|
bool PutFormSession)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
extern const char *Hlp_ASSESSMENT_Exams_sessions;
|
|
|
|
|
extern const char *Txt_Sessions;
|
2020-05-21 14:17:26 +02:00
|
|
|
|
char *HiddenSubQuery;
|
2020-05-21 04:02:29 +02:00
|
|
|
|
char *GroupsSubQuery;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
MYSQL_RES *mysql_res;
|
2020-05-17 02:28:30 +02:00
|
|
|
|
unsigned NumSessions;
|
|
|
|
|
long SesCodToBeEdited;
|
|
|
|
|
bool PutFormNewSession;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-21 14:17:26 +02:00
|
|
|
|
/***** Subquery: get hidden sessions depending on user's role *****/
|
|
|
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
|
|
|
{
|
|
|
|
|
case Rol_STD:
|
|
|
|
|
if (asprintf (&HiddenSubQuery," AND Hidden='N'") < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
break;
|
|
|
|
|
case Rol_NET:
|
|
|
|
|
case Rol_TCH:
|
|
|
|
|
case Rol_DEG_ADM:
|
|
|
|
|
case Rol_CTR_ADM:
|
|
|
|
|
case Rol_INS_ADM:
|
|
|
|
|
case Rol_SYS_ADM:
|
|
|
|
|
if (asprintf (&HiddenSubQuery,"%s","") < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
Rol_WrongRoleExit ();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Subquery: get sessions depending on groups *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
if (Gbl.Crs.Grps.WhichGrps == Grp_MY_GROUPS)
|
|
|
|
|
{
|
2020-05-21 04:02:29 +02:00
|
|
|
|
if (asprintf (&GroupsSubQuery," AND"
|
|
|
|
|
"(SesCod NOT IN"
|
|
|
|
|
" (SELECT SesCod FROM exa_groups)"
|
|
|
|
|
" OR"
|
|
|
|
|
" SesCod IN"
|
|
|
|
|
" (SELECT exa_groups.SesCod"
|
|
|
|
|
" FROM exa_groups,crs_grp_usr"
|
|
|
|
|
" WHERE crs_grp_usr.UsrCod=%ld"
|
|
|
|
|
" AND exa_groups.GrpCod=crs_grp_usr.GrpCod))",
|
2020-04-20 01:26:46 +02:00
|
|
|
|
Gbl.Usrs.Me.UsrDat.UsrCod) < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
}
|
|
|
|
|
else // Gbl.Crs.Grps.WhichGrps == Grp_ALL_GROUPS
|
2020-05-21 04:02:29 +02:00
|
|
|
|
if (asprintf (&GroupsSubQuery,"%s","") < 0)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
|
2020-05-21 14:17:26 +02:00
|
|
|
|
/***** Get data of sessions from database *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
NumSessions = (unsigned)
|
|
|
|
|
DB_QuerySELECT (&mysql_res,"can not get sessions",
|
|
|
|
|
"SELECT SesCod," // row[0]
|
2020-05-13 15:22:56 +02:00
|
|
|
|
"ExaCod," // row[1]
|
|
|
|
|
"Hidden," // row[2]
|
|
|
|
|
"UsrCod," // row[3]
|
|
|
|
|
"UNIX_TIMESTAMP(StartTime)," // row[4]
|
|
|
|
|
"UNIX_TIMESTAMP(EndTime)," // row[5]
|
|
|
|
|
"NOW() BETWEEN StartTime AND EndTime," // row[6]
|
|
|
|
|
"Title," // row[7]
|
|
|
|
|
"ShowUsrResults" // row[8]
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" FROM exa_sessions"
|
2020-05-21 14:17:26 +02:00
|
|
|
|
" WHERE ExaCod=%ld%s%s"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" ORDER BY SesCod",
|
2020-05-21 14:17:26 +02:00
|
|
|
|
Exam->ExaCod,HiddenSubQuery,GroupsSubQuery);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-21 14:17:26 +02:00
|
|
|
|
/***** Free allocated memory for subqueries *****/
|
2020-05-21 04:02:29 +02:00
|
|
|
|
free (GroupsSubQuery);
|
2020-05-21 14:17:26 +02:00
|
|
|
|
free (HiddenSubQuery);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Begin box *****/
|
|
|
|
|
Exams->ExaCod = Exam->ExaCod;
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Box_BoxBegin ("100%",Txt_Sessions,
|
|
|
|
|
ExaSes_PutIconsInListOfSessions,Exams,
|
|
|
|
|
Hlp_ASSESSMENT_Exams_sessions,Box_NOT_CLOSABLE);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Select whether show only my groups or all groups *****/
|
2020-05-15 01:07:46 +02:00
|
|
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-15 01:07:46 +02:00
|
|
|
|
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;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Show the table with the sessions *****/
|
|
|
|
|
if (NumSessions)
|
2020-05-05 21:49:00 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
SesCodToBeEdited = PutFormSession && Session->SesCod > 0 ? Session->SesCod :
|
|
|
|
|
-1L;
|
|
|
|
|
ExaSes_ListOneOrMoreSessions (Exams,Exam,SesCodToBeEdited,NumSessions,mysql_res);
|
2020-05-05 21:49:00 +02:00
|
|
|
|
}
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Put button to create a new exam session in this exam *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
|
|
|
{
|
|
|
|
|
case Rol_NET:
|
|
|
|
|
case Rol_TCH:
|
|
|
|
|
case Rol_SYS_ADM:
|
2020-05-17 02:28:30 +02:00
|
|
|
|
PutFormNewSession = PutFormSession && Session->SesCod <= 0;
|
|
|
|
|
if (PutFormNewSession)
|
2020-04-28 03:14:25 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Reset session */
|
|
|
|
|
ExaSes_ResetSession (Session);
|
|
|
|
|
Session->ExaCod = Exam->ExaCod;
|
|
|
|
|
Session->TimeUTC[Dat_START_TIME] = Gbl.StartExecutionTimeUTC; // Now
|
|
|
|
|
Session->TimeUTC[Dat_END_TIME ] = Gbl.StartExecutionTimeUTC + (1 * 60 * 60); // Now + 1 hour
|
|
|
|
|
Str_Copy (Session->Title,Exam->Title,
|
|
|
|
|
ExaSes_MAX_BYTES_TITLE);
|
|
|
|
|
|
|
|
|
|
/* Put form to create new session */
|
|
|
|
|
ExaSes_PutFormSession (Session); // Form to create session
|
2020-04-28 03:14:25 +02:00
|
|
|
|
}
|
2020-04-20 01:26:46 +02:00
|
|
|
|
else
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutButtonNewSession (Exams,Exam->ExaCod); // Button to create a new exam session
|
2020-04-20 01:26:46 +02:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** End box *****/
|
|
|
|
|
Box_BoxEnd ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/******************* Get exam session data using its code ********************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_GetDataOfSessionByCod (struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
MYSQL_RES *mysql_res;
|
|
|
|
|
unsigned long NumRows;
|
|
|
|
|
|
2020-05-06 12:47:36 +02:00
|
|
|
|
/***** Trivial check *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if (Session->SesCod <= 0)
|
2020-05-06 12:47:36 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Initialize to empty exam session */
|
|
|
|
|
ExaSes_ResetSession (Session);
|
2020-05-06 12:47:36 +02:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get exam data session from database *****/
|
2020-05-05 20:09:28 +02:00
|
|
|
|
NumRows = (unsigned)
|
2020-05-17 02:28:30 +02:00
|
|
|
|
DB_QuerySELECT (&mysql_res,"can not get sessions",
|
|
|
|
|
"SELECT SesCod," // row[0]
|
2020-05-14 01:41:20 +02:00
|
|
|
|
"ExaCod," // row[1]
|
|
|
|
|
"Hidden," // row[2]
|
|
|
|
|
"UsrCod," // row[3]
|
|
|
|
|
"UNIX_TIMESTAMP(StartTime)," // row[4]
|
|
|
|
|
"UNIX_TIMESTAMP(EndTime)," // row[5]
|
|
|
|
|
"NOW() BETWEEN StartTime AND EndTime," // row[6]
|
|
|
|
|
"Title," // row[7]
|
|
|
|
|
"ShowUsrResults" // row[8]
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" FROM exa_sessions"
|
|
|
|
|
" WHERE SesCod=%ld"
|
2020-05-05 20:09:28 +02:00
|
|
|
|
" AND ExaCod IN" // Extra check
|
|
|
|
|
" (SELECT ExaCod FROM exa_exams"
|
|
|
|
|
" WHERE CrsCod='%ld')",
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->SesCod,
|
2020-05-05 20:09:28 +02:00
|
|
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if (NumRows) // Session found...
|
|
|
|
|
/* Get exam session data from row */
|
|
|
|
|
ExaSes_GetSessionDataFromRow (mysql_res,Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
else
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Initialize to empty exam session */
|
|
|
|
|
ExaSes_ResetSession (Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***************** Put icons in list of sessions of an exam ******************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_PutIconsInListOfSessions (void *Exams)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
bool ICanEditSessions;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
if (Exams)
|
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Put icon to create a new exam session in current exam *****/
|
|
|
|
|
ICanEditSessions = ExaSes_CheckIfICanEditSessions ();
|
|
|
|
|
if (ICanEditSessions)
|
|
|
|
|
ExaSes_PutIconToCreateNewSession ((struct Exa_Exams *) Exams);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/******************* Put icon to create a new exam session *******************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_PutIconToCreateNewSession (struct Exa_Exams *Exams)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
extern const char *Txt_New_session;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Put form to create a new exam session *****/
|
2020-05-18 02:15:10 +02:00
|
|
|
|
Ico_PutContextualIconToAdd (ActReqNewExaSes,ExaSes_NEW_SESSION_SECTION_ID,
|
2020-04-22 22:40:07 +02:00
|
|
|
|
Exa_PutParams,Exams,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Txt_New_session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/********************** List exam sessions for edition ***********************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessions (struct Exa_Exams *Exams,
|
|
|
|
|
const struct Exa_Exam *Exam,
|
|
|
|
|
long EvtCodToBeEdited,
|
|
|
|
|
unsigned NumSessions,
|
|
|
|
|
MYSQL_RES *mysql_res)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
unsigned NumSession;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
unsigned UniqueId;
|
2020-05-05 20:09:28 +02:00
|
|
|
|
char *Anchor;
|
2020-05-17 02:28:30 +02:00
|
|
|
|
struct ExaSes_Session Session;
|
|
|
|
|
bool ICanEditSessions = ExaSes_CheckIfICanEditSessions ();
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-04-28 12:34:56 +02:00
|
|
|
|
/***** Trivial check *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if (!NumSessions)
|
2020-04-28 12:34:56 +02:00
|
|
|
|
return;
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Reset session *****/
|
|
|
|
|
ExaSes_ResetSession (&Session);
|
2020-04-23 23:09:28 +02:00
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/***** Write the heading *****/
|
|
|
|
|
HTM_TABLE_BeginWidePadding (2);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ListOneOrMoreSessionsHeading (ICanEditSessions);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Write rows *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
for (NumSession = 0, UniqueId = 1;
|
|
|
|
|
NumSession < NumSessions;
|
|
|
|
|
NumSession++, UniqueId++)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Gbl.RowEvenOdd = NumSession % 2;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get exam session data from row *****/
|
|
|
|
|
ExaSes_GetSessionDataFromRow (mysql_res,&Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if (ExaSes_CheckIfICanListThisSessionBasedOnGrps (Session.SesCod))
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-05 20:09:28 +02:00
|
|
|
|
/***** Build anchor string *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if (asprintf (&Anchor,"evt_%ld_%ld",Exam->ExaCod,Session.SesCod) < 0)
|
2020-05-05 20:09:28 +02:00
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Begin row for this exam session ****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
|
|
|
|
/* Icons */
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if (ICanEditSessions)
|
|
|
|
|
if (ExaSes_CheckIfICanEditThisSession (&Session))
|
|
|
|
|
ExaSes_ListOneOrMoreSessionsIcons (Exams,&Session,Anchor);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Session participant */
|
|
|
|
|
ExaSes_ListOneOrMoreSessionsAuthor (&Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/* Start/end date/time */
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ListOneOrMoreSessionsTimes (&Session,UniqueId);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/* Title and groups */
|
2020-05-21 16:59:14 +02:00
|
|
|
|
ExaSes_ListOneOrMoreSessionsTitleGrps (Exams,Exam,&Session,Anchor);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Session result visible? */
|
|
|
|
|
ExaSes_ListOneOrMoreSessionsResult (Exams,&Session);
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** End row for this session ****/
|
2020-05-05 20:09:28 +02:00
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** For to edit this session ****/
|
|
|
|
|
if (Session.SesCod == EvtCodToBeEdited)
|
2020-05-05 21:49:00 +02:00
|
|
|
|
{
|
|
|
|
|
HTM_TR_Begin (NULL);
|
2020-05-13 15:22:56 +02:00
|
|
|
|
HTM_TD_Begin ("colspan=\"6\" class=\"CT COLOR%u\"",Gbl.RowEvenOdd);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutFormSession (&Session); // Form to edit existing session
|
2020-05-05 21:49:00 +02:00
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-05 20:09:28 +02:00
|
|
|
|
/***** Free anchor string *****/
|
|
|
|
|
free (Anchor);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** End table *****/
|
|
|
|
|
HTM_TABLE_End ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/************* Put a column for exam session start and end times *************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsHeading (bool ICanEditSessions)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
|
|
|
|
extern const char *Txt_START_END_TIME[Dat_NUM_START_END_TIME];
|
2020-05-17 02:28:30 +02:00
|
|
|
|
extern const char *Txt_Session;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
extern const char *Txt_Results;
|
|
|
|
|
|
|
|
|
|
/***** Start row *****/
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
|
|
|
|
/***** Column for icons *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if (ICanEditSessions)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TH_Empty (1);
|
|
|
|
|
|
|
|
|
|
/***** The rest of columns *****/
|
|
|
|
|
HTM_TH (1,1,"LT",Txt_ROLES_SINGUL_Abc[Rol_TCH][Usr_SEX_UNKNOWN]);
|
2020-04-22 22:40:07 +02:00
|
|
|
|
HTM_TH (1,1,"LT",Txt_START_END_TIME[Exa_ORDER_BY_START_DATE]);
|
|
|
|
|
HTM_TH (1,1,"LT",Txt_START_END_TIME[Exa_ORDER_BY_END_DATE ]);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
HTM_TH (1,1,"LT",Txt_Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TH (1,1,"CT",Txt_Results);
|
|
|
|
|
|
|
|
|
|
/***** End row *****/
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/********************** Check if I can edit sessions *************************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static bool ExaSes_CheckIfICanEditSessions (void)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
|
|
|
{
|
|
|
|
|
case Rol_NET:
|
|
|
|
|
case Rol_TCH:
|
|
|
|
|
case Rol_SYS_ADM:
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/************ Check if I can edit (remove/resume) an exam session ************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static bool ExaSes_CheckIfICanEditThisSession (const struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
|
|
|
{
|
|
|
|
|
case Rol_NET:
|
2020-05-17 02:28:30 +02:00
|
|
|
|
return (Session->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod); // Only if I am the creator
|
2020-04-20 01:26:46 +02:00
|
|
|
|
case Rol_TCH:
|
|
|
|
|
case Rol_SYS_ADM:
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-30 19:33:55 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/********** Check if visibility of session results can be changed ************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
static bool ExaSes_CheckIfVisibilityOfResultsCanBeChanged (const struct ExaSes_Session *Session)
|
|
|
|
|
{
|
|
|
|
|
if (Session->ShowUsrResults || // Results are currently visible
|
|
|
|
|
Session->TimeUTC[Dat_END_TIME] < Gbl.StartExecutionTimeUTC) // End of time is in the past
|
|
|
|
|
if (ExaSes_CheckIfICanEditThisSession (Session))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************************* Put a column for icons ****************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsIcons (struct Exa_Exams *Exams,
|
2020-06-23 12:57:31 +02:00
|
|
|
|
const struct ExaSes_Session *Session,
|
|
|
|
|
const char *Anchor)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-05 21:49:00 +02:00
|
|
|
|
/***** Begin cell *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"BT%u\"",Gbl.RowEvenOdd);
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exams->ExaCod = Session->ExaCod;
|
|
|
|
|
Exams->SesCod = Session->SesCod;
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Icon to remove the exam session *****/
|
2020-05-18 02:15:10 +02:00
|
|
|
|
Frm_StartForm (ActReqRemExaSes);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutParamsEdit (Exams);
|
2020-05-05 20:09:28 +02:00
|
|
|
|
Ico_PutIconRemove ();
|
|
|
|
|
Frm_EndForm ();
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Icon to hide/unhide the exam session *****/
|
|
|
|
|
if (Session->Hidden)
|
2020-05-18 02:15:10 +02:00
|
|
|
|
Ico_PutContextualIconToUnhide (ActUnhExaSes,Anchor,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutParamsEdit,Exams);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
else
|
2020-05-18 02:15:10 +02:00
|
|
|
|
Ico_PutContextualIconToHide (ActHidExaSes,Anchor,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutParamsEdit,Exams);
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Icon to edit the exam session *****/
|
2020-05-18 02:15:10 +02:00
|
|
|
|
Ico_PutContextualIconToEdit (ActEdiOneExaSes,Anchor,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutParamsEdit,Exams);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-05 21:49:00 +02:00
|
|
|
|
/***** End cell *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/********** Put a column for teacher who created the exam session ************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsAuthor (const struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Session author (teacher) *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Usr_WriteAuthor1Line (Session->UsrCod,Session->Hidden);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/************* Put a column for exam session start and end times *************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsTimes (const struct ExaSes_Session *Session,
|
|
|
|
|
unsigned UniqueId)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
Dat_StartEndTime_t StartEndTime;
|
2020-05-05 20:09:28 +02:00
|
|
|
|
const char *Color;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
char *Id;
|
|
|
|
|
|
|
|
|
|
for (StartEndTime = (Dat_StartEndTime_t) 0;
|
|
|
|
|
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
|
|
|
|
|
StartEndTime++)
|
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Color = Session->Open ? (Session->Hidden ? "DATE_GREEN_LIGHT":
|
2020-05-07 01:14:50 +02:00
|
|
|
|
"DATE_GREEN") :
|
2020-05-17 02:28:30 +02:00
|
|
|
|
(Session->Hidden ? "DATE_RED_LIGHT":
|
2020-05-07 01:14:50 +02:00
|
|
|
|
"DATE_RED");
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
if (asprintf (&Id,"exa_time_%u_%u",(unsigned) StartEndTime,UniqueId) < 0)
|
|
|
|
|
Lay_NotEnoughMemoryExit ();
|
|
|
|
|
HTM_TD_Begin ("id=\"%s\" class=\"%s LT COLOR%u\"",
|
2020-05-05 20:09:28 +02:00
|
|
|
|
Id,Color,Gbl.RowEvenOdd);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Dat_WriteLocalDateHMSFromUTC (Id,Session->TimeUTC[StartEndTime],
|
2020-04-20 01:26:46 +02:00
|
|
|
|
Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK,
|
2020-05-15 01:07:46 +02:00
|
|
|
|
true,true,true,0x6);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
free (Id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/************** Put a column for exam session title and grous ****************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsTitleGrps (struct Exa_Exams *Exams,
|
2020-05-21 16:59:14 +02:00
|
|
|
|
const struct Exa_Exam *Exam,
|
|
|
|
|
const struct ExaSes_Session *Session,
|
|
|
|
|
const char *Anchor)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Play;
|
|
|
|
|
extern const char *Txt_Resume;
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"LT COLOR%u\"",Gbl.RowEvenOdd);
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Session title *****/
|
2020-05-05 20:09:28 +02:00
|
|
|
|
HTM_ARTICLE_Begin (Anchor);
|
2020-05-21 16:59:14 +02:00
|
|
|
|
if (ExaSes_CheckIfICanAnswerThisSession (Exam,Session))
|
2020-05-15 01:07:46 +02:00
|
|
|
|
{
|
|
|
|
|
Frm_StartForm (ActSeeExaPrn);
|
|
|
|
|
Exa_PutParams (Exams);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutParamSesCod (Session->SesCod);
|
2020-05-15 01:07:46 +02:00
|
|
|
|
HTM_BUTTON_SUBMIT_Begin (Gbl.Usrs.Me.Role.Logged == Rol_STD ? Txt_Play :
|
|
|
|
|
Txt_Resume,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->Hidden ? "BT_LINK LT ASG_TITLE_LIGHT":
|
2020-05-21 16:59:14 +02:00
|
|
|
|
"BT_LINK LT ASG_TITLE",
|
2020-05-15 01:07:46 +02:00
|
|
|
|
NULL);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
HTM_Txt (Session->Title);
|
2020-05-15 01:07:46 +02:00
|
|
|
|
HTM_BUTTON_End ();
|
|
|
|
|
Frm_EndForm ();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
HTM_SPAN_Begin ("class=\"%s\"",Session->Hidden ? "LT ASG_TITLE_LIGHT":
|
2020-05-21 16:59:14 +02:00
|
|
|
|
"LT ASG_TITLE");
|
2020-05-17 02:28:30 +02:00
|
|
|
|
HTM_Txt (Session->Title);
|
2020-05-15 01:07:46 +02:00
|
|
|
|
HTM_SPAN_End ();
|
|
|
|
|
}
|
2020-05-05 20:09:28 +02:00
|
|
|
|
HTM_ARTICLE_End ();
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Groups whose students can answer this exam session *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
if (Gbl.Crs.Grps.NumGrps)
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_GetAndWriteNamesOfGrpsAssociatedToSession (Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/********* Get and write the names of the groups of an exam session **********/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_GetAndWriteNamesOfGrpsAssociatedToSession (const struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Group;
|
|
|
|
|
extern const char *Txt_Groups;
|
|
|
|
|
extern const char *Txt_and;
|
|
|
|
|
extern const char *Txt_The_whole_course;
|
|
|
|
|
MYSQL_RES *mysql_res;
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
unsigned long NumRow;
|
|
|
|
|
unsigned long NumRows;
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get groups associated to an exam session from database *****/
|
|
|
|
|
NumRows = DB_QuerySELECT (&mysql_res,"can not get groups of an exam session",
|
|
|
|
|
"SELECT crs_grp_types.GrpTypName," // row[0]
|
|
|
|
|
"crs_grp.GrpName" // row[1]
|
2020-04-20 01:26:46 +02:00
|
|
|
|
" FROM exa_groups,crs_grp,crs_grp_types"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" WHERE exa_groups.SesCod=%ld"
|
2020-04-20 01:26:46 +02:00
|
|
|
|
" AND exa_groups.GrpCod=crs_grp.GrpCod"
|
|
|
|
|
" AND crs_grp.GrpTypCod=crs_grp_types.GrpTypCod"
|
|
|
|
|
" ORDER BY crs_grp_types.GrpTypName,crs_grp.GrpName",
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->SesCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Write heading *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
HTM_DIV_Begin ("class=\"%s\"",Session->Hidden ? "ASG_GRP_LIGHT":
|
|
|
|
|
"ASG_GRP");
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TxtColonNBSP (NumRows == 1 ? Txt_Group :
|
|
|
|
|
Txt_Groups);
|
|
|
|
|
|
|
|
|
|
/***** Write groups *****/
|
|
|
|
|
if (NumRows) // Groups found...
|
|
|
|
|
{
|
|
|
|
|
/* Get and write the group types and names */
|
|
|
|
|
for (NumRow = 0;
|
|
|
|
|
NumRow < NumRows;
|
|
|
|
|
NumRow++)
|
|
|
|
|
{
|
|
|
|
|
/* Get next group */
|
|
|
|
|
row = mysql_fetch_row (mysql_res);
|
|
|
|
|
|
|
|
|
|
/* Write group type name and group name */
|
|
|
|
|
HTM_TxtF ("%s %s",row[0],row[1]);
|
|
|
|
|
|
|
|
|
|
if (NumRows >= 2)
|
|
|
|
|
{
|
|
|
|
|
if (NumRow == NumRows-2)
|
|
|
|
|
HTM_TxtF (" %s ",Txt_and);
|
|
|
|
|
if (NumRows >= 3)
|
|
|
|
|
if (NumRow < NumRows-2)
|
|
|
|
|
HTM_Txt (", ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
HTM_TxtF ("%s %s",Txt_The_whole_course,Gbl.Hierarchy.Crs.ShrtName);
|
|
|
|
|
|
|
|
|
|
HTM_DIV_End ();
|
|
|
|
|
|
|
|
|
|
/***** Free structure that stores the query result *****/
|
|
|
|
|
DB_FreeMySQLResult (&mysql_res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/************ Put a column for visibility of exam session result *************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsResult (struct Exa_Exams *Exams,
|
|
|
|
|
const struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
HTM_TD_Begin ("class=\"DAT CT COLOR%u\"",Gbl.RowEvenOdd);
|
|
|
|
|
|
|
|
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
|
|
|
{
|
|
|
|
|
case Rol_STD:
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ListOneOrMoreSessionsResultStd (Exams,Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
break;
|
|
|
|
|
case Rol_NET:
|
|
|
|
|
case Rol_TCH:
|
|
|
|
|
case Rol_SYS_ADM:
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ListOneOrMoreSessionsResultTch (Exams,Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
Rol_WrongRoleExit ();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsResultStd (struct Exa_Exams *Exams,
|
|
|
|
|
const struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Results;
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Is exam session result visible or hidden? *****/
|
|
|
|
|
if (Session->ShowUsrResults)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
/* Result is visible by me */
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exams->ExaCod = Session->ExaCod;
|
|
|
|
|
Exams->SesCod = Session->SesCod;
|
2020-05-18 02:15:10 +02:00
|
|
|
|
Lay_PutContextualLinkOnlyIcon (ActSeeMyExaResSes,ExaRes_RESULTS_BOX_ID,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutParamsEdit,Exams,
|
2020-04-20 01:26:46 +02:00
|
|
|
|
"trophy.svg",
|
|
|
|
|
Txt_Results);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
/* Result is forbidden to me */
|
|
|
|
|
Ico_PutIconNotVisible ();
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ListOneOrMoreSessionsResultTch (struct Exa_Exams *Exams,
|
|
|
|
|
const struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *Txt_Visible_results;
|
|
|
|
|
extern const char *Txt_Hidden_results;
|
|
|
|
|
extern const char *Txt_Results;
|
|
|
|
|
|
2020-05-30 19:33:55 +02:00
|
|
|
|
Exams->ExaCod = Session->ExaCod;
|
|
|
|
|
Exams->SesCod = Session->SesCod;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-30 19:33:55 +02:00
|
|
|
|
/***** Show exam session results *****/
|
|
|
|
|
if (ExaSes_CheckIfICanEditThisSession (Session))
|
2020-05-18 22:59:07 +02:00
|
|
|
|
Lay_PutContextualLinkOnlyIcon (ActSeeUsrExaResSes,ExaRes_RESULTS_BOX_ID,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutParamsEdit,Exams,
|
2020-04-20 01:26:46 +02:00
|
|
|
|
"trophy.svg",
|
|
|
|
|
Txt_Results);
|
|
|
|
|
|
2020-05-30 19:33:55 +02:00
|
|
|
|
/***** Check if visibility of session results can be changed *****/
|
|
|
|
|
if (ExaSes_CheckIfVisibilityOfResultsCanBeChanged (Session))
|
|
|
|
|
{
|
|
|
|
|
/***** Put form to change visibility of session results *****/
|
2020-05-18 02:15:10 +02:00
|
|
|
|
Lay_PutContextualLinkOnlyIcon (ActChgVisExaRes,NULL,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutParamsEdit,Exams,
|
|
|
|
|
Session->ShowUsrResults ? "eye-green.svg" :
|
|
|
|
|
"eye-slash-red.svg",
|
|
|
|
|
Session->ShowUsrResults ? Txt_Visible_results :
|
|
|
|
|
Txt_Hidden_results);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
2020-05-30 19:33:55 +02:00
|
|
|
|
else // Don't put form
|
|
|
|
|
/***** Put icon showing the current visibility of session results *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Ico_PutIconOff (Session->ShowUsrResults ? "eye-green.svg" :
|
|
|
|
|
"eye-slash-red.svg",
|
|
|
|
|
Session->ShowUsrResults ? Txt_Visible_results :
|
|
|
|
|
Txt_Hidden_results);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***************** Toggle visibility of exam session results *****************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_ToggleVisResultsSesUsr (void)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
struct Exa_Exams Exams;
|
|
|
|
|
struct Exa_Exam Exam;
|
2020-05-17 02:28:30 +02:00
|
|
|
|
struct ExaSes_Session Session;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-04-23 23:09:28 +02:00
|
|
|
|
/***** Reset exams context *****/
|
2020-04-22 03:48:38 +02:00
|
|
|
|
Exa_ResetExams (&Exams);
|
2020-04-23 23:09:28 +02:00
|
|
|
|
Exa_ResetExam (&Exam);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ResetSession (&Session);
|
2020-04-23 23:09:28 +02:00
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/***** Get and check parameters *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_GetAndCheckParameters (&Exams,&Exam,&Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-30 19:33:55 +02:00
|
|
|
|
/***** Check if visibility of session results can be changed *****/
|
|
|
|
|
if (!ExaSes_CheckIfVisibilityOfResultsCanBeChanged (&Session))
|
2020-04-20 01:26:46 +02:00
|
|
|
|
Lay_NoPermissionExit ();
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Toggle visibility of exam session results *****/
|
|
|
|
|
Session.ShowUsrResults = !Session.ShowUsrResults;
|
|
|
|
|
DB_QueryUPDATE ("can not toggle visibility of session results",
|
2020-05-30 19:33:55 +02:00
|
|
|
|
"UPDATE exa_sessions,exa_exams"
|
|
|
|
|
" SET exa_sessions.ShowUsrResults='%c'"
|
|
|
|
|
" WHERE exa_sessions.SesCod=%ld"
|
|
|
|
|
" AND exa_sessions.ExaCod=%ld" // Extra check
|
|
|
|
|
" AND exa_sessions.ExaCod=exa_exams.ExaCod"
|
|
|
|
|
" AND exa_exams.CrsCod=%ld", // Extra check
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session.ShowUsrResults ? 'Y' :
|
2020-05-30 19:33:55 +02:00
|
|
|
|
'N',
|
|
|
|
|
Session.SesCod,
|
|
|
|
|
Session.ExaCod,
|
|
|
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Show current exam *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exa_ShowOnlyOneExam (&Exams,&Exam,&Session,
|
|
|
|
|
false); // Do not put form for session
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/******************** Get exam data from a database row **********************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_GetSessionDataFromRow (MYSQL_RES *mysql_res,
|
|
|
|
|
struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
MYSQL_ROW row;
|
|
|
|
|
Dat_StartEndTime_t StartEndTime;
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get exam session data *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
row = mysql_fetch_row (mysql_res);
|
|
|
|
|
/*
|
2020-05-17 02:28:30 +02:00
|
|
|
|
row[0] SesCod
|
2020-05-13 15:22:56 +02:00
|
|
|
|
row[1] ExaCod
|
|
|
|
|
row[2] Hidden
|
|
|
|
|
row[3] UsrCod
|
|
|
|
|
row[4] UNIX_TIMESTAMP(StartTime)
|
|
|
|
|
row[5] UNIX_TIMESTAMP(EndTime)
|
|
|
|
|
row[6] Open = NOW() BETWEEN StartTime AND EndTime
|
|
|
|
|
row[7] Title
|
|
|
|
|
row[8] ShowUsrResults
|
2020-04-20 01:26:46 +02:00
|
|
|
|
*/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get session data *****/
|
|
|
|
|
/* Code of the session (row[0]) */
|
|
|
|
|
if ((Session->SesCod = Str_ConvertStrCodToLongCod (row[0])) <= 0)
|
|
|
|
|
Lay_ShowErrorAndExit ("Wrong code of exam session.");
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/* Code of the exam (row[1]) */
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if ((Session->ExaCod = Str_ConvertStrCodToLongCod (row[1])) <= 0)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
Lay_ShowErrorAndExit ("Wrong code of exam.");
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Get whether the session is hidden (row[2]) */
|
|
|
|
|
Session->Hidden = (row[2][0] == 'Y');
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Get session teacher (row[3]) */
|
|
|
|
|
Session->UsrCod = Str_ConvertStrCodToLongCod (row[3]);
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
|
|
|
|
/* Get start/end times (row[4], row[5] hold start/end UTC times) */
|
2020-04-20 01:26:46 +02:00
|
|
|
|
for (StartEndTime = (Dat_StartEndTime_t) 0;
|
|
|
|
|
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
|
|
|
|
|
StartEndTime++)
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->TimeUTC[StartEndTime] = Dat_GetUNIXTimeFromStr (row[4 + StartEndTime]);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Get whether the session is open or closed (row(6)) */
|
|
|
|
|
Session->Open = (row[6][0] == '1');
|
2020-05-07 01:14:50 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Get the title of the session (row[7]) */
|
2020-05-07 01:14:50 +02:00
|
|
|
|
if (row[7])
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Str_Copy (Session->Title,row[7],
|
|
|
|
|
ExaSes_MAX_BYTES_TITLE);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
else
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->Title[0] = '\0';
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-13 15:22:56 +02:00
|
|
|
|
/* Get whether to show user results or not (row(8)) */
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->ShowUsrResults = (row[8][0] == 'Y');
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/********** Request the removal of an exam session (exam instance) ***********/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_RequestRemoveSession (void)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-23 20:51:51 +02:00
|
|
|
|
extern const char *Txt_Do_you_really_want_to_remove_the_session_X;
|
|
|
|
|
extern const char *Txt_Remove_session;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
struct Exa_Exams Exams;
|
|
|
|
|
struct Exa_Exam Exam;
|
2020-05-17 02:28:30 +02:00
|
|
|
|
struct ExaSes_Session Session;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-04-23 23:09:28 +02:00
|
|
|
|
/***** Reset exams context *****/
|
2020-04-22 03:48:38 +02:00
|
|
|
|
Exa_ResetExams (&Exams);
|
2020-04-23 23:09:28 +02:00
|
|
|
|
Exa_ResetExam (&Exam);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ResetSession (&Session);
|
2020-04-23 23:09:28 +02:00
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/***** Get and check parameters *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_GetAndCheckParameters (&Exams,&Exam,&Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Show question and button to remove question *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exams.ExaCod = Session.ExaCod;
|
|
|
|
|
Exams.SesCod = Session.SesCod;
|
2020-05-18 02:15:10 +02:00
|
|
|
|
Ale_ShowAlertAndButton (ActRemExaSes,NULL,NULL,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutParamsEdit,&Exams,
|
2020-05-23 20:51:51 +02:00
|
|
|
|
Btn_REMOVE_BUTTON,Txt_Remove_session,
|
|
|
|
|
Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_session_X,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session.Title);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Show current exam *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exa_ShowOnlyOneExam (&Exams,&Exam,&Session,
|
|
|
|
|
false); // Do not put form for session
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/****************** Remove an exam session (exam instance) *******************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_RemoveSession (void)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
extern const char *Txt_Session_X_removed;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
struct Exa_Exams Exams;
|
|
|
|
|
struct Exa_Exam Exam;
|
2020-05-17 02:28:30 +02:00
|
|
|
|
struct ExaSes_Session Session;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-04-23 23:09:28 +02:00
|
|
|
|
/***** Reset exams context *****/
|
2020-04-22 03:48:38 +02:00
|
|
|
|
Exa_ResetExams (&Exams);
|
2020-04-23 23:09:28 +02:00
|
|
|
|
Exa_ResetExam (&Exam);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ResetSession (&Session);
|
2020-04-23 23:09:28 +02:00
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/***** Get and check parameters *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_GetAndCheckParameters (&Exams,&Exam,&Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Check if I can remove this exam session *****/
|
|
|
|
|
if (!ExaSes_CheckIfICanEditThisSession (&Session))
|
2020-04-20 01:26:46 +02:00
|
|
|
|
Lay_NoPermissionExit ();
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Remove the exam session from all database tables *****/
|
|
|
|
|
ExaSes_RemoveSessionFromAllTables (Session.SesCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Write message *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Ale_ShowAlert (Ale_SUCCESS,Txt_Session_X_removed,
|
|
|
|
|
Session.Title);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get exam data again to update it after changes in session *****/
|
2020-05-07 01:14:50 +02:00
|
|
|
|
Exa_GetDataOfExamByCod (&Exam);
|
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/***** Show current exam *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exa_ShowOnlyOneExam (&Exams,&Exam,&Session,
|
|
|
|
|
false); // Do not put form for session
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/******************* Remove exam session from all tables *********************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-24 16:20:56 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_RemoveSessionFromAllTables (long SesCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-24 16:20:56 +02:00
|
|
|
|
/* To delete orphan exam prints:
|
|
|
|
|
// DELETE FROM exa_print_questions WHERE PrnCod IN (SELECT PrnCod FROM exa_prints WHERE SesCod NOT IN (SELECT SesCod FROM exa_sessions));
|
|
|
|
|
// DELETE FROM exa_prints WHERE SesCod NOT IN (SELECT SesCod FROM exa_sessions);
|
|
|
|
|
*/
|
|
|
|
|
/***** Remove exam prints in this session *****/
|
|
|
|
|
/*
|
|
|
|
|
* TODO: DO NOT REMOVE EXAMS PRINTS. Instead move them to tables of deleted prints
|
|
|
|
|
DB_QueryDELETE ("can not remove exam print questions in exam session",
|
|
|
|
|
"DELETE FROM exa_print_questions"
|
|
|
|
|
" USING exa_print_questions,exa_prints"
|
|
|
|
|
" WHERE exa_prints.SesCod=%ld"
|
|
|
|
|
" AND exa_prints.PrnCod=exa_print_questions.PrnCod",
|
|
|
|
|
SesCod);
|
|
|
|
|
DB_QueryDELETE ("can not remove exam prints in exam session",
|
|
|
|
|
"DELETE FROM exa_prints"
|
|
|
|
|
" WHERE exa_prints.SesCod=%ld",
|
|
|
|
|
SesCod);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/***** Remove groups associated to this exam session *****/
|
|
|
|
|
DB_QueryDELETE ("can not remove groups associated to exam session",
|
|
|
|
|
"DELETE FROM exa_groups WHERE SesCod=%ld",
|
|
|
|
|
SesCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Remove exam session from main table *****/
|
|
|
|
|
DB_QueryDELETE ("can not remove exam session",
|
|
|
|
|
"DELETE FROM exa_sessions WHERE SesCod=%ld",
|
|
|
|
|
SesCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/**************** Remove exam session in exam from all tables ****************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_RemoveSessionsInExamFromAllTables (long ExaCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-24 16:20:56 +02:00
|
|
|
|
/***** Remove exam prints in this session *****/
|
|
|
|
|
/*
|
|
|
|
|
* TODO: DO NOT REMOVE EXAMS PRINTS. Instead move them to tables of deleted prints
|
|
|
|
|
DB_QueryDELETE ("can not remove exam print questions in exam",
|
|
|
|
|
"DELETE FROM exa_print_questions"
|
|
|
|
|
" USING exa_print_questions,exa_prints,exa_sessions"
|
|
|
|
|
" WHERE exa_sessions.ExaCod=%ld"
|
|
|
|
|
" AND exa_sessions.SesCod=exa_prints.SesCod"
|
|
|
|
|
" AND exa_prints.PrnCod=exa_print_questions.PrnCod",
|
|
|
|
|
ExaCod);
|
|
|
|
|
DB_QueryDELETE ("can not remove exam prints in exam",
|
|
|
|
|
"DELETE FROM exa_prints"
|
|
|
|
|
" USING exa_prints,exa_sessions"
|
|
|
|
|
" WHERE exa_sessions.ExaCod=%ld"
|
|
|
|
|
" AND exa_sessions.SesCod=exa_prints.SesCod",
|
|
|
|
|
ExaCod);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/***** Remove groups associated to exam sessions of this exam *****/
|
|
|
|
|
DB_QueryDELETE ("can not remove groups associated to sessions of an exam",
|
|
|
|
|
"DELETE FROM exa_groups"
|
|
|
|
|
" USING exa_sessions,exa_groups"
|
|
|
|
|
" WHERE exa_sessions.ExaCod=%ld"
|
|
|
|
|
" AND exa_sessions.SesCod=exa_groups.SesCod",
|
|
|
|
|
ExaCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Remove sessions from main table *****/
|
|
|
|
|
DB_QueryDELETE ("can not remove sessions of an exam",
|
|
|
|
|
"DELETE FROM exa_sessions WHERE ExaCod=%ld",
|
2020-04-20 01:26:46 +02:00
|
|
|
|
ExaCod);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/*************** Remove exam session in course from all tables ***************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_RemoveSessionInCourseFromAllTables (long CrsCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-24 16:20:56 +02:00
|
|
|
|
/***** Remove exam prints in this course *****/
|
|
|
|
|
/*
|
|
|
|
|
* TODO: DO NOT REMOVE EXAMS PRINTS. Instead move them to tables of deleted prints
|
|
|
|
|
DB_QueryDELETE ("can not remove exam print questions in course",
|
|
|
|
|
"DELETE FROM exa_print_questions"
|
|
|
|
|
" USING exa_print_questions,exa_prints,exa_sessions,exa_exams"
|
|
|
|
|
" WHERE exa_exams.CrsCod=%ld"
|
|
|
|
|
" AND exa_exams.ExaCod=exa_sessions"
|
|
|
|
|
" AND exa_sessions.SesCod=exa_prints.SesCod"
|
|
|
|
|
" AND exa_prints.PrnCod=exa_print_questions.PrnCod",
|
|
|
|
|
CrsCod);
|
|
|
|
|
DB_QueryDELETE ("can not remove exam print questions in course",
|
|
|
|
|
"DELETE FROM exa_prints"
|
|
|
|
|
" USING exa_prints,exa_sessions,exa_exams"
|
|
|
|
|
" WHERE exa_exams.CrsCod=%ld"
|
|
|
|
|
" AND exa_exams.ExaCod=exa_sessions"
|
|
|
|
|
" AND exa_sessions.SesCod=exa_prints.SesCod",
|
|
|
|
|
CrsCod);
|
|
|
|
|
*/
|
|
|
|
|
|
2020-05-18 22:59:07 +02:00
|
|
|
|
/***** Remove sessions from table of sessions groups *****/
|
|
|
|
|
DB_QueryDELETE ("can not remove sessions of a course",
|
|
|
|
|
"DELETE FROM exa_groups"
|
|
|
|
|
" USING exa_exams,exa_sessions,exa_groups"
|
|
|
|
|
" WHERE exa_exams.CrsCod=%ld"
|
|
|
|
|
" AND exa_exams.ExaCod=exa_sessions.ExaCod"
|
|
|
|
|
" AND exa_sessions.SesCod=exa_groups.SesCod",
|
|
|
|
|
CrsCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-18 22:59:07 +02:00
|
|
|
|
/***** Remove sessions from exam sessions table *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
DB_QueryDELETE ("can not remove sessions of a course",
|
|
|
|
|
"DELETE FROM exa_sessions"
|
|
|
|
|
" USING exa_exams,exa_sessions"
|
2020-04-20 01:26:46 +02:00
|
|
|
|
" WHERE exa_exams.CrsCod=%ld"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" AND exa_exams.ExaCod=exa_sessions.ExaCod",
|
2020-04-20 01:26:46 +02:00
|
|
|
|
CrsCod);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/************* Remove user from secondary exam session tables ****************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_RemoveUsrFromSessionTablesInCrs (long UsrCod,long CrsCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
/***** Remove student from secondary tables *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_RemoveUsrSesResultsInCrs (UsrCod,CrsCod,"exa_prints");
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_RemoveUsrSesResultsInCrs (long UsrCod,long CrsCod,const char *TableName)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Remove sessions in course from secondary table *****/
|
|
|
|
|
DB_QueryDELETE ("can not remove sessions of a user from table",
|
2020-04-20 01:26:46 +02:00
|
|
|
|
"DELETE FROM %s"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" USING exa_exams,exa_sessions,%s"
|
2020-04-20 01:26:46 +02:00
|
|
|
|
" WHERE exa_exams.CrsCod=%ld"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" AND exa_exams.ExaCod=exa_sessions.ExaCod"
|
|
|
|
|
" AND exa_sessions.SesCod=%s.SesCod"
|
2020-04-20 01:26:46 +02:00
|
|
|
|
" AND %s.UsrCod=%ld",
|
|
|
|
|
TableName,
|
|
|
|
|
TableName,
|
|
|
|
|
CrsCod,
|
|
|
|
|
TableName,
|
|
|
|
|
TableName,
|
|
|
|
|
UsrCod);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-05 20:09:28 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/******************************* Hide an session *****************************/
|
2020-05-05 20:09:28 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_HideSession (void)
|
2020-05-05 20:09:28 +02:00
|
|
|
|
{
|
|
|
|
|
struct Exa_Exams Exams;
|
|
|
|
|
struct Exa_Exam Exam;
|
2020-05-17 02:28:30 +02:00
|
|
|
|
struct ExaSes_Session Session;
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
|
|
|
|
/***** Reset exams context *****/
|
|
|
|
|
Exa_ResetExams (&Exams);
|
|
|
|
|
Exa_ResetExam (&Exam);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ResetSession (&Session);
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
|
|
|
|
/***** Get and check parameters *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_GetAndCheckParameters (&Exams,&Exam,&Session);
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Check if I can remove this exam session *****/
|
|
|
|
|
if (!ExaSes_CheckIfICanEditThisSession (&Session))
|
2020-05-05 20:09:28 +02:00
|
|
|
|
Lay_NoPermissionExit ();
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Hide session *****/
|
|
|
|
|
DB_QueryUPDATE ("can not hide exam sessions",
|
2020-05-30 19:33:55 +02:00
|
|
|
|
"UPDATE exa_sessions,exa_exams"
|
|
|
|
|
" SET exa_sessions.Hidden='Y'"
|
|
|
|
|
" WHERE exa_sessions.SesCod=%ld"
|
|
|
|
|
" AND exa_sessions.ExaCod=%ld" // Extra check
|
|
|
|
|
" AND exa_sessions.ExaCod=exa_exams.ExaCod"
|
|
|
|
|
" AND exa_exams.CrsCod=%ld", // Extra check
|
|
|
|
|
Session.SesCod,
|
|
|
|
|
Session.ExaCod,
|
|
|
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
|
|
|
|
/***** Show current exam *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exa_ShowOnlyOneExam (&Exams,&Exam,&Session,
|
|
|
|
|
false); // Do not put form for session
|
2020-05-05 20:09:28 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***************************** Unhide an session *****************************/
|
2020-05-05 20:09:28 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_UnhideSession (void)
|
2020-05-05 20:09:28 +02:00
|
|
|
|
{
|
|
|
|
|
struct Exa_Exams Exams;
|
|
|
|
|
struct Exa_Exam Exam;
|
2020-05-17 02:28:30 +02:00
|
|
|
|
struct ExaSes_Session Session;
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
|
|
|
|
/***** Reset exams context *****/
|
|
|
|
|
Exa_ResetExams (&Exams);
|
|
|
|
|
Exa_ResetExam (&Exam);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ResetSession (&Session);
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
|
|
|
|
/***** Get and check parameters *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_GetAndCheckParameters (&Exams,&Exam,&Session);
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Check if I can remove this exam session *****/
|
|
|
|
|
if (!ExaSes_CheckIfICanEditThisSession (&Session))
|
2020-05-05 20:09:28 +02:00
|
|
|
|
Lay_NoPermissionExit ();
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Unhide session *****/
|
|
|
|
|
DB_QueryUPDATE ("can not unhide exam session",
|
2020-05-30 19:33:55 +02:00
|
|
|
|
"UPDATE exa_sessions,exa_exams"
|
|
|
|
|
" SET exa_sessions.Hidden='N'"
|
|
|
|
|
" WHERE exa_sessions.SesCod=%ld"
|
|
|
|
|
" AND exa_sessions.ExaCod=%ld" // Extra check
|
|
|
|
|
" AND exa_sessions.ExaCod=exa_exams.ExaCod"
|
|
|
|
|
" AND exa_exams.CrsCod=%ld", // Extra check
|
|
|
|
|
Session.SesCod,
|
|
|
|
|
Session.ExaCod,
|
|
|
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
2020-05-05 20:09:28 +02:00
|
|
|
|
|
|
|
|
|
/***** Show current exam *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exa_ShowOnlyOneExam (&Exams,&Exam,&Session,
|
|
|
|
|
false); // Do not put form for session
|
2020-05-05 20:09:28 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/******************* Params used to edit an exam session *********************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_PutParamsEdit (void *Exams)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
if (Exams)
|
|
|
|
|
{
|
2020-04-22 22:40:07 +02:00
|
|
|
|
Exa_PutParams (Exams);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_PutParamSesCod (((struct Exa_Exams *) Exams)->SesCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/**************** Write parameter with code of exam session ******************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 20:12:37 +02:00
|
|
|
|
void ExaSes_PutParamSesCod (long SesCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Par_PutHiddenParamLong (NULL,"SesCod",SesCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/************************** Get and check parameters *************************/
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_GetAndCheckParameters (struct Exa_Exams *Exams,
|
2020-04-20 01:26:46 +02:00
|
|
|
|
struct Exa_Exam *Exam,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
/***** Get parameters *****/
|
2020-04-25 01:36:53 +02:00
|
|
|
|
Exa_GetParams (Exams);
|
|
|
|
|
if (Exams->ExaCod <= 0)
|
|
|
|
|
Lay_WrongExamExit ();
|
|
|
|
|
Exam->ExaCod = Exams->ExaCod;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
Grp_GetParamWhichGroups ();
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if ((Session->SesCod = ExaSes_GetParamSesCod ()) <= 0)
|
|
|
|
|
Lay_WrongExamSessionExit ();
|
2020-04-25 01:36:53 +02:00
|
|
|
|
|
2020-05-15 01:07:46 +02:00
|
|
|
|
/***** Get exam data from database *****/
|
2020-04-25 01:36:53 +02:00
|
|
|
|
Exa_GetDataOfExamByCod (Exam);
|
2020-05-05 21:49:00 +02:00
|
|
|
|
if (Exam->CrsCod != Gbl.Hierarchy.Crs.CrsCod)
|
|
|
|
|
Lay_WrongExamExit ();
|
2020-04-27 19:37:49 +02:00
|
|
|
|
Exams->ExaCod = Exam->ExaCod;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-15 01:07:46 +02:00
|
|
|
|
/***** Get set data from database *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_GetDataOfSessionByCod (Session);
|
|
|
|
|
if (Session->ExaCod != Exam->ExaCod)
|
2020-05-15 01:07:46 +02:00
|
|
|
|
Lay_WrongSetExit ();
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exams->SesCod = Session->SesCod;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/**************** Get parameter with code of exam session ********************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
long ExaSes_GetParamSesCod (void)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get code of exam session *****/
|
|
|
|
|
return Par_GetParToLong ("SesCod");
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Put a big button to play exam session (start a new session) as a teacher **/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_PutFormSession (const struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
extern const char *Hlp_ASSESSMENT_Exams_sessions;
|
2020-05-18 22:59:07 +02:00
|
|
|
|
extern const char *Txt_New_session;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
extern const char *Txt_Title;
|
2020-05-18 22:59:07 +02:00
|
|
|
|
extern const char *Txt_Create_session;
|
2020-04-28 03:14:25 +02:00
|
|
|
|
extern const char *Txt_Save_changes;
|
|
|
|
|
static const Dat_SetHMS SetHMS[Dat_NUM_START_END_TIME] =
|
|
|
|
|
{
|
|
|
|
|
[Dat_START_TIME] = Dat_HMS_DO_NOT_SET,
|
|
|
|
|
[Dat_END_TIME ] = Dat_HMS_DO_NOT_SET
|
|
|
|
|
};
|
2020-05-17 02:28:30 +02:00
|
|
|
|
bool ItsANewSession = Session->SesCod <= 0;
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Start section for a new exam session *****/
|
|
|
|
|
HTM_SECTION_Begin (ExaSes_NEW_SESSION_SECTION_ID);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Begin form *****/
|
2020-05-18 02:15:10 +02:00
|
|
|
|
Frm_StartForm (ItsANewSession ? ActNewExaSes : // New session
|
|
|
|
|
ActChgExaSes); // Existing session
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exa_PutParamExamCod (Session->ExaCod);
|
|
|
|
|
if (!ItsANewSession) // Existing session
|
|
|
|
|
ExaSes_PutParamSesCod (Session->SesCod);
|
2020-05-06 01:43:48 +02:00
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/***** Begin box and table *****/
|
2020-05-18 22:59:07 +02:00
|
|
|
|
Box_BoxTableBegin (NULL,ItsANewSession ? Txt_New_session :
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->Title,
|
2020-04-20 01:26:46 +02:00
|
|
|
|
NULL,NULL,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Hlp_ASSESSMENT_Exams_sessions,Box_NOT_CLOSABLE,2);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Session title *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
|
|
|
|
/* Label */
|
|
|
|
|
Frm_LabelColumn ("RT","Title",Txt_Title);
|
|
|
|
|
|
|
|
|
|
/* Data */
|
|
|
|
|
HTM_TD_Begin ("class=\"LT\"");
|
2020-05-17 02:28:30 +02:00
|
|
|
|
HTM_INPUT_TEXT ("Title",ExaSes_MAX_CHARS_TITLE,Session->Title,
|
2020-04-27 03:16:55 +02:00
|
|
|
|
HTM_DONT_SUBMIT_ON_CHANGE,
|
2020-04-20 01:26:46 +02:00
|
|
|
|
"id=\"Title\" size=\"45\" required=\"required\"");
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
|
2020-04-28 03:14:25 +02:00
|
|
|
|
/***** Start and end dates *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Dat_PutFormStartEndClientLocalDateTimes (Session->TimeUTC,
|
2020-05-15 01:07:46 +02:00
|
|
|
|
Dat_FORM_SECONDS_OFF,
|
2020-04-28 03:14:25 +02:00
|
|
|
|
SetHMS);
|
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/***** Groups *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ShowLstGrpsToCreateSession (Session->SesCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-04-28 03:14:25 +02:00
|
|
|
|
/***** End table, send button and end box *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if (ItsANewSession)
|
2020-05-18 22:59:07 +02:00
|
|
|
|
Box_BoxTableWithButtonEnd (Btn_CREATE_BUTTON,Txt_Create_session);
|
2020-04-28 03:14:25 +02:00
|
|
|
|
else
|
|
|
|
|
Box_BoxTableWithButtonEnd (Btn_CONFIRM_BUTTON,Txt_Save_changes);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** End form *****/
|
|
|
|
|
Frm_EndForm ();
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** End section for a new exam session *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_SECTION_End ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/************* Show list of groups to create a new exam session **************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_ShowLstGrpsToCreateSession (long SesCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
extern const char *The_ClassFormInBox[The_NUM_THEMES];
|
|
|
|
|
extern const char *Txt_Groups;
|
|
|
|
|
extern const char *Txt_The_whole_course;
|
|
|
|
|
unsigned NumGrpTyp;
|
|
|
|
|
|
|
|
|
|
/***** Get list of groups types and groups in this course *****/
|
|
|
|
|
Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS);
|
|
|
|
|
|
|
|
|
|
if (Gbl.Crs.Grps.GrpTypes.Num)
|
|
|
|
|
{
|
|
|
|
|
/***** Begin box and table *****/
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
2020-06-18 20:06:17 +02:00
|
|
|
|
HTM_TxtColon (Txt_Groups);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("class=\"LT\"");
|
|
|
|
|
Box_BoxTableBegin ("95%",NULL,
|
|
|
|
|
NULL,NULL,
|
|
|
|
|
NULL,Box_NOT_CLOSABLE,0);
|
|
|
|
|
|
|
|
|
|
/***** First row: checkbox to select the whole course *****/
|
|
|
|
|
HTM_TR_Begin (NULL);
|
|
|
|
|
|
|
|
|
|
HTM_TD_Begin ("colspan=\"7\" class=\"DAT LM\"");
|
|
|
|
|
HTM_LABEL_Begin (NULL);
|
2020-04-28 03:14:25 +02:00
|
|
|
|
HTM_INPUT_CHECKBOX ("WholeCrs",HTM_DONT_SUBMIT_ON_CHANGE,
|
2020-05-06 01:43:48 +02:00
|
|
|
|
"id=\"WholeCrs\" value=\"Y\"%s"
|
|
|
|
|
" onclick=\"uncheckChildren(this,'GrpCods')\"",
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Grp_CheckIfAssociatedToGrps ("exa_groups","SesCod",SesCod) ? "" :
|
2020-05-06 01:43:48 +02:00
|
|
|
|
" checked=\"checked\"");
|
2020-04-20 01:26:46 +02:00
|
|
|
|
HTM_TxtF ("%s %s",Txt_The_whole_course,Gbl.Hierarchy.Crs.ShrtName);
|
|
|
|
|
HTM_LABEL_End ();
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
|
|
|
|
|
/***** List the groups for each group type *****/
|
|
|
|
|
for (NumGrpTyp = 0;
|
|
|
|
|
NumGrpTyp < Gbl.Crs.Grps.GrpTypes.Num;
|
|
|
|
|
NumGrpTyp++)
|
|
|
|
|
if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps)
|
2020-05-06 01:43:48 +02:00
|
|
|
|
Grp_ListGrpsToEditAsgAttSvyEvtMch (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp],
|
2020-05-17 02:28:30 +02:00
|
|
|
|
SesCod,
|
|
|
|
|
Grp_EXA_EVENT);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** End table and box *****/
|
|
|
|
|
Box_BoxTableEnd ();
|
|
|
|
|
HTM_TD_End ();
|
|
|
|
|
HTM_TR_End ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Free list of groups types and groups in this course *****/
|
|
|
|
|
Grp_FreeListGrpTypesAndGrps ();
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-28 03:14:25 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/******************** Put button to create a new session *********************/
|
2020-04-28 03:14:25 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_PutButtonNewSession (struct Exa_Exams *Exams,long ExaCod)
|
2020-04-28 03:14:25 +02:00
|
|
|
|
{
|
2020-05-18 22:59:07 +02:00
|
|
|
|
extern const char *Txt_New_session;
|
2020-04-28 03:14:25 +02:00
|
|
|
|
|
|
|
|
|
Exams->ExaCod = ExaCod;
|
2020-05-18 02:15:10 +02:00
|
|
|
|
Frm_StartFormAnchor (ActReqNewExaSes,ExaSes_NEW_SESSION_SECTION_ID);
|
2020-04-28 03:14:25 +02:00
|
|
|
|
Exa_PutParams (Exams);
|
2020-05-18 22:59:07 +02:00
|
|
|
|
Btn_PutConfirmButton (Txt_New_session);
|
2020-04-28 03:14:25 +02:00
|
|
|
|
Frm_EndForm ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/****************** Request the creation of a new session ********************/
|
2020-04-28 03:14:25 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_RequestCreatOrEditSession (void)
|
2020-04-28 03:14:25 +02:00
|
|
|
|
{
|
|
|
|
|
struct Exa_Exams Exams;
|
|
|
|
|
struct Exa_Exam Exam;
|
2020-05-17 02:28:30 +02:00
|
|
|
|
struct ExaSes_Session Session;
|
|
|
|
|
bool ItsANewSession;
|
2020-04-28 03:14:25 +02:00
|
|
|
|
|
|
|
|
|
/***** Reset exams context *****/
|
|
|
|
|
Exa_ResetExams (&Exams);
|
|
|
|
|
Exa_ResetExam (&Exam);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ResetSession (&Session);
|
2020-04-28 03:14:25 +02:00
|
|
|
|
|
|
|
|
|
/***** Get parameters *****/
|
|
|
|
|
Exa_GetParams (&Exams);
|
|
|
|
|
if (Exams.ExaCod <= 0)
|
|
|
|
|
Lay_WrongExamExit ();
|
|
|
|
|
Exam.ExaCod = Exams.ExaCod;
|
2020-05-05 21:49:00 +02:00
|
|
|
|
Grp_GetParamWhichGroups ();
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session.SesCod = ExaSes_GetParamSesCod ();
|
|
|
|
|
ItsANewSession = (Session.SesCod <= 0);
|
2020-04-28 03:14:25 +02:00
|
|
|
|
|
|
|
|
|
/***** Get exam data from database *****/
|
|
|
|
|
Exa_GetDataOfExamByCod (&Exam);
|
2020-05-05 21:49:00 +02:00
|
|
|
|
if (Exam.CrsCod != Gbl.Hierarchy.Crs.CrsCod)
|
|
|
|
|
Lay_WrongExamExit ();
|
2020-04-28 03:14:25 +02:00
|
|
|
|
Exams.ExaCod = Exam.ExaCod;
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get session data *****/
|
|
|
|
|
if (ItsANewSession)
|
|
|
|
|
/* Initialize to empty session */
|
|
|
|
|
ExaSes_ResetSession (&Session);
|
2020-05-05 21:49:00 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Get session data from database */
|
|
|
|
|
ExaSes_GetDataOfSessionByCod (&Session);
|
|
|
|
|
if (Exam.ExaCod != Session.ExaCod)
|
2020-05-05 21:49:00 +02:00
|
|
|
|
Lay_WrongExamExit ();
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exams.SesCod = Session.SesCod;
|
2020-05-05 21:49:00 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-28 03:14:25 +02:00
|
|
|
|
/***** Show exam *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exa_ShowOnlyOneExam (&Exams,&Exam,&Session,
|
|
|
|
|
true); // Put form for session
|
2020-04-28 03:14:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/****************** Create a new exam session (by a teacher) *****************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_ReceiveFormSession (void)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-04-28 12:05:33 +02:00
|
|
|
|
extern const char *Txt_Created_new_event_X;
|
2020-05-06 01:43:48 +02:00
|
|
|
|
extern const char *Txt_The_event_has_been_modified;
|
2020-04-28 12:05:33 +02:00
|
|
|
|
struct Exa_Exams Exams;
|
|
|
|
|
struct Exa_Exam Exam;
|
2020-05-17 02:28:30 +02:00
|
|
|
|
struct ExaSes_Session Session;
|
|
|
|
|
bool ItsANewSession;
|
2020-04-28 12:05:33 +02:00
|
|
|
|
|
|
|
|
|
/***** Reset exams context *****/
|
|
|
|
|
Exa_ResetExams (&Exams);
|
|
|
|
|
Exa_ResetExam (&Exam);
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_ResetSession (&Session);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-06 01:43:48 +02:00
|
|
|
|
/***** Get main parameters *****/
|
2020-04-28 12:05:33 +02:00
|
|
|
|
Exa_GetParams (&Exams);
|
|
|
|
|
if (Exams.ExaCod <= 0)
|
|
|
|
|
Lay_WrongExamExit ();
|
2020-05-06 01:43:48 +02:00
|
|
|
|
Exam.ExaCod = Exams.ExaCod;
|
|
|
|
|
Grp_GetParamWhichGroups ();
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session.SesCod = ExaSes_GetParamSesCod ();
|
|
|
|
|
ItsANewSession = (Session.SesCod <= 0);
|
2020-05-06 01:43:48 +02:00
|
|
|
|
|
|
|
|
|
/***** Get exam data from database *****/
|
|
|
|
|
Exa_GetDataOfExamByCod (&Exam);
|
|
|
|
|
if (Exam.CrsCod != Gbl.Hierarchy.Crs.CrsCod)
|
|
|
|
|
Lay_WrongExamExit ();
|
|
|
|
|
Exams.ExaCod = Exam.ExaCod;
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get session data from database *****/
|
|
|
|
|
if (ItsANewSession)
|
2020-05-10 15:23:11 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Initialize to empty session */
|
|
|
|
|
ExaSes_ResetSession (&Session);
|
|
|
|
|
Session.ExaCod = Exam.ExaCod;
|
2020-05-10 15:23:11 +02:00
|
|
|
|
}
|
2020-05-06 01:43:48 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Get session data from database */
|
|
|
|
|
ExaSes_GetDataOfSessionByCod (&Session);
|
|
|
|
|
if (Session.ExaCod != Exam.ExaCod)
|
2020-05-06 01:43:48 +02:00
|
|
|
|
Lay_WrongExamExit ();
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exams.SesCod = Session.SesCod;
|
2020-05-06 01:43:48 +02:00
|
|
|
|
}
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-06 01:43:48 +02:00
|
|
|
|
/***** Get parameters from form *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Get session title */
|
|
|
|
|
Par_GetParToText ("Title",Session.Title,ExaSes_MAX_BYTES_TITLE);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-04-28 13:12:18 +02:00
|
|
|
|
/* Get start/end date-times */
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session.TimeUTC[Dat_START_TIME] = Dat_GetTimeUTCFromForm ("StartTimeUTC");
|
|
|
|
|
Session.TimeUTC[Dat_END_TIME ] = Dat_GetTimeUTCFromForm ("EndTimeUTC" );
|
2020-04-28 13:12:18 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/* Get groups associated to the session */
|
2020-04-20 01:26:46 +02:00
|
|
|
|
Grp_GetParCodsSeveralGrps ();
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Create/update session *****/
|
|
|
|
|
if (ItsANewSession)
|
|
|
|
|
ExaSes_CreateSession (&Session);
|
2020-05-06 01:43:48 +02:00
|
|
|
|
else
|
2020-05-30 19:33:55 +02:00
|
|
|
|
{
|
|
|
|
|
if (Session.TimeUTC[Dat_END_TIME] >= Gbl.StartExecutionTimeUTC) // End of time is in the future
|
|
|
|
|
Session.ShowUsrResults = false; // Force results to be hidden
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_UpdateSession (&Session);
|
2020-05-30 19:33:55 +02:00
|
|
|
|
}
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
|
|
|
|
/***** Free memory for list of selected groups *****/
|
|
|
|
|
Grp_FreeListCodSelectedGrps ();
|
2020-04-28 12:05:33 +02:00
|
|
|
|
|
2020-05-06 01:43:48 +02:00
|
|
|
|
/***** Write success message *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
if (ItsANewSession)
|
2020-05-06 01:43:48 +02:00
|
|
|
|
Ale_ShowAlert (Ale_SUCCESS,Txt_Created_new_event_X,
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session.Title);
|
2020-05-06 01:43:48 +02:00
|
|
|
|
else
|
|
|
|
|
Ale_ShowAlert (Ale_SUCCESS,Txt_The_event_has_been_modified);
|
2020-04-28 12:05:33 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get exam data again to update it after changes in session *****/
|
2020-05-07 01:14:50 +02:00
|
|
|
|
Exa_GetDataOfExamByCod (&Exam);
|
|
|
|
|
|
2020-04-28 12:05:33 +02:00
|
|
|
|
/***** Show current exam *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Exa_ShowOnlyOneExam (&Exams,&Exam,&Session,
|
|
|
|
|
false); // Do not put form for session
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/*************************** Create a new session ****************************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_CreateSession (struct ExaSes_Session *Session)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Insert this new exam session into database *****/
|
|
|
|
|
Session->SesCod =
|
|
|
|
|
DB_QueryINSERTandReturnCode ("can not create exam session",
|
|
|
|
|
"INSERT exa_sessions "
|
2020-05-13 15:22:56 +02:00
|
|
|
|
"(ExaCod,Hidden,UsrCod,StartTime,EndTime,Title,ShowUsrResults)"
|
2020-04-28 12:05:33 +02:00
|
|
|
|
" VALUES "
|
2020-05-13 15:22:56 +02:00
|
|
|
|
"(%ld," // ExaCod
|
|
|
|
|
"'%c'," // Hidden
|
|
|
|
|
"%ld," // UsrCod
|
2020-04-28 13:12:18 +02:00
|
|
|
|
"FROM_UNIXTIME(%ld)," // Start time
|
|
|
|
|
"FROM_UNIXTIME(%ld)," // End time
|
2020-05-13 15:22:56 +02:00
|
|
|
|
"'%s'," // Title
|
|
|
|
|
"'N')", // ShowUsrResults: Don't show user results initially
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->ExaCod,
|
|
|
|
|
Session->Hidden ? 'Y' :
|
2020-05-13 15:22:56 +02:00
|
|
|
|
'N',
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Gbl.Usrs.Me.UsrDat.UsrCod, // Session creator
|
|
|
|
|
Session->TimeUTC[Dat_START_TIME], // Start time
|
|
|
|
|
Session->TimeUTC[Dat_END_TIME ], // End time
|
|
|
|
|
Session->Title);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Create groups associated to the exam session *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
if (Gbl.Crs.Grps.LstGrpsSel.NumGrps)
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_CreateGrps (Session->SesCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 01:43:48 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/************************ Update an existing session *************************/
|
2020-05-06 01:43:48 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_UpdateSession (struct ExaSes_Session *Session)
|
2020-05-06 01:43:48 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Insert this new exam session into database *****/
|
|
|
|
|
DB_QueryUPDATE ("can not update exam session",
|
|
|
|
|
"UPDATE exa_sessions,exa_exams"
|
2020-05-30 19:33:55 +02:00
|
|
|
|
" SET exa_sessions.Hidden='%c',"
|
|
|
|
|
"exa_sessions.StartTime=FROM_UNIXTIME(%ld),"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
"exa_sessions.EndTime=FROM_UNIXTIME(%ld),"
|
|
|
|
|
"exa_sessions.Title='%s',"
|
2020-05-30 19:33:55 +02:00
|
|
|
|
"exa_sessions.ShowUsrResults='%c'"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" WHERE exa_sessions.SesCod=%ld"
|
2020-05-30 19:33:55 +02:00
|
|
|
|
" AND exa_sessions.ExaCod=%ld" // Extra check
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" AND exa_sessions.ExaCod=exa_exams.ExaCod"
|
2020-05-06 01:43:48 +02:00
|
|
|
|
" AND exa_exams.CrsCod=%ld", // Extra check
|
2020-05-30 19:33:55 +02:00
|
|
|
|
Session->Hidden ? 'Y' :
|
|
|
|
|
'N',
|
|
|
|
|
Session->TimeUTC[Dat_START_TIME], // Start time
|
2020-05-17 02:28:30 +02:00
|
|
|
|
Session->TimeUTC[Dat_END_TIME ], // End time
|
|
|
|
|
Session->Title,
|
2020-05-30 19:33:55 +02:00
|
|
|
|
Session->ShowUsrResults ? 'Y' :
|
|
|
|
|
'N',
|
|
|
|
|
Session->SesCod,
|
|
|
|
|
Session->ExaCod,
|
|
|
|
|
Gbl.Hierarchy.Crs.CrsCod);
|
2020-05-06 01:43:48 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Update groups associated to the exam session *****/
|
|
|
|
|
ExaSes_RemoveGroups (Session->SesCod); // Remove all groups associated to this session
|
2020-05-06 01:43:48 +02:00
|
|
|
|
if (Gbl.Crs.Grps.LstGrpsSel.NumGrps)
|
2020-05-17 02:28:30 +02:00
|
|
|
|
ExaSes_CreateGrps (Session->SesCod); // Associate new groups
|
2020-05-06 01:43:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/*************** Create groups associated to an exam session *****************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_CreateGrps (long SesCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
|
|
|
|
unsigned NumGrpSel;
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Create groups associated to the exam session *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
for (NumGrpSel = 0;
|
|
|
|
|
NumGrpSel < Gbl.Crs.Grps.LstGrpsSel.NumGrps;
|
|
|
|
|
NumGrpSel++)
|
|
|
|
|
/* Create group */
|
2020-05-17 02:28:30 +02:00
|
|
|
|
DB_QueryINSERT ("can not associate a group to an exam session",
|
2020-04-20 01:26:46 +02:00
|
|
|
|
"INSERT INTO exa_groups"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" (SesCod,GrpCod)"
|
2020-04-20 01:26:46 +02:00
|
|
|
|
" VALUES"
|
|
|
|
|
" (%ld,%ld)",
|
2020-05-17 02:28:30 +02:00
|
|
|
|
SesCod,Gbl.Crs.Grps.LstGrpsSel.GrpCods[NumGrpSel]);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 01:43:48 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/******************** Remove all groups from one session *********************/
|
2020-05-06 01:43:48 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
static void ExaSes_RemoveGroups (long SesCod)
|
2020-05-06 01:43:48 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Remove all groups from one session *****/
|
|
|
|
|
DB_QueryDELETE ("can not remove groups associated to a session",
|
|
|
|
|
"DELETE FROM exa_groups WHERE SesCod=%ld",
|
|
|
|
|
SesCod);
|
2020-05-06 01:43:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/******************** Remove one group from all sessions *********************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_RemoveGroup (long GrpCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Remove group from all the sessions *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
DB_QueryDELETE ("can not remove group"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" from the associations between sessions and groups",
|
2020-04-20 01:26:46 +02:00
|
|
|
|
"DELETE FROM exa_groups WHERE GrpCod=%ld",
|
|
|
|
|
GrpCod);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/**************** Remove groups of one type from all sessions ****************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
void ExaSes_RemoveGroupsOfType (long GrpTypCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Remove group from all the sessions *****/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
DB_QueryDELETE ("can not remove groups of a type"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" from the associations between sessions and groups",
|
2020-04-20 01:26:46 +02:00
|
|
|
|
"DELETE FROM exa_groups"
|
|
|
|
|
" USING crs_grp,exa_groups"
|
|
|
|
|
" WHERE crs_grp.GrpTypCod=%ld"
|
|
|
|
|
" AND crs_grp.GrpCod=exa_groups.GrpCod",
|
|
|
|
|
GrpTypCod);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/********************* Get number of sessions in an exam *********************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
unsigned ExaSes_GetNumSessionsInExam (long ExaCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-13 15:22:56 +02:00
|
|
|
|
/***** Trivial check *****/
|
|
|
|
|
if (ExaCod < 0) // A non-existing exam...
|
2020-05-17 02:28:30 +02:00
|
|
|
|
return 0; // ...has no sessions
|
2020-04-20 01:26:46 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get number of sessions in an exam from database *****/
|
2020-05-13 15:22:56 +02:00
|
|
|
|
return
|
2020-05-17 02:28:30 +02:00
|
|
|
|
(unsigned) DB_QueryCOUNT ("can not get number of sessions of an exam",
|
|
|
|
|
"SELECT COUNT(*) FROM exa_sessions"
|
2020-05-13 15:22:56 +02:00
|
|
|
|
" WHERE ExaCod=%ld",
|
|
|
|
|
ExaCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***************** Get number of open sessions in an exam ********************/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
unsigned ExaSes_GetNumOpenSessionsInExam (long ExaCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-13 15:22:56 +02:00
|
|
|
|
/***** Trivial check *****/
|
|
|
|
|
if (ExaCod < 0) // A non-existing exam...
|
2020-05-17 02:28:30 +02:00
|
|
|
|
return 0; // ...has no sessions
|
2020-05-13 15:22:56 +02:00
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/***** Get number of open sessions in an exam from database *****/
|
2020-05-13 15:22:56 +02:00
|
|
|
|
return
|
2020-05-17 02:28:30 +02:00
|
|
|
|
(unsigned) DB_QueryCOUNT ("can not get number of open sessions of an exam",
|
|
|
|
|
"SELECT COUNT(*) FROM exa_sessions"
|
2020-05-13 15:22:56 +02:00
|
|
|
|
" WHERE ExaCod=%ld"
|
|
|
|
|
" AND NOW() BETWEEN StartTime AND EndTime",
|
|
|
|
|
ExaCod);
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
/******** Check if I belong to any of the groups of an exam session **********/
|
2020-04-20 01:26:46 +02:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-05-21 16:59:14 +02:00
|
|
|
|
bool ExaSes_CheckIfICanAnswerThisSession (const struct Exa_Exam *Exam,
|
|
|
|
|
const struct ExaSes_Session *Session)
|
2020-05-15 01:07:46 +02:00
|
|
|
|
{
|
2020-05-21 16:59:14 +02:00
|
|
|
|
/***** 1. Sessions in hidden exams are not accesible
|
|
|
|
|
2. Hidden or closed sessions are not accesible *****/
|
|
|
|
|
if (Exam->Hidden || Session->Hidden || !Session->Open)
|
2020-05-15 01:07:46 +02:00
|
|
|
|
return false;
|
|
|
|
|
|
2020-05-21 16:59:14 +02:00
|
|
|
|
/***** Exam is visible, session is visible and open ==>
|
|
|
|
|
==> I can answer this session if I can list it based on groups *****/
|
2020-05-17 02:28:30 +02:00
|
|
|
|
return ExaSes_CheckIfICanListThisSessionBasedOnGrps (Session->SesCod);
|
2020-05-15 01:07:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-17 02:28:30 +02:00
|
|
|
|
bool ExaSes_CheckIfICanListThisSessionBasedOnGrps (long SesCod)
|
2020-04-20 01:26:46 +02:00
|
|
|
|
{
|
2020-05-13 15:22:56 +02:00
|
|
|
|
switch (Gbl.Usrs.Me.Role.Logged)
|
|
|
|
|
{
|
|
|
|
|
case Rol_STD:
|
|
|
|
|
/***** Check if I belong to any of the groups
|
2020-05-17 02:28:30 +02:00
|
|
|
|
associated to the exam session *****/
|
|
|
|
|
return (DB_QueryCOUNT ("can not check if I can play an exam session",
|
|
|
|
|
"SELECT COUNT(*) FROM exa_sessions"
|
|
|
|
|
" WHERE SesCod=%ld"
|
2020-05-13 15:22:56 +02:00
|
|
|
|
" AND"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
"(SesCod NOT IN"
|
|
|
|
|
" (SELECT SesCod FROM exa_groups)"
|
2020-05-13 15:22:56 +02:00
|
|
|
|
" OR"
|
2020-05-17 02:28:30 +02:00
|
|
|
|
" SesCod IN"
|
|
|
|
|
" (SELECT exa_groups.SesCod"
|
2020-05-13 15:22:56 +02:00
|
|
|
|
" FROM exa_groups,crs_grp_usr"
|
|
|
|
|
" WHERE crs_grp_usr.UsrCod=%ld"
|
2020-05-29 12:40:07 +02:00
|
|
|
|
" AND crs_grp_usr.GrpCod=exa_groups.GrpCod))",
|
2020-05-17 02:28:30 +02:00
|
|
|
|
SesCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0);
|
2020-05-13 15:22:56 +02:00
|
|
|
|
break;
|
|
|
|
|
case Rol_NET:
|
|
|
|
|
case Rol_TCH:
|
|
|
|
|
case Rol_SYS_ADM:
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2020-04-20 01:26:46 +02:00
|
|
|
|
}
|