swad-core/swad_enrolment.c

3541 lines
129 KiB
C
Raw Permalink Normal View History

2017-03-30 11:20:06 +02:00
// swad_enrolment.c: enrolment (registration) or removing of users
2014-12-12 18:52:06 +01: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-2024 Antonio Ca<EFBFBD>as Vargas
2014-12-12 18:52:06 +01:00
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General 3 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 *********************************/
/*****************************************************************************/
2018-10-17 10:32:18 +02:00
#define _GNU_SOURCE // For asprintf
#include <stdio.h> // For asprintf
2014-12-12 18:52:06 +01:00
#include <stdlib.h> // For exit, system, malloc, free, rand, etc.
#include <string.h> // For string functions
2014-12-12 22:39:55 +01:00
#include "swad_account.h"
#include "swad_account_database.h"
#include "swad_action_list.h"
#include "swad_admin.h"
#include "swad_admin_database.h"
#include "swad_alert.h"
2014-12-12 18:52:06 +01:00
#include "swad_announcement.h"
#include "swad_attendance_database.h"
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
#include "swad_browser_database.h"
2014-12-12 18:52:06 +01:00
#include "swad_database.h"
2016-06-16 19:30:29 +02:00
#include "swad_duplicate.h"
2017-03-30 11:20:06 +02:00
#include "swad_enrolment.h"
#include "swad_enrolment_database.h"
#include "swad_error.h"
#include "swad_exam_database.h"
#include "swad_figure_cache.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2014-12-12 18:52:06 +01:00
#include "swad_global.h"
2021-02-11 22:57:09 +01:00
#include "swad_hierarchy.h"
2019-10-23 19:05:05 +02:00
#include "swad_HTML.h"
2014-12-12 18:52:06 +01:00
#include "swad_ID.h"
#include "swad_info_database.h"
#include "swad_mail_database.h"
2019-09-29 23:13:20 +02:00
#include "swad_match.h"
2020-04-14 17:15:17 +02:00
#include "swad_message.h"
#include "swad_message_database.h"
2014-12-12 18:52:06 +01:00
#include "swad_notification.h"
#include "swad_notification_database.h"
2014-12-12 18:52:06 +01:00
#include "swad_parameter.h"
#include "swad_parameter_code.h"
2020-04-14 17:15:17 +02:00
#include "swad_photo.h"
#include "swad_record_database.h"
2016-12-13 13:32:19 +01:00
#include "swad_role.h"
#include "swad_role_database.h"
#include "swad_setting.h"
#include "swad_setting_database.h"
2020-05-07 18:33:26 +02:00
#include "swad_test_print.h"
2014-12-12 18:52:06 +01:00
#include "swad_user.h"
#include "swad_user_database.h"
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
2019-11-21 16:47:07 +01:00
/******************************* Private types *******************************/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
2017-01-29 21:41:08 +01:00
#define Enr_NUM_REG_REM_USRS_ACTIONS 6
2014-12-12 18:52:06 +01:00
typedef enum
{
2017-01-29 21:41:08 +01:00
Enr_REG_REM_USRS_UNKNOWN_ACTION = 0,
2017-01-29 12:42:19 +01:00
Enr_REGISTER_SPECIFIED_USRS_IN_CRS = 1,
Enr_REMOVE_SPECIFIED_USRS_FROM_CRS = 2,
Enr_REMOVE_NOT_SPECIFIED_USRS_FROM_CRS = 3,
Enr_UPDATE_USRS_IN_CRS = 4,
Enr_ELIMINATE_USRS_FROM_PLATFORM = 5,
2014-12-12 18:52:06 +01:00
} Enr_RegRemUsrsAction_t;
2019-09-29 23:13:20 +02:00
/* Remove important user production (works and match results)? */
2014-12-12 18:52:06 +01:00
typedef enum
{
2019-09-29 23:13:20 +02:00
Enr_DO_NOT_REMOVE_USR_PRODUCTION,
Enr_REMOVE_USR_PRODUCTION,
} Enr_RemoveUsrProduction_t;
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static void Enr_NotifyAfterEnrolment (const struct Usr_Data *UsrDat,
Rol_Role_t NewRole);
2015-09-17 20:41:31 +02:00
2015-09-14 09:50:55 +02:00
static void Enr_ReqAdminUsrs (Rol_Role_t Role);
2015-09-14 09:32:27 +02:00
static void Enr_ShowFormRegRemSeveralUsrs (Rol_Role_t Role);
2014-12-12 18:52:06 +01:00
static void Enr_PutAreaToEnterUsrsIDs (void);
static void Enr_PutActionsRegRemSeveralUsrs (void);
static void Enr_ReceiveUsrsCrs (Rol_Role_t Role);
2015-09-14 09:50:55 +02:00
static void Enr_PutActionModifyOneUsr (Cns_UncheckedOrChecked_t *UncheckedOrChecked,
Usr_Belong_t UsrBelongsToCrs,Usr_MeOrOther_t MeOrOther);
static void Enr_PutActionRegOneDegAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked);
static void Enr_PutActionRegOneCtrAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked);
static void Enr_PutActionRegOneInsAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked);
static void Enr_PutActionRepUsrAsDup (Cns_UncheckedOrChecked_t *UncheckedOrChecked);
static void Enr_PutActionRemUsrFromCrs (Cns_UncheckedOrChecked_t *UncheckedOrChecked,Usr_MeOrOther_t MeOrOther);
static void Enr_PutActionRemUsrAsDegAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked,Usr_MeOrOther_t MeOrOther);
static void Enr_PutActionRemUsrAsCtrAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked,Usr_MeOrOther_t MeOrOther);
static void Enr_PutActionRemUsrAsInsAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked,Usr_MeOrOther_t MeOrOther);
static void Enr_PutActionRemUsrAcc (Cns_UncheckedOrChecked_t *UncheckedOrChecked,Usr_MeOrOther_t MeOrOther);
static void Enr_RegRemOneUsrActionBegin (Enr_RegRemOneUsrAction_t RegRemOneUsrAction,
Cns_UncheckedOrChecked_t *UncheckedOrChecked);
static void Enr_RegRemOneUsrActionEnd (void);
2019-03-10 14:44:12 +01:00
static void Enr_RegisterUsr (struct Usr_Data *UsrDat,Rol_Role_t RegRemRole,
2014-12-12 18:52:06 +01:00
struct ListCodGrps *LstGrps,unsigned *NumUsrsRegistered);
2015-11-20 14:44:54 +01:00
static void Enr_PutLinkToRemAllStdsThisCrs (void);
2017-03-30 11:20:06 +02:00
static void Enr_ShowEnrolmentRequestsGivenRoles (unsigned RolesSelected);
2016-03-24 15:09:52 +01:00
static void Enr_RemUsrEnrolmentRequestInCrs (long UsrCod,long CrsCod);
2014-12-12 18:52:06 +01:00
2015-09-12 14:12:40 +02:00
static void Enr_ReqRegRemUsr (Rol_Role_t Role);
static void Enr_ReqAnotherUsrIDToRegisterRemove (Rol_Role_t Role);
static void Enr_AskIfRegRemMe (Rol_Role_t Role);
static void Enr_AskIfRegRemAnotherUsr (Rol_Role_t Role);
static void Enr_AskIfRegRemUsr (struct Usr_ListUsrCods *ListUsrCods,Rol_Role_t Role);
2014-12-12 18:52:06 +01:00
static void Enr_ShowFormToEditOtherUsr (void);
static Usr_Can_t Enr_CheckIfICanRemUsrFromCrs (void);
2017-06-04 15:11:41 +02:00
static void Enr_AskIfRemoveUsrFromCrs (struct Usr_Data *UsrDat);
static void Enr_EffectivelyRemUsrFromCrs (struct Usr_Data *UsrDat,
struct Hie_Node *Crs,
2019-09-29 23:13:20 +02:00
Enr_RemoveUsrProduction_t RemoveUsrWorks,
Cns_QuietOrVerbose_t QuietOrVerbose);
2014-12-12 22:39:55 +01:00
static FigCch_FigureCached_t Enr_GetFigureNumUsrsInCrss (unsigned Roles);
2015-11-20 14:44:54 +01:00
/*****************************************************************************/
2017-10-08 12:29:44 +02:00
/** Check if current course has students and show warning no students found **/
2015-11-20 14:44:54 +01:00
/*****************************************************************************/
2017-05-29 21:34:43 +02:00
void Enr_CheckStdsAndPutButtonToRegisterStdsInCurrentCrs (void)
2015-11-20 14:44:54 +01:00
{
2017-05-29 21:34:43 +02:00
/***** Put link to register students *****/
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged == Rol_TCH) // Course selected and I am logged as teacher
if (!Enr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Node[Hie_CRS].HieCod,
2020-01-08 23:49:04 +01:00
1 << Rol_STD)) // No students in course
Usr_ShowWarningNoUsersFound (Rol_STD);
2017-02-09 19:27:18 +01:00
}
/*****************************************************************************/
2017-10-08 12:29:44 +02:00
/****************** Put inline button to register students *******************/
2017-02-09 19:27:18 +01:00
/*****************************************************************************/
void Enr_PutButtonInlineToRegisterStds (long CrsCod,
unsigned Level,const Lay_LastItem_t *IsLastItemInLevel,
Lay_Highlight_t Highlight)
2017-02-09 19:27:18 +01:00
{
extern const char *Lay_HighlightClass[Lay_NUM_HIGHLIGHT];
2017-05-29 21:34:43 +02:00
extern const char *Txt_Register_students;
2017-02-09 19:27:18 +01:00
if (Rol_GetMyRoleInCrs (CrsCod) == Rol_TCH) // I am a teacher in the given course
if (!Enr_GetNumUsrsInCrss (Hie_CRS,CrsCod,
2020-01-08 23:49:04 +01:00
1 << Rol_STD)) // No students in course
2017-05-29 21:34:43 +02:00
{
HTM_LI_Begin (Lay_HighlightClass[Highlight]);
Lay_IndentDependingOnLevel (Level,IsLastItemInLevel,
Lay_NO_HORIZONTAL_LINE_AT_RIGHT);
Frm_BeginForm (ActReqEnrSevStd);
ParCod_PutPar (ParCod_Crs,CrsCod);
Btn_PutCreateButtonInline (Txt_Register_students);
Frm_EndForm ();
HTM_LI_End ();
2017-05-29 21:34:43 +02:00
}
2015-11-20 14:44:54 +01:00
}
2015-01-16 12:11:27 +01:00
/*****************************************************************************/
/************ Show form to request sign up in the current course *************/
/*****************************************************************************/
void Enr_PutLinkToRequestSignUp (void)
{
extern const char *Txt_Sign_up;
/***** Show the form *****/
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkIconText (ActReqSignUp,NULL,
NULL,NULL,
"hand-point-up.svg",Ico_BLACK,
Txt_Sign_up,NULL);
2015-01-16 12:11:27 +01:00
}
2014-12-12 20:25:00 +01:00
/*****************************************************************************/
/***************** Modify the role of a user in a course *********************/
/*****************************************************************************/
void Enr_ModifyRoleInCurrentCrs (struct Usr_Data *UsrDat,Rol_Role_t NewRole)
2014-12-12 20:25:00 +01:00
{
/***** Trivial check 1: current course code should be > 0 *****/
if (Gbl.Hierarchy.Node[Hie_CRS].HieCod <= 0)
Err_WrongCourseExit ();
/***** Trivial check 2: check if user's role is allowed *****/
2016-12-17 21:36:57 +01:00
switch (NewRole)
2014-12-12 20:25:00 +01:00
{
2017-05-18 19:13:41 +02:00
case Rol_STD:
2017-05-21 21:23:13 +02:00
case Rol_NET:
2017-05-18 19:13:41 +02:00
case Rol_TCH:
2016-12-17 21:36:57 +01:00
break;
default:
Err_WrongRoleExit ();
2016-12-17 21:36:57 +01:00
}
2014-12-12 20:25:00 +01:00
2016-12-17 21:36:57 +01:00
/***** Update the role of a user in a course *****/
Rol_DB_UpdateUsrRoleInCrs (Gbl.Hierarchy.Node[Hie_CRS].HieCod,UsrDat->UsrCod,NewRole);
2015-09-17 20:41:31 +02:00
2017-07-02 20:36:15 +02:00
/***** Flush caches *****/
Usr_FlushCachesUsr ();
2014-12-12 20:25:00 +01:00
2017-07-02 20:36:15 +02:00
/***** Set user's roles *****/
UsrDat->Roles.InCurrentCrs = NewRole;
2017-06-08 15:32:33 +02:00
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrss (UsrDat); // Get roles
2017-07-02 20:36:15 +02:00
/***** Create notification for this user.
If this user wants to receive notifications by email,
activate the sending of a notification *****/
Enr_NotifyAfterEnrolment (UsrDat,NewRole);
2014-12-12 20:25:00 +01:00
}
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
/*********************** Register user in current course *********************/
/*****************************************************************************/
// Before calling this function, you must be sure that
// the user does not belong to the current course
void Enr_RegisterUsrInCurrentCrs (struct Usr_Data *UsrDat,Rol_Role_t NewRole,
2014-12-12 18:52:06 +01:00
Enr_KeepOrSetAccepted_t KeepOrSetAccepted)
{
/***** Trivial check 1: current course code should be > 0 *****/
if (Gbl.Hierarchy.Node[Hie_CRS].HieCod <= 0)
Err_WrongCourseExit ();
2014-12-12 18:52:06 +01:00
/***** Trivial check 2: check if user's role is allowed *****/
2015-09-17 20:41:31 +02:00
switch (NewRole)
{
2017-05-18 19:13:41 +02:00
case Rol_STD:
2017-05-21 21:23:13 +02:00
case Rol_NET:
2017-05-18 19:13:41 +02:00
case Rol_TCH:
2015-09-17 20:41:31 +02:00
break;
default:
Err_WrongRoleExit ();
2015-09-17 20:41:31 +02:00
}
2014-12-12 18:52:06 +01:00
/***** Register user in current course in database *****/
Enr_DB_InsertUsrInCurrentCrs (UsrDat->UsrCod,Gbl.Hierarchy.Node[Hie_CRS].HieCod,
NewRole,KeepOrSetAccepted);
2020-04-30 01:55:23 +02:00
/***** Register last prefs in current course in database *****/
Set_DB_InsertUsrInCrsSettings (UsrDat->UsrCod,Gbl.Hierarchy.Node[Hie_CRS].HieCod);
2017-07-02 20:36:15 +02:00
/***** Flush caches *****/
Usr_FlushCachesUsr ();
/***** Set roles *****/
UsrDat->Roles.InCurrentCrs = NewRole;
2017-06-08 15:32:33 +02:00
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
Rol_GetRolesInAllCrss (UsrDat); // Get roles
2014-12-12 18:52:06 +01:00
2014-12-12 22:39:55 +01:00
/***** Create notification for this user.
2016-11-16 23:19:52 +01:00
If this user wants to receive notifications by email,
2014-12-12 22:39:55 +01:00
activate the sending of a notification *****/
2017-03-30 11:20:06 +02:00
Enr_NotifyAfterEnrolment (UsrDat,NewRole);
2014-12-12 18:52:06 +01:00
}
2015-09-17 20:41:31 +02:00
/*****************************************************************************/
/********* Create notification after register user in current course *********/
/*****************************************************************************/
static void Enr_NotifyAfterEnrolment (const struct Usr_Data *UsrDat,
Rol_Role_t NewRole)
2015-09-17 20:41:31 +02:00
{
static const Ntf_NotifyEvent_t NotifyEvent[Rol_NUM_ROLES] =
{
[Rol_STD] = Ntf_EVENT_ENROLMENT_STD,
[Rol_NET] = Ntf_EVENT_ENROLMENT_NET,
[Rol_TCH] = Ntf_EVENT_ENROLMENT_TCH,
};
2015-09-17 20:41:31 +02:00
bool CreateNotif;
bool NotifyByEmail;
/***** Check if user's role is allowed *****/
if (!NotifyEvent[NewRole])
Err_WrongRoleExit ();
2015-09-17 20:41:31 +02:00
2017-03-30 11:20:06 +02:00
/***** Remove possible enrolment request ******/
Enr_RemUsrEnrolmentRequestInCrs (UsrDat->UsrCod,Gbl.Hierarchy.Node[Hie_CRS].HieCod);
2015-09-17 20:41:31 +02:00
2017-03-30 11:20:06 +02:00
/***** Remove old enrolment notifications before inserting the new one ******/
Ntf_DB_MarkNotifToOneUsrAsRemoved (Ntf_EVENT_ENROLMENT_STD,-1,UsrDat->UsrCod);
Ntf_DB_MarkNotifToOneUsrAsRemoved (Ntf_EVENT_ENROLMENT_NET,-1,UsrDat->UsrCod);
Ntf_DB_MarkNotifToOneUsrAsRemoved (Ntf_EVENT_ENROLMENT_TCH,-1,UsrDat->UsrCod);
2015-09-17 20:41:31 +02:00
/***** Create new notification ******/
CreateNotif = (UsrDat->NtfEvents.CreateNotif & (1 << NotifyEvent[NewRole]));
NotifyByEmail = CreateNotif && Usr_ItsMe (UsrDat->UsrCod) == Usr_OTHER &&
(UsrDat->NtfEvents.SendEmail & (1 << NotifyEvent[NewRole]));
2015-09-17 20:41:31 +02:00
if (CreateNotif)
Ntf_DB_StoreNotifyEventToUsr (NotifyEvent[NewRole],UsrDat->UsrCod,-1L,
(Ntf_Status_t) (NotifyByEmail ? Ntf_STATUS_BIT_EMAIL :
0),
Gbl.Hierarchy.Node[Hie_INS].HieCod,
Gbl.Hierarchy.Node[Hie_CTR].HieCod,
Gbl.Hierarchy.Node[Hie_DEG].HieCod,
Gbl.Hierarchy.Node[Hie_CRS].HieCod);
2015-09-17 20:41:31 +02:00
}
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
2017-09-20 17:25:00 +02:00
/****** Write a form to request another user's ID, @nickname or email ********/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
void Enr_WriteFormToReqAnotherUsrID (Act_Action_t NextAction,void (*FuncPars) (void))
2014-12-12 18:52:06 +01:00
{
2014-12-12 22:39:55 +01:00
extern const char *Txt_nick_email_or_ID;
extern const char *Txt_Continue;
2014-12-12 18:52:06 +01:00
2016-11-16 23:19:52 +01:00
/***** Form to request user's ID, @nickname or email address *****/
Frm_BeginForm (NextAction);
if (FuncPars)
FuncPars ();
/***** Label *****/
HTM_LABEL_Begin ("for=\"OtherUsrIDNickOrEMail\" class=\"RM FORM_IN_%s\"",
The_GetSuffix ());
HTM_TxtColonNBSP (Txt_nick_email_or_ID);
HTM_LABEL_End ();
2019-11-07 14:34:03 +01:00
/***** Input box to enter user *****/
HTM_INPUT_TEXT ("OtherUsrIDNickOrEMail",Cns_MAX_CHARS_EMAIL_ADDRESS,"",
HTM_DONT_SUBMIT_ON_CHANGE,
"id=\"OtherUsrIDNickOrEMail\" size=\"16\""
" class=\"INPUT_%s\""
" required=\"required\"",
The_GetSuffix ());
2014-12-12 18:52:06 +01:00
/***** Send button*****/
Btn_PutConfirmButton (Txt_Continue);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/****** Request acceptation / refusion of register in current course *********/
/*****************************************************************************/
void Enr_ReqAcceptRegisterInCrs (void)
{
2017-03-30 15:20:25 +02:00
extern const char *Hlp_USERS_SignUp_confirm_enrolment;
2017-03-30 11:20:06 +02:00
extern const char *Txt_Enrolment;
extern const char *Txt_A_teacher_or_administrator_has_enroled_you_as_X_into_the_course_Y;
2017-01-19 18:55:21 +01:00
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2017-03-30 11:20:06 +02:00
extern const char *Txt_Confirm_my_enrolment;
2014-12-12 18:52:06 +01:00
extern const char *Txt_Remove_me_from_this_course;
static const struct
{
struct
{
Act_Action_t Accept;
Act_Action_t Refuse;
} NextAction;
Ntf_NotifyEvent_t NotifyEvent;
} WhatToDo[Rol_NUM_ROLES] =
{
[Rol_STD] = {{ActAccEnrStd,ActRemMe_Std},Ntf_EVENT_ENROLMENT_STD},
[Rol_NET] = {{ActAccEnrNET,ActRemMe_NET},Ntf_EVENT_ENROLMENT_NET},
[Rol_TCH] = {{ActAccEnrTch,ActRemMe_Tch},Ntf_EVENT_ENROLMENT_TCH},
};
2014-12-12 18:52:06 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
Box_BoxBegin (Txt_Enrolment,NULL,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_SignUp_confirm_enrolment,Box_NOT_CLOSABLE);
2016-04-05 14:04:23 +02:00
/***** Show message *****/
Ale_ShowAlert (Ale_INFO,Txt_A_teacher_or_administrator_has_enroled_you_as_X_into_the_course_Y,
Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs][Gbl.Usrs.Me.UsrDat.Sex],
Gbl.Hierarchy.Node[Hie_CRS].FullName);
2014-12-12 18:52:06 +01:00
/***** Send button to accept register in the current course *****/
if (!WhatToDo[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs].NextAction.Accept)
Err_WrongRoleExit ();
Frm_BeginForm (WhatToDo[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs].NextAction.Accept);
Btn_PutCreateButtonInline (Txt_Confirm_my_enrolment);
Frm_EndForm ();
2014-12-12 18:52:06 +01:00
/***** Send button to refuse register in the current course *****/
if (!WhatToDo[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs].NextAction.Refuse)
Err_WrongRoleExit ();
Frm_BeginForm (WhatToDo[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs].NextAction.Refuse);
Btn_PutRemoveButtonInline (Txt_Remove_me_from_this_course);
Frm_EndForm ();
2015-04-02 14:22:21 +02:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2014-12-12 18:52:06 +01:00
/***** Mark possible notification as seen *****/
if (!WhatToDo[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs].NotifyEvent)
Err_WrongRoleExit ();
Ntf_DB_MarkNotifsInCrsAsSeen (WhatToDo[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs].NotifyEvent);
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
/****************** Put an enrolment into a notification ********************/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
void Enr_GetNotifEnrolment (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1],
long CrsCod,long UsrCod)
2014-12-12 18:52:06 +01:00
{
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
struct Usr_Data UsrDat;
2014-12-12 18:52:06 +01:00
Rol_Role_t Role;
/***** Get user's role in course from database *****/
Role = Rol_GetRoleUsrInCrs (UsrCod,CrsCod);
2014-12-12 18:52:06 +01:00
/***** Set summary string *****/
/* Initialize structure with user's data */
Usr_UsrDataConstructor (&UsrDat);
2014-12-12 18:52:06 +01:00
/* Get user's data */
UsrDat.UsrCod = UsrCod;
Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CRS);
2014-12-12 18:52:06 +01:00
/* Set summary string depending on role and sex */
Str_Copy (SummaryStr,Txt_ROLES_SINGUL_Abc[Role][UsrDat.Sex],
Ntf_MAX_BYTES_SUMMARY);
2014-12-12 18:52:06 +01:00
/* Free memory used for user's data */
Usr_UsrDataDestructor (&UsrDat);
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/***************************** Update user's data ****************************/
/*****************************************************************************/
// UsrDat->UsrCod must be > 0
void Enr_UpdateUsrData (struct Usr_Data *UsrDat)
2014-12-12 18:52:06 +01:00
{
/***** Check if user's code is initialized *****/
if (UsrDat->UsrCod <= 0)
Err_WrongUserExit ();
2014-12-12 18:52:06 +01:00
/***** Filter some user's data before updating */
Usr_FilterUsrBirthday (&UsrDat->Birthday);
2014-12-12 18:52:06 +01:00
/***** Update user's common data *****/
Acc_DB_UpdateUsrData (UsrDat);
2014-12-12 18:52:06 +01:00
}
2014-12-31 02:46:20 +01:00
/*****************************************************************************/
/************** Form to request the user's ID of another user ****************/
/*****************************************************************************/
2015-09-14 09:50:55 +02:00
void Enr_ReqAdminStds (void)
{
2017-05-18 19:13:41 +02:00
Enr_ReqAdminUsrs (Rol_STD);
2015-09-14 09:50:55 +02:00
}
2017-05-21 19:25:46 +02:00
void Enr_ReqAdminNonEditingTchs (void)
{
2017-05-21 21:23:13 +02:00
Enr_ReqAdminUsrs (Rol_NET);
2017-05-21 19:25:46 +02:00
}
2015-09-14 09:50:55 +02:00
void Enr_ReqAdminTchs (void)
{
2017-05-18 19:13:41 +02:00
Enr_ReqAdminUsrs (Rol_TCH);
2015-09-14 09:50:55 +02:00
}
static void Enr_ReqAdminUsrs (Rol_Role_t Role)
2014-12-31 02:46:20 +01:00
{
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2014-12-31 02:46:20 +01:00
{
2017-05-18 19:13:41 +02:00
case Rol_GST:
case Rol_STD:
2017-05-21 21:23:13 +02:00
case Rol_NET:
Enr_AskIfRegRemMe (Role);
2014-12-31 02:46:20 +01:00
break;
2017-05-18 19:13:41 +02:00
case Rol_TCH:
if (Gbl.Hierarchy.Level == Hie_CRS && Role == Rol_STD)
2017-05-18 19:13:41 +02:00
Enr_ShowFormRegRemSeveralUsrs (Rol_STD);
2014-12-31 02:46:20 +01:00
else
2017-05-18 19:13:41 +02:00
Enr_AskIfRegRemMe (Rol_TCH);
2014-12-31 02:46:20 +01:00
break;
2015-04-07 21:44:24 +02:00
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
if (Gbl.Hierarchy.Level == Hie_CRS)
2015-09-14 09:32:27 +02:00
Enr_ShowFormRegRemSeveralUsrs (Role);
2014-12-31 02:46:20 +01:00
else
2015-09-14 09:50:55 +02:00
Enr_ReqAnotherUsrIDToRegisterRemove (Role);
2014-12-31 02:46:20 +01:00
break;
default:
Err_NoPermissionExit ();
2014-12-31 02:46:20 +01:00
break;
}
}
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
/***** Register/remove users (taken from a list) in/from current course ******/
/*****************************************************************************/
2015-09-14 09:32:27 +02:00
static void Enr_ShowFormRegRemSeveralUsrs (Rol_Role_t Role)
2014-12-12 18:52:06 +01:00
{
2017-01-31 00:25:10 +01:00
extern const char *Hlp_USERS_Administration_administer_multiple_users;
extern const char *Txt_Administer_multiple_students;
2017-05-21 21:23:13 +02:00
extern const char *Txt_Administer_multiple_non_editing_teachers;
2017-01-31 00:25:10 +01:00
extern const char *Txt_Administer_multiple_teachers;
2014-12-12 18:52:06 +01:00
extern const char *Txt_Step_1_Provide_a_list_of_users;
extern const char *Txt_Type_or_paste_a_list_of_IDs_nicks_or_emails_;
2015-09-14 10:47:39 +02:00
extern const char *Txt_Step_2_Select_the_desired_action;
extern const char *Txt_Step_3_Optionally_select_groups;
2014-12-12 18:52:06 +01:00
extern const char *Txt_Select_the_groups_in_from_which_you_want_to_register_remove_users_;
extern const char *Txt_No_groups_have_been_created_in_the_course_X_Therefore_;
2017-03-30 11:20:06 +02:00
extern const char *Txt_Step_4_Confirm_the_enrolment_removing;
2014-12-12 18:52:06 +01:00
extern const char *Txt_Confirm;
static const struct
{
Act_Action_t NextAction;
const char **Title;
} WhatToDo[Rol_NUM_ROLES] =
{
[Rol_STD] = {ActRcvFrmEnrSevStd,&Txt_Administer_multiple_students },
[Rol_NET] = {ActRcvFrmEnrSevNET,&Txt_Administer_multiple_non_editing_teachers},
[Rol_TCH] = {ActRcvFrmEnrSevTch,&Txt_Administer_multiple_teachers },
};
2014-12-12 18:52:06 +01:00
2019-10-24 09:46:20 +02:00
/***** Contextual menu *****/
if (Gbl.Hierarchy.Level == Hie_CRS) // Course selected
2015-09-14 09:50:55 +02:00
{
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuBegin ();
2014-12-12 18:52:06 +01:00
switch (Role)
{
case Rol_STD:
/* Put link to go to admin student */
Enr_PutLinkToAdminOneUsr (ActReqMdfOneStd);
/* Put link to remove all students in the current course */
if (Enr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Node[Hie_CRS].HieCod,
1 << Rol_STD)) // This course has students
Enr_PutLinkToRemAllStdsThisCrs ();
break;
case Rol_NET:
/* Put link to go to admin teacher */
Enr_PutLinkToAdminOneUsr (ActReqMdfOneTch);
break;
case Rol_TCH:
/* Put link to go to admin teacher */
Enr_PutLinkToAdminOneUsr (ActReqMdfOneTch);
break;
default:
Err_WrongRoleExit ();
break;
}
2015-02-08 19:11:54 +01:00
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuEnd ();
2015-09-14 09:50:55 +02:00
}
2014-12-12 18:52:06 +01:00
2017-03-30 11:20:06 +02:00
/***** Form to send students to be enroled / removed *****/
if (!WhatToDo[Role].NextAction)
Err_WrongRoleExit ();
Frm_BeginForm (WhatToDo[Role].NextAction);
2015-04-11 23:46:21 +02:00
/***** Begin box *****/
Box_BoxBegin (*WhatToDo[Role].Title,NULL,NULL,
Hlp_USERS_Administration_administer_multiple_users,
Box_NOT_CLOSABLE);
/***** Step 1: List of students to be enroled / removed *****/
HTM_DIV_Begin ("class=\"TITLE_%s LM\"",The_GetSuffix ());
HTM_Txt (Txt_Step_1_Provide_a_list_of_users);
HTM_DIV_End ();
Ale_ShowAlert (Ale_INFO,Txt_Type_or_paste_a_list_of_IDs_nicks_or_emails_);
Enr_PutAreaToEnterUsrsIDs ();
/***** Step 2: Put different actions to register/remove users to/from current course *****/
HTM_DIV_Begin ("class=\"TITLE_%s LM\"",The_GetSuffix ());
HTM_Txt (Txt_Step_2_Select_the_desired_action);
HTM_DIV_End ();
Enr_PutActionsRegRemSeveralUsrs ();
/***** Step 3: Select groups in which register / remove users *****/
HTM_DIV_Begin ("class=\"TITLE_%s LM\"",The_GetSuffix ());
HTM_Txt (Txt_Step_3_Optionally_select_groups);
HTM_DIV_End ();
if (Gbl.Hierarchy.Level == Hie_CRS) // Course selected
{
if (Gbl.Crs.Grps.NumGrps) // This course has groups?
{
Ale_ShowAlert (Ale_INFO,Txt_Select_the_groups_in_from_which_you_want_to_register_remove_users_);
Grp_ShowLstGrpsToChgOtherUsrsGrps (-1L);
}
else
/* Write help message */
Ale_ShowAlert (Ale_INFO,Txt_No_groups_have_been_created_in_the_course_X_Therefore_,
Gbl.Hierarchy.Node[Hie_CRS].FullName);
}
2014-12-12 18:52:06 +01:00
/***** Step 4: Confirm register / remove students *****/
HTM_DIV_Begin ("class=\"TITLE_%s LM\"",The_GetSuffix ());
HTM_Txt (Txt_Step_4_Confirm_the_enrolment_removing);
HTM_DIV_End ();
Pwd_AskForConfirmationOnDangerousAction ();
2014-12-12 18:52:06 +01:00
/***** Send button and end box *****/
Box_BoxWithButtonEnd (Btn_CONFIRM_BUTTON,Txt_Confirm);
2015-04-11 23:46:21 +02:00
2017-06-12 14:16:33 +02:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/******************** Put a link (form) to remove old users ******************/
/*****************************************************************************/
2015-09-12 14:12:40 +02:00
void Enr_PutLinkToRemOldUsrs (void)
2014-12-12 18:52:06 +01:00
{
2015-10-07 23:21:10 +02:00
extern const char *Txt_Eliminate_old_users;
2014-12-12 18:52:06 +01:00
/***** Put form to remove old users *****/
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkIconText (ActReqRemOldUsr,NULL,
NULL,NULL,
"trash.svg",Ico_RED,
Txt_Eliminate_old_users,NULL);
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/*********************** Write form to remove old users **********************/
/*****************************************************************************/
void Enr_AskRemoveOldUsrs (void)
{
2015-10-07 23:21:10 +02:00
extern const char *Txt_Eliminate_old_users;
2017-03-30 11:20:06 +02:00
extern const char *Txt_Eliminate_all_users_who_are_not_enroled_on_any_courses_PART_1_OF_2;
extern const char *Txt_Eliminate_all_users_who_are_not_enroled_on_any_courses_PART_2_OF_2;
2014-12-12 18:52:06 +01:00
extern const char *Txt_Eliminate;
2014-12-12 22:39:55 +01:00
unsigned Months;
2014-12-12 18:52:06 +01:00
2019-10-20 22:00:28 +02:00
/***** Begin form *****/
Frm_BeginForm (ActRemOldUsr);
2015-10-07 23:21:10 +02:00
/***** Begin box *****/
Box_BoxBegin (Txt_Eliminate_old_users,NULL,NULL,NULL,Box_NOT_CLOSABLE);
/***** Form to request number of months without clicks *****/
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ());
HTM_TxtF ("%s&nbsp;",Txt_Eliminate_all_users_who_are_not_enroled_on_any_courses_PART_1_OF_2);
HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE,NULL,
"name=\"Months\" class=\"INPUT_%s\"",
The_GetSuffix ());
for (Months = Usr_MIN_MONTHS_WITHOUT_ACCESS_TO_REMOVE_OLD_USRS;
Months <= Usr_MAX_MONTHS_WITHOUT_ACCESS_TO_REMOVE_OLD_USRS;
Months++)
HTM_OPTION (HTM_Type_UNSIGNED,&Months,
Months == Usr_DEF_MONTHS_WITHOUT_ACCESS_TO_REMOVE_OLD_USRS ? HTM_OPTION_SELECTED :
HTM_OPTION_UNSELECTED,
HTM_OPTION_ENABLED,
"%u",Months);
HTM_SELECT_End ();
HTM_NBSP ();
HTM_TxtF (Txt_Eliminate_all_users_who_are_not_enroled_on_any_courses_PART_2_OF_2,
Cfg_PLATFORM_SHORT_NAME);
HTM_LABEL_End ();
/***** Send button and end box *****/
Box_BoxWithButtonEnd (Btn_REMOVE_BUTTON,Txt_Eliminate);
2015-10-07 23:21:10 +02:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/******************************* Remove old users ****************************/
/*****************************************************************************/
void Enr_RemoveOldUsrs (void)
{
2017-03-30 11:20:06 +02:00
extern const char *Txt_Eliminating_X_users_who_were_not_enroled_in_any_course_and_with_more_than_Y_months_without_access_to_Z;
2014-12-12 18:52:06 +01:00
extern const char *Txt_X_users_have_been_eliminated;
unsigned MonthsWithoutAccess;
2015-12-21 11:07:54 +01:00
time_t SecondsWithoutAccess;
2014-12-12 18:52:06 +01:00
MYSQL_RES *mysql_res;
unsigned NumUsr;
unsigned NumUsrs;
2014-12-12 18:52:06 +01:00
unsigned NumUsrsEliminated = 0;
struct Usr_Data UsrDat;
2014-12-12 18:52:06 +01:00
/***** Get parameter with number of months without access *****/
2017-01-29 21:41:08 +01:00
MonthsWithoutAccess = (unsigned)
Par_GetParUnsignedLong ("Months",
Usr_MIN_MONTHS_WITHOUT_ACCESS_TO_REMOVE_OLD_USRS,
Usr_MAX_MONTHS_WITHOUT_ACCESS_TO_REMOVE_OLD_USRS,
(unsigned long) UINT_MAX);
2017-01-29 12:42:19 +01:00
if (MonthsWithoutAccess == UINT_MAX)
Err_ShowErrorAndExit ("Wrong number of months.");
2015-12-21 11:07:54 +01:00
SecondsWithoutAccess = (time_t) MonthsWithoutAccess * Dat_SECONDS_IN_ONE_MONTH;
2014-12-12 18:52:06 +01:00
/***** Get old users from database *****/
if ((NumUsrs = Usr_DB_GetOldUsrs (&mysql_res,SecondsWithoutAccess)))
2014-12-12 18:52:06 +01:00
{
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,Txt_Eliminating_X_users_who_were_not_enroled_in_any_course_and_with_more_than_Y_months_without_access_to_Z,
2019-02-16 01:20:54 +01:00
NumUsrs,
MonthsWithoutAccess,
Cfg_PLATFORM_SHORT_NAME);
2014-12-12 18:52:06 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** Remove users *****/
for (NumUsr = 0;
NumUsr < NumUsrs;
NumUsr++)
{
UsrDat.UsrCod = DB_GetNextCode (mysql_res);
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CRS))
2014-12-12 18:52:06 +01:00
{
// User's data exist...
2014-12-12 22:39:55 +01:00
Acc_CompletelyEliminateAccount (&UsrDat,Cns_QUIET);
2014-12-12 18:52:06 +01:00
NumUsrsEliminated++;
}
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
/***** Move unused contents of messages to table of deleted contents of messages *****/
Msg_DB_MoveUnusedMsgsContentToDeleted ();
2014-12-12 18:52:06 +01:00
}
/***** Write end message *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_X_users_have_been_eliminated,
2019-02-16 01:20:54 +01:00
NumUsrsEliminated);
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
/***** Put text area to enter/paste IDs of users to be enroled/removed ******/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
static void Enr_PutAreaToEnterUsrsIDs (void)
{
extern const char *Txt_List_of_nicks_emails_or_IDs;
2016-12-26 18:35:52 +01:00
/***** Text area for users' IDs *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginCenterPadding (2);
HTM_TR_Begin (NULL);
2019-10-07 08:55:06 +02:00
/* Label */
Frm_LabelColumn ("RT","UsrsIDs",Txt_List_of_nicks_emails_or_IDs);
2019-10-07 08:55:06 +02:00
/* Data */
HTM_TD_Begin ("class=\"LT\"");
HTM_TEXTAREA_Begin ("id=\"UsrsIDs\" name=\"UsrsIDs\""
" cols=\"60\" rows=\"10\""
" class=\"INPUT_%s\"",
The_GetSuffix ());
HTM_TEXTAREA_End ();
HTM_TD_End ();
2019-10-07 08:55:06 +02:00
HTM_TR_End ();
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/*** Put different actions to register/remove users to/from current course ***/
/*****************************************************************************/
static void Enr_PutActionsRegRemSeveralUsrs (void)
{
extern const char *HTM_CheckedTxt[Cns_NUM_UNCHECKED_CHECKED];
2014-12-12 18:52:06 +01:00
extern const char *Txt_Register_the_users_indicated_in_step_1;
extern const char *Txt_Remove_the_users_indicated_in_step_1;
extern const char *Txt_Remove_the_users_not_indicated_in_step_1;
extern const char *Txt_Register_the_users_indicated_in_step_1_and_remove_the_users_not_indicated;
extern const char *Txt_Eliminate_from_the_platform_the_users_indicated_in_step_1;
/***** Begin list of options *****/
HTM_UL_Begin ("class=\"LIST_LEFT FORM_IN_%s\"",The_GetSuffix ());
2014-12-12 18:52:06 +01:00
/***** Register / remove users listed or not listed *****/
if (Gbl.Hierarchy.Level == Hie_CRS) // Course selected
{
HTM_LI_Begin (NULL);
HTM_LABEL_Begin (NULL);
HTM_INPUT_RADIO ("RegRemAction",HTM_DONT_SUBMIT_ON_CLICK,
" value=\"%u\"%s",
(unsigned) Enr_REGISTER_SPECIFIED_USRS_IN_CRS,
HTM_CheckedTxt[Cns_CHECKED]);
HTM_Txt (Txt_Register_the_users_indicated_in_step_1);
HTM_LABEL_End ();
HTM_LI_End ();
HTM_LI_Begin (NULL);
HTM_LABEL_Begin (NULL);
HTM_INPUT_RADIO ("RegRemAction",HTM_DONT_SUBMIT_ON_CLICK,
" value=\"%u\"",
(unsigned) Enr_REMOVE_SPECIFIED_USRS_FROM_CRS);
HTM_Txt (Txt_Remove_the_users_indicated_in_step_1);
HTM_LABEL_End ();
HTM_LI_End ();
HTM_LI_Begin (NULL);
HTM_LABEL_Begin (NULL);
HTM_INPUT_RADIO ("RegRemAction",HTM_DONT_SUBMIT_ON_CLICK,
" value=\"%u\"",
(unsigned) Enr_REMOVE_NOT_SPECIFIED_USRS_FROM_CRS);
HTM_Txt (Txt_Remove_the_users_not_indicated_in_step_1);
HTM_LABEL_End ();
HTM_LI_End ();
HTM_LI_Begin (NULL);
HTM_LABEL_Begin (NULL);
HTM_INPUT_RADIO ("RegRemAction",HTM_DONT_SUBMIT_ON_CLICK,
" value=\"%u\"",
(unsigned) Enr_UPDATE_USRS_IN_CRS);
HTM_Txt (Txt_Register_the_users_indicated_in_step_1_and_remove_the_users_not_indicated);
HTM_LABEL_End ();
HTM_LI_End ();
}
2014-12-12 18:52:06 +01:00
/***** Only for superusers *****/
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
{
HTM_LI_Begin (NULL);
HTM_LABEL_Begin (NULL);
HTM_INPUT_RADIO ("RegRemAction",HTM_DONT_SUBMIT_ON_CLICK,
" value=\"%u\"",
(unsigned) Enr_ELIMINATE_USRS_FROM_PLATFORM);
HTM_Txt (Txt_Eliminate_from_the_platform_the_users_indicated_in_step_1);
HTM_LABEL_End ();
HTM_LI_End ();
}
2014-12-12 18:52:06 +01:00
/***** End list of options *****/
2019-10-26 02:19:42 +02:00
HTM_UL_End ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/******* Receive the list of users of the course to register/remove **********/
/*****************************************************************************/
void Enr_ReceiveAdminStds (void)
2015-09-14 09:50:55 +02:00
{
Enr_ReceiveUsrsCrs (Rol_STD);
2015-09-14 09:50:55 +02:00
}
void Enr_ReceiveAdminNonEditTchs (void)
2017-05-21 21:23:13 +02:00
{
Enr_ReceiveUsrsCrs (Rol_NET);
2017-05-21 21:23:13 +02:00
}
void Enr_ReceiveAdminTchs (void)
2015-09-14 09:50:55 +02:00
{
Enr_ReceiveUsrsCrs (Rol_TCH);
2015-09-14 09:50:55 +02:00
}
static void Enr_ReceiveUsrsCrs (Rol_Role_t Role)
2014-12-12 18:52:06 +01:00
{
2017-03-30 11:20:06 +02:00
extern const char *Txt_In_a_type_of_group_with_single_enrolment_students_can_not_be_registered_in_more_than_one_group;
2014-12-12 18:52:06 +01:00
extern const char *Txt_No_user_has_been_eliminated;
extern const char *Txt_One_user_has_been_eliminated;
extern const char *Txt_No_user_has_been_removed;
extern const char *Txt_One_user_has_been_removed;
extern const char *Txt_X_users_have_been_eliminated;
extern const char *Txt_X_users_have_been_removed;
2017-03-30 11:20:06 +02:00
extern const char *Txt_No_user_has_been_enroled;
extern const char *Txt_One_user_has_been_enroled;
extern const char *Txt_X_users_have_been_enroled_including_possible_repetitions;
2014-12-12 18:52:06 +01:00
struct
{
bool RemoveUsrs;
bool RemoveSpecifiedUsrs;
bool EliminateUsrs;
bool RegisterUsrs;
} WhatToDo;
char *ListUsrsIDs;
struct Usr_ListUsrCods ListUsrCods; // List with users' codes for a given user's ID
2014-12-12 18:52:06 +01:00
unsigned NumUsrFound;
const char *Ptr;
unsigned NumCurrentUsr;
unsigned NumUsrsRegistered = 0;
unsigned NumUsrsRemoved = 0;
unsigned NumUsrsEliminated = 0;
struct ListCodGrps LstGrps;
struct Usr_Data UsrDat;
2014-12-12 18:52:06 +01:00
bool ItLooksLikeAUsrID;
Enr_RegRemUsrsAction_t RegRemUsrsAction;
2015-09-14 10:47:39 +02:00
/***** Check the role of users to register / remove *****/
switch (Role)
{
2017-05-18 19:13:41 +02:00
case Rol_STD:
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged < Rol_TCH) // Can I register/remove students?
2017-05-22 00:51:45 +02:00
// No, I can not
Err_NoPermissionExit ();
2015-09-14 10:47:39 +02:00
break;
2017-05-22 00:51:45 +02:00
case Rol_NET:
2017-05-18 19:13:41 +02:00
case Rol_TCH:
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged < Rol_DEG_ADM) // Can I register/remove teachers?
2017-05-22 00:51:45 +02:00
// No, I can not
Err_NoPermissionExit ();
2015-09-14 10:47:39 +02:00
break;
default:
Err_WrongRoleExit ();
2015-09-14 10:47:39 +02:00
break;
}
2014-12-12 18:52:06 +01:00
/***** Get confirmation *****/
if (!Pwd_GetConfirmationOnDangerousAction ())
return;
/***** Get the action to do *****/
WhatToDo.RemoveUsrs = false;
WhatToDo.RemoveSpecifiedUsrs = false;
WhatToDo.EliminateUsrs = false;
WhatToDo.RegisterUsrs = false;
2017-01-29 21:41:08 +01:00
RegRemUsrsAction = (Enr_RegRemUsrsAction_t)
Par_GetParUnsignedLong ("RegRemAction",
0,
Enr_NUM_REG_REM_USRS_ACTIONS - 1,
(unsigned long) Enr_REG_REM_USRS_UNKNOWN_ACTION);
2017-01-29 12:42:19 +01:00
switch (RegRemUsrsAction)
{
case Enr_REGISTER_SPECIFIED_USRS_IN_CRS:
WhatToDo.RemoveUsrs = false;
WhatToDo.RemoveSpecifiedUsrs = false; // Ignored
WhatToDo.EliminateUsrs = false; // Ignored
2017-01-29 12:42:19 +01:00
WhatToDo.RegisterUsrs = true;
break;
case Enr_REMOVE_SPECIFIED_USRS_FROM_CRS:
WhatToDo.RemoveUsrs = true;
WhatToDo.RemoveSpecifiedUsrs = true;
WhatToDo.EliminateUsrs = false;
WhatToDo.RegisterUsrs = false;
break;
case Enr_REMOVE_NOT_SPECIFIED_USRS_FROM_CRS:
WhatToDo.RemoveUsrs = true;
WhatToDo.RemoveSpecifiedUsrs = false;
WhatToDo.EliminateUsrs = false;
WhatToDo.RegisterUsrs = false;
break;
case Enr_UPDATE_USRS_IN_CRS:
WhatToDo.RemoveUsrs = true;
WhatToDo.RemoveSpecifiedUsrs = false;
WhatToDo.EliminateUsrs = false;
WhatToDo.RegisterUsrs = true;
break;
case Enr_ELIMINATE_USRS_FROM_PLATFORM:
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
2014-12-12 18:52:06 +01:00
{
2017-01-29 12:42:19 +01:00
WhatToDo.RemoveUsrs = true;
WhatToDo.RemoveSpecifiedUsrs = true;
WhatToDo.EliminateUsrs = true;
WhatToDo.RegisterUsrs = false;
2014-12-12 18:52:06 +01:00
}
2017-01-29 12:42:19 +01:00
else
Err_NoPermissionExit ();
2017-01-29 12:42:19 +01:00
break;
default:
Err_ShowErrorAndExit ("Wrong registering / removing specification.");
2017-01-29 12:42:19 +01:00
break;
2014-12-12 18:52:06 +01:00
}
2017-01-29 12:42:19 +01:00
/***** Get groups to which register/remove users *****/
LstGrps.NumGrps = 0;
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.NumGrps) // This course has groups?
2014-12-12 18:52:06 +01:00
{
2017-01-29 12:42:19 +01:00
/***** Get list of groups types and groups in current course *****/
Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS);
/***** Get the list of groups to which register/remove students *****/
LstGrps.GrpCods = NULL; // Initialized to avoid bug reported by Coverity
LstGrps.NumGrps = 0; // Initialized to avoid bug reported by Coverity
Grp_GetLstCodsGrpWanted (&LstGrps);
2017-05-22 00:51:45 +02:00
/***** A student can't belong to more than one group
when the type of group only allows to register in one group *****/
2017-06-20 01:58:16 +02:00
if (WhatToDo.RegisterUsrs)
2017-03-30 11:20:06 +02:00
/* Check if I have selected more than one group of single enrolment */
2017-06-20 01:58:16 +02:00
if (!Grp_CheckIfSelectionGrpsSingleEnrolmentIsValid (Role,&LstGrps))
2014-12-12 18:52:06 +01:00
{
2017-01-29 12:42:19 +01:00
/* Show warning message and exit */
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_In_a_type_of_group_with_single_enrolment_students_can_not_be_registered_in_more_than_one_group);
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
/* Free memory used by lists of groups and abort */
Grp_FreeListCodGrp (&LstGrps);
Grp_FreeListGrpTypesAndGrps ();
return;
}
}
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
/***** Get list of users' IDs *****/
if ((ListUsrsIDs = malloc (ID_MAX_BYTES_LIST_USRS_IDS + 1)) == NULL)
Err_NotEnoughMemoryExit ();
Par_GetParText ("UsrsIDs",ListUsrsIDs,ID_MAX_BYTES_LIST_USRS_IDS);
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
/***** Remove users *****/
if (WhatToDo.RemoveUsrs)
{
/***** Get list of users in current course *****/
Usr_GetListUsrs (Hie_CRS,Role);
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
if (Gbl.Usrs.LstUsrs[Role].NumUsrs)
2014-12-12 18:52:06 +01:00
{
2017-01-29 12:42:19 +01:00
/***** Initialize list of users to remove *****/
for (NumCurrentUsr = 0;
NumCurrentUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs;
NumCurrentUsr++)
Gbl.Usrs.LstUsrs[Role].Lst[NumCurrentUsr].Remove = !WhatToDo.RemoveSpecifiedUsrs;
/***** Loop 1: go through form list setting if a student must be removed *****/
/* Get users from a list of users' IDs */
2014-12-12 18:52:06 +01:00
Ptr = ListUsrsIDs;
while (*Ptr)
{
/* Reset user */
UsrDat.UsrCod = -1L;
/* Find next string in text */
2017-03-07 19:55:29 +01:00
Str_GetNextStringUntilSeparator (&Ptr,UsrDat.UsrIDNickOrEmail,
sizeof (UsrDat.UsrIDNickOrEmail) - 1);
2014-12-12 18:52:06 +01:00
/* Reset default list of users' codes */
ListUsrCods.NumUsrs = 0;
ListUsrCods.Lst = NULL;
2017-01-29 12:42:19 +01:00
/* Check if string is a user's ID, user's nickname or user's email address */
if (Nck_CheckIfNickWithArrIsValid (UsrDat.UsrIDNickOrEmail)) // 1: It's a nickname
2014-12-12 18:52:06 +01:00
{
if ((UsrDat.UsrCod = Nck_GetUsrCodFromNickname (UsrDat.UsrIDNickOrEmail)) > 0)
{
ListUsrCods.NumUsrs = 1;
Usr_AllocateListUsrCods (&ListUsrCods);
ListUsrCods.Lst[0] = UsrDat.UsrCod;
}
}
2017-01-29 12:42:19 +01:00
else if (Mai_CheckIfEmailIsValid (UsrDat.UsrIDNickOrEmail)) // 2: It's an email
2014-12-12 18:52:06 +01:00
{
if ((UsrDat.UsrCod = Mai_DB_GetUsrCodFromEmail (UsrDat.UsrIDNickOrEmail)) > 0)
2014-12-12 18:52:06 +01:00
{
ListUsrCods.NumUsrs = 1;
Usr_AllocateListUsrCods (&ListUsrCods);
ListUsrCods.Lst[0] = UsrDat.UsrCod;
}
}
else // 3: It looks like a user's ID
{
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (UsrDat.UsrIDNickOrEmail);
if (ID_CheckIfUsrIDSeemsAValidID (UsrDat.UsrIDNickOrEmail))
{
2017-01-29 12:42:19 +01:00
/***** Find users for this user's ID *****/
2014-12-12 18:52:06 +01:00
ID_ReallocateListIDs (&UsrDat,1); // Only one user's ID
2017-01-15 18:02:52 +01:00
Str_Copy (UsrDat.IDs.List[0].ID,UsrDat.UsrIDNickOrEmail,
sizeof (UsrDat.IDs.List[0].ID) - 1);
2017-01-29 12:42:19 +01:00
Str_ConvertToUpperText (UsrDat.IDs.List[0].ID);
2014-12-12 18:52:06 +01:00
ID_GetListUsrCodsFromUsrID (&UsrDat,NULL,&ListUsrCods,false);
}
}
2017-01-29 12:42:19 +01:00
if (WhatToDo.RemoveSpecifiedUsrs) // Remove the specified users (of the role)
{
if (ListUsrCods.NumUsrs == 1) // If more than one user found ==> do not remove
for (NumCurrentUsr = 0;
NumCurrentUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs;
NumCurrentUsr++)
if (Gbl.Usrs.LstUsrs[Role].Lst[NumCurrentUsr].UsrCod == ListUsrCods.Lst[0]) // User found
Gbl.Usrs.LstUsrs[Role].Lst[NumCurrentUsr].Remove = true; // Mark as removable
}
else // Remove all users (of the role) except these specified
2017-01-29 12:42:19 +01:00
{
for (NumCurrentUsr = 0;
NumCurrentUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs;
NumCurrentUsr++)
for (NumUsrFound = 0;
NumUsrFound < ListUsrCods.NumUsrs;
NumUsrFound++)
if (Gbl.Usrs.LstUsrs[Role].Lst[NumCurrentUsr].UsrCod == ListUsrCods.Lst[NumUsrFound]) // User found
Gbl.Usrs.LstUsrs[Role].Lst[NumCurrentUsr].Remove = false; // Mark as not removable
}
2014-12-12 18:52:06 +01:00
/* Free memory used for list of users' codes found for this ID */
Usr_FreeListUsrCods (&ListUsrCods);
}
2017-01-29 12:42:19 +01:00
/***** Loop 2: go through users list removing users *****/
for (NumCurrentUsr = 0;
NumCurrentUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs;
NumCurrentUsr++)
if (Gbl.Usrs.LstUsrs[Role].Lst[NumCurrentUsr].Remove) // If this student must be removed
{
UsrDat.UsrCod = Gbl.Usrs.LstUsrs[Role].Lst[NumCurrentUsr].UsrCod;
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CRS))
2017-01-29 12:42:19 +01:00
{
// User's data exist...
2017-01-29 12:42:19 +01:00
if (WhatToDo.EliminateUsrs) // Eliminate user completely from the platform
{
Acc_CompletelyEliminateAccount (&UsrDat,Cns_QUIET); // Remove definitely the user from the platform
NumUsrsEliminated++;
}
else
{
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.NumGrps) // If there are groups in the course
2017-01-29 12:42:19 +01:00
{
if (LstGrps.NumGrps) // If the teacher has selected groups
{
if (Grp_RemoveUsrFromGroups (&UsrDat,&LstGrps)) // Remove user from the selected groups, not from the whole course
NumUsrsRemoved++;
}
else // The teacher has not selected groups
{
Enr_EffectivelyRemUsrFromCrs (&UsrDat,&Gbl.Hierarchy.Node[Hie_CRS],
2019-09-29 23:13:20 +02:00
Enr_DO_NOT_REMOVE_USR_PRODUCTION,
Cns_QUIET); // Remove user from the course
2017-01-29 12:42:19 +01:00
NumUsrsRemoved++;
}
}
else // No groups
{
Enr_EffectivelyRemUsrFromCrs (&UsrDat,&Gbl.Hierarchy.Node[Hie_CRS],
2019-09-29 23:13:20 +02:00
Enr_DO_NOT_REMOVE_USR_PRODUCTION,
Cns_QUIET); // Remove user from the course
2017-01-29 12:42:19 +01:00
NumUsrsRemoved++;
}
}
}
}
}
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
/***** Free memory for users list *****/
Usr_FreeUsrsList (Role);
}
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
/***** Register users *****/
if (WhatToDo.RegisterUsrs) // TODO: !!!!! NO CAMBIAR EL ROL DE LOS USUARIOS QUE YA EST<53>N EN LA ASIGNATURA SI HAY M<>S DE UN USUARIO ENCONTRADO PARA EL MISMO DNI !!!!!!
{
/***** Get users from a list of users' IDs ******/
Ptr = ListUsrsIDs;
while (*Ptr)
2014-12-12 18:52:06 +01:00
{
2017-01-29 12:42:19 +01:00
/* Reset user */
UsrDat.UsrCod = -1L;
ItLooksLikeAUsrID = false;
/* Find next string in text */
2017-03-07 19:55:29 +01:00
Str_GetNextStringUntilSeparator (&Ptr,UsrDat.UsrIDNickOrEmail,
sizeof (UsrDat.UsrIDNickOrEmail) - 1);
2017-01-29 12:42:19 +01:00
/* Reset default list of users' codes */
ListUsrCods.NumUsrs = 0;
ListUsrCods.Lst = NULL;
/* Check if the string is a user's ID, a user's nickname or a user's email address */
if (Nck_CheckIfNickWithArrIsValid (UsrDat.UsrIDNickOrEmail)) // 1: It's a nickname
2017-01-29 12:42:19 +01:00
{
if ((UsrDat.UsrCod = Nck_GetUsrCodFromNickname (UsrDat.UsrIDNickOrEmail)) > 0)
2014-12-12 18:52:06 +01:00
{
2017-01-29 12:42:19 +01:00
ListUsrCods.NumUsrs = 1;
Usr_AllocateListUsrCods (&ListUsrCods);
ListUsrCods.Lst[0] = UsrDat.UsrCod;
2014-12-12 18:52:06 +01:00
}
2017-01-29 12:42:19 +01:00
}
else if (Mai_CheckIfEmailIsValid (UsrDat.UsrIDNickOrEmail)) // 2: It's an email
{
if ((UsrDat.UsrCod = Mai_DB_GetUsrCodFromEmail (UsrDat.UsrIDNickOrEmail)) > 0)
2014-12-12 18:52:06 +01:00
{
2017-01-29 12:42:19 +01:00
ListUsrCods.NumUsrs = 1;
Usr_AllocateListUsrCods (&ListUsrCods);
ListUsrCods.Lst[0] = UsrDat.UsrCod;
}
}
else // 3: It looks like a user's ID
{
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (UsrDat.UsrIDNickOrEmail);
if (ID_CheckIfUsrIDSeemsAValidID (UsrDat.UsrIDNickOrEmail))
{
ItLooksLikeAUsrID = true;
/* Find users for this user's ID */
ID_ReallocateListIDs (&UsrDat,1); // Only one user's ID
Str_Copy (UsrDat.IDs.List[0].ID,UsrDat.UsrIDNickOrEmail,
sizeof (UsrDat.IDs.List[0].ID) - 1);
2017-01-29 12:42:19 +01:00
Str_ConvertToUpperText (UsrDat.IDs.List[0].ID);
ID_GetListUsrCodsFromUsrID (&UsrDat,NULL,&ListUsrCods,false);
2014-12-12 18:52:06 +01:00
}
2017-01-29 12:42:19 +01:00
}
/* Register user(s) */
if (ListUsrCods.NumUsrs) // User(s) found
for (NumUsrFound = 0;
NumUsrFound < ListUsrCods.NumUsrs;
NumUsrFound++)
{
UsrDat.UsrCod = ListUsrCods.Lst[NumUsrFound];
Enr_RegisterUsr (&UsrDat,Role,&LstGrps,&NumUsrsRegistered);
}
else if (ItLooksLikeAUsrID) // User not found. He/she is a new user. Register him/her using ID
Enr_RegisterUsr (&UsrDat,Role,&LstGrps,&NumUsrsRegistered);
/* Free memory used for list of users' codes found for this ID */
Usr_FreeListUsrCods (&ListUsrCods);
2014-12-12 18:52:06 +01:00
}
2017-01-29 12:42:19 +01:00
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
if (NumUsrsEliminated)
/***** Move unused contents of messages to table of deleted contents of messages *****/
Msg_DB_MoveUnusedMsgsContentToDeleted ();
2017-01-29 12:42:19 +01:00
2017-03-30 11:20:06 +02:00
/***** Write messages with the number of users enroled/removed *****/
2017-01-29 12:42:19 +01:00
if (WhatToDo.RemoveUsrs)
{
if (WhatToDo.EliminateUsrs) // Eliminate completely from the platform
switch (NumUsrsEliminated)
{
case 0:
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,Txt_No_user_has_been_eliminated);
2017-01-29 12:42:19 +01:00
break;
case 1:
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_One_user_has_been_eliminated);
2017-01-29 12:42:19 +01:00
break;
default:
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_X_users_have_been_eliminated,
2019-02-16 01:20:54 +01:00
NumUsrsEliminated);
2017-01-29 12:42:19 +01:00
break;
}
else // Only remove from course / groups
2017-01-29 12:42:19 +01:00
switch (NumUsrsRemoved)
2014-12-12 18:52:06 +01:00
{
case 0:
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,Txt_No_user_has_been_removed);
2014-12-12 18:52:06 +01:00
break;
case 1:
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_One_user_has_been_removed);
2014-12-12 18:52:06 +01:00
break;
default:
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_X_users_have_been_removed,
2019-02-16 01:20:54 +01:00
NumUsrsRemoved);
2014-12-12 18:52:06 +01:00
break;
}
2017-01-29 12:42:19 +01:00
}
if (WhatToDo.RegisterUsrs)
switch (NumUsrsRegistered)
{
case 0:
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,Txt_No_user_has_been_enroled);
2017-01-29 12:42:19 +01:00
break;
case 1:
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_One_user_has_been_enroled);
2017-01-29 12:42:19 +01:00
break;
default:
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_X_users_have_been_enroled_including_possible_repetitions,
2019-02-16 01:20:54 +01:00
NumUsrsRegistered);
2017-01-29 12:42:19 +01:00
break;
}
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
/***** Free memory used by the list of user's IDs *****/
free (ListUsrsIDs);
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
/***** Free memory with the list of groups to/from which register/remove users *****/
Grp_FreeListCodGrp (&LstGrps);
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
/***** Free list of groups types and groups in current course *****/
Grp_FreeListGrpTypesAndGrps ();
2014-12-12 18:52:06 +01:00
}
2019-03-10 14:44:12 +01:00
/*****************************************************************************/
/*** Put different actions to register/remove users to/from current course ***/
/*****************************************************************************/
// Returns true if at least one action can be shown
bool Enr_PutActionsRegRemOneUsr (Usr_MeOrOther_t MeOrOther)
2019-03-10 14:44:12 +01:00
{
bool OptionsShown = false;
Usr_Belong_t UsrBelongsToCrs = Usr_DONT_BELONG;
2019-03-10 14:44:12 +01:00
bool UsrIsDegAdmin = false;
bool UsrIsCtrAdmin = false;
bool UsrIsInsAdmin = false;
Cns_UncheckedOrChecked_t UncheckedOrChecked = Cns_UNCHECKED;
2019-03-10 14:44:12 +01:00
/***** Check if the other user belongs to the current course *****/
if (Gbl.Hierarchy.Level == Hie_CRS)
UsrBelongsToCrs = Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat);
2019-03-10 14:44:12 +01:00
if (Gbl.Hierarchy.Node[Hie_INS].HieCod > 0)
2019-03-10 14:44:12 +01:00
{
/***** Check if the other user is administrator of the current institution *****/
UsrIsInsAdmin = Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod,
Hie_INS);
2019-03-10 14:44:12 +01:00
if (Gbl.Hierarchy.Node[Hie_CTR].HieCod > 0)
2019-03-10 14:44:12 +01:00
{
/***** Check if the other user is administrator of the current center *****/
UsrIsCtrAdmin = Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod,
Hie_CTR);
2019-03-10 14:44:12 +01:00
if (Gbl.Hierarchy.Node[Hie_DEG].HieCod > 0)
2019-03-10 14:44:12 +01:00
/***** Check if the other user is administrator of the current degree *****/
UsrIsDegAdmin = Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod,
Hie_DEG);
2019-03-10 14:44:12 +01:00
}
}
/***** Begin list of options *****/
HTM_UL_Begin ("class=\"LIST_LEFT FORM_IN_%s\"",The_GetSuffix ());
2019-03-10 14:44:12 +01:00
/***** Register user in course / Modify user's data *****/
if (Gbl.Hierarchy.Level == Hie_CRS && Gbl.Usrs.Me.Role.Logged >= Rol_STD)
{
Enr_PutActionModifyOneUsr (&UncheckedOrChecked,UsrBelongsToCrs,MeOrOther);
OptionsShown = true;
}
2019-03-10 14:44:12 +01:00
if (Gbl.Hierarchy.Node[Hie_INS].HieCod > 0)
2019-03-10 14:44:12 +01:00
{
if (Gbl.Hierarchy.Node[Hie_CTR].HieCod > 0)
{
if (Gbl.Hierarchy.Node[Hie_DEG].HieCod > 0)
/***** Register user as administrator of degree *****/
if (!UsrIsDegAdmin && Gbl.Usrs.Me.Role.Logged >= Rol_CTR_ADM)
{
Enr_PutActionRegOneDegAdm (&UncheckedOrChecked);
OptionsShown = true;
}
/***** Register user as administrator of center *****/
if (!UsrIsCtrAdmin && Gbl.Usrs.Me.Role.Logged >= Rol_INS_ADM)
2019-03-10 14:44:12 +01:00
{
Enr_PutActionRegOneCtrAdm (&UncheckedOrChecked);
2019-03-10 14:44:12 +01:00
OptionsShown = true;
}
}
2019-03-10 14:44:12 +01:00
/***** Register user as administrator of institution *****/
if (!UsrIsInsAdmin && Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
2019-03-10 14:44:12 +01:00
{
Enr_PutActionRegOneInsAdm (&UncheckedOrChecked);
2019-03-10 14:44:12 +01:00
OptionsShown = true;
}
}
/***** Report user as possible duplicate *****/
if (MeOrOther == Usr_OTHER && Gbl.Usrs.Me.Role.Logged >= Rol_TCH)
2019-03-10 14:44:12 +01:00
{
Enr_PutActionRepUsrAsDup (&UncheckedOrChecked);
2019-03-10 14:44:12 +01:00
OptionsShown = true;
}
/***** Remove user from the course *****/
if (UsrBelongsToCrs == Usr_BELONG)
{
Enr_PutActionRemUsrFromCrs (&UncheckedOrChecked,MeOrOther);
OptionsShown = true;
}
2019-03-10 14:44:12 +01:00
if (Gbl.Hierarchy.Node[Hie_INS].HieCod > 0)
2019-03-10 14:44:12 +01:00
{
if (Gbl.Hierarchy.Node[Hie_CTR].HieCod > 0)
{
if (Gbl.Hierarchy.Node[Hie_INS].HieCod > 0)
/***** Remove user as an administrator of the degree *****/
if (UsrIsDegAdmin &&
(MeOrOther == Usr_ME || Gbl.Usrs.Me.Role.Logged >= Rol_CTR_ADM))
{
Enr_PutActionRemUsrAsDegAdm (&UncheckedOrChecked,MeOrOther);
OptionsShown = true;
}
/***** Remove user as an administrator of the center *****/
if (UsrIsCtrAdmin &&
(MeOrOther == Usr_ME || Gbl.Usrs.Me.Role.Logged >= Rol_INS_ADM))
2019-03-10 14:44:12 +01:00
{
Enr_PutActionRemUsrAsCtrAdm (&UncheckedOrChecked,MeOrOther);
2019-03-10 14:44:12 +01:00
OptionsShown = true;
}
}
2019-03-10 14:44:12 +01:00
/***** Remove user as an administrator of the institution *****/
if (UsrIsInsAdmin &&
(MeOrOther == Usr_ME || Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM))
2019-03-10 14:44:12 +01:00
{
Enr_PutActionRemUsrAsInsAdm (&UncheckedOrChecked,MeOrOther);
2019-03-10 14:44:12 +01:00
OptionsShown = true;
}
}
/***** Eliminate user completely from platform *****/
if (Acc_CheckIfICanEliminateAccount (Gbl.Usrs.Other.UsrDat.UsrCod) == Usr_CAN)
2019-03-10 14:44:12 +01:00
{
Enr_PutActionRemUsrAcc (&UncheckedOrChecked,MeOrOther);
2019-03-10 14:44:12 +01:00
OptionsShown = true;
}
/***** End list of options *****/
2019-10-26 02:19:42 +02:00
HTM_UL_End ();
2019-03-10 14:44:12 +01:00
return OptionsShown;
}
/*****************************************************************************/
/**************** Put action to modify user in current course ****************/
/*****************************************************************************/
static void Enr_PutActionModifyOneUsr (Cns_UncheckedOrChecked_t *UncheckedOrChecked,
Usr_Belong_t UsrBelongsToCrs,Usr_MeOrOther_t MeOrOther)
2019-03-10 14:44:12 +01:00
{
extern const char *Txt_Register_me_in_X;
extern const char *Txt_Register_USER_in_the_course_X;
extern const char *Txt_Modify_me_in_the_course_X;
extern const char *Txt_Modify_user_in_the_course_X;
const char *Txt[Usr_NUM_BELONG][Usr_NUM_ME_OR_OTHER] =
{
[Usr_DONT_BELONG][Usr_ME ] = Txt_Register_me_in_X,
[Usr_DONT_BELONG][Usr_OTHER] = Txt_Register_USER_in_the_course_X,
[Usr_BELONG ][Usr_ME ] = Txt_Modify_me_in_the_course_X,
[Usr_BELONG ][Usr_OTHER] = Txt_Modify_user_in_the_course_X,
};
2019-03-10 14:44:12 +01:00
Enr_RegRemOneUsrActionBegin (Enr_REGISTER_MODIFY_ONE_USR_IN_CRS,UncheckedOrChecked);
HTM_TxtF (Txt[UsrBelongsToCrs][MeOrOther],
Gbl.Hierarchy.Node[Hie_CRS].ShrtName);
Enr_RegRemOneUsrActionEnd ();
2019-03-10 14:44:12 +01:00
}
/*****************************************************************************/
/**************** Put action to register user as degree admin ****************/
/*****************************************************************************/
static void Enr_PutActionRegOneDegAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked)
2019-03-10 14:44:12 +01:00
{
extern const char *Txt_Register_USER_as_an_administrator_of_the_degree_X;
Enr_RegRemOneUsrActionBegin (Enr_REGISTER_ONE_DEG_ADMIN,UncheckedOrChecked);
HTM_TxtF (Txt_Register_USER_as_an_administrator_of_the_degree_X,
Gbl.Hierarchy.Node[Hie_DEG].ShrtName);
Enr_RegRemOneUsrActionEnd ();
2019-03-10 14:44:12 +01:00
}
/*****************************************************************************/
/**************** Put action to register user as center admin ****************/
2019-03-10 14:44:12 +01:00
/*****************************************************************************/
static void Enr_PutActionRegOneCtrAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked)
2019-03-10 14:44:12 +01:00
{
extern const char *Txt_Register_USER_as_an_administrator_of_the_center_X;
2019-03-10 14:44:12 +01:00
Enr_RegRemOneUsrActionBegin (Enr_REGISTER_ONE_CTR_ADMIN,UncheckedOrChecked);
HTM_TxtF (Txt_Register_USER_as_an_administrator_of_the_center_X,
Gbl.Hierarchy.Node[Hie_CTR].ShrtName);
Enr_RegRemOneUsrActionEnd ();
2019-03-10 14:44:12 +01:00
}
/*****************************************************************************/
/************* Put action to register user as institution admin **************/
/*****************************************************************************/
static void Enr_PutActionRegOneInsAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked)
2019-03-10 14:44:12 +01:00
{
extern const char *Txt_Register_USER_as_an_administrator_of_the_institution_X;
Enr_RegRemOneUsrActionBegin (Enr_REGISTER_ONE_INS_ADMIN,UncheckedOrChecked);
HTM_TxtF (Txt_Register_USER_as_an_administrator_of_the_institution_X,
Gbl.Hierarchy.Node[Hie_INS].ShrtName);
Enr_RegRemOneUsrActionEnd ();
2019-03-10 14:44:12 +01:00
}
/*****************************************************************************/
/****************** Put action to report user as duplicate *******************/
/*****************************************************************************/
static void Enr_PutActionRepUsrAsDup (Cns_UncheckedOrChecked_t *UncheckedOrChecked)
2019-03-10 14:44:12 +01:00
{
extern const char *Txt_Report_possible_duplicate_user;
Enr_RegRemOneUsrActionBegin (Enr_REPORT_USR_AS_POSSIBLE_DUPLICATE,UncheckedOrChecked);
HTM_Txt (Txt_Report_possible_duplicate_user);
Enr_RegRemOneUsrActionEnd ();
2019-03-10 14:44:12 +01:00
}
/*****************************************************************************/
/****************** Put action to remove user from course ********************/
/*****************************************************************************/
static void Enr_PutActionRemUsrFromCrs (Cns_UncheckedOrChecked_t *UncheckedOrChecked,Usr_MeOrOther_t MeOrOther)
2019-03-10 14:44:12 +01:00
{
extern const char *Txt_Remove_me_from_THE_COURSE_X;
extern const char *Txt_Remove_USER_from_THE_COURSE_X;
const char *Txt[Usr_NUM_ME_OR_OTHER] =
{
[Usr_ME ] = Txt_Remove_me_from_THE_COURSE_X,
[Usr_OTHER] = Txt_Remove_USER_from_THE_COURSE_X,
};
2019-03-10 14:44:12 +01:00
Enr_RegRemOneUsrActionBegin (Enr_REMOVE_ONE_USR_FROM_CRS,UncheckedOrChecked);
HTM_TxtF (Txt[MeOrOther],Gbl.Hierarchy.Node[Hie_CRS].ShrtName);
Enr_RegRemOneUsrActionEnd ();
2019-03-10 14:44:12 +01:00
}
/*****************************************************************************/
/***************** Put action to remove user as degree admin *****************/
/*****************************************************************************/
static void Enr_PutActionRemUsrAsDegAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked,Usr_MeOrOther_t MeOrOther)
2019-03-10 14:44:12 +01:00
{
extern const char *Txt_Remove_me_as_an_administrator_of_the_degree_X;
extern const char *Txt_Remove_USER_as_an_administrator_of_the_degree_X;
const char *Txt[Usr_NUM_ME_OR_OTHER] =
{
[Usr_ME ] = Txt_Remove_me_as_an_administrator_of_the_degree_X,
[Usr_OTHER] = Txt_Remove_USER_as_an_administrator_of_the_degree_X,
};
2019-03-10 14:44:12 +01:00
Enr_RegRemOneUsrActionBegin (Enr_REMOVE_ONE_DEG_ADMIN,UncheckedOrChecked);
HTM_TxtF (Txt[MeOrOther],Gbl.Hierarchy.Node[Hie_DEG].ShrtName);
Enr_RegRemOneUsrActionEnd ();
2019-03-10 14:44:12 +01:00
}
/*****************************************************************************/
/***************** Put action to remove user as center admin *****************/
2019-03-10 14:44:12 +01:00
/*****************************************************************************/
static void Enr_PutActionRemUsrAsCtrAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked,Usr_MeOrOther_t MeOrOther)
2019-03-10 14:44:12 +01:00
{
extern const char *Txt_Remove_me_as_an_administrator_of_the_center_X;
extern const char *Txt_Remove_USER_as_an_administrator_of_the_center_X;
const char *Txt[Usr_NUM_ME_OR_OTHER] =
{
[Usr_ME ] = Txt_Remove_me_as_an_administrator_of_the_center_X,
[Usr_OTHER] = Txt_Remove_USER_as_an_administrator_of_the_center_X,
};
2019-03-10 14:44:12 +01:00
Enr_RegRemOneUsrActionBegin (Enr_REMOVE_ONE_CTR_ADMIN,UncheckedOrChecked);
HTM_TxtF (Txt[MeOrOther],Gbl.Hierarchy.Node[Hie_CTR].ShrtName);
Enr_RegRemOneUsrActionEnd ();
2019-03-10 14:44:12 +01:00
}
/*****************************************************************************/
/************** Put action to remove user as institution admin ***************/
/*****************************************************************************/
static void Enr_PutActionRemUsrAsInsAdm (Cns_UncheckedOrChecked_t *UncheckedOrChecked,Usr_MeOrOther_t MeOrOther)
2019-03-10 14:44:12 +01:00
{
extern const char *Txt_Remove_me_as_an_administrator_of_the_institution_X;
extern const char *Txt_Remove_USER_as_an_administrator_of_the_institution_X;
const char *Txt[Usr_NUM_ME_OR_OTHER] =
{
[Usr_ME ] = Txt_Remove_me_as_an_administrator_of_the_institution_X,
[Usr_OTHER] = Txt_Remove_USER_as_an_administrator_of_the_institution_X,
};
2019-03-10 14:44:12 +01:00
Enr_RegRemOneUsrActionBegin (Enr_REMOVE_ONE_INS_ADMIN,UncheckedOrChecked);
HTM_TxtF (Txt[MeOrOther],Gbl.Hierarchy.Node[Hie_INS].ShrtName);
Enr_RegRemOneUsrActionEnd ();
2019-03-10 14:44:12 +01:00
}
/*****************************************************************************/
/********************* Put action to remove user account *********************/
/*****************************************************************************/
static void Enr_PutActionRemUsrAcc (Cns_UncheckedOrChecked_t *UncheckedOrChecked,Usr_MeOrOther_t MeOrOther)
2019-03-10 14:44:12 +01:00
{
extern const char *Txt_Eliminate_my_user_account;
extern const char *Txt_Eliminate_user_account;
const char *Txt[Usr_NUM_ME_OR_OTHER] =
{
[Usr_ME ] = Txt_Eliminate_my_user_account,
[Usr_OTHER] = Txt_Eliminate_user_account,
};
2019-03-10 14:44:12 +01:00
Enr_RegRemOneUsrActionBegin (Enr_ELIMINATE_ONE_USR_FROM_PLATFORM,UncheckedOrChecked);
HTM_Txt (Txt[MeOrOther]);
Enr_RegRemOneUsrActionEnd ();
2019-03-10 14:44:12 +01:00
}
/*****************************************************************************/
/************ Put start/end of action to register/remove one user ************/
/*****************************************************************************/
static void Enr_RegRemOneUsrActionBegin (Enr_RegRemOneUsrAction_t RegRemOneUsrAction,
Cns_UncheckedOrChecked_t *UncheckedOrChecked)
2019-03-10 14:44:12 +01:00
{
extern const char *HTM_CheckedTxt[Cns_NUM_UNCHECKED_CHECKED];
Cns_UncheckedOrChecked_t ThisUncheckedOrChecked = (*UncheckedOrChecked == Cns_CHECKED) ? Cns_UNCHECKED :
Cns_CHECKED;
2019-10-26 22:49:13 +02:00
HTM_LI_Begin (NULL);
HTM_LABEL_Begin (NULL);
HTM_INPUT_RADIO ("RegRemAction",HTM_DONT_SUBMIT_ON_CLICK,
"value=\"%u\"%s",
(unsigned) RegRemOneUsrAction,
HTM_CheckedTxt[ThisUncheckedOrChecked]);
*UncheckedOrChecked = Cns_CHECKED;
2019-03-10 14:44:12 +01:00
}
static void Enr_RegRemOneUsrActionEnd (void)
2019-03-10 14:44:12 +01:00
{
HTM_LABEL_End ();
2019-10-26 22:49:13 +02:00
HTM_LI_End ();
2019-03-10 14:44:12 +01:00
}
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
/********************** Register a user using his/her ID *********************/
/*****************************************************************************/
// If user does not exists, UsrDat->IDs must hold the user's ID
static void Enr_RegisterUsr (struct Usr_Data *UsrDat,Rol_Role_t RegRemRole,
2014-12-12 18:52:06 +01:00
struct ListCodGrps *LstGrps,unsigned *NumUsrsRegistered)
{
/***** Check if I can register this user *****/
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged == Rol_TCH &&
2017-05-18 19:13:41 +02:00
RegRemRole != Rol_STD)
Err_ShowErrorAndExit ("A teacher only can register several users as students.");
2014-12-12 18:52:06 +01:00
/***** Check if the record of the user exists and get the type of user *****/
if (UsrDat->UsrCod > 0) // User exists in database
/* Get user's data */
Usr_GetAllUsrDataFromUsrCod (UsrDat,
Usr_DONT_GET_PREFS,
Usr_GET_ROLE_IN_CRS);
2014-12-12 18:52:06 +01:00
else // User does not exist in database, create it using his/her ID!
{
/* Reset user's data */
2014-12-12 18:52:06 +01:00
Usr_ResetUsrDataExceptUsrCodAndIDs (UsrDat); // It's necessary, because the same struct UsrDat was used for former user
/* User does not exist in database; list of IDs is initialized */
2014-12-12 18:52:06 +01:00
UsrDat->IDs.List[0].Confirmed = true; // If he/she is a new user ==> his/her ID will be stored as confirmed in database
Acc_CreateNewUsr (UsrDat,Usr_OTHER);
2014-12-12 18:52:06 +01:00
}
/***** Register user in current course in database *****/
if (Gbl.Hierarchy.Level == Hie_CRS) // Course selected
2014-12-12 18:52:06 +01:00
{
switch (Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
2016-12-17 21:36:57 +01:00
{
case Usr_BELONG:
if (RegRemRole != UsrDat->Roles.InCurrentCrs) // The role must be updated
/* Modify role */
Enr_ModifyRoleInCurrentCrs (UsrDat,RegRemRole);
break;
case Usr_DONT_BELONG: // User does not belong to this course
default:
/* Register user */
Enr_RegisterUsrInCurrentCrs (UsrDat,RegRemRole,
Enr_SET_ACCEPTED_TO_FALSE);
break;
2016-12-17 21:36:57 +01:00
}
2014-12-12 18:52:06 +01:00
/***** Register user in the selected groups *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.NumGrps) // If there are groups in the course
2014-12-12 18:52:06 +01:00
Grp_RegisterUsrIntoGroups (UsrDat,LstGrps);
}
(*NumUsrsRegistered)++;
}
/*****************************************************************************/
/****** Put a link (form) to remove all students in the current course *******/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
2015-11-20 14:44:54 +01:00
static void Enr_PutLinkToRemAllStdsThisCrs (void)
2014-12-12 18:52:06 +01:00
{
extern const char *Txt_Remove_all_students;
/***** Put form to remove all students in the current course *****/
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkIconText (ActReqRemAllStdCrs,NULL,
NULL,NULL,
"trash.svg",Ico_RED,
Txt_Remove_all_students,NULL);
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/************ Ask for removing all students from current course **************/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
void Enr_AskRemAllStdsThisCrs (void)
{
2017-01-31 09:42:54 +01:00
extern const char *Hlp_USERS_Administration_remove_all_students;
2017-01-31 00:48:33 +01:00
extern const char *Txt_Remove_all_students;
2014-12-12 18:52:06 +01:00
extern const char *Txt_Do_you_really_want_to_remove_the_X_students_from_the_course_Y_;
unsigned NumStds = Enr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Node[Hie_CRS].HieCod,
2020-01-08 23:49:04 +01:00
1 << Rol_STD); // This course has students
2014-12-12 18:52:06 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
Box_BoxBegin (Txt_Remove_all_students,NULL,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Administration_remove_all_students,Box_NOT_CLOSABLE);
2017-01-31 00:48:33 +01:00
if (NumStds)
{
/***** Show question and button to remove students *****/
/* Begin alert */
Ale_ShowAlertAndButtonBegin (Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_X_students_from_the_course_Y_,
NumStds,
Gbl.Hierarchy.Node[Hie_CRS].FullName);
/* Show form to request confirmation */
Frm_BeginForm (ActRemAllStdCrs);
Grp_PutParAllGroups ();
Pwd_AskForConfirmationOnDangerousAction ();
Btn_PutRemoveButton (Txt_Remove_all_students);
Frm_EndForm ();
2017-04-28 10:02:17 +02:00
/* End alert */
Ale_ShowAlertAndButtonEnd (ActUnk,NULL,NULL,
NULL,NULL,
Btn_NO_BUTTON,NULL);
}
else // Gbl.Hierarchy.Node[Hie_CRS].NumUsrs[Rol_STD] == 0
/***** Show warning indicating no students found *****/
Usr_ShowWarningNoUsersFound (Rol_STD);
2017-01-31 00:48:33 +01:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/******************* Remove all students from current course *****************/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
void Enr_RemAllStdsThisCrs (void)
{
extern const char *Txt_The_X_students_who_belonged_to_the_course_Y_have_been_removed_from_it;
unsigned NumStdsInCrs;
if (Pwd_GetConfirmationOnDangerousAction ())
{
if ((NumStdsInCrs = Enr_RemAllStdsInCrs (&Gbl.Hierarchy.Node[Hie_CRS])))
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_The_X_students_who_belonged_to_the_course_Y_have_been_removed_from_it,
NumStdsInCrs,Gbl.Hierarchy.Node[Hie_CRS].FullName);
2017-05-29 21:34:43 +02:00
else // NumStdsInCrs == 0
2017-02-09 19:27:18 +01:00
/***** Show warning indicating no students found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_STD);
2014-12-12 18:52:06 +01:00
}
}
/*****************************************************************************/
/******************* Remove all students from a given course *****************/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
// Returns the numbers of students in list
2014-12-12 18:52:06 +01:00
unsigned Enr_RemAllStdsInCrs (struct Hie_Node *Crs)
2014-12-12 18:52:06 +01:00
{
unsigned NumStdsInCrs;
unsigned NumUsr;
/***** Get list of students in current course *****/
Gbl.Crs.Grps.AllGrps = true; // Get all students of the current course
Usr_GetListUsrs (Hie_CRS,Rol_STD);
2017-05-18 19:13:41 +02:00
NumStdsInCrs = Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs;
2014-12-12 18:52:06 +01:00
/***** Remove all students *****/
2014-12-12 18:52:06 +01:00
for (NumUsr = 0;
NumUsr < NumStdsInCrs;
NumUsr++)
{
2017-05-18 19:13:41 +02:00
Gbl.Usrs.Other.UsrDat.UsrCod = Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumUsr].UsrCod;
Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs = Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumUsr].RoleInCurrentCrsDB;
2014-12-12 18:52:06 +01:00
Enr_EffectivelyRemUsrFromCrs (&Gbl.Usrs.Other.UsrDat,Crs,
2019-09-29 23:13:20 +02:00
Enr_REMOVE_USR_PRODUCTION,
Cns_QUIET);
2014-12-12 18:52:06 +01:00
}
/***** Free memory for students list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_STD);
2014-12-12 18:52:06 +01:00
return NumStdsInCrs;
}
/*****************************************************************************/
/************* Form to request sign up in the current course *****************/
/*****************************************************************************/
void Enr_ReqSignUpInCrs (void)
{
2017-03-30 11:20:06 +02:00
extern const char *Txt_You_were_already_enroled_as_X_in_the_course_Y;
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2014-12-12 18:52:06 +01:00
/***** Check if I already belong to course *****/
if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs >= Rol_STD)
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_You_were_already_enroled_as_X_in_the_course_Y,
Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs][Gbl.Usrs.Me.UsrDat.Sex],
Gbl.Hierarchy.Node[Hie_CRS].FullName);
2017-06-04 18:18:54 +02:00
else if (Gbl.Usrs.Me.Role.Logged == Rol_GST ||
Gbl.Usrs.Me.Role.Logged == Rol_USR)
2014-12-12 18:52:06 +01:00
/***** Show form to modify only the user's role or the user's data *****/
2017-05-30 02:17:33 +02:00
Rec_ShowFormSignUpInCrsWithMySharedRecord ();
2014-12-12 18:52:06 +01:00
else
Err_ShowErrorAndExit ("You must be logged to sign up in a course."); // This never should happen
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/*********************** Sign up in the current course ***********************/
/*****************************************************************************/
void Enr_SignUpInCrs (void)
{
2017-03-30 11:20:06 +02:00
extern const char *Txt_You_were_already_enroled_as_X_in_the_course_Y;
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2017-03-30 11:20:06 +02:00
extern const char *Txt_Your_request_for_enrolment_as_X_in_the_course_Y_has_been_accepted_for_processing;
2014-12-12 18:52:06 +01:00
Rol_Role_t RoleFromForm;
2020-01-23 22:49:58 +01:00
bool Notify;
2014-12-12 18:52:06 +01:00
long ReqCod = -1L;
/***** Check if I already belong to course *****/
if (Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs >= Rol_STD)
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_You_were_already_enroled_as_X_in_the_course_Y,
Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs][Gbl.Usrs.Me.UsrDat.Sex],
Gbl.Hierarchy.Node[Hie_CRS].FullName);
2014-12-12 18:52:06 +01:00
else
{
/***** Get new role from record form *****/
2017-01-29 21:41:08 +01:00
RoleFromForm = (Rol_Role_t)
Par_GetParUnsignedLong ("Role",
0,
Rol_NUM_ROLES - 1,
(unsigned long) Rol_UNK);
2014-12-12 18:52:06 +01:00
/* Check if role is correct */
2017-05-18 19:13:41 +02:00
if (!(RoleFromForm == Rol_STD ||
2017-05-22 00:51:45 +02:00
RoleFromForm == Rol_NET ||
2017-05-18 19:13:41 +02:00
RoleFromForm == Rol_TCH))
Err_WrongRoleExit ();
2014-12-12 18:52:06 +01:00
/***** Try to get and old request of the same user (me) in the current course *****/
ReqCod = Enr_DB_GetUsrEnrolmentRequestInCrs (Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Hierarchy.Node[Hie_CRS].HieCod);
2014-12-12 18:52:06 +01:00
/***** Request user in current course in database *****/
if (ReqCod > 0) // Old request exists in database
Enr_DB_UpdateMyEnrolmentRequestInCurrentCrs (ReqCod,RoleFromForm);
else // No request in database for this user in this course
ReqCod = Enr_DB_CreateMyEnrolmentRequestInCurrentCrs (RoleFromForm);
2014-12-12 18:52:06 +01:00
/***** Show confirmation message *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_Your_request_for_enrolment_as_X_in_the_course_Y_has_been_accepted_for_processing,
2019-02-16 01:20:54 +01:00
Txt_ROLES_SINGUL_abc[RoleFromForm][Gbl.Usrs.Me.UsrDat.Sex],
Gbl.Hierarchy.Node[Hie_CRS].FullName);
2014-12-12 18:52:06 +01:00
2017-03-30 11:20:06 +02:00
/***** Notify teachers or admins by email about the new enrolment request *****/
2020-01-23 22:49:58 +01:00
// If I want to be a teacher ==> send notification to other teachers, administrators or superusers
2014-12-12 18:52:06 +01:00
// If this course has teachers ==> send notification to teachers
2020-01-23 22:49:58 +01:00
if (RoleFromForm == Rol_TCH)
Notify = true;
else
Notify = (Enr_GetNumUsrsInCrss (Hie_CRS,Gbl.Hierarchy.Node[Hie_CRS].HieCod,
2020-01-23 22:49:58 +01:00
1 << Rol_TCH) != 0); // This course has teachers
if (Notify)
Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_ENROLMENT_REQUEST,ReqCod);
2014-12-12 18:52:06 +01:00
}
}
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
/************** Put an enrolment request into a notification *****************/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
void Enr_GetNotifEnrolmentRequest (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1],
char **ContentStr,
long ReqCod,Ntf_GetContent_t GetContent)
2014-12-12 18:52:06 +01:00
{
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2014-12-12 18:52:06 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
struct Usr_Data UsrDat;
2014-12-12 18:52:06 +01:00
Rol_Role_t DesiredRole;
SummaryStr[0] = '\0'; // Return nothing on error
/***** Get user and requested role from database *****/
if (Enr_DB_GetEnrolmentRequestByCod (&mysql_res,ReqCod) == 1) // Result should have a unique row
2018-10-20 21:19:30 +02:00
{
/***** Get user and requested role *****/
row = mysql_fetch_row (mysql_res);
2014-12-12 18:52:06 +01:00
2018-10-20 21:19:30 +02:00
/* Initialize structure with user's data */
Usr_UsrDataConstructor (&UsrDat);
2014-12-12 18:52:06 +01:00
2018-10-20 21:19:30 +02:00
/* User's code (row[0]) */
UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CRS);
2018-10-20 21:19:30 +02:00
/* Role (row[1]) */
DesiredRole = Rol_ConvertUnsignedStrToRole (row[1]);
Str_Copy (SummaryStr,Txt_ROLES_SINGUL_Abc[DesiredRole][UsrDat.Sex],
Ntf_MAX_BYTES_SUMMARY);
if (GetContent == Ntf_GET_CONTENT)
2018-10-20 21:19:30 +02:00
/* Write desired role into content */
if (asprintf (ContentStr,
"%s", // TODO: Write more info in this content
Txt_ROLES_SINGUL_Abc[DesiredRole][UsrDat.Sex]) < 0)
Err_NotEnoughMemoryExit ();
2018-10-20 21:19:30 +02:00
/* Free memory used for user's data */
Usr_UsrDataDestructor (&UsrDat);
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
2017-04-28 09:43:32 +02:00
/******* Ask if reject the request for enrolment of a user in a course *******/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
void Enr_AskIfRejectSignUp (void)
{
2017-03-30 11:20:06 +02:00
extern const char *Txt_THE_USER_X_is_already_enroled_in_the_course_Y;
extern const char *Txt_Do_you_really_want_to_reject_the_enrolment_request_;
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2014-12-12 18:52:06 +01:00
extern const char *Txt_Reject;
Rol_Role_t Role;
/***** Get user's code *****/
Usr_GetParOtherUsrCodEncryptedAndGetListIDs ();
2014-12-12 18:52:06 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CRS))
// User's data exist...
switch (Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat))
{
case Usr_BELONG:
/* User already belongs to this course */
Ale_ShowAlert (Ale_WARNING,Txt_THE_USER_X_is_already_enroled_in_the_course_Y,
Gbl.Usrs.Other.UsrDat.FullName,
Gbl.Hierarchy.Node[Hie_CRS].FullName);
Rec_ShowSharedRecordUnmodifiable (&Gbl.Usrs.Other.UsrDat);
2014-12-12 18:52:06 +01:00
/* Remove inscription request because it has not sense */
Enr_RemUsrEnrolmentRequestInCrs (Gbl.Usrs.Other.UsrDat.UsrCod,
Gbl.Hierarchy.Node[Hie_CRS].HieCod);
break;
case Usr_DONT_BELONG: // User does not belong to this course
default:
Role = Rol_DB_GetRequestedRole (Gbl.Hierarchy.Node[Hie_CRS].HieCod,
Gbl.Usrs.Other.UsrDat.UsrCod);
if (Role == Rol_STD ||
Role == Rol_NET ||
Role == Rol_TCH)
{
/***** Show question and button to reject user's enrolment request *****/
/* Begin alert */
Ale_ShowAlertAndButtonBegin (Ale_QUESTION,Txt_Do_you_really_want_to_reject_the_enrolment_request_,
Gbl.Usrs.Other.UsrDat.FullName,
Txt_ROLES_SINGUL_abc[Role][Gbl.Usrs.Other.UsrDat.Sex],
Gbl.Hierarchy.Node[Hie_CRS].FullName);
/* Show user's record */
Rec_ShowSharedRecordUnmodifiable (&Gbl.Usrs.Other.UsrDat);
/* End alert */
Ale_ShowAlertAndButtonEnd (ActRejSignUp,NULL,NULL,
Usr_PutParOtherUsrCodEncrypted,Gbl.Usrs.Other.UsrDat.EnUsrCod,
Btn_REMOVE_BUTTON,Txt_Reject);
}
else
Err_WrongRoleExit ();
break;
2014-12-12 18:52:06 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
/********* Reject the request for enrolment of a user in a course ***********/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
void Enr_RejectSignUp (void)
{
2017-03-30 11:20:06 +02:00
extern const char *Txt_THE_USER_X_is_already_enroled_in_the_course_Y;
extern const char *Txt_Enrolment_of_X_rejected;
2014-12-12 18:52:06 +01:00
/***** Get user's code *****/
Usr_GetParOtherUsrCodEncryptedAndGetListIDs ();
2014-12-12 18:52:06 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CRS))
2014-12-12 18:52:06 +01:00
{
// User's data exist...
if (Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat) == Usr_BELONG)
2014-12-12 18:52:06 +01:00
{
/* User already belongs to this course */
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_THE_USER_X_is_already_enroled_in_the_course_Y,
Gbl.Usrs.Other.UsrDat.FullName,
Gbl.Hierarchy.Node[Hie_CRS].FullName);
2016-11-18 01:07:00 +01:00
Rec_ShowSharedRecordUnmodifiable (&Gbl.Usrs.Other.UsrDat);
2014-12-12 18:52:06 +01:00
}
/* Remove inscription request */
Enr_RemUsrEnrolmentRequestInCrs (Gbl.Usrs.Other.UsrDat.UsrCod,
Gbl.Hierarchy.Node[Hie_CRS].HieCod);
2014-12-12 18:52:06 +01:00
/* Confirmation message */
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_Enrolment_of_X_rejected,
2019-02-16 01:20:54 +01:00
Gbl.Usrs.Other.UsrDat.FullName);
2014-12-12 18:52:06 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2014-12-12 18:52:06 +01:00
/* Show again the rest of registrarion requests */
2017-03-30 11:20:06 +02:00
Enr_ShowEnrolmentRequests ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
/******** Show pending requests for enrolment in the current course *********/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
void Enr_ShowEnrolmentRequests (void)
2016-03-24 15:09:52 +01:00
{
2017-03-30 11:20:06 +02:00
/***** Show enrolment request (default roles depend on my logged role) *****/
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2016-03-24 15:09:52 +01:00
{
2017-05-18 19:13:41 +02:00
case Rol_TCH:
Enr_ShowEnrolmentRequestsGivenRoles ((1 << Rol_STD) |
2017-05-22 00:51:45 +02:00
(1 << Rol_NET) |
(1 << Rol_TCH));
2016-03-24 15:09:52 +01:00
break;
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
2017-05-22 00:51:45 +02:00
Enr_ShowEnrolmentRequestsGivenRoles ((1 << Rol_NET) |
(1 << Rol_TCH));
2016-03-24 15:09:52 +01:00
break;
default:
Err_NoPermissionExit ();
2016-03-24 15:09:52 +01:00
break;
}
}
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
/******* Update pending requests for enrolment in the current course ********/
2016-03-24 15:09:52 +01:00
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
void Enr_UpdateEnrolmentRequests (void)
2016-03-24 15:09:52 +01:00
{
2016-03-24 17:12:01 +01:00
unsigned RolesSelected;
2016-03-24 15:09:52 +01:00
/***** Get selected roles *****/
2016-03-24 17:12:01 +01:00
RolesSelected = Rol_GetSelectedRoles ();
2016-03-24 15:09:52 +01:00
2017-03-30 11:20:06 +02:00
/***** Update enrolment requests *****/
Enr_ShowEnrolmentRequestsGivenRoles (RolesSelected);
2016-03-24 15:09:52 +01:00
}
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
/************* Show pending requests for enrolment given roles **************/
2016-03-24 15:09:52 +01:00
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
static void Enr_ShowEnrolmentRequestsGivenRoles (unsigned RolesSelected)
2014-12-12 18:52:06 +01:00
{
extern bool (*Hie_GetDataByCod[Hie_NUM_LEVELS]) (struct Hie_Node *Node);
2016-11-21 19:47:44 +01:00
extern const char *Hlp_USERS_Requests;
2017-03-30 11:20:06 +02:00
extern const char *Txt_Enrolment_requests;
2014-12-12 18:52:06 +01:00
extern const char *Txt_Scope;
extern const char *Txt_Users;
extern const char *Txt_HIERARCHY_SINGUL_Abc[Hie_NUM_LEVELS];
2017-05-30 21:43:05 +02:00
extern const char *Txt_ROLES_PLURAL_BRIEF_Abc[Rol_NUM_ROLES];
2014-12-12 18:52:06 +01:00
extern const char *Txt_Requester;
extern const char *Txt_Role;
extern const char *Txt_Date;
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2014-12-12 18:52:06 +01:00
extern const char *Txt_Register;
extern const char *Txt_Reject;
2017-03-30 11:20:06 +02:00
extern const char *Txt_No_enrolment_requests;
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
};
2014-12-12 18:52:06 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumReqs;
unsigned NumReq;
2014-12-12 18:52:06 +01:00
long ReqCod;
struct Hie_Node Deg;
struct Hie_Node Crs;
struct Usr_Data UsrDat;
2014-12-12 18:52:06 +01:00
bool UsrExists;
Usr_Belong_t UsrBelongsToCrs;
2014-12-12 18:52:06 +01:00
Rol_Role_t DesiredRole;
static Act_Action_t NextAction[Rol_NUM_ROLES] =
{
[Rol_STD] = ActReqMdfStd,
[Rol_NET] = ActReqMdfNET,
[Rol_TCH] = ActReqMdfTch,
};
2014-12-12 18:52:06 +01:00
2017-03-30 11:20:06 +02:00
/***** Remove expired enrolment requests *****/
Enr_DB_RemoveExpiredEnrolmentRequests ();
2016-03-27 20:33:39 +02:00
2016-03-24 16:49:36 +01:00
/***** Get scope *****/
Gbl.Scope.Allowed = 1 << Hie_SYS |
1 << Hie_CTY |
1 << Hie_INS |
1 << Hie_CTR |
1 << Hie_DEG |
1 << Hie_CRS;
Sco_GetScope ("ScopeEnr",Hie_CRS);
2016-03-24 16:49:36 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
Box_BoxBegin (Txt_Enrolment_requests,NULL,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Requests,Box_NOT_CLOSABLE);
2015-10-04 16:24:10 +02:00
/***** Selection of scope and roles *****/
/* Begin form and table */
Frm_BeginForm (ActUpdSignUpReq);
HTM_TABLE_BeginWideMarginPadding (2);
2014-12-12 18:52:06 +01:00
/* Scope (whole platform, current center, current degree or current course) */
HTM_TR_Begin (NULL);
2019-10-07 08:55:06 +02:00
/* Label */
Frm_LabelColumn ("RT","ScopeEnr",Txt_Scope);
2019-10-07 08:55:06 +02:00
/* Data */
HTM_TD_Begin ("class=\"LM\"");
Sco_PutSelectorScope ("ScopeEnr",HTM_SUBMIT_ON_CHANGE);
HTM_TD_End ();
2019-10-07 08:55:06 +02:00
HTM_TR_End ();
2014-12-12 18:52:06 +01:00
/* Users' roles in listing */
HTM_TR_Begin (NULL);
2019-10-07 08:55:06 +02:00
Frm_LabelColumn ("RT","Role",Txt_Users);
2019-10-07 08:55:06 +02:00
HTM_TD_Begin ("class=\"LT DAT_%s\"",The_GetSuffix ());
Rol_WriteSelectorRoles (1 << Rol_STD |
1 << Rol_NET |
1 << Rol_TCH,
RolesSelected,
Cns_DISABLED,
HTM_SUBMIT_ON_CHANGE);
HTM_TD_End ();
2019-10-07 08:55:06 +02:00
HTM_TR_End ();
2015-03-24 20:26:31 +01:00
/* End table and form */
HTM_TABLE_End ();
Frm_EndForm ();
2014-12-12 18:52:06 +01:00
/***** List requests *****/
if ((NumReqs = Enr_DB_GetEnrolmentRequests (&mysql_res,RolesSelected)))
{
/* Initialize structure with user's data */
Usr_UsrDataConstructor (&UsrDat);
/* Begin table */
HTM_TABLE_BeginCenterPadding (2);
/* Table heading */
HTM_TR_Begin (NULL);
HTM_TH_Empty (1);
HTM_TH (Txt_HIERARCHY_SINGUL_Abc[Hie_CRS] ,HTM_HEAD_LEFT );
HTM_TH (Txt_ROLES_PLURAL_BRIEF_Abc[Rol_TCH],HTM_HEAD_RIGHT );
HTM_TH_Span (Txt_Requester ,HTM_HEAD_LEFT ,1,2,NULL);
HTM_TH (Txt_Role ,HTM_HEAD_LEFT );
HTM_TH (Txt_Date ,HTM_HEAD_CENTER);
HTM_TH_Empty (2);
HTM_TR_End ();
/* List requests */
for (NumReq = 0;
NumReq < NumReqs;
NumReq++)
{
row = mysql_fetch_row (mysql_res);
/* Get request code (row[0]) */
ReqCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get course code (row[1]) */
Crs.HieCod = Str_ConvertStrCodToLongCod (row[1]);
/* Get user code (row[2]) */
UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[2]);
UsrExists = Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CRS);
/***** Get requested role (row[3]) *****/
DesiredRole = Rol_ConvertUnsignedStrToRole (row[3]);
if (UsrExists)
UsrBelongsToCrs = Hie_CheckIfUsrBelongsTo (Hie_CRS,
UsrDat.UsrCod,
Crs.HieCod,
false);
else
UsrBelongsToCrs = Usr_DONT_BELONG;
if (UsrExists &&
UsrBelongsToCrs == Usr_DONT_BELONG &&
(DesiredRole == Rol_STD ||
DesiredRole == Rol_NET ||
DesiredRole == Rol_TCH))
{
HTM_TR_Begin (NULL);
/***** Number *****/
HTM_TD_Begin ("class=\"RT DAT_%s\"",
The_GetSuffix ());
HTM_Unsigned (NumReqs - NumReq);
HTM_TD_End ();
/***** Link to course *****/
HTM_TD_Begin ("class=\"LT DAT_%s\"",The_GetSuffix ());
Hie_GetDataByCod[Hie_CRS] (&Crs);
Deg.HieCod = Crs.PrtCod;
Hie_GetDataByCod[Hie_DEG] (&Deg);
Frm_BeginFormGoTo (ActSeeCrsInf);
ParCod_PutPar (ParCod_Crs,Crs.HieCod);
HTM_BUTTON_Submit_Begin (Str_BuildGoToTitle (Crs.FullName),
"class=\"LT BT_LINK\"");
Str_FreeGoToTitle ();
HTM_TxtF ("%s &gt; %s",Deg.ShrtName,Crs.ShrtName);
HTM_BUTTON_End ();
Frm_EndForm ();
HTM_TD_End ();
/***** Number of teachers in the course *****/
HTM_TD_Begin ("class=\"RT DAT_%s\"",
The_GetSuffix ());
HTM_Unsigned (Enr_GetNumUsrsInCrss (Hie_CRS,Crs.HieCod,
1 << Rol_TCH));
HTM_TD_End ();
/***** User photo *****/
HTM_TD_Begin ("class=\"CT DAT_%s\" style=\"width:22px;\"",
The_GetSuffix ());
Pho_ShowUsrPhotoIfAllowed (&UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
HTM_TD_End ();
/***** User name *****/
HTM_TD_Begin ("class=\"LT DAT_%s\"",
The_GetSuffix ());
HTM_DIV_Begin ("class=\"REQUESTER_NAME\""); // Limited width
Usr_WriteFirstNameBRSurnames (&UsrDat);
HTM_DIV_End ();
HTM_TD_End ();
/***** Requested role (row[3]) *****/
HTM_TD_Begin ("class=\"LT DAT_%s\"",
The_GetSuffix ());
HTM_Txt (Txt_ROLES_SINGUL_abc[DesiredRole][UsrDat.Sex]);
HTM_TD_End ();
/***** Request time (row[4]) *****/
Msg_WriteMsgDate (Dat_GetUNIXTimeFromStr (row[4]),
"DAT",The_GetColorRows ());
/***** Button to confirm the request *****/
HTM_TD_Begin ("class=\"LT DAT_%s\"",
The_GetSuffix ());
if (!NextAction[DesiredRole])
Err_WrongRoleExit ();
Frm_BeginForm (NextAction[DesiredRole]);
ParCod_PutPar (ParCod_Crs,Crs.HieCod);
Usr_PutParUsrCodEncrypted (UsrDat.EnUsrCod);
Btn_PutCreateButtonInline (Txt_Register);
Frm_EndForm ();
HTM_TD_End ();
/***** Button to reject the request *****/
HTM_TD_Begin ("class=\"LT DAT_%s\"",
The_GetSuffix ());
Frm_BeginForm (ActReqRejSignUp);
ParCod_PutPar (ParCod_Crs,Crs.HieCod);
Usr_PutParUsrCodEncrypted (UsrDat.EnUsrCod);
Btn_PutRemoveButtonInline (Txt_Reject);
Frm_EndForm ();
HTM_TD_End ();
HTM_TR_End ();
/***** Mark possible notification as seen *****/
Ntf_DB_MarkNotifAsSeenUsingCod (Ntf_EVENT_ENROLMENT_REQUEST,
ReqCod);
}
else // User does not exists or user already belongs to course ==> remove pair from crs_requests table
Enr_RemUsrEnrolmentRequestInCrs (UsrDat.UsrCod,Crs.HieCod);
}
2014-12-12 18:52:06 +01:00
/* End table */
HTM_TABLE_End ();
2014-12-12 18:52:06 +01:00
/* Free memory used for user's data */
Usr_UsrDataDestructor (&UsrDat);
}
else // There are no requests
Ale_ShowAlert (Ale_INFO,Txt_No_enrolment_requests);
2015-10-04 16:24:10 +02:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
/********************* Remove a request for enrolment ***********************/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
static void Enr_RemUsrEnrolmentRequestInCrs (long UsrCod,long CrsCod)
2014-12-12 18:52:06 +01:00
{
long ReqCod;
/***** Get request code *****/
ReqCod = Enr_DB_GetUsrEnrolmentRequestInCrs (UsrCod,CrsCod);
if (ReqCod > 0)
{
/***** Mark possible notifications as removed
Important: do this before removing the request *****/
Ntf_DB_MarkNotifAsRemoved (Ntf_EVENT_ENROLMENT_REQUEST,ReqCod);
/***** Remove enrolment request *****/
Enr_DB_RemRequest (ReqCod);
}
2014-12-12 18:52:06 +01:00
}
2014-12-31 01:32:42 +01:00
/*****************************************************************************/
/********************** Write a form to admin one user ***********************/
/*****************************************************************************/
2015-09-12 14:12:40 +02:00
void Enr_PutLinkToAdminOneUsr (Act_Action_t NextAction)
2014-12-31 01:32:42 +01:00
{
2017-01-31 00:25:10 +01:00
extern const char *Txt_Administer_me;
extern const char *Txt_Administer_one_user;
static const char **TitleText[] =
{
[Usr_CAN_NOT] = &Txt_Administer_me,
[Usr_CAN ] = &Txt_Administer_one_user,
};
2014-12-31 01:32:42 +01:00
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkIconText (NextAction,NULL,
NULL,NULL,
"user-cog.svg",Ico_BLACK,
*TitleText[Adm_CheckIfICanAdminOtherUsrs ()],NULL);
2014-12-31 01:32:42 +01:00
}
2015-02-08 19:11:54 +01:00
/*****************************************************************************/
/******************* Write a form to admin several users *********************/
/*****************************************************************************/
2015-09-14 09:32:27 +02:00
void Enr_PutLinkToAdminSeveralUsrs (Rol_Role_t Role)
2015-02-08 19:11:54 +01:00
{
2017-01-31 00:25:10 +01:00
extern const char *Txt_Administer_multiple_students;
2017-05-29 22:07:43 +02:00
extern const char *Txt_Administer_multiple_non_editing_teachers;
2017-01-31 00:25:10 +01:00
extern const char *Txt_Administer_multiple_teachers;
static const struct
2017-05-21 19:25:46 +02:00
{
Act_Action_t NextAction;
const char **Title;
} WhatToDo[Rol_NUM_ROLES] =
{
[Rol_STD] = {ActReqEnrSevStd,&Txt_Administer_multiple_students },
[Rol_NET] = {ActReqEnrSevNET,&Txt_Administer_multiple_non_editing_teachers},
[Rol_TCH] = {ActReqEnrSevTch,&Txt_Administer_multiple_teachers },
};
if (!WhatToDo[Role].NextAction)
Err_WrongRoleExit ();
Lay_PutContextualLinkIconText (WhatToDo[Role].NextAction,NULL,
2020-03-26 02:54:30 +01:00
NULL,NULL,
"users-cog.svg",Ico_BLACK,
*WhatToDo[Role].Title,NULL);
2015-02-08 19:11:54 +01:00
}
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
/************** Form to request the user's ID of another user ****************/
/*****************************************************************************/
2015-09-17 16:54:02 +02:00
void Enr_ReqRegRemOth (void)
2015-09-12 14:12:40 +02:00
{
2017-05-29 22:07:43 +02:00
/***** Form to request user to be administered *****/
2017-05-18 19:13:41 +02:00
Enr_ReqRegRemUsr (Rol_GST);
2015-09-12 14:12:40 +02:00
}
void Enr_ReqRegRemStd (void)
{
2019-10-24 09:46:20 +02:00
/***** Contextual menu *****/
if (Adm_CheckIfICanAdminOtherUsrs () == Usr_CAN)
2019-01-11 12:59:41 +01:00
{
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuBegin ();
Enr_PutLinkToAdminSeveralUsrs (Rol_STD); // Admin several students
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuEnd ();
2019-01-11 12:59:41 +01:00
}
2017-05-29 22:07:43 +02:00
/***** Form to request user to be administered *****/
2017-05-18 19:13:41 +02:00
Enr_ReqRegRemUsr (Rol_STD);
2015-09-12 14:12:40 +02:00
}
void Enr_ReqRegRemTch (void)
{
2017-05-29 22:07:43 +02:00
/***** Form to request user to be administered *****/
2017-05-18 19:13:41 +02:00
Enr_ReqRegRemUsr (Rol_TCH);
2015-09-12 14:12:40 +02:00
}
static void Enr_ReqRegRemUsr (Rol_Role_t Role)
2014-12-12 18:52:06 +01:00
{
switch (Adm_CheckIfICanAdminOtherUsrs ())
{
case Usr_CAN:
/***** Form to request the user's ID of another user *****/
Enr_ReqAnotherUsrIDToRegisterRemove (Role);
break;
case Usr_CAN_NOT:
default:
/***** Form to request if register/remove me *****/
Enr_AskIfRegRemMe (Role);
break;
}
2015-09-16 00:15:20 +02:00
}
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
2016-11-16 23:19:52 +01:00
/****** Write a form to request another user's ID, @nickname or email ********/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
2015-09-12 14:12:40 +02:00
static void Enr_ReqAnotherUsrIDToRegisterRemove (Rol_Role_t Role)
2014-12-12 18:52:06 +01:00
{
2017-01-31 00:25:10 +01:00
extern const char *Hlp_USERS_Administration_administer_one_user;
extern const char *Txt_Administer_one_user;
static Act_Action_t NextAction[Rol_NUM_ROLES] =
{
[Rol_GST] = ActReqMdfOth,
[Rol_STD] = ActReqMdfStd,
[Rol_NET] = ActReqMdfNET,
[Rol_TCH] = ActReqMdfTch,
};
2014-12-12 18:52:06 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
Box_BoxBegin (Txt_Administer_one_user,NULL,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Administration_administer_one_user,Box_NOT_CLOSABLE);
2014-12-12 18:52:06 +01:00
/***** Write form to request another user's ID *****/
if (!NextAction[Role])
Err_WrongRoleExit ();
Enr_WriteFormToReqAnotherUsrID (NextAction[Role],NULL);
2015-02-08 18:45:13 +01:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/********************** Ask me for register/remove me ************************/
/*****************************************************************************/
2015-09-12 14:12:40 +02:00
static void Enr_AskIfRegRemMe (Rol_Role_t Role)
2014-12-12 18:52:06 +01:00
{
struct Usr_ListUsrCods ListUsrCods;
2014-12-12 18:52:06 +01:00
/***** I only can admin me *****/
Gbl.Usrs.Other.UsrDat.UsrCod = Gbl.Usrs.Me.UsrDat.UsrCod;
ListUsrCods.NumUsrs = 1;
Usr_AllocateListUsrCods (&ListUsrCods);
ListUsrCods.Lst[0] = Gbl.Usrs.Other.UsrDat.UsrCod;
2015-09-12 14:12:40 +02:00
Enr_AskIfRegRemUsr (&ListUsrCods,Role);
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/****************** Ask me for register/remove another user ******************/
/*****************************************************************************/
2015-09-17 16:54:02 +02:00
void Enr_AskIfRegRemAnotherOth (void)
2015-09-12 14:12:40 +02:00
{
2017-05-18 19:13:41 +02:00
Enr_AskIfRegRemAnotherUsr (Rol_GST);
2015-09-12 14:12:40 +02:00
}
void Enr_AskIfRegRemAnotherStd (void)
{
2017-05-18 19:13:41 +02:00
Enr_AskIfRegRemAnotherUsr (Rol_STD);
2015-09-12 14:12:40 +02:00
}
void Enr_AskIfRegRemAnotherTch (void)
{
2017-05-18 19:13:41 +02:00
Enr_AskIfRegRemAnotherUsr (Rol_TCH);
2015-09-12 14:12:40 +02:00
}
static void Enr_AskIfRegRemAnotherUsr (Rol_Role_t Role)
2014-12-12 18:52:06 +01:00
{
struct Usr_ListUsrCods ListUsrCods;
2014-12-12 18:52:06 +01:00
/***** Check if UsrCod is present in parameters *****/
Usr_GetParOtherUsrCodEncryptedAndGetListIDs ();
2014-12-12 18:52:06 +01:00
if (Gbl.Usrs.Other.UsrDat.UsrCod > 0)
{
/***** If UsrCod is present in parameters,
2017-03-30 11:20:06 +02:00
use this parameter to identify the user to be enroled / removed *****/
2014-12-12 18:52:06 +01:00
ListUsrCods.NumUsrs = 1;
Usr_AllocateListUsrCods (&ListUsrCods);
ListUsrCods.Lst[0] = Gbl.Usrs.Other.UsrDat.UsrCod;
}
else // Parameter with user code not present
/***** If UsrCod is not present in parameters from form,
2017-03-30 11:20:06 +02:00
use user's ID to identify the user to be enroled /removed *****/
Usr_GetParOtherUsrIDNickOrEMailAndGetUsrCods (&ListUsrCods);
2014-12-12 18:52:06 +01:00
2015-09-12 14:12:40 +02:00
Enr_AskIfRegRemUsr (&ListUsrCods,Role);
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/********************** Ask me for register/remove user **********************/
/*****************************************************************************/
static void Enr_AskIfRegRemUsr (struct Usr_ListUsrCods *ListUsrCods,Rol_Role_t Role)
2014-12-12 18:52:06 +01:00
{
extern const char *Txt_There_are_X_users_with_the_ID_Y;
2017-01-27 10:42:20 +01:00
extern const char *Txt_The_user_is_new_not_yet_in_X;
2014-12-12 18:52:06 +01:00
extern const char *Txt_If_this_is_a_new_user_in_X_you_should_indicate_her_his_ID;
unsigned NumUsr;
bool NewUsrIDValid;
if (ListUsrCods->NumUsrs) // User(s) found with the ID
{
/***** Warning if more than one user found *****/
if (ListUsrCods->NumUsrs > 1)
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,Txt_There_are_X_users_with_the_ID_Y,
2019-02-16 01:20:54 +01:00
ListUsrCods->NumUsrs,Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail);
2014-12-12 18:52:06 +01:00
/***** For each user found... *****/
for (NumUsr = 0;
NumUsr < ListUsrCods->NumUsrs;
NumUsr++)
{
/* Get user's data */
Gbl.Usrs.Other.UsrDat.UsrCod = ListUsrCods->Lst[NumUsr];
Usr_GetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat,
Usr_DONT_GET_PREFS,
Usr_GET_ROLE_IN_CRS);
2014-12-12 18:52:06 +01:00
2019-03-09 22:01:06 +01:00
/* Show form to edit user */
Enr_ShowFormToEditOtherUsr ();
2014-12-12 18:52:06 +01:00
}
/***** Free list of users' codes *****/
Usr_FreeListUsrCods (ListUsrCods);
}
else // No users found, he/she is a new user
{
/***** If UsrCod is not present in parameters from form,
2017-03-30 11:20:06 +02:00
use user's ID to identify the user to be enroled *****/
2014-12-12 18:52:06 +01:00
if (Gbl.Usrs.Other.UsrDat.IDs.List)
NewUsrIDValid = ID_CheckIfUsrIDIsValid (Gbl.Usrs.Other.UsrDat.IDs.List[0].ID); // Check the first element of the list
else
NewUsrIDValid = false;
if (NewUsrIDValid)
{
/***** Show form to enter the data of a new user *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,Txt_The_user_is_new_not_yet_in_X,
2019-02-16 01:20:54 +01:00
Cfg_PLATFORM_SHORT_NAME);
2017-01-27 12:57:31 +01:00
Rec_ShowFormOtherNewSharedRecord (&Gbl.Usrs.Other.UsrDat,Role);
2014-12-12 18:52:06 +01:00
}
else // User's ID is not valid
{
/* Write message and request a new user's ID */
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_If_this_is_a_new_user_in_X_you_should_indicate_her_his_ID,
2019-02-16 01:20:54 +01:00
Cfg_PLATFORM_SHORT_NAME);
2015-09-12 14:12:40 +02:00
Enr_ReqRegRemUsr (Role);
2014-12-12 18:52:06 +01:00
}
}
}
/*****************************************************************************/
2019-03-09 22:01:06 +01:00
/********* Show other existing user's shared record to be edited *************/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
static void Enr_ShowFormToEditOtherUsr (void)
{
2019-03-09 22:01:06 +01:00
extern const char *Txt_THE_USER_X_is_already_enroled_in_the_course_Y;
extern const char *Txt_THE_USER_X_is_in_the_course_Y_but_has_not_yet_accepted_the_enrolment;
extern const char *Txt_THE_USER_X_exists_in_Y_but_is_not_enroled_in_the_course_Z;
extern const char *Txt_THE_USER_X_already_exists_in_Y;
/***** If user exists... *****/
if (Usr_DB_ChkIfUsrCodExists (Gbl.Usrs.Other.UsrDat.UsrCod))
2019-03-09 22:01:06 +01:00
{
/***** Show form to edit user *****/
if (Gbl.Hierarchy.Level == Hie_CRS) // Course selected
2019-03-09 22:01:06 +01:00
/* Check if this user belongs to the current course */
switch (Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat))
2019-03-09 22:01:06 +01:00
{
case Usr_BELONG:
Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat);
if (Gbl.Usrs.Other.UsrDat.Accepted)
Ale_ShowAlert (Ale_INFO,Txt_THE_USER_X_is_already_enroled_in_the_course_Y,
Gbl.Usrs.Other.UsrDat.FullName,
Gbl.Hierarchy.Node[Hie_CRS].FullName);
else // Enrolment not yet accepted
Ale_ShowAlert (Ale_INFO,Txt_THE_USER_X_is_in_the_course_Y_but_has_not_yet_accepted_the_enrolment,
Gbl.Usrs.Other.UsrDat.FullName,
Gbl.Hierarchy.Node[Hie_CRS].FullName);
Rec_ShowOtherSharedRecordEditable ();
break;
case Usr_DONT_BELONG: // User does not belong to the current course
default:
Ale_ShowAlert (Ale_INFO,Txt_THE_USER_X_exists_in_Y_but_is_not_enroled_in_the_course_Z,
Gbl.Usrs.Other.UsrDat.FullName,
Cfg_PLATFORM_SHORT_NAME,
Gbl.Hierarchy.Node[Hie_CRS].FullName);
2019-03-09 22:01:06 +01:00
Rec_ShowOtherSharedRecordEditable ();
break;
2019-03-09 22:01:06 +01:00
}
else // No course selected
{
Ale_ShowAlert (Ale_INFO,Txt_THE_USER_X_already_exists_in_Y,
Gbl.Usrs.Other.UsrDat.FullName,Cfg_PLATFORM_SHORT_NAME);
Rec_ShowOtherSharedRecordEditable ();
}
}
else
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/****************** Ask for remove me from current course ********************/
/*****************************************************************************/
void Enr_ReqRemMeFromCrs (void)
{
2017-06-04 15:11:41 +02:00
Enr_AskIfRemoveUsrFromCrs (&Gbl.Usrs.Me.UsrDat);
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/************** Ask for remove of a user from current course *****************/
/*****************************************************************************/
void Enr_ReqRemUsrFromCrs (void)
{
2017-06-04 15:11:41 +02:00
/***** Get user to be removed *****/
if (Usr_GetParOtherUsrCodEncryptedAndGetUsrData ())
switch (Enr_CheckIfICanRemUsrFromCrs ())
{
case Usr_CAN:
Enr_AskIfRemoveUsrFromCrs (&Gbl.Usrs.Other.UsrDat);
break;
case Usr_CAN_NOT:
default:
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
break;
}
2017-06-04 15:11:41 +02:00
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/********************* Remove a user from current course *********************/
/*****************************************************************************/
2017-06-04 15:11:41 +02:00
void Enr_RemUsrFromCrs1 (void)
2014-12-12 18:52:06 +01:00
{
if (Pwd_GetConfirmationOnDangerousAction ())
2017-06-04 15:11:41 +02:00
{
/***** Get user to be removed *****/
if (Usr_GetParOtherUsrCodEncryptedAndGetUsrData ())
switch (Enr_CheckIfICanRemUsrFromCrs ())
{
case Usr_CAN:
Enr_EffectivelyRemUsrFromCrs (&Gbl.Usrs.Other.UsrDat,
&Gbl.Hierarchy.Node[Hie_CRS],
Enr_DO_NOT_REMOVE_USR_PRODUCTION,
Cns_VERBOSE);
break;
case Usr_CAN_NOT:
default:
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
break;
}
2017-06-04 15:11:41 +02:00
else
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-06-04 15:11:41 +02:00
}
}
void Enr_RemUsrFromCrs2 (void)
{
2019-03-09 22:01:06 +01:00
/* Show possible alerts */
2019-03-09 20:12:44 +01:00
Ale_ShowAlerts (NULL);
2019-03-09 22:01:06 +01:00
/* Show form to edit user again */
Enr_ShowFormToEditOtherUsr ();
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
2017-06-04 15:11:41 +02:00
/*********** Check if I can remove another user in current course ************/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
static Usr_Can_t Enr_CheckIfICanRemUsrFromCrs (void)
2014-12-12 18:52:06 +01:00
{
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2014-12-12 18:52:06 +01:00
{
2017-06-04 15:11:41 +02:00
case Rol_STD:
case Rol_NET:
// A student or non-editing teacher can remove herself/himself
return (Usr_ItsMe (Gbl.Usrs.Other.UsrDat.UsrCod) == Usr_ME) ? Usr_CAN :
Usr_CAN_NOT;
2017-06-04 15:11:41 +02:00
case Rol_TCH:
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
// A teacher or administrator can remove anyone
return Usr_CAN;
2017-06-04 15:11:41 +02:00
default:
return Usr_CAN_NOT;
2014-12-12 18:52:06 +01:00
}
}
/*****************************************************************************/
2017-03-30 11:20:06 +02:00
/*************** Accept my enrolment in the current course ******************/
2014-12-12 18:52:06 +01:00
/*****************************************************************************/
void Enr_AcceptRegisterMeInCrs (void)
{
2017-03-30 11:20:06 +02:00
extern const char *Txt_You_have_confirmed_your_enrolment_in_the_course_X;
2014-12-12 18:52:06 +01:00
2017-03-30 11:20:06 +02:00
/***** Confirm my enrolment *****/
Enr_DB_AcceptUsrInCrs (Gbl.Usrs.Me.UsrDat.UsrCod,Gbl.Hierarchy.Node[Hie_CRS].HieCod);
2014-12-12 18:52:06 +01:00
2017-03-30 11:20:06 +02:00
/***** Mark all notifications about enrolment (as student or as teacher)
2015-09-17 20:41:31 +02:00
in current course as removed *****/
Ntf_DB_MarkNotifToOneUsrAsRemoved (Ntf_EVENT_ENROLMENT_STD,-1L,
2015-09-17 20:41:31 +02:00
Gbl.Usrs.Me.UsrDat.UsrCod);
Ntf_DB_MarkNotifToOneUsrAsRemoved (Ntf_EVENT_ENROLMENT_TCH,-1L,
2015-09-17 20:41:31 +02:00
Gbl.Usrs.Me.UsrDat.UsrCod);
2014-12-12 18:52:06 +01:00
/***** Confirmation message *****/
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_You_have_confirmed_your_enrolment_in_the_course_X,
Gbl.Hierarchy.Node[Hie_CRS].FullName);
2014-12-12 18:52:06 +01:00
}
/*****************************************************************************/
/******************* Create and show data from other user ********************/
/*****************************************************************************/
2016-12-17 22:20:31 +01:00
void Enr_CreateNewUsr1 (void)
2014-12-12 18:52:06 +01:00
{
2016-12-17 21:36:57 +01:00
extern const char *Txt_The_role_of_THE_USER_X_in_the_course_Y_has_changed_from_A_to_B;
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2017-03-30 11:20:06 +02:00
extern const char *Txt_THE_USER_X_has_been_enroled_in_the_course_Y;
2014-12-12 18:52:06 +01:00
extern const char *Txt_The_ID_X_is_not_valid;
2016-12-17 21:36:57 +01:00
Rol_Role_t OldRole;
2014-12-12 18:52:06 +01:00
Rol_Role_t NewRole;
static Act_Action_t Action[Rol_NUM_ROLES] =
{
[Rol_GST] = ActCreOth,
[Rol_STD] = ActCreStd,
[Rol_NET] = ActCreNET,
[Rol_TCH] = ActCreTch,
};
2014-12-12 18:52:06 +01:00
/***** Get user's ID from form *****/
ID_GetParOtherUsrIDPlain (); // User's ID was already modified and passed as a hidden parameter
2014-12-12 18:52:06 +01:00
if (ID_CheckIfUsrIDIsValid (Gbl.Usrs.Other.UsrDat.IDs.List[0].ID)) // User's ID valid
{
Gbl.Usrs.Other.UsrDat.UsrCod = -1L;
/***** Get new role *****/
NewRole = Rec_GetRoleFromRecordForm ();
/***** Get user's name from form *****/
Rec_GetUsrNameFromRecordForm (&Gbl.Usrs.Other.UsrDat);
/***** Create user *****/
Gbl.Usrs.Other.UsrDat.IDs.List[0].Confirmed = true; // User's ID will be stored as confirmed
Acc_CreateNewUsr (&Gbl.Usrs.Other.UsrDat,Usr_OTHER);
2014-12-12 18:52:06 +01:00
/***** Register user in current course in database *****/
if (Gbl.Hierarchy.Level == Hie_CRS) // Course selected
2014-12-12 18:52:06 +01:00
{
switch (Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat))
2016-12-17 21:36:57 +01:00
{
case Usr_BELONG:
OldRole = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs; // Remember old role before changing it
if (NewRole != OldRole) // The role must be updated
{
/* Modify role */
Enr_ModifyRoleInCurrentCrs (&Gbl.Usrs.Other.UsrDat,NewRole);
/* Success message */
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_The_role_of_THE_USER_X_in_the_course_Y_has_changed_from_A_to_B,
Gbl.Usrs.Other.UsrDat.FullName,
Gbl.Hierarchy.Node[Hie_CRS].FullName,
Txt_ROLES_SINGUL_abc[OldRole][Gbl.Usrs.Other.UsrDat.Sex],
Txt_ROLES_SINGUL_abc[NewRole][Gbl.Usrs.Other.UsrDat.Sex]);
}
break;
case Usr_DONT_BELONG: // User does not belong to current course
default:
/* Register user */
Enr_RegisterUsrInCurrentCrs (&Gbl.Usrs.Other.UsrDat,NewRole,
Enr_SET_ACCEPTED_TO_FALSE);
2016-12-17 21:36:57 +01:00
2016-12-17 22:20:31 +01:00
/* Success message */
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_THE_USER_X_has_been_enroled_in_the_course_Y,
2019-03-09 20:12:44 +01:00
Gbl.Usrs.Other.UsrDat.FullName,
Gbl.Hierarchy.Node[Hie_CRS].FullName);
break;
2016-12-17 20:44:13 +01:00
}
2017-06-04 18:18:54 +02:00
/***** Change user's groups *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.NumGrps) // This course has groups?
2017-06-04 18:18:54 +02:00
Grp_ChangeOtherUsrGrps ();
2014-12-12 18:52:06 +01:00
}
2016-12-17 22:20:31 +01:00
/***** Change current action *****/
if (!Action[NewRole])
Err_WrongRoleExit ();
Gbl.Action.Act = Action[NewRole];
2016-12-17 22:20:31 +01:00
Tab_SetCurrentTab ();
2014-12-12 18:52:06 +01:00
}
else // User's ID not valid
2016-12-17 22:20:31 +01:00
/***** Error message *****/
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_ERROR,NULL,
Txt_The_ID_X_is_not_valid,
Gbl.Usrs.Other.UsrDat.IDs.List[0].ID);
2016-12-17 22:20:31 +01:00
}
void Enr_CreateNewUsr2 (void)
{
2019-03-09 20:12:44 +01:00
if (Ale_GetTypeOfLastAlert () == Ale_ERROR) // User's ID not valid
Ale_ShowAlerts (NULL);
else // User's ID valid
2016-12-17 22:20:31 +01:00
{
2019-03-10 00:34:16 +01:00
/***** Show possible alerts *****/
Ale_ShowAlerts (NULL);
2016-12-17 22:20:31 +01:00
/***** Show user's record *****/
Rec_ShowSharedRecordUnmodifiable (&Gbl.Usrs.Other.UsrDat);
2014-12-12 18:52:06 +01:00
}
}
/*****************************************************************************/
/**** Modify other user's data and register her/him in course and groups *****/
/*****************************************************************************/
2016-12-18 19:06:48 +01:00
void Enr_ModifyUsr1 (void)
2014-12-12 18:52:06 +01:00
{
2016-12-17 21:36:57 +01:00
extern const char *Txt_The_role_of_THE_USER_X_in_the_course_Y_has_changed_from_A_to_B;
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2017-03-30 11:20:06 +02:00
extern const char *Txt_THE_USER_X_has_been_enroled_in_the_course_Y;
Usr_MeOrOther_t MeOrOther;
2016-12-17 21:36:57 +01:00
Rol_Role_t OldRole;
2014-12-12 18:52:06 +01:00
Rol_Role_t NewRole;
static Act_Action_t Action[Rol_NUM_ROLES] =
{
[Rol_GST] = ActUpdOth,
[Rol_STD] = ActUpdStd,
[Rol_NET] = ActUpdNET,
[Rol_TCH] = ActUpdTch,
};
2016-12-18 19:06:48 +01:00
2014-12-12 18:52:06 +01:00
/***** Get user from form *****/
if (Usr_GetParOtherUsrCodEncryptedAndGetUsrData ())
2014-12-12 18:52:06 +01:00
{
MeOrOther = Usr_ItsMe (Gbl.Usrs.Other.UsrDat.UsrCod);
2014-12-12 18:52:06 +01:00
/***** Get the action to do *****/
2017-01-29 12:42:19 +01:00
Gbl.Usrs.RegRemAction = (Enr_RegRemOneUsrAction_t)
Par_GetParUnsignedLong ("RegRemAction",
0,
Enr_REG_REM_ONE_USR_NUM_ACTIONS - 1,
(unsigned long) Enr_REG_REM_ONE_USR_UNKNOWN_ACTION);
2017-01-29 12:42:19 +01:00
switch (Gbl.Usrs.RegRemAction)
{
case Enr_REGISTER_MODIFY_ONE_USR_IN_CRS:
if (MeOrOther == Usr_ME || Gbl.Usrs.Me.Role.Logged >= Rol_TCH)
2014-12-12 18:52:06 +01:00
{
2017-01-29 12:42:19 +01:00
/***** Get user's name from record form *****/
if (Usr_ICanChangeOtherUsrData (&Gbl.Usrs.Other.UsrDat) == Usr_CAN)
2017-01-29 12:42:19 +01:00
Rec_GetUsrNameFromRecordForm (&Gbl.Usrs.Other.UsrDat);
2014-12-12 18:52:06 +01:00
2017-01-29 12:42:19 +01:00
/***** Update user's data in database *****/
Enr_UpdateUsrData (&Gbl.Usrs.Other.UsrDat);
2014-12-12 18:52:06 +01:00
if (Gbl.Hierarchy.Level == Hie_CRS) // Course selected
2017-01-29 12:42:19 +01:00
{
/***** Get new role from record form *****/
NewRole = Rec_GetRoleFromRecordForm ();
2016-12-17 20:44:13 +01:00
2017-01-29 12:42:19 +01:00
/***** Register user in current course in database *****/
switch (Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat))
2017-01-29 12:42:19 +01:00
{
case Usr_BELONG:
OldRole = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs; // Remember old role before changing it
if (NewRole != OldRole) // The role must be updated
{
/* Modify role */
Enr_ModifyRoleInCurrentCrs (&Gbl.Usrs.Other.UsrDat,NewRole);
/* Set success message */
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_The_role_of_THE_USER_X_in_the_course_Y_has_changed_from_A_to_B,
Gbl.Usrs.Other.UsrDat.FullName,
Gbl.Hierarchy.Node[Hie_CRS].FullName,
Txt_ROLES_SINGUL_abc[OldRole][Gbl.Usrs.Other.UsrDat.Sex],
Txt_ROLES_SINGUL_abc[NewRole][Gbl.Usrs.Other.UsrDat.Sex]);
}
break;
case Usr_DONT_BELONG: // User does not belong to current course
default:
/* Register user */
Enr_RegisterUsrInCurrentCrs (&Gbl.Usrs.Other.UsrDat,NewRole,
Enr_SET_ACCEPTED_TO_FALSE);
2017-01-29 12:42:19 +01:00
2017-05-09 11:39:08 +02:00
/* Set success message */
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_THE_USER_X_has_been_enroled_in_the_course_Y,
2019-03-09 20:12:44 +01:00
Gbl.Usrs.Other.UsrDat.FullName,
Gbl.Hierarchy.Node[Hie_CRS].FullName);
break;
2017-01-29 12:42:19 +01:00
}
2017-06-04 18:18:54 +02:00
/***** Change user's groups *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Grps.NumGrps) // This course has groups?
switch (MeOrOther)
{
case Usr_ME:
Grp_ChangeMyGrps (Cns_QUIET);
break;
case Usr_OTHER:
Grp_ChangeOtherUsrGrps ();
break;
}
2017-06-04 18:18:54 +02:00
2017-06-04 14:22:04 +02:00
/***** If it's me, change my roles *****/
if (MeOrOther == Usr_ME)
2017-06-04 14:22:04 +02:00
{
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs;
2017-06-08 15:32:33 +02:00
Gbl.Usrs.Me.UsrDat.Roles.InCrss = Gbl.Usrs.Other.UsrDat.Roles.InCrss;
2017-06-04 14:22:04 +02:00
Rol_SetMyRoles ();
}
2017-01-29 12:42:19 +01:00
/***** Change current action *****/
if (!Action[NewRole])
Err_WrongRoleExit ();
Gbl.Action.Act = Action[NewRole];
2017-01-29 12:42:19 +01:00
Tab_SetCurrentTab ();
}
2014-12-12 18:52:06 +01:00
}
2017-01-29 12:42:19 +01:00
else
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
case Enr_REGISTER_ONE_DEG_ADMIN:
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged < Rol_CTR_ADM)
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
case Enr_REGISTER_ONE_CTR_ADMIN:
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged < Rol_INS_ADM)
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
case Enr_REGISTER_ONE_INS_ADMIN:
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged != Rol_SYS_ADM)
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
case Enr_REPORT_USR_AS_POSSIBLE_DUPLICATE:
if (MeOrOther == Usr_ME || Gbl.Usrs.Me.Role.Logged < Rol_TCH)
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
case Enr_REMOVE_ONE_USR_FROM_CRS:
if (MeOrOther == Usr_OTHER && Gbl.Usrs.Me.Role.Logged < Rol_TCH)
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
case Enr_REMOVE_ONE_DEG_ADMIN:
if (MeOrOther == Usr_OTHER && Gbl.Usrs.Me.Role.Logged < Rol_CTR_ADM)
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
case Enr_REMOVE_ONE_CTR_ADMIN:
if (MeOrOther == Usr_OTHER && Gbl.Usrs.Me.Role.Logged < Rol_INS_ADM)
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
case Enr_REMOVE_ONE_INS_ADMIN:
if (MeOrOther == Usr_OTHER && Gbl.Usrs.Me.Role.Logged != Rol_SYS_ADM)
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
case Enr_ELIMINATE_ONE_USR_FROM_PLATFORM:
if (Acc_CheckIfICanEliminateAccount (Gbl.Usrs.Other.UsrDat.UsrCod) == Usr_CAN_NOT)
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
default:
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-01-29 12:42:19 +01:00
break;
}
2014-12-12 18:52:06 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2016-12-18 19:06:48 +01:00
}
2014-12-12 18:52:06 +01:00
2016-12-18 19:06:48 +01:00
void Enr_ModifyUsr2 (void)
{
2019-03-09 20:12:44 +01:00
if (Ale_GetTypeOfLastAlert () == Ale_WARNING)
2019-03-09 22:01:06 +01:00
{
2019-03-10 00:34:16 +01:00
/***** Show possible alerts *****/
2019-03-09 20:12:44 +01:00
Ale_ShowAlerts (NULL);
2019-03-09 22:01:06 +01:00
2019-03-10 00:34:16 +01:00
/***** Show form to edit user again *****/
2019-03-09 22:01:06 +01:00
Enr_ShowFormToEditOtherUsr ();
}
2016-12-18 19:06:48 +01:00
else // No error
switch (Gbl.Usrs.RegRemAction)
{
case Enr_REGISTER_MODIFY_ONE_USR_IN_CRS:
2019-03-10 00:34:16 +01:00
/***** Show possible alerts *****/
2019-03-09 22:01:06 +01:00
Ale_ShowAlerts (NULL);
2016-12-18 19:06:48 +01:00
2019-03-10 00:34:16 +01:00
/***** Show form to edit user again *****/
2019-03-09 22:01:06 +01:00
Enr_ShowFormToEditOtherUsr ();
2016-12-18 19:06:48 +01:00
break;
case Enr_REGISTER_ONE_DEG_ADMIN:
Adm_ReqAddAdm (Hie_DEG);
2016-12-18 19:06:48 +01:00
break;
case Enr_REGISTER_ONE_CTR_ADMIN:
Adm_ReqAddAdm (Hie_CTR);
2016-12-18 19:06:48 +01:00
break;
case Enr_REGISTER_ONE_INS_ADMIN:
Adm_ReqAddAdm (Hie_INS);
2016-12-18 19:06:48 +01:00
break;
case Enr_REPORT_USR_AS_POSSIBLE_DUPLICATE:
Dup_ReportUsrAsPossibleDuplicate ();
break;
case Enr_REMOVE_ONE_USR_FROM_CRS:
Enr_ReqRemUsrFromCrs ();
break;
case Enr_REMOVE_ONE_DEG_ADMIN:
Adm_ReqRemAdmOfDeg ();
2016-12-18 19:06:48 +01:00
break;
case Enr_REMOVE_ONE_CTR_ADMIN:
Adm_ReqRemAdmOfCtr ();
2016-12-18 19:06:48 +01:00
break;
case Enr_REMOVE_ONE_INS_ADMIN:
Adm_ReqRemAdmOfIns ();
2016-12-18 19:06:48 +01:00
break;
case Enr_ELIMINATE_ONE_USR_FROM_PLATFORM:
Acc_ReqRemAccountOrRemAccount (Acc_REQUEST_REMOVE_USR);
break;
2017-01-29 12:42:19 +01:00
default:
break;
2016-12-18 19:06:48 +01:00
}
2014-12-12 18:52:06 +01:00
}
2014-12-12 22:39:55 +01:00
/*****************************************************************************/
/******************* Ask if really wanted to remove a user *******************/
/*****************************************************************************/
static void Enr_AskIfRemoveUsrFromCrs (struct Usr_Data *UsrDat)
2014-12-12 22:39:55 +01:00
{
extern const char *Txt_Do_you_really_want_to_be_removed_from_the_course_X;
extern const char *Txt_Do_you_really_want_to_remove_the_following_user_from_the_course_X;
extern const char *Txt_Remove_me_from_this_course;
extern const char *Txt_Remove_user_from_this_course;
Usr_MeOrOther_t MeOrOther;
static Act_Action_t NextAction[Rol_NUM_ROLES] =
{
[Rol_STD] = ActRemStdCrs,
[Rol_NET] = ActRemNETCrs,
[Rol_TCH] = ActRemTchCrs,
};
const char *Question[Usr_NUM_ME_OR_OTHER] =
{
[Usr_ME ] = Txt_Do_you_really_want_to_be_removed_from_the_course_X,
[Usr_OTHER] = Txt_Do_you_really_want_to_remove_the_following_user_from_the_course_X
};
const char *TxtButton[Usr_NUM_ME_OR_OTHER] =
{
[Usr_ME ] = Txt_Remove_me_from_this_course,
[Usr_OTHER] = Txt_Remove_user_from_this_course
};
2014-12-12 22:39:55 +01:00
switch (Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
2014-12-12 22:39:55 +01:00
{
case Usr_BELONG:
MeOrOther = Usr_ItsMe (Gbl.Usrs.Other.UsrDat.UsrCod);
2017-06-04 15:11:41 +02:00
/***** Show question and button to remove user as administrator *****/
/* Begin alert */
Ale_ShowAlertAndButtonBegin (Ale_QUESTION,Question[MeOrOther],
Gbl.Hierarchy.Node[Hie_CRS].FullName);
2014-12-12 22:39:55 +01:00
/* Show user's record */
Rec_ShowSharedRecordUnmodifiable (UsrDat);
2014-12-12 22:39:55 +01:00
/* Show form to request confirmation */
if (!NextAction[UsrDat->Roles.InCurrentCrs])
Err_WrongRoleExit ();
Frm_BeginForm (NextAction[UsrDat->Roles.InCurrentCrs]);
Usr_PutParUsrCodEncrypted (UsrDat->EnUsrCod);
Pwd_AskForConfirmationOnDangerousAction ();
Btn_PutRemoveButton (TxtButton[MeOrOther]);
Frm_EndForm ();
2017-04-27 23:44:00 +02:00
/* End alert */
Ale_ShowAlertAndButtonEnd (ActUnk,NULL,NULL,
NULL,NULL,
Btn_NO_BUTTON,NULL);
break;
case Usr_DONT_BELONG: // User does not belong to current course
default:
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
break;
2014-12-12 22:39:55 +01:00
}
}
/*****************************************************************************/
/************************ Remove a user from a course ************************/
/*****************************************************************************/
static void Enr_EffectivelyRemUsrFromCrs (struct Usr_Data *UsrDat,
struct Hie_Node *Crs,
2019-09-29 23:13:20 +02:00
Enr_RemoveUsrProduction_t RemoveUsrWorks,
Cns_QuietOrVerbose_t QuietOrVerbose)
2014-12-12 22:39:55 +01:00
{
extern const char *Txt_THE_USER_X_has_been_removed_from_the_course_Y;
switch (Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
2014-12-12 22:39:55 +01:00
{
case Usr_BELONG:
/***** Remove user from all attendance events in course *****/
Att_DB_RemoveUsrFromCrsEvents (UsrDat->UsrCod,Crs->HieCod);
2014-12-12 22:39:55 +01:00
/***** Remove user from all groups in course *****/
Grp_RemUsrFromAllGrpsInCrs (UsrDat->UsrCod,Crs->HieCod);
2014-12-12 22:39:55 +01:00
/***** Remove user's status about reading of course information *****/
Inf_DB_RemoveUsrFromCrsInfoRead (UsrDat->UsrCod,Crs->HieCod);
2014-12-12 22:39:55 +01:00
/***** Remove important production of this user in course *****/
if (RemoveUsrWorks == Enr_REMOVE_USR_PRODUCTION)
{
/* Remove works zone in course */
Brw_RemoveUsrWorksInCrs (UsrDat,Crs);
/* Remove tests, exams and matches results made by user in course */
TstPrn_RemovePrintsMadeByUsrInCrs (UsrDat->UsrCod,Crs->HieCod);
Exa_DB_RemovePrintQstsMadeByUsrInCrs (UsrDat->UsrCod,Crs->HieCod);
Exa_DB_RemoveAllPrintsMadeByUsrInCrs (UsrDat->UsrCod,Crs->HieCod);
Mch_RemoveMatchesMadeByUsrInCrs (UsrDat->UsrCod,Crs->HieCod);
}
2019-09-29 23:13:20 +02:00
/***** Remove fields of this user in its course record *****/
Rec_DB_RemoveAllFieldContentsFromUsrRecordInCrs (UsrDat->UsrCod,Crs->HieCod);
2014-12-12 22:39:55 +01:00
/***** Remove some information about files in course and groups *****/
Brw_DB_RemoveSomeInfoAboutCrsUsrFiles (UsrDat->UsrCod,Crs->HieCod);
2014-12-12 22:39:55 +01:00
/***** Set all notifications for this user in this course as removed,
except notifications about new messages *****/
Ntf_DB_MarkNotifInCrsAsRemoved (UsrDat->UsrCod,Crs->HieCod);
2014-12-12 22:39:55 +01:00
/***** Remove user from the tables of courses-users *****/
Set_DB_RemUsrFromCrsSettings (UsrDat->UsrCod,Crs->HieCod);
Enr_DB_RemUsrFromCrs (UsrDat->UsrCod,Crs->HieCod);
2014-12-12 22:39:55 +01:00
/***** Flush caches *****/
Usr_FlushCachesUsr ();
2017-06-20 14:43:26 +02:00
/***** If it's me, change my roles *****/
switch (Usr_ItsMe (UsrDat->UsrCod))
{
case Usr_ME:
/* Now I don't belong to current course */
Gbl.Usrs.Me.IBelongToCurrent[Hie_CRS] = Usr_DONT_BELONG;
Gbl.Usrs.Me.UsrDat.Accepted = false;
/* Fill the list with the courses I belong to */
Gbl.Usrs.Me.Hierarchy[Hie_CRS].Filled = false;
Hie_GetMyHierarchy (Hie_CRS);
/* Set my roles */
Gbl.Usrs.Me.Role.FromSession =
Gbl.Usrs.Me.Role.Logged =
Gbl.Usrs.Me.Role.LoggedBeforeCloseSession =
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs =
UsrDat->Roles.InCurrentCrs = Rol_UNK;
Gbl.Usrs.Me.UsrDat.Roles.InCrss =
UsrDat->Roles.InCrss = -1; // not yet filled/calculated
Rol_SetMyRoles ();
break;
case Usr_OTHER:
/* Now he/she does not belong to current course */
UsrDat->Accepted = false;
UsrDat->Roles.InCurrentCrs = Rol_USR;
break;
}
2017-06-04 15:11:41 +02:00
if (QuietOrVerbose == Cns_VERBOSE)
Ale_CreateAlert (Ale_SUCCESS,NULL,
Txt_THE_USER_X_has_been_removed_from_the_course_Y,
UsrDat->FullName,Crs->FullName);
break;
case Usr_DONT_BELONG: // User does not belong to course
default:
if (QuietOrVerbose == Cns_VERBOSE)
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
break;
2014-12-12 22:39:55 +01:00
}
}
/*****************************************************************************/
/***** Check if user belongs (no matter if he/she has accepted or not) *******/
/***** to the current course *******/
/*****************************************************************************/
void Enr_FlushCacheUsrBelongsToCurrentCrs (void)
{
Gbl.Cache.UsrBelongsToCurrentCrs.Valid = false;
}
Usr_Belong_t Enr_CheckIfUsrBelongsToCurrentCrs (const struct Usr_Data *UsrDat)
{
/***** 1. Fast check: Trivial cases *****/
if (UsrDat->UsrCod <= 0 ||
Gbl.Hierarchy.Node[Hie_CRS].HieCod <= 0)
return Usr_DONT_BELONG;
/***** 2. Fast check: If cached... *****/
if (Gbl.Cache.UsrBelongsToCurrentCrs.Valid &&
UsrDat->UsrCod == Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod)
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
/***** 3. Fast check: If we know role of user in the current course *****/
if (UsrDat->Roles.InCurrentCrs != Rol_UNK)
{
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = (UsrDat->Roles.InCurrentCrs == Rol_STD ||
UsrDat->Roles.InCurrentCrs == Rol_NET ||
UsrDat->Roles.InCurrentCrs == Rol_TCH) ? Usr_BELONG :
Usr_DONT_BELONG;
Gbl.Cache.UsrBelongsToCurrentCrs.Valid = true;
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
}
/***** 4. Fast / slow check: Get if user belongs to current course *****/
Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = Hie_CheckIfUsrBelongsTo (Hie_CRS,UsrDat->UsrCod,
Gbl.Hierarchy.Node[Hie_CRS].HieCod,
false);
Gbl.Cache.UsrBelongsToCurrentCrs.Valid = true;
return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs;
}
/*****************************************************************************/
/***** Check if user belongs (no matter if he/she has accepted or not) *******/
/***** to the current course *******/
/*****************************************************************************/
void Enr_FlushCacheUsrHasAcceptedInCurrentCrs (void)
{
Gbl.Cache.UsrHasAcceptedInCurrentCrs.Valid = false;
}
bool Enr_CheckIfUsrHasAcceptedInCurrentCrs (const struct Usr_Data *UsrDat)
{
/***** 1. Fast check: Trivial cases *****/
if (UsrDat->UsrCod <= 0 ||
Gbl.Hierarchy.Node[Hie_CRS].HieCod <= 0)
return false;
/***** 2. Fast check: If cached... *****/
if (Gbl.Cache.UsrHasAcceptedInCurrentCrs.Valid &&
UsrDat->UsrCod == Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod)
return Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted;
/***** 3. Fast / slow check: Get if user belongs to current course
and has accepted *****/
Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted = (Hie_CheckIfUsrBelongsTo (Hie_CRS,UsrDat->UsrCod,
Gbl.Hierarchy.Node[Hie_CRS].HieCod,
true) == Usr_BELONG);
Gbl.Cache.UsrHasAcceptedInCurrentCrs.Valid = true;
return Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted;
}
/*****************************************************************************/
/*************** Check if a user belongs to any of my courses ****************/
/*****************************************************************************/
void Enr_FlushCacheUsrSharesAnyOfMyCrs (void)
{
Gbl.Cache.UsrSharesAnyOfMyCrs.Valid = false;
}
bool Enr_CheckIfUsrSharesAnyOfMyCrs (struct Usr_Data *UsrDat)
{
/***** 1. Fast check: Am I logged? *****/
if (!Gbl.Usrs.Me.Logged)
return false;
/***** 2. Fast check: It is a valid user code? *****/
if (UsrDat->UsrCod <= 0)
return false;
/***** 3. Fast check: It's me? *****/
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
return true;
/***** 4. Fast check: Is already calculated if user shares any course with me? *****/
if (Gbl.Cache.UsrSharesAnyOfMyCrs.Valid &&
UsrDat->UsrCod == Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod)
return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs;
/***** 5. Fast check: Is course selected and we both belong to it? *****/
if (Gbl.Usrs.Me.IBelongToCurrent[Hie_CRS] == Usr_BELONG)
if (Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat) == Usr_BELONG) // Course selected and we both belong to it
{
Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = true;
Gbl.Cache.UsrSharesAnyOfMyCrs.Valid = true;
return true;
}
/***** 6. Fast/slow check: Does he/she belong to any course? *****/
Rol_GetRolesInAllCrss (UsrDat);
if (!(UsrDat->Roles.InCrss & ((1 << Rol_STD) | // Any of his/her roles is student
(1 << Rol_NET) | // or non-editing teacher
(1 << Rol_TCH)))) // or teacher?
{
Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = false;
Gbl.Cache.UsrSharesAnyOfMyCrs.Valid = true;
return false;
}
/***** 7. Slow check: Get if user shares any course with me from database *****/
Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = UsrDat->UsrCod;
Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = Enr_DB_CheckIfUsrSharesAnyOfMyCrs (UsrDat->UsrCod);
return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs;
}
/*****************************************************************************/
/******* Get total number of users of one or several roles in courses ********/
/*****************************************************************************/
#define Enr_DB_MAX_BYTES_SUBQUERY_ROLES (Rol_NUM_ROLES * (10 + 1) - 1)
unsigned Enr_GetNumUsrsInCrss (Hie_Level_t Level,long Cod,unsigned Roles)
{
bool AnyUserInCourses;
unsigned NumUsrs;
/***** Reset roles that can not belong to courses.
Only
- students,
- non-editing teachers,
- teachers
can belong to a course *****/
Roles &= ((1 << Rol_STD) |
(1 << Rol_NET) |
(1 << Rol_TCH));
/***** Check if no roles requested *****/
if (Roles == 0)
return 0;
/***** Check if any user in courses is requested *****/
AnyUserInCourses = (Roles == ((1 << Rol_STD) |
(1 << Rol_NET) |
(1 << Rol_TCH)));
/***** Get number of users from database *****/
NumUsrs = Enr_DB_GetNumUsrsInCrss (Level,Cod,Roles,AnyUserInCourses);
FigCch_UpdateFigureIntoCache (Enr_GetFigureNumUsrsInCrss (Roles),Level,Cod,
FigCch_UNSIGNED,&NumUsrs);
return NumUsrs;
}
unsigned Enr_GetCachedNumUsrsInCrss (Hie_Level_t Level,long Cod,unsigned Roles)
{
unsigned NumUsrsInCrss;
/***** Get number of users in courses from cache *****/
if (!FigCch_GetFigureFromCache (Enr_GetFigureNumUsrsInCrss (Roles),Level,Cod,
FigCch_UNSIGNED,&NumUsrsInCrss))
/***** Get current number of users in courses from database and update cache *****/
NumUsrsInCrss = Enr_GetNumUsrsInCrss (Level,Cod,Roles);
return NumUsrsInCrss;
}
static FigCch_FigureCached_t Enr_GetFigureNumUsrsInCrss (unsigned Roles)
{
switch (Roles)
{
case 1 << Rol_STD: // Students
return FigCch_NUM_STDS_IN_CRSS;
case 1 << Rol_NET: // Non-editing teachers
return FigCch_NUM_NETS_IN_CRSS;
case 1 << Rol_TCH: // Teachers
return FigCch_NUM_TCHS_IN_CRSS;
case 1 << Rol_NET |
1 << Rol_TCH: // Any teacher in courses
return FigCch_NUM_ALLT_IN_CRSS;
case 1 << Rol_STD |
1 << Rol_NET |
1 << Rol_TCH: // Any user in courses
return FigCch_NUM_USRS_IN_CRSS;
default:
Err_WrongRoleExit ();
return FigCch_UNKNOWN; // Not reached
}
}
/*****************************************************************************/
/******** Get total number of users who do not belong to any course **********/
/*****************************************************************************/
unsigned Enr_GetCachedNumUsrsNotBelongingToAnyCrs (void)
{
unsigned NumGsts;
/***** Get number of guests from cache *****/
if (!FigCch_GetFigureFromCache (FigCch_NUM_GSTS,Hie_SYS,-1L,
FigCch_UNSIGNED,&NumGsts))
{
/***** Get current number of guests from database and update cache *****/
NumGsts = Enr_DB_GetNumUsrsNotBelongingToAnyCrs ();
FigCch_UpdateFigureIntoCache (FigCch_NUM_GSTS,Hie_SYS,-1L,
FigCch_UNSIGNED,&NumGsts);
}
return NumGsts;
}
/*****************************************************************************/
/************ Get average number of courses with users of a type *************/
/*****************************************************************************/
double Enr_GetCachedAverageNumUsrsPerCrs (Hie_Level_t Level,long Cod,Rol_Role_t Role)
{
static const FigCch_FigureCached_t FigureNumUsrsPerCrs[Rol_NUM_ROLES] =
{
[Rol_UNK] = FigCch_NUM_USRS_PER_CRS, // Number of users per course
[Rol_STD] = FigCch_NUM_STDS_PER_CRS, // Number of students per course
[Rol_NET] = FigCch_NUM_NETS_PER_CRS, // Number of non-editing teachers per course
[Rol_TCH] = FigCch_NUM_TCHS_PER_CRS, // Number of teachers per course
};
double AverageNumUsrsPerCrs;
/***** Get number of users per course from cache *****/
if (!FigCch_GetFigureFromCache (FigureNumUsrsPerCrs[Role],Level,Cod,
FigCch_DOUBLE,&AverageNumUsrsPerCrs))
{
/***** Get current number of users per course from database and update cache *****/
AverageNumUsrsPerCrs = Enr_DB_GetAverageNumUsrsPerCrs (Level,Cod,Role);
FigCch_UpdateFigureIntoCache (FigureNumUsrsPerCrs[Role],Level,Cod,
FigCch_DOUBLE,&AverageNumUsrsPerCrs);
}
return AverageNumUsrsPerCrs;
}
/*****************************************************************************/
/************ Get average number of courses with users of a role *************/
/*****************************************************************************/
double Enr_GetCachedAverageNumCrssPerUsr (Hie_Level_t Level,long Cod,Rol_Role_t Role)
{
static const FigCch_FigureCached_t FigureNumCrssPerUsr[Rol_NUM_ROLES] =
{
[Rol_UNK] = FigCch_NUM_CRSS_PER_USR, // Number of courses per user
[Rol_STD] = FigCch_NUM_CRSS_PER_STD, // Number of courses per student
[Rol_NET] = FigCch_NUM_CRSS_PER_NET, // Number of courses per non-editing teacher
[Rol_TCH] = FigCch_NUM_CRSS_PER_TCH, // Number of courses per teacher
};
double AverageNumCrssPerUsr;
/***** Get number of courses per user from cache *****/
if (!FigCch_GetFigureFromCache (FigureNumCrssPerUsr[Role],Level,Cod,
FigCch_DOUBLE,&AverageNumCrssPerUsr))
{
/***** Get current number of courses per user from database and update cache *****/
AverageNumCrssPerUsr = Enr_DB_GetAverageNumCrssPerUsr (Level,Cod,Role);
FigCch_UpdateFigureIntoCache (FigureNumCrssPerUsr[Role],Level,Cod,
FigCch_DOUBLE,&AverageNumCrssPerUsr);
}
return AverageNumCrssPerUsr;
}