swad-core/swad_user.c

6783 lines
231 KiB
C
Raw Normal View History

2014-12-01 23:55:08 +01:00
// swad_user.c: users
/*
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-2023 Antonio Ca<EFBFBD>as Vargas
2014-12-01 23:55:08 +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 *********************************/
/*****************************************************************************/
2019-11-15 03:34:48 +01:00
#define _GNU_SOURCE // For asprintf
2014-12-01 23:55:08 +01:00
#include <ctype.h> // For isalnum, isdigit, etc.
#include <limits.h> // For maximum values
#include <linux/limits.h> // For PATH_MAX
2019-12-29 12:39:00 +01:00
#include <stddef.h> // For NULL
2019-11-15 03:34:48 +01:00
#include <stdio.h> // For asprintf
2014-12-01 23:55:08 +01:00
#include <stdlib.h> // For exit, system, malloc, free, rand, etc.
#include <string.h> // For string functions
#include <sys/wait.h> // For the macro WEXITSTATUS
#include <unistd.h> // For access, lstat, getpid, chdir, symlink, unlink
2014-12-12 22:39:55 +01:00
#include "swad_account.h"
#include "swad_action_list.h"
#include "swad_admin.h"
#include "swad_admin_database.h"
2020-04-14 17:15:17 +02:00
#include "swad_agenda.h"
2014-12-01 23:55:08 +01:00
#include "swad_announcement.h"
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
2015-11-21 20:23:28 +01:00
#include "swad_calendar.h"
#include "swad_center_database.h"
2014-12-01 23:55:08 +01:00
#include "swad_config.h"
#include "swad_constant.h"
#include "swad_connected_database.h"
#include "swad_country_database.h"
2014-12-01 23:55:08 +01:00
#include "swad_course.h"
#include "swad_database.h"
#include "swad_degree_database.h"
2020-04-14 17:15:17 +02:00
#include "swad_department.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"
2020-04-14 17:15:17 +02:00
#include "swad_figure.h"
2020-05-03 20:58:03 +02:00
#include "swad_figure_cache.h"
2019-02-22 14:04:54 +01:00
#include "swad_follow.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2014-12-01 23:55:08 +01:00
#include "swad_global.h"
#include "swad_group.h"
2015-10-06 20:34:49 +02:00
#include "swad_help.h"
2016-11-14 16:47:46 +01:00
#include "swad_hierarchy.h"
#include "swad_hierarchy_level.h"
2019-10-23 19:05:05 +02:00
#include "swad_HTML.h"
2014-12-01 23:55:08 +01:00
#include "swad_ID.h"
#include "swad_institution_database.h"
2017-05-07 18:06:34 +02:00
#include "swad_language.h"
#include "swad_mail_database.h"
#include "swad_message.h"
2016-06-03 13:42:28 +02:00
#include "swad_MFU.h"
2014-12-01 23:55:08 +01:00
#include "swad_nickname.h"
#include "swad_nickname_database.h"
2014-12-01 23:55:08 +01:00
#include "swad_notification.h"
#include "swad_parameter.h"
#include "swad_password.h"
2020-04-14 17:15:17 +02:00
#include "swad_photo.h"
2016-12-09 13:59:33 +01:00
#include "swad_privacy.h"
#include "swad_profile.h"
2016-12-07 00:41:36 +01:00
#include "swad_QR.h"
2014-12-01 23:55:08 +01:00
#include "swad_record.h"
#include "swad_record_database.h"
2016-12-13 13:32:19 +01:00
#include "swad_role.h"
#include "swad_session.h"
#include "swad_session_database.h"
2019-03-26 11:53:21 +01:00
#include "swad_setting.h"
2015-01-04 15:48:24 +01:00
#include "swad_tab.h"
2014-12-01 23:55:08 +01:00
#include "swad_user.h"
#include "swad_user_database.h"
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/****************************** Public constants *****************************/
/*****************************************************************************/
2018-12-08 16:43:13 +01:00
const char *Usr_StringsSexIcons[Usr_NUM_SEXS] =
{
2019-11-22 01:04:03 +01:00
[Usr_SEX_UNKNOWN] = "?",
[Usr_SEX_FEMALE ] = "&female;",
[Usr_SEX_MALE ] = "&male;",
[Usr_SEX_ALL ] = "*",
2018-12-08 16:43:13 +01:00
};
2014-12-01 23:55:08 +01:00
const char *Usr_StringsSexDB[Usr_NUM_SEXS] =
{
2019-11-22 01:04:03 +01:00
[Usr_SEX_UNKNOWN] = "unknown",
[Usr_SEX_FEMALE ] = "female",
[Usr_SEX_MALE ] = "male",
[Usr_SEX_ALL ] = "all",
2014-12-01 23:55:08 +01:00
};
2017-05-26 20:11:24 +02:00
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
static const char *Usr_IconsClassPhotoOrList[Set_NUM_USR_LIST_TYPES] =
2014-12-01 23:55:08 +01:00
{
[Set_USR_LIST_UNKNOWN ] = "",
[Set_USR_LIST_AS_CLASS_PHOTO] = "th.svg",
[Set_USR_LIST_AS_LISTING ] = "list-ol.svg",
2014-12-01 23:55:08 +01:00
};
2017-05-26 20:11:24 +02:00
static const char *Usr_NameSelUnsel[Rol_NUM_ROLES] =
{
2020-05-03 20:58:03 +02:00
[Rol_GST] = "SEL_UNSEL_GSTS",
[Rol_STD] = "SEL_UNSEL_STDS",
[Rol_NET] = "SEL_UNSEL_NETS",
[Rol_TCH] = "SEL_UNSEL_TCHS",
2017-05-26 20:11:24 +02:00
};
static const char *Usr_ParUsrCod[Rol_NUM_ROLES] =
2017-05-26 20:11:24 +02:00
{
2020-05-03 20:58:03 +02:00
[Rol_UNK] = "UsrCodAll", // here means all users
[Rol_GST] = "UsrCodGst",
[Rol_STD] = "UsrCodStd",
[Rol_NET] = "UsrCodNET",
[Rol_TCH] = "UsrCodTch",
2017-05-26 20:11:24 +02:00
};
2016-07-25 16:08:25 +02:00
#define Usr_NUM_MAIN_FIELDS_DATA_ADM 7
2020-04-29 02:34:54 +02:00
#define Usr_NUM_ALL_FIELDS_DATA_GST 14
#define Usr_NUM_ALL_FIELDS_DATA_STD 10
2014-12-01 23:55:08 +01:00
#define Usr_NUM_ALL_FIELDS_DATA_TCH 11
const char *Usr_UsrDatMainFieldNames[Usr_NUM_MAIN_FIELDS_DATA_USR];
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
2019-04-11 09:55:35 +02:00
/****************************** Private variables ****************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
static void (*Usr_FuncParsBigList) (void *Args); // Used to pass pointer to function
2019-04-11 09:55:35 +02:00
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static void Usr_GetMyLastData (void);
static void Usr_GetUsrCommentsFromString (char *Str,struct Usr_Data *UsrDat);
2014-12-01 23:55:08 +01:00
static Usr_Sex_t Usr_GetSexFromStr (const char *Str);
static void Usr_GetParOtherUsrIDNickOrEMail (void);
2014-12-01 23:55:08 +01:00
static bool Usr_ChkUsrAndGetUsrDataFromDirectLogin (void);
static bool Usr_ChkUsrAndGetUsrDataFromSession (void);
2016-03-01 03:16:29 +01:00
static void Usr_ShowAlertUsrDoesNotExistsOrWrongPassword (void);
static void Usr_ShowAlertThereAreMoreThanOneUsr (void);
2014-12-01 23:55:08 +01:00
2017-06-04 14:22:04 +02:00
static void Usr_SetMyPrefsAndRoles (void);
2014-12-01 23:55:08 +01:00
2020-04-09 21:36:21 +02:00
static void Usr_PutLinkToLogOut (__attribute__((unused)) void *Args);
2018-10-09 19:18:43 +02:00
static void Usr_WriteRowGstAllData (struct Usr_Data *UsrDat);
static void Usr_WriteRowStdAllData (struct Usr_Data *UsrDat,char *GroupNames);
static void Usr_WriteRowTchAllData (struct Usr_Data *UsrDat);
static void Usr_WriteRowAdmData (unsigned NumUsr,struct Usr_Data *UsrDat);
static void Usr_WriteMainUsrDataExceptUsrID (struct Usr_Data *UsrDat,
2016-07-27 14:58:26 +02:00
const char *BgColor);
static void Usr_WriteEmail (struct Usr_Data *UsrDat,const char *BgColor);
2016-04-23 13:23:09 +02:00
static void Usr_WriteUsrData (const char *BgColor,
const char *Data,const char *Link,
bool NonBreak,bool Accepted);
2014-12-01 23:55:08 +01:00
static void Usr_GetGstsLst (HieLvl_Level_t Scope);
2016-06-23 13:10:43 +02:00
static void Usr_AllocateUsrsList (Rol_Role_t Role);
2016-07-04 12:50:17 +02:00
2019-04-11 09:55:35 +02:00
static void Usr_PutButtonToConfirmIWantToSeeBigList (unsigned NumUsrs,
void (*FuncPars) (void *Args),void *Args,
2019-04-11 09:55:35 +02:00
const char *OnSubmit);
static void Usr_PutParsConfirmIWantToSeeBigList (void *Args);
2014-12-01 23:55:08 +01:00
static void Usr_BuildParName (char **ParName,
const char *ParRoot,
const char *ParSuffix);
2019-11-15 03:34:48 +01:00
static void Usr_AllocateListSelectedEncryptedUsrCods (struct Usr_SelectedUsrs *SelectedUsrs,
2019-11-15 03:34:48 +01:00
Rol_Role_t Role);
2014-12-01 23:55:08 +01:00
static void Usr_AllocateListOtherRecipients (void);
static void Set_FormToSelectUsrListType (void (*FuncPars) (void *Args),void *Args,
Set_ShowUsrsType_t ListType);
2019-11-15 03:34:48 +01:00
static void Usr_PutCheckboxToSelectAllUsers (Rol_Role_t Role,
struct Usr_SelectedUsrs *SelectedUsrs);
2016-06-23 13:10:43 +02:00
static Usr_Sex_t Usr_GetSexOfUsrsLst (Rol_Role_t Role);
2017-05-30 17:34:49 +02:00
static void Usr_PutCheckboxToSelectUser (Rol_Role_t Role,
const char *EncryptedUsrCod,
2019-11-15 03:34:48 +01:00
bool UsrIsTheMsgSender,
struct Usr_SelectedUsrs *SelectedUsrs);
2015-10-02 01:04:28 +02:00
static void Usr_PutCheckboxListWithPhotos (void);
2015-09-30 23:10:15 +02:00
2014-12-01 23:55:08 +01:00
static void Usr_ListMainDataGsts (bool PutCheckBoxToSelectUsr);
static void Usr_ListMainDataStds (bool PutCheckBoxToSelectUsr);
2019-11-15 03:34:48 +01:00
static void Usr_ListMainDataTchs (Rol_Role_t Role,
bool PutCheckBoxToSelectUsr);
static void Usr_ListUsrsForSelection (Rol_Role_t Role,
struct Usr_SelectedUsrs *SelectedUsrs);
2017-05-26 01:12:15 +02:00
static void Usr_ListRowsAllDataTchs (Rol_Role_t Role,
const char *FieldNames[Usr_NUM_ALL_FIELDS_DATA_TCH],
unsigned NumColumns);
2015-04-02 18:39:49 +02:00
2015-09-17 16:54:02 +02:00
static void Usr_PutLinkToSeeAdmins (void);
static void Usr_PutLinkToSeeGuests (void);
2016-03-18 21:28:45 +01:00
2019-03-12 13:23:46 +01:00
static bool Usr_SetOptionsListUsrsAllowed (Rol_Role_t UsrsRole,
bool ICanChooseOption[Usr_LIST_USRS_NUM_OPTIONS]);
static void Usr_PutOptionsListUsrs (const bool ICanChooseOption[Usr_LIST_USRS_NUM_OPTIONS]);
2019-03-12 09:27:04 +01:00
static void Usr_ShowOneListUsrsOption (Usr_ListUsrsOption_t ListUsrsAction,
const char *Label);
static Usr_ListUsrsOption_t Usr_GetListUsrsOption (Usr_ListUsrsOption_t DefaultAction);
2019-03-11 00:51:54 +01:00
2020-04-09 21:36:21 +02:00
static void Usr_PutIconsListGsts (__attribute__((unused)) void *Args);
static void Usr_PutIconsListStds (__attribute__((unused)) void *Args);
static void Usr_PutIconsListTchs (__attribute__((unused)) void *Args);
2016-11-07 00:46:13 +01:00
2016-03-18 21:28:45 +01:00
static void Usr_PutIconToPrintGsts (void);
static void Usr_PutIconToPrintStds (void);
static void Usr_PutIconToPrintTchs (void);
static void Usr_PutIconToShowGstsAllData (void);
static void Usr_PutIconToShowStdsAllData (void);
static void Usr_PutIconToShowTchsAllData (void);
static void Usr_ShowGstsAllDataPars (__attribute__((unused)) void *Args);
static void Usr_ShowStdsAllDataPars (__attribute__((unused)) void *Args);
static void Usr_ShowTchsAllDataPars (__attribute__((unused)) void *Args);
2015-04-02 18:39:49 +02:00
2014-12-01 23:55:08 +01:00
static void Usr_DrawClassPhoto (Usr_ClassPhotoType_t ClassPhotoType,
2019-11-15 03:34:48 +01:00
Rol_Role_t Role,
struct Usr_SelectedUsrs *SelectedUsrs,
2019-11-15 03:34:48 +01:00
bool PutCheckBoxToSelectUsr);
2014-12-01 23:55:08 +01:00
static void Usr_GetAndShowNumUsrsInCrss (Rol_Role_t Role);
static void Usr_GetAndShowNumUsrsNotBelongingToAnyCrs (void);
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/**** Show alert about number of clicks remaining before sending my photo ****/
/*****************************************************************************/
void Usr_InformAboutNumClicksBeforePhoto (void)
{
extern const char *Txt_You_must_send_your_photo_because_;
extern const char *Txt_You_can_only_perform_X_further_actions_;
2017-05-30 09:42:01 +02:00
extern const char *Txt_Upload_photo;
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Me.NumAccWithoutPhoto)
{
2014-12-12 22:39:55 +01:00
if (Gbl.Usrs.Me.NumAccWithoutPhoto >= Pho_MAX_CLICKS_WITHOUT_PHOTO)
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_You_must_send_your_photo_because_);
2018-04-24 13:21:53 +02:00
else if (Act_GetBrowserTab (Gbl.Action.Act) == Act_BRW_1ST_TAB)
2020-03-26 02:54:30 +01:00
Ale_ShowAlertAndButton (ActReqMyPho,NULL,NULL,
NULL,NULL,
2019-02-17 01:14:55 +01:00
Btn_CONFIRM_BUTTON,Txt_Upload_photo,
Ale_WARNING,Txt_You_can_only_perform_X_further_actions_,
Pho_MAX_CLICKS_WITHOUT_PHOTO - Gbl.Usrs.Me.NumAccWithoutPhoto);
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/************************** Create data for a user ***************************/
/*****************************************************************************/
void Usr_UsrDataConstructor (struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
/***** Allocate memory for the comments *****/
if ((UsrDat->Comments = malloc (Cns_MAX_BYTES_TEXT + 1)) == NULL)
Err_NotEnoughMemoryExit ();
2014-12-01 23:55:08 +01:00
/***** Initialize to zero the data of the user *****/
Usr_ResetUsrDataExceptUsrCodAndIDs (UsrDat);
UsrDat->IDs.Num = 0;
UsrDat->IDs.List = NULL;
}
/*****************************************************************************/
/****************** Reset user's data except UsrCod and ID *******************/
/*****************************************************************************/
// UsrCod and ID are not changed
void Usr_ResetUsrDataExceptUsrCodAndIDs (struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
UsrDat->EnUsrCod[0] = '\0';
2014-12-01 23:55:08 +01:00
UsrDat->Nickname[0] = '\0';
UsrDat->Password[0] = '\0';
UsrDat->Roles.InCurrentCrs = Rol_UNK;// not yet got from database
UsrDat->Roles.InCrss = -1; // not yet got from database
2019-03-07 22:15:47 +01:00
UsrDat->Accepted = false;
2014-12-01 23:55:08 +01:00
UsrDat->Sex = Usr_SEX_UNKNOWN;
2016-01-18 10:21:18 +01:00
UsrDat->Surname1[0] = '\0';
UsrDat->Surname2[0] = '\0';
UsrDat->FrstName[0] = '\0';
2016-01-18 10:21:18 +01:00
UsrDat->FullName[0] = '\0';
2014-12-01 23:55:08 +01:00
UsrDat->Email[0] = '\0';
UsrDat->EmailConfirmed = false;
UsrDat->Photo[0] = '\0';
2019-03-22 15:21:46 +01:00
UsrDat->PhotoVisibility = Pri_PHOTO_VIS_DEFAULT;
UsrDat->BaPrfVisibility = Pri_BASIC_PROFILE_VIS_DEFAULT;
UsrDat->ExPrfVisibility = Pri_EXTENDED_PROFILE_VIS_DEFAULT;
2014-12-01 23:55:08 +01:00
UsrDat->CtyCod = -1L;
UsrDat->StrBirthday[0] = '\0';
2016-01-18 10:21:18 +01:00
UsrDat->Birthday.Day = 0;
2014-12-01 23:55:08 +01:00
UsrDat->Birthday.Month = 0;
2016-01-18 10:21:18 +01:00
UsrDat->Birthday.Year = 0;
2020-04-29 16:43:07 +02:00
UsrDat->Phone[0][0] =
UsrDat->Phone[1][0] = '\0';
2014-12-01 23:55:08 +01:00
if (UsrDat->Comments)
UsrDat->Comments[0] = '\0';
2016-01-18 10:21:18 +01:00
UsrDat->InsCtyCod = -1L;
UsrDat->InsCod = -1L;
2014-12-01 23:55:08 +01:00
UsrDat->Tch.CtrCod = -1L;
UsrDat->Tch.DptCod = -1L;
2016-01-18 10:21:18 +01:00
UsrDat->Tch.Office[0] = '\0';
2014-12-01 23:55:08 +01:00
UsrDat->Tch.OfficePhone[0] = '\0';
UsrDat->Prefs.Language = Lan_LANGUAGE_UNKNOWN; // Language unknown
UsrDat->Prefs.FirstDayOfWeek = Cal_FIRST_DAY_OF_WEEK_DEFAULT; // Default first day of week
UsrDat->Prefs.DateFormat = Dat_FORMAT_DEFAULT ; // Default date format
UsrDat->Prefs.Theme = The_THEME_DEFAULT;
UsrDat->Prefs.IconSet = Ico_ICON_SET_DEFAULT;
UsrDat->Prefs.Menu = Mnu_MENU_DEFAULT;
UsrDat->Prefs.SideCols = Cfg_DEFAULT_COLUMNS;
UsrDat->Prefs.PhotoShape = PhoSha_SHAPE_DEFAULT;
UsrDat->Prefs.AcceptCookies = false; // By default, don't accept third party cookies
UsrDat->NtfEvents.SendEmail = 0; // By default, don't notify anything
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************************** Reset my last data *****************************/
/*****************************************************************************/
void Usr_ResetMyLastData (void)
{
2019-04-01 23:15:17 +02:00
Gbl.Usrs.Me.UsrLast.WhatToSearch = Sch_WHAT_TO_SEARCH_DEFAULT;
Gbl.Usrs.Me.UsrLast.LastHie.Scope = HieLvl_UNK;
2019-04-01 23:15:17 +02:00
Gbl.Usrs.Me.UsrLast.LastHie.Cod = -1L;
Gbl.Usrs.Me.UsrLast.LastAct = ActUnk;
Gbl.Usrs.Me.UsrLast.LastRole = Rol_UNK;
2019-04-03 21:49:10 +02:00
Gbl.Usrs.Me.UsrLast.LastTime = 0;
2019-04-01 23:15:17 +02:00
Gbl.Usrs.Me.UsrLast.LastAccNotif = 0;
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************** Free memory used to store the data of a user ***************/
/*****************************************************************************/
void Usr_UsrDataDestructor (struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
/***** Free memory allocated for comments *****/
if (UsrDat->Comments)
{
2019-11-06 19:45:20 +01:00
free (UsrDat->Comments);
2014-12-01 23:55:08 +01:00
UsrDat->Comments = NULL;
}
/***** Free memory allocated for list of IDs *****/
ID_FreeListIDs (UsrDat);
}
/*****************************************************************************/
/*************** Get all user's data from a given user's code ****************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
// Input: UsrDat->UsrCod must hold user's code
void Usr_GetAllUsrDataFromUsrCod (struct Usr_Data *UsrDat,
Usr_GetPrefs_t GetPrefs,
Usr_GetRoleInCurrentCrs_t GetRoleInCurrentCrs)
2014-12-01 23:55:08 +01:00
{
ID_GetListIDsFromUsrCod (UsrDat);
Usr_GetUsrDataFromUsrCod (UsrDat,GetPrefs,GetRoleInCurrentCrs);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************** Allocate memory for the list of users' codes ***************/
/*****************************************************************************/
void Usr_AllocateListUsrCods (struct Usr_ListUsrCods *ListUsrCods)
2014-12-01 23:55:08 +01:00
{
if ((ListUsrCods->Lst = malloc (ListUsrCods->NumUsrs *
sizeof (*ListUsrCods->Lst))) == NULL)
Err_NotEnoughMemoryExit ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****************** Free memory for the list of users' codes *****************/
/*****************************************************************************/
void Usr_FreeListUsrCods (struct Usr_ListUsrCods *ListUsrCods)
2014-12-01 23:55:08 +01:00
{
if (ListUsrCods->NumUsrs && ListUsrCods->Lst)
{
2019-11-06 19:45:20 +01:00
free (ListUsrCods->Lst);
2014-12-01 23:55:08 +01:00
ListUsrCods->Lst = NULL;
ListUsrCods->NumUsrs = 0;
}
}
2018-10-10 23:56:42 +02:00
/*****************************************************************************/
/************************ Check if I am a given user *************************/
/*****************************************************************************/
Usr_MeOrOther_t Usr_ItsMe (long UsrCod)
2018-10-10 23:56:42 +02:00
{
return (Gbl.Usrs.Me.Logged &&
UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) ? Usr_ME :
Usr_OTHER;
2018-10-10 23:56:42 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-01-20 21:18:38 +01:00
/******** Get user's code from database using encrypted user's code **********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
// Input: UsrDat->EncryptedUsrCod must hold user's encrypted code
void Usr_GetUsrCodFromEncryptedUsrCod (struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
if (UsrDat->EnUsrCod[0])
2014-12-01 23:55:08 +01:00
/***** Get user's code from database *****/
UsrDat->UsrCod = Usr_DB_GetUsrCodFromEncryptedUsrCod (UsrDat->EnUsrCod);
2014-12-01 23:55:08 +01:00
else
UsrDat->UsrCod = -1L;
}
/*****************************************************************************/
/************ Get user's data from database giving a user's code *************/
/*****************************************************************************/
// UsrDat->UsrCod must contain an existing user's code
void Usr_GetUsrDataFromUsrCod (struct Usr_Data *UsrDat,
Usr_GetPrefs_t GetPrefs,
Usr_GetRoleInCurrentCrs_t GetRoleInCurrentCrs)
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
/***** Get user's data from database *****/
if (Usr_DB_GetUsrDataFromUsrCod (&mysql_res,UsrDat->UsrCod,GetPrefs))
2019-03-19 13:22:14 +01:00
{
/***** Read user's data *****/
row = mysql_fetch_row (mysql_res);
2017-01-17 03:10:43 +01:00
/* Get encrypted user's code (row[0])
and encrypted password (row[1]) */
Str_Copy (UsrDat->EnUsrCod,row[0],sizeof (UsrDat->EnUsrCod) - 1);
Str_Copy (UsrDat->Password,row[1],sizeof (UsrDat->Password) - 1);
2019-03-19 13:22:14 +01:00
/* Get roles */
switch (GetRoleInCurrentCrs)
{
case Usr_DONT_GET_ROLE_IN_CURRENT_CRS:
UsrDat->Roles.InCurrentCrs = Rol_UNK;
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
break;
case Usr_GET_ROLE_IN_CURRENT_CRS:
UsrDat->Roles.InCurrentCrs = Rol_GetRoleUsrInCrs (UsrDat->UsrCod,
Gbl.Hierarchy.Crs.CrsCod);
UsrDat->Roles.InCrss = -1; // Force roles to be got from database
break;
}
2016-05-01 01:52:35 +02:00
/* Get name (row[2], row[3], row[4]) */
Str_Copy (UsrDat->Surname1,row[2],sizeof (UsrDat->Surname1) - 1);
Str_Copy (UsrDat->Surname2,row[3],sizeof (UsrDat->Surname2) - 1);
Str_Copy (UsrDat->FrstName,row[4],sizeof (UsrDat->FrstName) - 1);
Str_ConvertToTitleType (UsrDat->Surname1 );
Str_ConvertToTitleType (UsrDat->Surname2 );
Str_ConvertToTitleType (UsrDat->FrstName);
Usr_BuildFullName (UsrDat); // Create full name using FirstName, Surname1 and Surname2
/* Get sex (row[5]) */
UsrDat->Sex = Usr_GetSexFromStr (row[5]);
/* Get photo (row[6]) */
Str_Copy (UsrDat->Photo,row[6],sizeof (UsrDat->Photo) - 1);
/* Get photo visibility (row[7]) */
UsrDat->PhotoVisibility = Pri_GetVisibilityFromStr (row[7]);
/* Get profile visibility (row[8], row[9]) */
UsrDat->BaPrfVisibility = Pri_GetVisibilityFromStr (row[8]);
UsrDat->ExPrfVisibility = Pri_GetVisibilityFromStr (row[9]);
/* Get country (row[10]), institution country (row[11]),
institution (row[12]), department (row[13]) and center (row[14]) */
UsrDat->CtyCod = Str_ConvertStrCodToLongCod (row[10]);
UsrDat->InsCtyCod = Str_ConvertStrCodToLongCod (row[11]);
UsrDat->InsCod = Str_ConvertStrCodToLongCod (row[12]);
UsrDat->Tch.DptCod = Str_ConvertStrCodToLongCod (row[13]);
UsrDat->Tch.CtrCod = Str_ConvertStrCodToLongCod (row[14]);
/* Get office (row[15]) and office phone (row[16]) */
Str_Copy (UsrDat->Tch.Office ,row[15],sizeof (UsrDat->Tch.Office ) - 1);
Str_Copy (UsrDat->Tch.OfficePhone,row[16],sizeof (UsrDat->Tch.OfficePhone) - 1);
/* Get phones (row[17]) and row[18] */
Str_Copy (UsrDat->Phone[0],row[17],sizeof (UsrDat->Phone[0]) - 1);
Str_Copy (UsrDat->Phone[1],row[18],sizeof (UsrDat->Phone[1]) - 1);
/* Get birthday (row[19]) */
Dat_GetDateFromYYYYMMDD (&(UsrDat->Birthday),row[19]);
Dat_ConvDateToDateStr (&(UsrDat->Birthday),UsrDat->StrBirthday);
/* Get comments (row[20]) */
Usr_GetUsrCommentsFromString (row[20] ? row[20] :
"",
UsrDat);
/* Get on which events the user wants to be notified inside the platform (row[21]) */
if (sscanf (row[21],"%u",&UsrDat->NtfEvents.CreateNotif) != 1)
UsrDat->NtfEvents.CreateNotif = (unsigned) -1; // 0xFF..FF
/* Get on which events the user wants to be notified by email (row[22]) */
if (sscanf (row[22],"%u",&UsrDat->NtfEvents.SendEmail) != 1)
UsrDat->NtfEvents.SendEmail = 0;
if (UsrDat->NtfEvents.SendEmail >= (1 << Ntf_NUM_NOTIFY_EVENTS)) // Maximum binary value for NotifyEvents is 000...0011...11
UsrDat->NtfEvents.SendEmail = 0;
/***** Get user's settings *****/
if (GetPrefs == Usr_GET_PREFS)
{
/* Get language (row[23]),
first day of week (row[24]),
date format (row[25]),
theme (row[26]),
icon set (row[27]),
menu (row[28]),
if user wants to show side columns (row[29]),
user settings on user photo shape (row[30]),
and if user accepts third party cookies (row[31]) */
UsrDat->Prefs.Language = Lan_GetLanguageFromStr (row[23]);
UsrDat->Prefs.FirstDayOfWeek = Cal_GetFirstDayOfWeekFromStr (row[24]);
UsrDat->Prefs.DateFormat = Dat_GetDateFormatFromStr (row[25]);
UsrDat->Prefs.Theme = The_GetThemeFromStr (row[26]);
UsrDat->Prefs.IconSet = Ico_GetIconSetFromStr (row[27]);
UsrDat->Prefs.Menu = Mnu_GetMenuFromStr (row[28]);
UsrDat->Prefs.SideCols = Set_GetSideColsFromStr (row[29]);
UsrDat->Prefs.PhotoShape = PhoSha_GetShapeFromStr (row[30]);
UsrDat->Prefs.AcceptCookies = (row[31][0] == 'Y');
}
2019-03-19 13:22:14 +01:00
}
else
Err_WrongUserExit ();
2014-12-01 23:55:08 +01:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
2016-11-16 23:19:52 +01:00
/***** Get nickname and email *****/
Nck_DB_GetNicknameFromUsrCod (UsrDat->UsrCod,UsrDat->Nickname);
2015-11-16 14:54:12 +01:00
Mai_GetEmailFromUsrCod (UsrDat);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********* Get the comments in the record of a user from a string ************/
/*****************************************************************************/
static void Usr_GetUsrCommentsFromString (char *Str,struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
/***** Check that memory for comments is allocated *****/
if (UsrDat->Comments)
/***** Copy comments from Str to Comments *****/
Str_Copy (UsrDat->Comments,Str,Cns_MAX_BYTES_TEXT - 1);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********** Get user's last data from database giving a user's code **********/
/*****************************************************************************/
static void Usr_GetMyLastData (void)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned UnsignedNum;
2019-04-01 13:15:15 +02:00
long ActCod;
2014-12-01 23:55:08 +01:00
2018-11-02 11:33:58 +01:00
/***** Get user's last data from database *****/
if (Usr_DB_GetMyLastData (&mysql_res))
2014-12-01 23:55:08 +01:00
{
row = mysql_fetch_row (mysql_res);
2019-04-01 13:15:15 +02:00
/* Get last type of search (row[0]) */
2017-01-29 12:42:19 +01:00
Gbl.Usrs.Me.UsrLast.WhatToSearch = Sch_SEARCH_UNKNOWN;
2014-12-01 23:55:08 +01:00
if (sscanf (row[0],"%u",&UnsignedNum) == 1)
if (UnsignedNum < Sch_NUM_WHAT_TO_SEARCH)
Gbl.Usrs.Me.UsrLast.WhatToSearch = (Sch_WhatToSearch_t) UnsignedNum;
2017-01-29 12:42:19 +01:00
if (Gbl.Usrs.Me.UsrLast.WhatToSearch == Sch_SEARCH_UNKNOWN)
Gbl.Usrs.Me.UsrLast.WhatToSearch = Sch_WHAT_TO_SEARCH_DEFAULT;
2014-12-01 23:55:08 +01:00
2019-04-01 23:15:17 +02:00
/* Get last hierarchy: scope (row[1]) and code (row[2]) */
Gbl.Usrs.Me.UsrLast.LastHie.Scope = Sco_GetScopeFromDBStr (row[1]);
switch (Gbl.Usrs.Me.UsrLast.LastHie.Scope)
{
case HieLvl_SYS: // System
2019-04-01 23:15:17 +02:00
Gbl.Usrs.Me.UsrLast.LastHie.Cod = -1L;
break;
case HieLvl_CTY: // Country
case HieLvl_INS: // Institution
case HieLvl_CTR: // Center
case HieLvl_DEG: // Degree
case HieLvl_CRS: // Course
2019-04-01 23:15:17 +02:00
Gbl.Usrs.Me.UsrLast.LastHie.Cod = Str_ConvertStrCodToLongCod (row[2]);
if (Gbl.Usrs.Me.UsrLast.LastHie.Cod <= 0)
{
Gbl.Usrs.Me.UsrLast.LastHie.Scope = HieLvl_UNK;
2019-04-01 23:15:17 +02:00
Gbl.Usrs.Me.UsrLast.LastHie.Cod = -1L;
}
break;
default:
Gbl.Usrs.Me.UsrLast.LastHie.Scope = HieLvl_UNK;
2019-04-01 23:15:17 +02:00
Gbl.Usrs.Me.UsrLast.LastHie.Cod = -1L;
break;
}
2014-12-01 23:55:08 +01:00
2019-04-01 13:15:15 +02:00
/* Get last action (row[3]) */
ActCod = Str_ConvertStrCodToLongCod (row[3]);
Gbl.Usrs.Me.UsrLast.LastAct = Act_GetActionFromActCod (ActCod);
2019-04-01 23:15:17 +02:00
/* Get last role (row[4]) */
2019-04-01 13:15:15 +02:00
Gbl.Usrs.Me.UsrLast.LastRole = Rol_ConvertUnsignedStrToRole (row[4]);
2019-04-03 21:49:10 +02:00
/* Get last access to platform (row[5]) */
Gbl.Usrs.Me.UsrLast.LastTime = 0L;
2019-04-01 13:15:15 +02:00
if (row[5])
2019-04-03 21:49:10 +02:00
sscanf (row[5],"%ld",&(Gbl.Usrs.Me.UsrLast.LastTime));
/* Get last access to notifications (row[6]) */
Gbl.Usrs.Me.UsrLast.LastAccNotif = 0L;
if (row[6])
sscanf (row[6],"%ld",&(Gbl.Usrs.Me.UsrLast.LastAccNotif));
2014-12-01 23:55:08 +01:00
}
else // No user's last data found
{
/***** Create entry for me in table of user's last data *****/
Usr_ResetMyLastData ();
Usr_DB_InsertMyLastData ();
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****************************** Get sex from string **************************/
/*****************************************************************************/
static Usr_Sex_t Usr_GetSexFromStr (const char *Str)
{
Usr_Sex_t Sex;
2019-12-15 20:02:34 +01:00
for (Sex = (Usr_Sex_t) 0;
Sex <= (Usr_Sex_t) (Usr_NUM_SEXS - 1);
2014-12-01 23:55:08 +01:00
Sex++)
if (!strcasecmp (Str,Usr_StringsSexDB[Sex]))
return Sex;
return Usr_SEX_UNKNOWN;
}
/*****************************************************************************/
/********** Build full name using FirstName, Surname1 and Surname2 ***********/
/*****************************************************************************/
void Usr_BuildFullName (struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
Str_Copy (UsrDat->FullName,UsrDat->FrstName,sizeof (UsrDat->FullName) - 1);
2014-12-01 23:55:08 +01:00
if (UsrDat->Surname1[0])
{
Str_Concat (UsrDat->FullName," " ,sizeof (UsrDat->FullName) - 1);
Str_Concat (UsrDat->FullName,UsrDat->Surname1,sizeof (UsrDat->FullName) - 1);
2014-12-01 23:55:08 +01:00
}
if (UsrDat->Surname2[0])
{
Str_Concat (UsrDat->FullName," " ,sizeof (UsrDat->FullName) - 1);
Str_Concat (UsrDat->FullName,UsrDat->Surname2,sizeof (UsrDat->FullName) - 1);
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
2017-03-05 15:12:48 +01:00
/********* Write user name in two lines. 1: first name, 2: surnames **********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
void Usr_WriteFirstNameBRSurnames (const struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
2017-03-05 15:12:48 +01:00
/***** Write first name and surname 1 *****/
HTM_Txt (UsrDat->FrstName);
2019-11-09 21:08:20 +01:00
HTM_BR ();
2019-11-10 12:36:37 +01:00
HTM_Txt (UsrDat->Surname1);
2014-12-01 23:55:08 +01:00
2017-03-05 15:12:48 +01:00
/***** Write surname2 if exists *****/
2014-12-01 23:55:08 +01:00
if (UsrDat->Surname2[0])
2019-11-11 10:59:24 +01:00
HTM_TxtF ("&nbsp;%s",UsrDat->Surname2);
2014-12-01 23:55:08 +01:00
}
2017-07-02 20:36:15 +02:00
/*****************************************************************************/
/********************* Flush all caches related to users *********************/
/*****************************************************************************/
void Usr_FlushCachesUsr (void)
{
Ins_FlushCacheUsrBelongsToIns ();
Ctr_FlushCacheUsrBelongsToCtr ();
Deg_FlushCacheUsrBelongsToDeg ();
Enr_FlushCacheUsrBelongsToCrs ();
Enr_FlushCacheUsrBelongsToCurrentCrs ();
Enr_FlushCacheUsrHasAcceptedInCurrentCrs ();
Enr_FlushCacheUsrSharesAnyOfMyCrs ();
Rol_FlushCacheMyRoleInCurrentCrs ();
2017-07-02 20:36:15 +02:00
Rol_FlushCacheRoleUsrInCrs ();
Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs ();
Grp_FlushCacheIBelongToGrp ();
2019-02-22 14:04:54 +01:00
Fol_FlushCacheFollow ();
2017-07-02 20:36:15 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********************* Check if a user is a superuser ************************/
/*****************************************************************************/
2017-06-20 14:43:26 +02:00
void Usr_FlushCacheUsrIsSuperuser (void)
{
Gbl.Cache.UsrIsSuperuser.UsrCod = -1L;
Gbl.Cache.UsrIsSuperuser.IsSuperuser = false;
}
2014-12-01 23:55:08 +01:00
bool Usr_CheckIfUsrIsSuperuser (long UsrCod)
{
2017-06-20 14:43:26 +02:00
/***** 1. Fast check: Trivial case *****/
2017-01-27 01:02:52 +01:00
if (UsrCod <= 0)
2017-06-20 14:43:26 +02:00
return false;
/***** 2. Fast check: If cached... *****/
if (UsrCod == Gbl.Cache.UsrIsSuperuser.UsrCod)
return Gbl.Cache.UsrIsSuperuser.IsSuperuser;
2017-01-27 01:02:52 +01:00
2017-06-20 14:43:26 +02:00
/***** 3. Slow check: If not cached, get if a user is superuser from database *****/
Gbl.Cache.UsrIsSuperuser.UsrCod = UsrCod;
Gbl.Cache.UsrIsSuperuser.IsSuperuser = Adm_DB_CheckIfUsrIsSuperuser (UsrCod);
2017-06-20 14:43:26 +02:00
return Gbl.Cache.UsrIsSuperuser.IsSuperuser;
2017-01-27 01:02:52 +01:00
}
2017-01-27 10:42:20 +01:00
/*****************************************************************************/
/**************** Check if I can change another user's data ******************/
/*****************************************************************************/
bool Usr_ICanChangeOtherUsrData (const struct Usr_Data *UsrDat)
2017-01-27 10:42:20 +01:00
{
/***** I can change my data *****/
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
2017-01-27 10:42:20 +01:00
return true;
/***** Check if I have permission to see another user's IDs *****/
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2017-01-27 10:42:20 +01:00
{
2017-05-18 19:13:41 +02:00
case Rol_TCH:
2017-01-27 15:21:01 +01:00
/* Check 1: I can change data of users who do not exist in database */
if (UsrDat->UsrCod <= 0) // User does not exist (when creating a new user)
return true;
2017-01-27 18:45:38 +01:00
/* Check 2: I change data of users without password */
if (!UsrDat->Password[0]) // User has no password (never logged)
2017-01-27 15:21:01 +01:00
return true;
return false;
2017-01-27 10:42:20 +01:00
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
2017-01-28 18:08:06 +01:00
return Usr_ICanEditOtherUsr (UsrDat);
2017-01-27 10:42:20 +01:00
default:
return false;
}
}
2017-01-27 01:02:52 +01:00
/*****************************************************************************/
2017-01-28 18:08:06 +01:00
/***************** Check if I can edit another user's data *******************/
2017-01-27 01:02:52 +01:00
/*****************************************************************************/
bool Usr_ICanEditOtherUsr (const struct Usr_Data *UsrDat)
2017-01-27 01:02:52 +01:00
{
/***** I can edit me *****/
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
2017-01-28 18:08:06 +01:00
return true;
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2017-01-27 01:02:52 +01:00
{
case Rol_DEG_ADM:
/* If I am an administrator of current degree,
I only can edit users from current degree who have accepted */
if (Deg_CheckIfUsrBelongsToDeg (UsrDat->UsrCod,Gbl.Hierarchy.Deg.DegCod))
2017-01-27 01:02:52 +01:00
// Degree admins can't edit superusers' data
if (!Usr_CheckIfUsrIsSuperuser (UsrDat->UsrCod))
return true;
return false;
case Rol_CTR_ADM:
/* If I am an administrator of current center,
I only can edit from current center who have accepted */
if (Ctr_CheckIfUsrBelongsToCtr (UsrDat->UsrCod,Gbl.Hierarchy.Ctr.CtrCod))
// Center admins can't edit superusers' data
2017-01-27 01:02:52 +01:00
if (!Usr_CheckIfUsrIsSuperuser (UsrDat->UsrCod))
return true;
return false;
case Rol_INS_ADM:
/* If I am an administrator of current institution,
I only can edit from current institution who have accepted */
if (Ins_CheckIfUsrBelongsToIns (UsrDat->UsrCod,Gbl.Hierarchy.Ins.InsCod))
2017-01-27 01:02:52 +01:00
// Institution admins can't edit superusers' data
if (!Usr_CheckIfUsrIsSuperuser (UsrDat->UsrCod))
return true;
return false;
case Rol_SYS_ADM:
return true;
default:
return false;
}
2014-12-01 23:55:08 +01:00
}
2016-12-09 13:59:33 +01:00
/*****************************************************************************/
/************ Check if I can view the record card of a student ***************/
/*****************************************************************************/
bool Usr_CheckIfICanViewRecordStd (const struct Usr_Data *UsrDat)
2016-12-09 13:59:33 +01:00
{
2017-06-23 15:12:49 +02:00
/***** 1. Fast check: Am I logged? *****/
if (!Gbl.Usrs.Me.Logged)
return false;
/***** 2. Fast check: Is it a valid user code? *****/
if (UsrDat->UsrCod <= 0)
return false;
/***** 3. Fast check: Is it a course selected? *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Hierarchy.Crs.CrsCod <= 0)
2017-06-23 15:12:49 +02:00
return false;
/***** 4. Fast check: Is he/she a student? *****/
if (UsrDat->Roles.InCurrentCrs != Rol_STD)
2017-06-23 15:12:49 +02:00
return false;
/***** 5. Fast check: Am I a system admin? *****/
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
return true;
/***** 6. Fast check: Do I belong to the current course? *****/
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
return false;
/***** 7. Fast check: It's me? *****/
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
2017-06-23 15:12:49 +02:00
return true;
/***** 8. Fast / slow check: Does he/she belong to the current course? *****/
if (!Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
2017-01-28 15:58:46 +01:00
return false;
2016-12-09 13:59:33 +01:00
2017-06-23 15:12:49 +02:00
/***** 9. Fast / slow check depending on roles *****/
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2017-01-28 15:58:46 +01:00
{
2017-05-18 19:13:41 +02:00
case Rol_STD:
2017-05-23 00:40:03 +02:00
case Rol_NET:
2017-06-23 15:12:49 +02:00
return Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (UsrDat);
2017-05-18 19:13:41 +02:00
case Rol_TCH:
2017-01-28 15:58:46 +01:00
return true;
default:
return false;
}
2016-12-09 13:59:33 +01:00
}
/*****************************************************************************/
/************ Check if I can view the record card of a teacher ***************/
/*****************************************************************************/
2017-05-23 20:42:38 +02:00
// Teacher here is intended as:
// - a non-editing teacher
// - or a teacher
2016-12-09 13:59:33 +01:00
bool Usr_CheckIfICanViewRecordTch (struct Usr_Data *UsrDat)
2016-12-09 13:59:33 +01:00
{
2016-12-13 13:32:19 +01:00
/***** 1. Fast check: Am I logged? *****/
if (!Gbl.Usrs.Me.Logged)
2016-12-09 13:59:33 +01:00
return false;
2017-06-23 15:12:49 +02:00
/***** 2. Fast check: Is it a valid user code? *****/
if (UsrDat->UsrCod <= 0)
2016-12-09 13:59:33 +01:00
return false;
2019-03-07 22:15:47 +01:00
/***** 3. Fast check: Is it a course selected? *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Hierarchy.Crs.CrsCod <= 0)
2019-03-07 22:15:47 +01:00
return false;
2016-12-09 13:59:33 +01:00
2019-03-07 22:15:47 +01:00
/***** 4. Fast check: Is he/she a non-editing teacher or a teacher? *****/
return (UsrDat->Roles.InCurrentCrs == Rol_NET ||
UsrDat->Roles.InCurrentCrs == Rol_TCH);
2016-12-09 13:59:33 +01:00
}
2017-06-08 15:32:33 +02:00
/*****************************************************************************/
2020-04-22 03:15:04 +02:00
/********* Check if I can view test/exam/match result of another user ********/
2017-06-08 15:32:33 +02:00
/*****************************************************************************/
bool Usr_CheckIfICanViewTstExaMchResult (const struct Usr_Data *UsrDat)
2019-09-22 14:15:38 +02:00
{
/***** 1. Fast check: Am I logged? *****/
if (!Gbl.Usrs.Me.Logged)
return false;
/***** 2. Fast check: Is it a valid user code? *****/
if (UsrDat->UsrCod <= 0)
return false;
/***** 3. Fast check: Is it a course selected? *****/
if (Gbl.Hierarchy.Crs.CrsCod <= 0)
return false;
/***** 4. Fast check: Am I a system admin? *****/
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
return true;
/***** 5. Fast check: Do I belong to the current course? *****/
2017-06-08 15:32:33 +02:00
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
return false;
2017-06-23 15:12:49 +02:00
/***** 6. Fast check: It's me? *****/
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
2017-06-08 15:32:33 +02:00
return true;
2017-06-23 15:12:49 +02:00
/***** 7. Fast check: Does he/she belong to the current course? *****/
if (!Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
2017-06-08 15:32:33 +02:00
return false;
2017-06-23 15:12:49 +02:00
/***** 8. Fast / slow check depending on roles *****/
2017-06-08 15:32:33 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_NET:
2017-06-09 15:04:02 +02:00
return Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (UsrDat);
2017-06-08 15:32:33 +02:00
case Rol_TCH:
return true;
default:
return false;
}
}
2017-10-05 22:29:33 +02:00
/*****************************************************************************/
/********** Check if I can view assigments / works of another user ***********/
/*****************************************************************************/
bool Usr_CheckIfICanViewAsgWrk (const struct Usr_Data *UsrDat)
2017-10-05 22:29:33 +02:00
{
/***** 1. Fast check: Am I logged? *****/
if (!Gbl.Usrs.Me.Logged)
return false;
/***** 2. Fast check: Is it a valid user code? *****/
if (UsrDat->UsrCod <= 0)
return false;
/***** 3. Fast check: Is it a course selected? *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Hierarchy.Crs.CrsCod <= 0)
2017-10-05 22:29:33 +02:00
return false;
/***** 4. Fast check: Does he/she belong to the current course? *****/
// Only users beloging to course can have files in assignments/works
if (!Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat))
2017-10-05 22:29:33 +02:00
return false;
/***** 5. Fast check: Am I a system admin? *****/
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
return true;
/***** 6. Fast check: Do I belong to the current course? *****/
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
return false;
/***** 7. Fast check: It's me? *****/
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
2017-10-05 22:29:33 +02:00
return true;
/***** 8. Fast / slow check depending on roles *****/
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_NET:
return Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (UsrDat);
case Rol_TCH:
return true;
default:
return false;
}
}
/*****************************************************************************/
/************** Check if I can view attendance of another user ***************/
/*****************************************************************************/
bool Usr_CheckIfICanViewAtt (const struct Usr_Data *UsrDat)
2017-10-05 22:29:33 +02:00
{
/***** 1. Fast check: Am I logged? *****/
if (!Gbl.Usrs.Me.Logged)
return false;
/***** 2. Fast check: Is it a valid user code? *****/
if (UsrDat->UsrCod <= 0)
return false;
/***** 3. Fast check: Is it a course selected? *****/
2019-04-04 10:45:15 +02:00
if (Gbl.Hierarchy.Crs.CrsCod <= 0)
2017-10-05 22:29:33 +02:00
return false;
2019-04-11 23:15:40 +02:00
/***** 4. Fast check: Am I a system admin? *****/
2017-10-05 22:29:33 +02:00
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
return true;
2019-04-11 23:15:40 +02:00
/***** 5. Fast check: Do I belong to the current course? *****/
2017-10-05 22:29:33 +02:00
if (!Gbl.Usrs.Me.IBelongToCurrentCrs)
return false;
2019-04-11 23:15:40 +02:00
/***** 6. Fast check: It's me? *****/
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
2017-10-05 22:29:33 +02:00
return true;
2019-04-11 23:15:40 +02:00
/***** 7. Fast / slow check depending on roles *****/
2017-10-05 22:29:33 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_NET:
return Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (UsrDat);
case Rol_TCH:
return true;
default:
return false;
}
}
2016-12-09 13:59:33 +01:00
/*****************************************************************************/
/******************* Check if I can view a user's agenda *********************/
/*****************************************************************************/
bool Usr_CheckIfICanViewUsrAgenda (struct Usr_Data *UsrDat)
2016-12-09 13:59:33 +01:00
{
/***** 1. Fast check: Am I logged? *****/
if (!Gbl.Usrs.Me.Logged)
return false;
/***** 2. Fast check: It's me? *****/
if (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME)
return true;
2014-12-01 23:55:08 +01:00
/***** 3. Fast check: Am I logged as system admin? *****/
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
return true;
2014-12-01 23:55:08 +01:00
/***** 4. Slow check: Get if user shares any course with me from database *****/
return Enr_CheckIfUsrSharesAnyOfMyCrs (UsrDat);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2016-03-01 03:16:29 +01:00
/***************************** Write landing page ****************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-03-01 03:16:29 +01:00
void Usr_WriteLandingPage (void)
2014-12-01 23:55:08 +01:00
{
2016-03-01 03:16:29 +01:00
/***** Form to log in *****/
2016-12-05 13:26:12 +01:00
Usr_WriteFormLogin (ActLogIn,NULL);
2015-10-06 01:19:21 +02:00
2016-03-21 19:52:40 +01:00
/***** Form to go to request the creation of a new account *****/
Acc_ShowFormGoToRequestNewAccount ();
2016-03-01 03:16:29 +01:00
}
/*****************************************************************************/
/************************ Write form for user log out ************************/
/*****************************************************************************/
void Usr_WriteFormLogout (void)
{
/***** Form to change my role *****/
Usr_ShowFormsLogoutAndRole ();
2017-03-30 11:20:06 +02:00
/***** Show help to enrol me *****/
2016-03-01 03:16:29 +01:00
Hlp_ShowHelpWhatWouldYouLikeToDo ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************* Message and form shown after log out ******************/
/*****************************************************************************/
void Usr_Logout (void)
{
2019-02-14 19:22:38 +01:00
// extern const char *Txt_The_session_has_been_closed;
2014-12-01 23:55:08 +01:00
/***** Confirmation message *****/
2019-02-16 14:37:34 +01:00
// Ale_ShowFixedAlert (Ale_INFO,Txt_The_session_has_been_closed);
2014-12-01 23:55:08 +01:00
/***** Form to log in *****/
2016-12-05 13:26:12 +01:00
Usr_WriteFormLogin (ActLogIn,NULL);
2014-12-01 23:55:08 +01:00
/***** Advertisement about mobile app *****/
Lay_AdvertisementMobile ();
}
2016-02-29 16:22:11 +01:00
/*****************************************************************************/
/*************************** Put link to log in ******************************/
/*****************************************************************************/
void Usr_PutLinkToLogin (void)
{
extern const char *Txt_Log_in;
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkIconText (ActFrmLogIn,NULL,
NULL,NULL,
"sign-in-alt.svg",Ico_GREEN,
Txt_Log_in,NULL);
2016-02-29 16:22:11 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************************ Write form for user log in *************************/
/*****************************************************************************/
void Usr_WriteFormLogin (Act_Action_t NextAction,void (*FuncPars) (void))
2014-12-01 23:55:08 +01:00
{
2017-03-02 21:18:52 +01:00
extern const char *Hlp_PROFILE_LogIn;
2015-03-27 16:56:48 +01:00
extern const char *Txt_Log_in;
2016-06-15 14:42:28 +02:00
extern const char *Txt_User[Usr_NUM_SEXS];
2014-12-01 23:55:08 +01:00
extern const char *Txt_nick_email_or_ID;
extern const char *Txt_Password;
2015-03-27 16:56:48 +01:00
extern const char *Txt_password;
2014-12-01 23:55:08 +01:00
2019-10-24 09:46:20 +02:00
/***** Contextual menu *****/
Mnu_ContextMenuBegin ();
Acc_PutLinkToCreateAccount (); // Create account
Pwd_PutLinkToSendNewPasswd (); // Send new password
Lan_PutLinkToChangeLanguage (); // Change language
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuEnd ();
2014-12-01 23:55:08 +01:00
2019-10-24 00:04:40 +02:00
HTM_DIV_Begin ("class=\"CM\"");
2016-12-04 03:50:25 +01:00
/***** Begin form *****/
Frm_BeginForm (NextAction);
if (FuncPars)
FuncPars ();
/***** Begin box and table *****/
Box_BoxTableBegin (NULL,Txt_Log_in,
NULL,NULL,
Hlp_PROFILE_LogIn,Box_NOT_CLOSABLE,2);
/***** User's ID/nickname *****/
HTM_DIV_Begin ("class=\"LM\"");
HTM_LABEL_Begin ("for=\"UsrId\"");
Ico_PutIcon ("user.svg",Ico_BLACK,
Txt_User[Usr_SEX_UNKNOWN],"CONTEXT_ICO16x16");
HTM_LABEL_End ();
HTM_INPUT_TEXT ("UsrId",Cns_MAX_CHARS_EMAIL_ADDRESS,Gbl.Usrs.Me.UsrIdLogin,
HTM_DONT_SUBMIT_ON_CHANGE,
"id=\"UsrId\" size=\"18\" placeholder=\"%s\""
" class=\"INPUT_%s\" autofocus=\"autofocus\""
" required=\"required\"",
Txt_nick_email_or_ID,
The_GetSuffix ());
HTM_DIV_End ();
2016-12-26 16:58:49 +01:00
/***** User's password *****/
HTM_DIV_Begin ("class=\"LM\"");
HTM_LABEL_Begin ("for=\"UsrPwd\"");
Ico_PutIcon ("key.svg",Ico_BLACK,
Txt_Password,"CONTEXT_ICO16x16");
HTM_LABEL_End ();
HTM_INPUT_PASSWORD ("UsrPwd",Txt_password,NULL,false,
"id=\"UsrPwd\" class=\"INPUT_%s\"",
The_GetSuffix ());
HTM_DIV_End ();
2014-12-01 23:55:08 +01:00
/***** End table, send button and end box *****/
Box_BoxTableWithButtonEnd (Btn_CONFIRM_BUTTON,Txt_Log_in);
2016-12-04 03:50:25 +01:00
/***** End form *****/
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
2019-10-23 20:07:56 +02:00
HTM_DIV_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************* Write type and name of logged user **********************/
/*****************************************************************************/
void Usr_WelcomeUsr (void)
{
extern const char *Ico_IconSetId[Ico_NUM_ICON_SETS];
2018-12-09 10:46:57 +01:00
extern const unsigned Txt_Current_CGI_SWAD_Language;
2019-02-15 13:59:30 +01:00
extern const char *Txt_NEW_YEAR_GREETING;
2019-02-14 23:03:47 +01:00
extern const char *Txt_Happy_birthday_X;
2019-02-14 13:22:11 +01:00
extern const char *Txt_Please_check_your_email_address;
extern const char *Txt_Check;
2018-12-08 16:43:13 +01:00
extern const char *Txt_Switching_to_LANGUAGE[1 + Lan_NUM_LANGUAGES];
char URLIconSet[PATH_MAX + 1];
unsigned CurrentDay = Dat_GetCurrentDay ();
unsigned CurrentMonth = Dat_GetCurrentMonth ();
unsigned CurrentYear = Dat_GetCurrentYear ();
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Me.Logged)
{
2018-12-09 10:46:57 +01:00
if (Gbl.Usrs.Me.UsrDat.Prefs.Language == Txt_Current_CGI_SWAD_Language)
2014-12-01 23:55:08 +01:00
{
if (Gbl.Usrs.Me.UsrDat.FrstName[0])
2014-12-01 23:55:08 +01:00
{
2019-02-15 13:59:30 +01:00
/***** New year greeting *****/
if (CurrentDay == 1 && CurrentMonth == 1)
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_INFO,Txt_NEW_YEAR_GREETING,
CurrentYear);
2019-02-15 13:59:30 +01:00
2019-02-15 12:12:26 +01:00
/***** Birthday congratulation *****/
if (Gbl.Usrs.Me.UsrDat.Birthday.Day == CurrentDay &&
Gbl.Usrs.Me.UsrDat.Birthday.Month == CurrentMonth)
if (Usr_DB_CheckIfMyBirthdayHasNotBeenCongratulated ())
2014-12-01 23:55:08 +01:00
{
2019-02-15 12:12:26 +01:00
/* Mark my birthday as already congratulated */
Usr_DB_DeleteOldBirthdays ();
Usr_DB_MarkMyBirthdayAsCongratulated ();
2019-02-15 12:12:26 +01:00
/* Begin alert */
2019-02-17 01:14:55 +01:00
Ale_ShowAlertAndButton1 (Ale_INFO,Txt_Happy_birthday_X,
Gbl.Usrs.Me.UsrDat.FrstName);
2019-02-15 12:12:26 +01:00
/* Show cake icon */
snprintf (URLIconSet,sizeof (URLIconSet),"%s/%s",
Cfg_URL_ICON_SETS_PUBLIC,Ico_IconSetId[Gbl.Prefs.IconSet]);
HTM_IMG (URLIconSet,"birthday-cake.svg",NULL,
2019-10-30 22:31:03 +01:00
"class=\"ICO160x160\"");
2019-02-15 12:12:26 +01:00
/* End alert */
2020-03-26 02:54:30 +01:00
Ale_ShowAlertAndButton2 (ActUnk,NULL,NULL,
NULL,NULL,
Btn_NO_BUTTON,NULL);
2014-12-01 23:55:08 +01:00
}
2019-02-14 13:22:11 +01:00
2019-02-15 12:12:26 +01:00
/***** Alert with button to check email address *****/
2019-02-14 23:03:47 +01:00
if ( Gbl.Usrs.Me.UsrDat.Email[0] &&
!Gbl.Usrs.Me.UsrDat.EmailConfirmed) // Email needs to be confirmed
2020-03-26 02:54:30 +01:00
Ale_ShowAlertAndButton (ActFrmMyAcc,NULL,NULL,
NULL,NULL,
2019-02-17 01:14:55 +01:00
Btn_CONFIRM_BUTTON,Txt_Check,
Ale_WARNING,Txt_Please_check_your_email_address);
2014-12-01 23:55:08 +01:00
}
2019-12-19 11:00:14 +01:00
/***** Games tool *****/
/*
2019-12-17 00:36:22 +01:00
Ale_ShowAlert (Ale_INFO,
"Herramienta <a href=\"https://github.com/acanas/swad-core/wiki/ASSESSMENT.Games.es\" target=\"_blank\">"
"Evaluaci&oacute;n &gt; Juegos</a><br />"
"<br />"
"Imagen de la izquierda: pantalla proyectada en el aula por el profesor.<br />"
"Imagen de la derecha: pantalla del estudiante en su m&oacute;vil."
"<br />"
"<br />"
"<img src=\"/img/juego.png\" alt=\"Juegos\" style=\"width:100%%\">");
2019-12-19 11:00:14 +01:00
*/
2019-12-17 00:36:22 +01:00
2018-11-14 11:49:41 +01:00
/***** Institutional video *****/
2018-12-08 16:43:13 +01:00
/*
2019-12-17 00:36:22 +01:00
Ale_ShowAlert (Ale_INFO,
2018-11-14 11:49:41 +01:00
"<a href=\"https://abierta.ugr.es/creative_commons/\" target=\"_blank\">"
"Curso MOOC LICENCIAS CREATIVE COMMONS Y OER</a><br />"
2018-12-08 12:56:19 +01:00
"Reconocimiento de 1 cr&eacute;dito por actividades universitarias<br />"
"&iexcl;&Uacute;ltimos d&iacute;as!<br />"
2018-11-14 11:49:41 +01:00
"<br />"
"<video style=\"width:480px; height:270px;\""
" poster=\"/img/abierta-ugr-creative-commons1280x720.jpg\""
" controls>"
"<source src=\"https://abierta.ugr.es/creative_commons/promo_cc.mp4\""
" type=\"video/mp4\">"
"<img src=\"/img/abierta-ugr-creative-commons1280x720.jpg\""
" class=\"img-responsive\""
" alt=\"Responsive image\">"
"</video>");
2018-12-08 16:43:13 +01:00
*/
2018-11-14 11:49:41 +01:00
2014-12-01 23:55:08 +01:00
/***** Show the global announcements I have not seen *****/
Ann_ShowMyAnnouncementsNotMarkedAsSeen ();
}
2016-12-05 13:26:12 +01:00
else
/* The current language is not my preferred language
==> change automatically to my language */
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_INFO,Txt_Switching_to_LANGUAGE[Gbl.Usrs.Me.UsrDat.Prefs.Language]);
2014-12-01 23:55:08 +01:00
}
}
2016-05-01 01:52:35 +02:00
/*****************************************************************************/
/************ Write birthday string to insert or update database *************/
/*****************************************************************************/
2018-10-08 12:37:29 +02:00
// It can include start and ending apostrophes
2016-05-01 01:52:35 +02:00
void Usr_CreateBirthdayStrDB (const struct Usr_Data *UsrDat,
2017-01-15 22:58:26 +01:00
char BirthdayStrDB[Usr_BIRTHDAY_STR_DB_LENGTH + 1])
2016-05-01 01:52:35 +02:00
{
char BirthdayStrTmp[1 + Cns_MAX_DECIMAL_DIGITS_UINT +
1 + Cns_MAX_DECIMAL_DIGITS_UINT +
1 + Cns_MAX_DECIMAL_DIGITS_UINT +
1 + 1];
2016-05-01 01:52:35 +02:00
if (UsrDat->Birthday.Year == 0 ||
UsrDat->Birthday.Month == 0 ||
UsrDat->Birthday.Day == 0)
Str_Copy (BirthdayStrDB,"NULL",Usr_BIRTHDAY_STR_DB_LENGTH); // Without apostrophes
2016-05-01 01:52:35 +02:00
else
{
sprintf (BirthdayStrTmp,"'%04u-%02u-%02u'", // With apostrophes
UsrDat->Birthday.Year,
UsrDat->Birthday.Month,
UsrDat->Birthday.Day);
Str_Copy (BirthdayStrDB,BirthdayStrTmp,Usr_BIRTHDAY_STR_DB_LENGTH);
}
2016-05-01 01:52:35 +02:00
}
/*****************************************************************************/
/************************* Filter some user's data ***************************/
/*****************************************************************************/
void Usr_FilterUsrBirthday (struct Dat_Date *Birthday)
{
unsigned CurrentYear = Dat_GetCurrentYear ();
/***** Fix birthday *****/
if (Birthday->Year < CurrentYear - 99 ||
Birthday->Year > CurrentYear - 16)
Birthday->Year =
Birthday->Month =
Birthday->Day = 0;
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************************ Write form for user log in *************************/
/*****************************************************************************/
void Usr_PutFormLogIn (void)
{
Frm_BeginForm (ActFrmLogIn);
Ico_PutIconLink ("sign-in-alt.svg",Ico_WHITE,ActFrmLogIn);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************* Write type and name of logged user **********************/
/*****************************************************************************/
void Usr_WriteLoggedUsrHead (void)
{
2016-11-13 12:52:07 +01:00
extern const char *Txt_Role;
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC18x24",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE18x24",
[PhoSha_SHAPE_OVAL ] = "PHOTOO18x24",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR18x24",
};
2017-03-06 01:31:06 +01:00
unsigned NumAvailableRoles = Rol_GetNumAvailableRoles ();
char *ClassSelect;
2017-03-06 01:31:06 +01:00
HTM_DIV_Begin ("class=\"HEAD_USR USR_%s\"",The_GetSuffix ());
2014-12-01 23:55:08 +01:00
/***** User's role *****/
if (NumAvailableRoles == 1)
{
Frm_BeginForm (ActFrmRolSes);
HTM_BUTTON_Submit_Begin (Txt_Role,"class=\"BT_LINK\"");
HTM_Txt (Txt_ROLES_SINGUL_Abc[Gbl.Usrs.Me.Role.Logged][Gbl.Usrs.Me.UsrDat.Sex]);
HTM_BUTTON_End ();
Frm_EndForm ();
2019-11-18 20:12:10 +01:00
HTM_Colon ();
}
else
{
if (asprintf (&ClassSelect,"SEL_ROLE INPUT_%s",
The_GetSuffix ()) < 0)
Err_NotEnoughMemoryExit ();
Rol_PutFormToChangeMyRole (ClassSelect);
free (ClassSelect);
}
HTM_NBSP ();
2014-12-01 23:55:08 +01:00
/***** Show my photo *****/
Pho_ShowUsrPhotoIfAllowed (&Gbl.Usrs.Me.UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
2014-12-01 23:55:08 +01:00
/***** User's name *****/
if (Gbl.Usrs.Me.UsrDat.FrstName[0])
HTM_TxtF ("&nbsp;%s",Gbl.Usrs.Me.UsrDat.FrstName);
2014-12-01 23:55:08 +01:00
2019-10-23 20:07:56 +02:00
HTM_DIV_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************** Put a form to close current session (log out) ***************/
/*****************************************************************************/
void Usr_PutFormLogOut (void)
{
Frm_BeginForm (ActLogOut);
Ico_PutIconLink ("sign-out-alt.svg",Ico_WHITE,ActLogOut);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******* Get parameter with my plain user's ID or nickname from a form *******/
/*****************************************************************************/
void Usr_GetParUsrIdLogin (void)
2014-12-01 23:55:08 +01:00
{
Par_GetParText ("UsrId",Gbl.Usrs.Me.UsrIdLogin,sizeof (Gbl.Usrs.Me.UsrIdLogin) - 1);
2016-09-23 15:03:25 +02:00
// Users' IDs are always stored internally without leading zeros
2014-12-01 23:55:08 +01:00
Str_RemoveLeadingZeros (Gbl.Usrs.Me.UsrIdLogin);
}
/*****************************************************************************/
/******* Get parameter user's identificator of other user from a form ********/
/*****************************************************************************/
static void Usr_GetParOtherUsrIDNickOrEMail (void)
2014-12-01 23:55:08 +01:00
{
2016-11-16 23:19:52 +01:00
/***** Get parameter with the plain user's ID, @nick or email of another user *****/
Par_GetParText ("OtherUsrIDNickOrEMail",
2017-01-29 21:41:08 +01:00
Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail,
sizeof (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail) - 1);
2014-12-01 23:55:08 +01:00
// If it's a user's ID (if does not contain '@')
2015-10-07 19:55:13 +02:00
if (strchr (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail,(int) '@') != NULL) // '@' not found
2014-12-01 23:55:08 +01:00
{
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail);
2016-03-21 19:52:40 +01:00
// Str_ConvertToUpperText (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail);
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/******* Get parameter user's identificator of other user from a form ********/
/******* and get user's data ********/
/*****************************************************************************/
2016-11-16 23:19:52 +01:00
// Returns the number of users for a given ID, @nick or email
2014-12-01 23:55:08 +01:00
unsigned Usr_GetParOtherUsrIDNickOrEMailAndGetUsrCods (struct Usr_ListUsrCods *ListUsrCods)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_The_ID_nickname_or_email_X_is_not_valid;
2015-10-07 19:55:13 +02:00
bool Wrong = false;
2014-12-01 23:55:08 +01:00
/***** Reset default list of users' codes *****/
ListUsrCods->NumUsrs = 0;
ListUsrCods->Lst = NULL;
2016-11-16 23:19:52 +01:00
/***** Get parameter with the plain user's ID, @nick or email of another user *****/
Usr_GetParOtherUsrIDNickOrEMail ();
2014-12-01 23:55:08 +01:00
2016-11-16 23:19:52 +01:00
/***** Check if it's an ID, a nickname or an email address *****/
2015-10-07 19:55:13 +02:00
if (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail[0])
2014-12-01 23:55:08 +01:00
{
if (Nck_CheckIfNickWithArrIsValid (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail)) // 1: It's a nickname
2014-12-01 23:55:08 +01:00
{
2015-10-07 19:55:13 +02:00
if ((Gbl.Usrs.Other.UsrDat.UsrCod = Nck_GetUsrCodFromNickname (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail)) > 0)
{
ListUsrCods->NumUsrs = 1; // One user found
Usr_AllocateListUsrCods (ListUsrCods);
ListUsrCods->Lst[0] = Gbl.Usrs.Other.UsrDat.UsrCod;
}
2014-12-01 23:55:08 +01:00
}
2016-11-16 23:19:52 +01:00
else if (Mai_CheckIfEmailIsValid (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail)) // 2: It's an email
2014-12-01 23:55:08 +01:00
{
if ((Gbl.Usrs.Other.UsrDat.UsrCod = Mai_DB_GetUsrCodFromEmail (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail)) > 0)
2015-10-07 19:55:13 +02:00
{
ListUsrCods->NumUsrs = 1; // One user found
Usr_AllocateListUsrCods (ListUsrCods);
ListUsrCods->Lst[0] = Gbl.Usrs.Other.UsrDat.UsrCod;
}
2014-12-01 23:55:08 +01:00
}
2016-11-16 23:19:52 +01:00
else // 3: It's not a nickname nor email
2014-12-01 23:55:08 +01:00
{
2015-10-07 19:55:13 +02:00
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail);
if (ID_CheckIfUsrIDIsValid (Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail))
2014-12-01 23:55:08 +01:00
{
2016-03-21 19:52:40 +01:00
/* Allocate space for the list */
ID_ReallocateListIDs (&Gbl.Usrs.Other.UsrDat,1);
2014-12-01 23:55:08 +01:00
2017-01-15 18:02:52 +01:00
Str_Copy (Gbl.Usrs.Other.UsrDat.IDs.List[0].ID,
Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail,
sizeof (Gbl.Usrs.Other.UsrDat.IDs.List[0].ID) - 1);
2016-03-21 19:52:40 +01:00
Str_ConvertToUpperText (Gbl.Usrs.Other.UsrDat.IDs.List[0].ID);
2014-12-01 23:55:08 +01:00
2016-03-21 19:52:40 +01:00
/* Check if user's ID exists in database */
ID_GetListUsrCodsFromUsrID (&Gbl.Usrs.Other.UsrDat,NULL,ListUsrCods,false);
2014-12-01 23:55:08 +01:00
}
2016-11-16 23:19:52 +01:00
else // Not a valid user's nickname, email or ID
2015-10-07 19:55:13 +02:00
Wrong = true;
2014-12-01 23:55:08 +01:00
}
2015-10-07 19:55:13 +02:00
}
else // Empty string
Wrong = true;
if (Wrong)
2016-11-16 23:19:52 +01:00
/***** String is not a valid user's nickname, email or ID *****/
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_The_ID_nickname_or_email_X_is_not_valid,
Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail);
2014-12-01 23:55:08 +01:00
return ListUsrCods->NumUsrs;
}
/*****************************************************************************/
/********* Put hidden parameter encrypted user's code of other user **********/
/*****************************************************************************/
void Usr_PutParMyUsrCodEncrypted (void *EncryptedUsrCod)
2017-02-17 06:32:57 +01:00
{
Usr_PutParUsrCodEncrypted ((const char *) EncryptedUsrCod);
2017-02-17 06:32:57 +01:00
}
void Usr_PutParOtherUsrCodEncrypted (void *EncryptedUsrCod)
2015-04-02 18:39:49 +02:00
{
Usr_PutParUsrCodEncrypted ((const char *) EncryptedUsrCod);
2015-04-02 18:39:49 +02:00
}
void Usr_PutParUsrCodEncrypted (const char EncryptedUsrCod[Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64 + 1])
2014-12-01 23:55:08 +01:00
{
Par_PutParString (NULL,"OtherUsrCod",EncryptedUsrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********* Get hidden parameter encrypted user's code of other user **********/
/*****************************************************************************/
void Usr_GetParOtherUsrCodEncrypted (struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
Par_GetParText ("OtherUsrCod",UsrDat->EnUsrCod,
2017-03-07 01:56:41 +01:00
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
if (UsrDat->EnUsrCod[0]) // If parameter exists...
2014-12-01 23:55:08 +01:00
{
2016-01-25 14:40:57 +01:00
Usr_GetUsrCodFromEncryptedUsrCod (UsrDat);
if (UsrDat->UsrCod <= 0) // Check is user's code is valid
Err_WrongUserExit ();
2014-12-01 23:55:08 +01:00
}
2016-01-25 14:40:57 +01:00
else
UsrDat->UsrCod = -1L;
}
/*****************************************************************************/
/********* Get hidden parameter encrypted user's code of other user **********/
/*****************************************************************************/
void Usr_GetParOtherUsrCodEncryptedAndGetListIDs (void)
2016-01-25 14:40:57 +01:00
{
Usr_GetParOtherUsrCodEncrypted (&Gbl.Usrs.Other.UsrDat);
2016-09-23 15:03:25 +02:00
if (Gbl.Usrs.Other.UsrDat.UsrCod > 0) // If parameter exists...
2016-01-25 14:40:57 +01:00
ID_GetListIDsFromUsrCod (&Gbl.Usrs.Other.UsrDat);
2016-09-23 15:03:25 +02:00
else // Parameter does not exist
2014-12-01 23:55:08 +01:00
{
Gbl.Usrs.Other.UsrDat.UsrIDNickOrEmail[0] = '\0';
Gbl.Usrs.Other.UsrDat.IDs.Num = 0;
Gbl.Usrs.Other.UsrDat.IDs.List = NULL;
}
}
/*****************************************************************************/
/*** Get parameter encrypted user's code of other user and get user's data ***/
/*****************************************************************************/
// Return true if user exists
bool Usr_GetParOtherUsrCodEncryptedAndGetUsrData (void)
2014-12-01 23:55:08 +01:00
{
/***** Get parameter with encrypted user's code *****/
Usr_GetParOtherUsrCodEncryptedAndGetListIDs ();
2014-12-01 23:55:08 +01:00
2016-01-14 01:39:02 +01:00
/***** Check if user exists and get her/his data *****/
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat,
Usr_DONT_GET_PREFS,
Usr_GET_ROLE_IN_CURRENT_CRS))
// Existing user
2014-12-01 23:55:08 +01:00
return true;
return false;
}
/*****************************************************************************/
/** Check and get user data from session, from internal or external login... */
/*****************************************************************************/
void Usr_ChkUsrAndGetUsrData (void)
{
2017-06-03 17:47:07 +02:00
extern const char *Txt_The_session_has_expired;
2016-12-04 03:50:25 +01:00
struct
{
bool PutForm;
Act_Action_t Action;
void (*FuncPars) (void);
2016-12-04 03:50:25 +01:00
} FormLogin =
{
false,
2016-12-05 13:26:12 +01:00
ActLogIn,
2016-12-04 03:50:25 +01:00
NULL
};
2014-12-01 23:55:08 +01:00
Act_Action_t Action;
if (Gbl.Session.HasBeenDisconnected)
{
2017-02-05 22:23:41 +01:00
if (!Gbl.Action.UsesAJAX)
2014-12-01 23:55:08 +01:00
{
2016-01-17 15:10:54 +01:00
Gbl.Action.Act = ActLogOut;
2015-01-04 15:48:24 +01:00
Tab_SetCurrentTab ();
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_The_session_has_expired);
2016-12-04 03:50:25 +01:00
FormLogin.PutForm = true;
2014-12-01 23:55:08 +01:00
}
}
else // !Gbl.Session.HasBeenDisconnected
{
/***** Check user and get user's data *****/
2016-01-17 15:10:54 +01:00
if (Gbl.Action.Act == ActCreUsrAcc)
2014-12-01 23:55:08 +01:00
{
2016-11-08 00:58:32 +01:00
/***** Create my new account and login *****/
if (Acc_CreateMyNewAccountAndLogIn ()) // User logged in
2014-12-01 23:55:08 +01:00
{
Gbl.Usrs.Me.Logged = true;
2017-06-04 14:22:04 +02:00
Usr_SetMyPrefsAndRoles ();
2014-12-01 23:55:08 +01:00
Act_AdjustCurrentAction ();
Ses_CreateSession ();
2019-03-26 11:53:21 +01:00
/* Set settings from current IP */
Set_SetSettingsFromIP ();
2014-12-01 23:55:08 +01:00
/* Send message via email to confirm the new email address */
Mai_SendMailMsgToConfirmEmail ();
2019-03-09 20:12:44 +01:00
Ale_ShowAlerts (NULL); // Show alert after sending email confirmation
2014-12-01 23:55:08 +01:00
}
}
2016-01-17 15:10:54 +01:00
else // Gbl.Action.Act != ActCreUsrAcc
2014-12-01 23:55:08 +01:00
{
/***** Check user and get user's data *****/
if (Gbl.Session.IsOpen)
{
2016-11-08 00:58:32 +01:00
if (Usr_ChkUsrAndGetUsrDataFromSession ()) // User logged in
2014-12-01 23:55:08 +01:00
{
Gbl.Usrs.Me.Logged = true;
2017-06-04 14:22:04 +02:00
Usr_SetMyPrefsAndRoles ();
2014-12-01 23:55:08 +01:00
2017-02-05 22:23:41 +01:00
if (Gbl.Action.IsAJAXAutoRefresh) // If refreshing ==> don't refresh LastTime in session
Ses_DB_UpdateSessionLastRefresh ();
2014-12-01 23:55:08 +01:00
else
{
Act_AdjustCurrentAction ();
Ses_DB_UpdateSession ();
Con_DB_UpdateMeInConnectedList ();
2014-12-01 23:55:08 +01:00
}
}
else
2016-12-04 03:50:25 +01:00
FormLogin.PutForm = true;
2014-12-01 23:55:08 +01:00
}
2016-12-05 13:26:12 +01:00
else if (Gbl.Action.Act == ActLogIn ||
2016-12-04 04:22:36 +01:00
Gbl.Action.Act == ActLogInUsrAgd) // Login using @nickname, email or ID from form
2016-09-23 15:03:25 +02:00
{
if (Usr_ChkUsrAndGetUsrDataFromDirectLogin ()) // User logged in
{
Gbl.Usrs.Me.Logged = true;
2017-06-04 14:22:04 +02:00
Usr_SetMyPrefsAndRoles ();
2016-09-23 15:03:25 +02:00
Act_AdjustCurrentAction ();
Ses_CreateSession ();
2019-03-26 11:53:21 +01:00
Set_SetSettingsFromIP (); // Set settings from current IP
2016-09-23 15:03:25 +02:00
}
else
2016-12-04 03:50:25 +01:00
{
FormLogin.PutForm = true;
2016-12-04 04:22:36 +01:00
if (Gbl.Action.Act == ActLogInUsrAgd)
2016-12-04 03:50:25 +01:00
{
2016-12-04 04:22:36 +01:00
FormLogin.Action = ActLogInUsrAgd;
FormLogin.FuncPars = Agd_PutParAgd;
2016-12-04 03:50:25 +01:00
}
}
2016-09-23 15:03:25 +02:00
}
2016-12-05 13:26:12 +01:00
else if (Gbl.Action.Act == ActLogInNew) // Empty account without password, login using encrypted user's code
2014-12-01 23:55:08 +01:00
{
2016-09-23 15:03:25 +02:00
/***** Get user's data *****/
Usr_GetParOtherUsrCodEncrypted (&Gbl.Usrs.Me.UsrDat);
2016-09-23 15:03:25 +02:00
Usr_GetUsrCodFromEncryptedUsrCod (&Gbl.Usrs.Me.UsrDat);
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,
Usr_GET_PREFS,
Usr_GET_ROLE_IN_CURRENT_CRS))
2014-12-01 23:55:08 +01:00
{
// User logged in
2014-12-01 23:55:08 +01:00
Gbl.Usrs.Me.Logged = true;
2017-06-04 14:22:04 +02:00
Usr_SetMyPrefsAndRoles ();
2014-12-01 23:55:08 +01:00
Act_AdjustCurrentAction ();
Ses_CreateSession ();
2019-03-26 11:53:21 +01:00
Set_SetSettingsFromIP (); // Set settings from current IP
2014-12-01 23:55:08 +01:00
}
else
2016-12-04 03:50:25 +01:00
FormLogin.PutForm = true;
2014-12-01 23:55:08 +01:00
}
}
}
/***** If session disconnected or error in login, show form to login *****/
2016-12-04 03:50:25 +01:00
if (FormLogin.PutForm)
2014-12-01 23:55:08 +01:00
{
Usr_WriteFormLogin (FormLogin.Action,FormLogin.FuncPars);
Err_ShowErrorAndExit (NULL);
2014-12-01 23:55:08 +01:00
}
/***** Adjust tab and action *****/
2017-02-05 22:23:41 +01:00
if (!Gbl.Action.UsesAJAX)
2014-12-01 23:55:08 +01:00
{
2019-04-01 23:15:17 +02:00
if (!Gbl.Usrs.Me.Logged && // No user logged...
Gbl.Action.Act == ActUnk) // ...and unknown action
2014-12-01 23:55:08 +01:00
Act_AdjustActionWhenNoUsrLogged ();
2019-04-01 11:15:38 +02:00
/***** When I change to another tab, go to:
- my last action in that tab if it is known, or
- the first option allowed *****/
2016-01-17 15:10:54 +01:00
if (Gbl.Action.Act == ActMnu)
2014-12-01 23:55:08 +01:00
{
2019-04-01 11:15:38 +02:00
/* Get my last action in current tab */
Action = (Gbl.Usrs.Me.Logged) ? MFU_GetMyLastActionInCurrentTab () :
ActUnk;
if (Action == ActUnk)
/* Get the first option allowed */
2015-12-08 01:47:48 +01:00
Action = Mnu_GetFirstActionAvailableInCurrentTab ();
2019-04-01 11:15:38 +02:00
Gbl.Action.Act = (Action == ActUnk) ? ((Gbl.Usrs.Me.Logged) ? ActSeeGblTL : // Default action if logged
ActFrmLogIn) : // Default action if not logged
2019-04-01 11:15:38 +02:00
Action;
Tab_SetCurrentTab ();
}
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/************** Check user and get user's data when direct login *************/
/*****************************************************************************/
// Returns true if user logged in successfully
// Returns false if user not logged in
static bool Usr_ChkUsrAndGetUsrDataFromDirectLogin (void)
{
struct Usr_ListUsrCods ListUsrCods;
2014-12-01 23:55:08 +01:00
bool PasswordCorrect = false;
2015-10-07 19:55:13 +02:00
/***** Check if user typed anything *****/
if (!Gbl.Usrs.Me.UsrIdLogin)
{
2016-03-01 03:16:29 +01:00
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
2015-10-07 19:55:13 +02:00
return false;
}
if (!Gbl.Usrs.Me.UsrIdLogin[0])
{
2016-03-01 03:16:29 +01:00
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
2015-10-07 19:55:13 +02:00
return false;
}
2016-11-16 23:19:52 +01:00
/***** Check if user has typed his user's ID, his nickname or his email address *****/
if (Nck_CheckIfNickWithArrIsValid (Gbl.Usrs.Me.UsrIdLogin)) // 1: It's a nickname
2014-12-01 23:55:08 +01:00
{
// User is trying to log using his/her nickname
if ((Gbl.Usrs.Me.UsrDat.UsrCod = Nck_GetUsrCodFromNickname (Gbl.Usrs.Me.UsrIdLogin)) <= 0)
{
2016-03-01 03:16:29 +01:00
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
2014-12-01 23:55:08 +01:00
return false;
}
}
2016-11-16 23:19:52 +01:00
else if (Mai_CheckIfEmailIsValid (Gbl.Usrs.Me.UsrIdLogin)) // 2: It's an email
2014-12-01 23:55:08 +01:00
{
2016-11-16 23:19:52 +01:00
// User is trying to log using his/her email
if ((Gbl.Usrs.Me.UsrDat.UsrCod = Mai_DB_GetUsrCodFromEmail (Gbl.Usrs.Me.UsrIdLogin)) <= 0)
2014-12-01 23:55:08 +01:00
{
2016-03-01 03:16:29 +01:00
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
2014-12-01 23:55:08 +01:00
return false;
}
}
2016-11-16 23:19:52 +01:00
else // 3: It's not a nickname nor email
2014-12-01 23:55:08 +01:00
{
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (Gbl.Usrs.Me.UsrIdLogin);
if (ID_CheckIfUsrIDIsValid (Gbl.Usrs.Me.UsrIdLogin))
{
/***** Allocate space for the list *****/
ID_ReallocateListIDs (&Gbl.Usrs.Me.UsrDat,1);
2017-01-15 18:02:52 +01:00
Str_Copy (Gbl.Usrs.Me.UsrDat.IDs.List[0].ID,Gbl.Usrs.Me.UsrIdLogin,
sizeof (Gbl.Usrs.Me.UsrDat.IDs.List[0].ID) - 1);
2014-12-01 23:55:08 +01:00
Str_ConvertToUpperText (Gbl.Usrs.Me.UsrDat.IDs.List[0].ID);
/* Check if user's ID exists in database, and get user's data */
if (ID_GetListUsrCodsFromUsrID (&Gbl.Usrs.Me.UsrDat,
Gbl.Usrs.Me.LoginEncryptedPassword, // Check password
&ListUsrCods,false))
{
if (ListUsrCods.NumUsrs == 1)
{
/* Free memory used for list of users' codes found for this ID */
Usr_FreeListUsrCods (&ListUsrCods);
PasswordCorrect = true;
}
else // ListUsrCods.NumUsrs > 1
{
/* Free memory used for list of users' codes found for this ID */
Usr_FreeListUsrCods (&ListUsrCods);
2016-03-01 03:16:29 +01:00
Usr_ShowAlertThereAreMoreThanOneUsr ();
2014-12-01 23:55:08 +01:00
return false;
}
}
else if (ID_GetListUsrCodsFromUsrID (&Gbl.Usrs.Me.UsrDat,
NULL, // Don't check password
&ListUsrCods,false))
{
if (ListUsrCods.NumUsrs == 1)
{
/* Free memory used for list of users' codes found for this ID */
Usr_FreeListUsrCods (&ListUsrCods);
if (Pwd_CheckPendingPassword ())
{
Pwd_AssignMyPendingPasswordToMyCurrentPassword ();
PasswordCorrect = true;
}
else
{
2016-03-01 03:16:29 +01:00
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
2014-12-01 23:55:08 +01:00
return false;
}
}
else // ListUsrCods.NumUsrs > 1
{
/* Free memory used for list of users' codes found for this ID */
Usr_FreeListUsrCods (&ListUsrCods);
2016-03-01 03:16:29 +01:00
Usr_ShowAlertThereAreMoreThanOneUsr ();
2014-12-01 23:55:08 +01:00
return false;
}
}
else // No users found for this ID
{
2016-03-01 03:16:29 +01:00
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
2014-12-01 23:55:08 +01:00
return false;
}
}
2016-11-16 23:19:52 +01:00
else // String is not a valid user's nickname, email or ID
2014-12-01 23:55:08 +01:00
{
2016-03-01 03:16:29 +01:00
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
2014-12-01 23:55:08 +01:00
return false;
}
}
/***** Get user's data *****/
Usr_GetAllUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,
Usr_GET_PREFS,
Usr_GET_ROLE_IN_CURRENT_CRS);
2014-12-01 23:55:08 +01:00
/***** Check password *****/
/* Check user's password:
is the encrypted password typed by user or coming from the session
the same as that stored in database? */
if (!PasswordCorrect)
PasswordCorrect = Pwd_CheckCurrentPassword ();
if (!PasswordCorrect) // If my password is not correct...
{
if (Pwd_CheckPendingPassword ())
Pwd_AssignMyPendingPasswordToMyCurrentPassword ();
else
{
2016-03-01 03:16:29 +01:00
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
2014-12-01 23:55:08 +01:00
return false;
}
}
return true;
}
/*****************************************************************************/
/******** Check user and get user's data when the session is open ************/
/*****************************************************************************/
static bool Usr_ChkUsrAndGetUsrDataFromSession (void)
{
/***** Session is open and user's code is get from session *****/
Gbl.Usrs.Me.UsrDat.UsrCod = Gbl.Session.UsrCod;
/* Check if user exists in database, and get his/her data */
if (!Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,
Usr_GET_PREFS,
Usr_GET_ROLE_IN_CURRENT_CRS))
2014-12-01 23:55:08 +01:00
{
2016-03-01 03:16:29 +01:00
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
2014-12-01 23:55:08 +01:00
return false;
}
/* Check user's password:
the encrypted password typed by user or coming from the session
is the same as the stored in database? */
if (!Pwd_CheckCurrentPassword ()) // If my password is not correct...
{
2016-03-01 03:16:29 +01:00
Usr_ShowAlertUsrDoesNotExistsOrWrongPassword ();
2014-12-01 23:55:08 +01:00
return false;
}
return true;
}
/*****************************************************************************/
2016-03-01 03:16:29 +01:00
/** Show alert indicating that user does not exists or password is incorrect */
/*****************************************************************************/
static void Usr_ShowAlertUsrDoesNotExistsOrWrongPassword (void)
{
extern const char *Txt_The_user_does_not_exist_or_password_is_incorrect;
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_The_user_does_not_exist_or_password_is_incorrect);
2016-03-01 03:16:29 +01:00
}
/*****************************************************************************/
/****** Show alert indicating that more than one user share the same ID ******/
/*****************************************************************************/
static void Usr_ShowAlertThereAreMoreThanOneUsr (void)
{
extern const char *Txt_There_are_more_than_one_user_with_the_ID_X_Please_type_a_nick_or_email;
Gbl.Action.Act = ActFrmLogIn;
Tab_SetCurrentTab ();
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_There_are_more_than_one_user_with_the_ID_X_Please_type_a_nick_or_email,
Gbl.Usrs.Me.UsrIdLogin);
2016-03-01 03:16:29 +01:00
}
/*****************************************************************************/
2019-03-26 11:53:21 +01:00
/********************** Set my settings and my roles *************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2017-06-04 14:22:04 +02:00
static void Usr_SetMyPrefsAndRoles (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Ico_IconSetId[Ico_NUM_ICON_SETS];
struct Sch_Search *Search;
2019-04-03 22:08:44 +02:00
bool GetRoleAndActionFromLastData;
2019-04-01 23:15:17 +02:00
Act_Action_t LastSuperAction;
bool JustAfterLogin = Gbl.Action.Act == ActLogIn ||
Gbl.Action.Act == ActLogInLan ||
Gbl.Action.Act == ActLogInNew ||
Gbl.Action.Act == ActAnnSee;
2014-12-01 23:55:08 +01:00
2015-02-01 20:17:24 +01:00
// In this point I am logged
2014-12-01 23:55:08 +01:00
2015-12-07 23:13:08 +01:00
/***** Set my language if unknown *****/
2018-12-08 16:43:13 +01:00
if (Gbl.Usrs.Me.UsrDat.Prefs.Language == Lan_LANGUAGE_UNKNOWN) // I have not chosen language
2017-05-07 18:06:34 +02:00
Lan_UpdateMyLanguageToCurrentLanguage (); // Update my language in database
2015-12-07 23:13:08 +01:00
2019-03-26 11:53:21 +01:00
/***** Set settings from my settings *****/
2015-11-21 21:00:18 +01:00
Gbl.Prefs.FirstDayOfWeek = Gbl.Usrs.Me.UsrDat.Prefs.FirstDayOfWeek;
2017-05-04 11:03:44 +02:00
Gbl.Prefs.DateFormat = Gbl.Usrs.Me.UsrDat.Prefs.DateFormat;
Gbl.Prefs.IconSet = Gbl.Usrs.Me.UsrDat.Prefs.IconSet;
2015-11-27 12:57:56 +01:00
Gbl.Prefs.Menu = Gbl.Usrs.Me.UsrDat.Prefs.Menu;
Gbl.Prefs.Theme = Gbl.Usrs.Me.UsrDat.Prefs.Theme;
2015-11-27 12:57:56 +01:00
Gbl.Prefs.SideCols = Gbl.Usrs.Me.UsrDat.Prefs.SideCols;
Gbl.Prefs.PhotoShape = Gbl.Usrs.Me.UsrDat.Prefs.PhotoShape;
2014-12-01 23:55:08 +01:00
2017-06-04 14:22:04 +02:00
/***** Construct the path to my directory *****/
Usr_ConstructPathUsr (Gbl.Usrs.Me.UsrDat.UsrCod,Gbl.Usrs.Me.PathDir);
/***** Check if my photo exists and create a link to it ****/
Gbl.Usrs.Me.MyPhotoExists = Pho_BuildLinkToPhoto (&Gbl.Usrs.Me.UsrDat,Gbl.Usrs.Me.PhotoURL);
2014-12-01 23:55:08 +01:00
/***** Get my last data *****/
Usr_GetMyLastData ();
2019-04-01 23:15:17 +02:00
if (JustAfterLogin) // If I just logged in...
2014-12-01 23:55:08 +01:00
{
/***** WhatToSearch is stored in session,
but in login it is got from user's last data *****/
Search = Sch_GetSearch ();
Search->WhatToSearch = Gbl.Usrs.Me.UsrLast.WhatToSearch;
2014-12-01 23:55:08 +01:00
2019-04-01 23:15:17 +02:00
/***** Location in hierarchy and role are stored in session,
but in login the are got from user's last data *****/
if (Gbl.Hierarchy.Level == HieLvl_SYS) // No country selected
2019-04-01 23:15:17 +02:00
{
/***** Copy last hierarchy to current hierarchy *****/
Hie_SetHierarchyFromUsrLastHierarchy ();
/* Course may have changed ==> get my role in current course again */
if (Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected
Gbl.Usrs.Me.UsrDat.Roles.InCurrentCrs = Rol_GetMyRoleInCrs (Gbl.Hierarchy.Crs.CrsCod);
2014-12-01 23:55:08 +01:00
2019-04-03 22:08:44 +02:00
// role and action will be got from last data
GetRoleAndActionFromLastData = true;
2019-04-01 23:15:17 +02:00
}
else // Country (and may be institution, center, degree or course) selected
2019-04-03 22:08:44 +02:00
// Role and action will be got from last data
2019-04-01 23:15:17 +02:00
// only if I am in the same hierarchy location that the stored one
2019-04-03 22:08:44 +02:00
GetRoleAndActionFromLastData =
2019-04-03 20:57:04 +02:00
(Gbl.Hierarchy.Level == Gbl.Usrs.Me.UsrLast.LastHie.Scope && // The same scope...
2019-04-01 23:15:17 +02:00
Gbl.Hierarchy.Cod == Gbl.Usrs.Me.UsrLast.LastHie.Cod); // ...and code in hierarchy
2019-04-03 22:08:44 +02:00
/***** Get role and action from last data *****/
if (GetRoleAndActionFromLastData)
{
/* Get role from last data */
Gbl.Usrs.Me.Role.Logged = Gbl.Usrs.Me.UsrLast.LastRole;
/* Last action is really got only if last access is recent */
if (Gbl.Usrs.Me.UsrLast.LastTime >= Dat_GetStartExecutionTimeUTC () -
2019-04-03 21:49:10 +02:00
Cfg_MAX_TIME_TO_REMEMBER_LAST_ACTION_ON_LOGIN)
2019-04-01 23:15:17 +02:00
{
2019-04-03 21:49:10 +02:00
/* Get action from last data */
LastSuperAction = Act_GetSuperAction (Gbl.Usrs.Me.UsrLast.LastAct);
if (LastSuperAction != ActUnk)
{
Gbl.Action.Act = LastSuperAction;
Tab_SetCurrentTab ();
}
}
2019-04-03 22:08:44 +02:00
/* If action is not set to last action,
it will be set later to a default action */
}
2014-12-01 23:55:08 +01:00
}
2019-04-01 23:15:17 +02:00
/***** Set my roles *****/
2017-06-04 14:22:04 +02:00
Rol_SetMyRoles ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2015-04-02 13:38:05 +02:00
/************** Show forms to log out and to change my role ******************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2015-04-02 13:38:05 +02:00
void Usr_ShowFormsLogoutAndRole (void)
2014-12-01 23:55:08 +01:00
{
2016-11-13 12:35:01 +01:00
extern const char *Hlp_PROFILE_Session_role;
2018-10-09 19:18:43 +02:00
extern const char *Txt_Session;
2016-11-13 12:35:01 +01:00
extern const char *Txt_Role;
2016-11-13 13:01:44 +01:00
extern const char *Txt_You_are_now_LOGGED_IN_as_X;
2014-12-01 23:55:08 +01:00
extern const char *Txt_logged[Usr_NUM_SEXS];
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2016-11-13 12:35:01 +01:00
extern const char *Txt_ROLES_SINGUL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
char *ClassSelect;
2014-12-01 23:55:08 +01:00
/***** Write message with my new logged role *****/
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.HasChanged)
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_SUCCESS,Txt_You_are_now_LOGGED_IN_as_X,
Txt_logged[Gbl.Usrs.Me.UsrDat.Sex],
Txt_ROLES_SINGUL_abc[Gbl.Usrs.Me.Role.Logged][Gbl.Usrs.Me.UsrDat.Sex]);
2016-11-13 12:35:01 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_Session,
2020-04-09 21:36:21 +02:00
Usr_PutLinkToLogOut,NULL,
2017-06-12 15:03:29 +02:00
Hlp_PROFILE_Session_role,Box_NOT_CLOSABLE);
2014-12-01 23:55:08 +01:00
/***** Put a form to change my role *****/
if (Rol_GetNumAvailableRoles () == 1)
{
HTM_SPAN_Begin ("class=\"DAT_%s\"",The_GetSuffix ());
HTM_TxtColonNBSP (Txt_Role);
HTM_SPAN_End ();
2019-11-07 10:24:00 +01:00
HTM_SPAN_Begin ("class=\"DAT_STRONG_%s BOLD\"",
The_GetSuffix ());
HTM_Txt (Txt_ROLES_SINGUL_Abc[Gbl.Usrs.Me.Role.Logged][Gbl.Usrs.Me.UsrDat.Sex]);
HTM_SPAN_End ();
}
else
{
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ());
HTM_TxtColonNBSP (Txt_Role);
if (asprintf (&ClassSelect,"INPUT_%s",
The_GetSuffix ()) < 0)
Err_NotEnoughMemoryExit ();
Rol_PutFormToChangeMyRole (ClassSelect);
free (ClassSelect);
HTM_LABEL_End ();
}
2016-11-13 12:35:01 +01:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2014-12-01 23:55:08 +01:00
}
2018-10-09 19:18:43 +02:00
/*****************************************************************************/
/************** Put an icon (form) to close the current session **************/
/*****************************************************************************/
2020-04-09 21:36:21 +02:00
static void Usr_PutLinkToLogOut (__attribute__((unused)) void *Args)
2018-10-09 19:18:43 +02:00
{
2020-04-09 21:36:21 +02:00
Lay_PutContextualLinkOnlyIcon (ActLogOut,NULL,
NULL,NULL,
"sign-out-alt.svg",Ico_RED);
2018-10-09 19:18:43 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2014-12-12 18:50:36 +01:00
/******* Check a user's code and get all user's data from user's code ********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2014-12-12 18:50:36 +01:00
// Input: UsrDat->UsrCod must hold a valid user code
// Output: When true ==> UsrDat will hold all user's data
// When false ==> UsrDat is reset, except user's code
2014-12-01 23:55:08 +01:00
bool Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (struct Usr_Data *UsrDat,
Usr_GetPrefs_t GetPrefs,
Usr_GetRoleInCurrentCrs_t GetRoleInCurrentCrs)
2014-12-01 23:55:08 +01:00
{
2014-12-12 18:50:36 +01:00
/***** Check if a user exists having this user's code *****/
if (Usr_DB_ChkIfUsrCodExists (UsrDat->UsrCod))
2014-12-12 18:50:36 +01:00
{
/* Get user's data */
Usr_GetAllUsrDataFromUsrCod (UsrDat,GetPrefs,GetRoleInCurrentCrs);
2014-12-12 18:50:36 +01:00
return true;
}
2014-12-01 23:55:08 +01:00
2014-12-12 18:50:36 +01:00
/***** No user's code found *****/
UsrDat->UsrIDNickOrEmail[0] = '\0';
Usr_ResetUsrDataExceptUsrCodAndIDs (UsrDat);
return false;
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2014-12-12 18:50:36 +01:00
/********* Update my last accessed course, tab and time in database **********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2014-12-12 18:50:36 +01:00
void Usr_UpdateMyLastData (void)
2014-12-01 23:55:08 +01:00
{
/***** Check if it exists an entry for me *****/
if (Usr_DB_CheckMyLastData ())
2014-12-01 23:55:08 +01:00
/***** Update my last accessed course, tab and time of click in database *****/
2015-01-22 00:17:12 +01:00
// WhatToSearch, LastAccNotif remain unchanged
Usr_DB_UpdateMyLastData ();
2014-12-01 23:55:08 +01:00
else
Usr_DB_InsertMyLastData ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2016-06-15 20:04:15 +02:00
/*********** Write a row of a table with the main data of a user *************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2017-03-08 03:48:23 +01:00
#define Usr_MAX_BYTES_BG_COLOR (16 - 1)
2017-01-15 22:58:26 +01:00
void Usr_WriteRowUsrMainData (unsigned NumUsr,struct Usr_Data *UsrDat,
2019-11-15 03:34:48 +01:00
bool PutCheckBoxToSelectUsr,Rol_Role_t Role,
struct Usr_SelectedUsrs *SelectedUsrs)
2014-12-01 23:55:08 +01:00
{
2017-03-30 11:20:06 +02:00
extern const char *Txt_Enrolment_confirmed;
extern const char *Txt_Enrolment_not_confirmed;
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
};
2017-03-08 03:48:23 +01:00
char BgColor[Usr_MAX_BYTES_BG_COLOR + 1];
2016-06-15 19:54:43 +02:00
bool UsrIsTheMsgSender = PutCheckBoxToSelectUsr &&
(UsrDat->UsrCod == Gbl.Usrs.Other.UsrDat.UsrCod);
2021-02-11 00:58:53 +01:00
struct Ins_Instit Ins;
2014-12-01 23:55:08 +01:00
/***** Begin row *****/
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2014-12-01 23:55:08 +01:00
/***** Checkbox to select user *****/
// Two colors are used alternatively to better distinguish the rows
if (UsrIsTheMsgSender)
Str_Copy (BgColor,"LIGHT_GREEN",sizeof (BgColor) - 1);
else
snprintf (BgColor,sizeof (BgColor),"%s",The_GetColorRows ());
2016-06-16 11:28:20 +02:00
if (PutCheckBoxToSelectUsr)
{
HTM_TD_Begin ("class=\"CM %s\"",BgColor);
Usr_PutCheckboxToSelectUser (Role,UsrDat->EnUsrCod,UsrIsTheMsgSender,
SelectedUsrs);
HTM_TD_End ();
}
/***** User has accepted enrolment? *****/
if (UsrIsTheMsgSender)
HTM_TD_Begin ("class=\"BM_SEL %s_%s\" title=\"%s\"",
UsrDat->Accepted ? "USR_LIST_NUM_N" :
"USR_LIST_NUM",
The_GetSuffix (),
UsrDat->Accepted ? Txt_Enrolment_confirmed :
Txt_Enrolment_not_confirmed);
else
HTM_TD_Begin ("class=\"BM %s_%s %s\" title=\"%s\"",
UsrDat->Accepted ? "USR_LIST_NUM_N" :
"USR_LIST_NUM",
The_GetSuffix (),
BgColor,
UsrDat->Accepted ? Txt_Enrolment_confirmed :
Txt_Enrolment_not_confirmed);
HTM_Txt (UsrDat->Accepted ? "&check;" :
"&cross;");
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write number of user in the list *****/
HTM_TD_Begin ("class=\"%s_%s RM %s\"",
2019-10-10 23:14:13 +02:00
UsrDat->Accepted ? "USR_LIST_NUM_N" :
"USR_LIST_NUM",
The_GetSuffix (),
BgColor);
HTM_Unsigned (NumUsr);
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Listing.WithPhotos)
{
/***** Show user's photo *****/
HTM_TD_Begin ("class=\"CM %s\"",BgColor);
Pho_ShowUsrPhotoIfAllowed (UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
HTM_TD_End ();
}
2014-12-01 23:55:08 +01:00
/****** Write user's IDs ******/
HTM_TD_Begin ("class=\"LM %s_%s %s\"",
UsrDat->Accepted ? "DAT_SMALL_STRONG" :
"DAT_SMALL",
The_GetSuffix (),
BgColor);
ID_WriteUsrIDs (UsrDat,NULL);
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write rest of main user's data *****/
Ins.InsCod = UsrDat->InsCod;
Ins_GetInstitDataByCod (&Ins);
Usr_WriteMainUsrDataExceptUsrID (UsrDat,BgColor);
2014-12-01 23:55:08 +01:00
HTM_TD_Begin ("class=\"LM %s\"",BgColor);
Ins_DrawInstitutionLogoWithLink (&Ins,25);
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** End row *****/
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************** Write a row of a table with the data of a guest *************/
/*****************************************************************************/
static void Usr_WriteRowGstAllData (struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
};
2021-02-11 00:58:53 +01:00
struct Ins_Instit Ins;
struct Ctr_Center Ctr;
2020-04-13 20:50:47 +02:00
struct Dpt_Department Dpt;
2014-12-01 23:55:08 +01:00
/***** Begin row *****/
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Listing.WithPhotos)
{
/***** Show guest's photo *****/
HTM_TD_Begin ("class=\"%s LM\"",The_GetColorRows ());
Pho_ShowUsrPhotoIfAllowed (UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_NO_ZOOM);
HTM_TD_End ();
}
2014-12-01 23:55:08 +01:00
/****** Write user's ID ******/
HTM_TD_Begin ("class=\"LM DAT_SMALL_%s %s\"",
The_GetSuffix (),
The_GetColorRows ());
ID_WriteUsrIDs (UsrDat,NULL);
HTM_NBSP ();
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write rest of guest's main data *****/
Ins.InsCod = UsrDat->InsCod;
Ins_GetInstitDataByCod (&Ins);
Usr_WriteMainUsrDataExceptUsrID (UsrDat,The_GetColorRows ());
Usr_WriteEmail (UsrDat,The_GetColorRows ());
Usr_WriteUsrData (The_GetColorRows (),
Ins.FullName,
NULL,true,false);
/***** Write the rest of the data of the guest *****/
if (UsrDat->Tch.CtrCod > 0)
{
Ctr.CtrCod = UsrDat->Tch.CtrCod;
Ctr_GetCenterDataByCod (&Ctr);
}
Usr_WriteUsrData (The_GetColorRows (),
UsrDat->Tch.CtrCod > 0 ? Ctr.FullName :
"&nbsp;",
NULL,true,false);
if (UsrDat->Tch.DptCod > 0)
{
Dpt.DptCod = UsrDat->Tch.DptCod;
Dpt_GetDepartmentDataByCod (&Dpt);
}
Usr_WriteUsrData (The_GetColorRows (),
UsrDat->Tch.DptCod > 0 ? Dpt.FullName :
"&nbsp;",
NULL,true,false);
Usr_WriteUsrData (The_GetColorRows (),
UsrDat->Tch.Office[0] ? UsrDat->Tch.Office :
"&nbsp;",
NULL,true,false);
Usr_WriteUsrData (The_GetColorRows (),
UsrDat->Tch.OfficePhone[0] ? UsrDat->Tch.OfficePhone :
"&nbsp;",
NULL,true,false);
Usr_WriteUsrData (The_GetColorRows (),
UsrDat->Phone[0][0] ? UsrDat->Phone[0] :
"&nbsp;",
NULL,true,false);
Usr_WriteUsrData (The_GetColorRows (),
UsrDat->Phone[1][0] ? UsrDat->Phone[1] :
"&nbsp;",
NULL,true,false);
Usr_WriteUsrData (The_GetColorRows (),
UsrDat->StrBirthday[0] ? UsrDat->StrBirthday :
"&nbsp;",
NULL,true,false);
2014-12-01 23:55:08 +01:00
/***** End row *****/
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************ Write a row of a table with the data of a student **************/
/*****************************************************************************/
static void Usr_WriteRowStdAllData (struct Usr_Data *UsrDat,char *GroupNames)
2014-12-01 23:55:08 +01:00
{
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-01 23:55:08 +01:00
unsigned NumGrpTyp,NumField;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2017-01-15 22:58:26 +01:00
char Text[Cns_MAX_BYTES_TEXT + 1];
2021-02-11 00:58:53 +01:00
struct Ins_Instit Ins;
2017-06-04 18:18:54 +02:00
bool ShowData = (Gbl.Usrs.Me.Role.Logged == Rol_TCH && UsrDat->Accepted) ||
Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM;
2014-12-01 23:55:08 +01:00
/***** Begin row *****/
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Listing.WithPhotos)
{
/***** Show student's photo *****/
HTM_TD_Begin ("class=\"LM %s\"",The_GetColorRows ());
Pho_ShowUsrPhotoIfAllowed (UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_NO_ZOOM);
HTM_TD_End ();
}
/****** Write user's ID ******/
HTM_TD_Begin ("class=\"LM %s_%s %s\"",
UsrDat->Accepted ? "DAT_SMALL_STRONG" :
"DAT_SMALL",
The_GetSuffix (),
The_GetColorRows ());
ID_WriteUsrIDs (UsrDat,NULL);
HTM_NBSP ();
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write rest of main student's data *****/
Ins.InsCod = UsrDat->InsCod;
Ins_GetInstitDataByCod (&Ins);
Usr_WriteMainUsrDataExceptUsrID (UsrDat,The_GetColorRows ());
Usr_WriteEmail (UsrDat,The_GetColorRows ());
Usr_WriteUsrData (The_GetColorRows (),
Ins.FullName,
NULL,true,UsrDat->Accepted);
2014-12-01 23:55:08 +01:00
/***** Write the rest of the data of the student *****/
Usr_WriteUsrData (The_GetColorRows (),
UsrDat->Phone[0][0] ? (ShowData ? UsrDat->Phone[0] :
"********") :
"&nbsp;",
NULL,true,UsrDat->Accepted);
Usr_WriteUsrData (The_GetColorRows (),
UsrDat->Phone[1][0] ? (ShowData ? UsrDat->Phone[1] :
"********") :
"&nbsp;",
NULL,true,UsrDat->Accepted);
Usr_WriteUsrData (The_GetColorRows (),
UsrDat->StrBirthday[0] ? (ShowData ? UsrDat->StrBirthday :
"********") :
"&nbsp;",
NULL,true,UsrDat->Accepted);
2014-12-01 23:55:08 +01:00
if (Gbl.Scope.Current == HieLvl_CRS)
{
/***** Write the groups a the que pertenece the student *****/
for (NumGrpTyp = 0;
NumGrpTyp < Gbl.Crs.Grps.GrpTypes.NumGrpTypes;
NumGrpTyp++)
if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) // If current course tiene groups of este type
{
Grp_GetNamesGrpsUsrBelongsTo (UsrDat->UsrCod,
Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].GrpTypCod,
GroupNames);
Usr_WriteUsrData (The_GetColorRows (),GroupNames,NULL,true,UsrDat->Accepted);
}
/***** Fields of the record dependientes of the course *****/
for (NumField = 0;
NumField < Gbl.Crs.Records.LstFields.Num;
NumField++)
{
/* Get the text of the field */
if (Rec_DB_GetFieldTxtFromUsrRecord (&mysql_res,
Gbl.Crs.Records.LstFields.Lst[NumField].FieldCod,
UsrDat->UsrCod))
{
row = mysql_fetch_row (mysql_res);
Str_Copy (Text,row[0],sizeof (Text) - 1);
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
Text,Cns_MAX_BYTES_TEXT,Str_DONT_REMOVE_SPACES);
}
else
Text[0] = '\0';
Usr_WriteUsrData (The_GetColorRows (),Text,NULL,false,UsrDat->Accepted);
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
}
}
2014-12-01 23:55:08 +01:00
/***** End row *****/
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*** Write a row of a table with the data of a teacher or an administrator ***/
/*****************************************************************************/
static void Usr_WriteRowTchAllData (struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
};
2021-02-11 00:58:53 +01:00
struct Ins_Instit Ins;
struct Ctr_Center Ctr;
2021-02-11 23:27:48 +01:00
struct Dpt_Department Dpt;
bool ShowData = (Usr_ItsMe (UsrDat->UsrCod) == Usr_ME || UsrDat->Accepted ||
2017-06-04 18:18:54 +02:00
Gbl.Usrs.Me.Role.Logged == Rol_DEG_ADM ||
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM);
2014-12-01 23:55:08 +01:00
/***** Begin row *****/
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
if (Gbl.Usrs.Listing.WithPhotos)
{
/***** Show teacher's photo *****/
HTM_TD_Begin ("class=\"LM %s\"",The_GetColorRows ());
Pho_ShowUsrPhotoIfAllowed (UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_NO_ZOOM);
HTM_TD_End ();
}
/****** Write the user's ID ******/
HTM_TD_Begin ("class=\"LM %s_%s %s\"",
UsrDat->Accepted ? "DAT_SMALL_STRONG" :
"DAT_SMALL",
The_GetSuffix (),
The_GetColorRows ());
ID_WriteUsrIDs (UsrDat,NULL);
HTM_NBSP ();
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write rest of main teacher's data *****/
Ins.InsCod = UsrDat->InsCod;
Ins_GetInstitDataByCod (&Ins);
Usr_WriteMainUsrDataExceptUsrID (UsrDat,The_GetColorRows ());
Usr_WriteEmail (UsrDat,The_GetColorRows ());
Usr_WriteUsrData (The_GetColorRows (),
Ins.FullName,
NULL,true,UsrDat->Accepted);
2014-12-01 23:55:08 +01:00
/***** Write the rest of teacher's data *****/
if (ShowData && UsrDat->Tch.CtrCod > 0)
{
Ctr.CtrCod = UsrDat->Tch.CtrCod;
Ctr_GetCenterDataByCod (&Ctr);
}
Usr_WriteUsrData (The_GetColorRows (),
(ShowData && UsrDat->Tch.CtrCod > 0) ? Ctr.FullName :
"&nbsp;",
NULL,true,UsrDat->Accepted);
if (ShowData && UsrDat->Tch.DptCod > 0)
{
Dpt.DptCod = UsrDat->Tch.DptCod;
Dpt_GetDepartmentDataByCod (&Dpt);
}
Usr_WriteUsrData (The_GetColorRows (),
(ShowData && UsrDat->Tch.DptCod > 0) ? Dpt.FullName :
"&nbsp;",
NULL,true,UsrDat->Accepted);
Usr_WriteUsrData (The_GetColorRows (),
(ShowData && UsrDat->Tch.Office[0]) ? UsrDat->Tch.Office :
"&nbsp;",
NULL,true,UsrDat->Accepted);
Usr_WriteUsrData (The_GetColorRows (),
(ShowData && UsrDat->Tch.OfficePhone[0]) ? UsrDat->Tch.OfficePhone :
"&nbsp;",
NULL,true,UsrDat->Accepted);
2014-12-01 23:55:08 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2016-04-23 13:23:09 +02:00
/********** Write a row of a table with the data of an administrator *********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
static void Usr_WriteRowAdmData (unsigned NumUsr,struct Usr_Data *UsrDat)
2014-12-01 23:55:08 +01:00
{
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
[PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
};
2021-02-11 00:58:53 +01:00
struct Ins_Instit Ins;
2014-12-01 23:55:08 +01:00
/***** Begin row *****/
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2014-12-01 23:55:08 +01:00
/***** Write number of user *****/
HTM_TD_Begin ("class=\"CM USR_LIST_NUM_N_%s %s\"",
The_GetSuffix (),
The_GetColorRows ());
HTM_Unsigned (NumUsr);
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.Listing.WithPhotos)
{
/***** Show administrator's photo *****/
HTM_TD_Begin ("class=\"LM %s\"",The_GetColorRows ());
Pho_ShowUsrPhotoIfAllowed (UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
HTM_TD_End ();
}
/****** Write the user's ID ******/
HTM_TD_Begin ("class=\"LM %s_%s %s\"",
UsrDat->Accepted ? "DAT_SMALL_STRONG" :
"DAT_SMALL",
The_GetSuffix (),
The_GetColorRows ());
ID_WriteUsrIDs (UsrDat,NULL);
HTM_NBSP ();
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write rest of main administrator's data *****/
Ins.InsCod = UsrDat->InsCod;
Ins_GetInstitDataByCod (&Ins);
Usr_WriteMainUsrDataExceptUsrID (UsrDat,The_GetColorRows ());
2014-12-01 23:55:08 +01:00
HTM_TD_Begin ("class=\"LM %s\"",The_GetColorRows ());
Ins_DrawInstitutionLogoWithLink (&Ins,25);
HTM_TD_End ();
2019-10-10 10:41:00 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
/***** Write degrees which are administrated by this administrator *****/
2016-11-14 16:47:46 +01:00
Hie_GetAndWriteInsCtrDegAdminBy (UsrDat->UsrCod,
2015-11-23 13:14:13 +01:00
Gbl.Usrs.Listing.WithPhotos ? Usr_NUM_MAIN_FIELDS_DATA_ADM :
Usr_NUM_MAIN_FIELDS_DATA_ADM-1);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************* Write main data of a user *************************/
/*****************************************************************************/
static void Usr_WriteMainUsrDataExceptUsrID (struct Usr_Data *UsrDat,
2016-07-27 14:58:26 +02:00
const char *BgColor)
2014-12-01 23:55:08 +01:00
{
Usr_WriteUsrData (BgColor,
UsrDat->Surname1[0] ? UsrDat->Surname1 :
"&nbsp;",
NULL,true,UsrDat->Accepted);
Usr_WriteUsrData (BgColor,
UsrDat->Surname2[0] ? UsrDat->Surname2 :
"&nbsp;",
NULL,true,UsrDat->Accepted);
Usr_WriteUsrData (BgColor,
UsrDat->FrstName[0] ? UsrDat->FrstName :
2014-12-01 23:55:08 +01:00
"&nbsp;",
NULL,true,UsrDat->Accepted);
2016-07-25 16:08:25 +02:00
}
/*****************************************************************************/
2016-11-16 23:19:52 +01:00
/**************************** Write user's email *****************************/
2016-07-25 16:08:25 +02:00
/*****************************************************************************/
static void Usr_WriteEmail (struct Usr_Data *UsrDat,const char *BgColor)
2016-07-25 16:08:25 +02:00
{
bool ShowEmail;
2017-03-13 13:17:53 +01:00
char MailLink[7 + Cns_MAX_BYTES_EMAIL_ADDRESS + 1]; // mailto:mail_address
2016-07-25 16:08:25 +02:00
2016-04-23 13:23:09 +02:00
if (UsrDat->Email[0])
{
2017-01-27 15:21:01 +01:00
ShowEmail = Mai_ICanSeeOtherUsrEmail (UsrDat);
if (ShowEmail)
snprintf (MailLink,sizeof (MailLink),"mailto:%s",UsrDat->Email);
2016-04-23 13:23:09 +02:00
}
else
ShowEmail = false;
2014-12-01 23:55:08 +01:00
Usr_WriteUsrData (BgColor,
UsrDat->Email[0] ? (ShowEmail ? UsrDat->Email :
"********") :
"&nbsp;",
ShowEmail ? MailLink :
NULL,
true,UsrDat->Accepted);
}
/*****************************************************************************/
/********************* Write a cell with data of a user **********************/
/*****************************************************************************/
2016-04-23 13:23:09 +02:00
static void Usr_WriteUsrData (const char *BgColor,
const char *Data,const char *Link,
bool NonBreak,bool Accepted)
2014-12-01 23:55:08 +01:00
{
2019-10-20 22:00:28 +02:00
/***** Begin table cell *****/
HTM_TD_Begin ("class=\"LM %s_%s %s\"",
Accepted ? (NonBreak ? "DAT_SMALL_NOBR_STRONG" :
"DAT_SMALL_STRONG") :
(NonBreak ? "DAT_SMALL_NOBR" :
"DAT_SMALL"),
The_GetSuffix (),
2019-10-10 23:14:13 +02:00
BgColor);
2017-03-06 10:11:10 +01:00
/***** Container to limit length *****/
HTM_DIV_Begin ("class=\"USR_DAT\"");
2017-03-06 10:11:10 +01:00
/***** Begin link *****/
if (Link)
HTM_A_Begin ("href=\"%s\" class=\"%s_%s\" target=\"_blank\"",
Link,Accepted ? "DAT_SMALL_NOBR_STRONG" :
"DAT_SMALL_NOBR",
The_GetSuffix ());
2017-03-06 10:11:10 +01:00
/***** Write data *****/
HTM_Txt (Data);
if (NonBreak)
HTM_NBSP ();
2017-03-06 10:11:10 +01:00
/***** End link *****/
if (Link)
HTM_A_End ();
2017-03-06 10:11:10 +01:00
/***** End container *****/
HTM_DIV_End ();
/***** End table cell *****/
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2016-06-23 11:31:51 +02:00
/*********** Get list of users with a given role in a given scope ************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-06-23 11:31:51 +02:00
// Role can be:
2017-05-23 00:40:03 +02:00
// - Rol_STD Student
// - Rol_NET Non-editing teacher
// - Rol_TCH Teacher
2014-12-01 23:55:08 +01:00
void Usr_GetListUsrs (HieLvl_Level_t Scope,Rol_Role_t Role)
2014-12-01 23:55:08 +01:00
{
2018-10-30 03:29:40 +01:00
char *Query = NULL;
2016-07-25 20:42:37 +02:00
/***** Build query *****/
Usr_DB_BuildQueryToGetUsrsLst (Scope,Role,&Query);
2016-06-23 11:31:51 +02:00
/***** Get list of users from database given a query *****/
2018-11-14 23:40:56 +01:00
Usr_GetListUsrsFromQuery (Query,Role,Scope);
/***** Free query string *****/
free (Query);
2016-06-23 11:31:51 +02:00
}
/*****************************************************************************/
2017-03-01 14:53:18 +01:00
/*********** Search for users with a given role in current scope *************/
2016-06-23 11:31:51 +02:00
/*****************************************************************************/
2016-06-29 18:27:49 +02:00
void Usr_SearchListUsrs (Rol_Role_t Role)
2016-06-23 11:31:51 +02:00
{
2018-10-30 03:29:40 +01:00
char *Query = NULL;
2016-07-25 20:42:37 +02:00
/***** Build query *****/
Usr_DB_BuildQueryToSearchListUsrs (Role,&Query);
2016-06-23 19:02:57 +02:00
2016-06-23 11:31:51 +02:00
/***** Get list of users from database given a query *****/
2018-11-14 23:40:56 +01:00
Usr_GetListUsrsFromQuery (Query,Role,Gbl.Scope.Current);
2016-06-24 15:31:09 +02:00
/***** Free query string *****/
free (Query);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************ Get list with data of guests ***********************/
/*****************************************************************************/
static void Usr_GetGstsLst (HieLvl_Level_t Scope)
2014-12-01 23:55:08 +01:00
{
2018-10-30 03:29:40 +01:00
char *Query = NULL;
2016-07-25 20:42:37 +02:00
/***** Build query *****/
Usr_DB_BuildQueryToGetGstsLst (Scope,&Query);
2014-12-01 23:55:08 +01:00
/***** Get list of students from database *****/
2018-11-14 23:40:56 +01:00
Usr_GetListUsrsFromQuery (Query,Rol_GST,Scope);
/***** Free query string *****/
free (Query);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************** Get the user's codes of all students of a degree *************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
void Usr_GetUnorderedStdsCodesInDeg (long DegCod)
{
2020-02-14 19:57:55 +01:00
char *Query = NULL;
2020-01-08 23:49:04 +01:00
/***** Build query string *****/
Usr_DB_BuildQueryToGetUnorderedStdsCodesInDeg (DegCod,&Query);
2014-12-01 23:55:08 +01:00
/***** Get list of students *****/
Usr_GetListUsrsFromQuery (Query,Rol_STD,HieLvl_DEG);
2020-01-08 23:49:04 +01:00
/***** Free query string *****/
free (Query);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************** Get list of users from database **********************/
/*****************************************************************************/
void Usr_GetListUsrsFromQuery (char *Query,Rol_Role_t Role,HieLvl_Level_t Scope)
2014-12-01 23:55:08 +01:00
{
2017-05-25 14:25:22 +02:00
extern const char *Txt_The_list_of_X_users_is_too_large_to_be_displayed;
2014-12-01 23:55:08 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumUsr;
struct Usr_InList *UsrInList;
2014-12-01 23:55:08 +01:00
bool Abort = false;
2018-11-14 23:40:56 +01:00
if (Query == NULL)
2018-10-29 22:22:02 +01:00
{
Gbl.Usrs.LstUsrs[Role].NumUsrs = 0;
return;
}
2018-11-14 23:40:56 +01:00
if (!Query[0])
2014-12-01 23:55:08 +01:00
{
2016-06-23 13:10:43 +02:00
Gbl.Usrs.LstUsrs[Role].NumUsrs = 0;
2014-12-01 23:55:08 +01:00
return;
}
/***** Query database *****/
if ((Gbl.Usrs.LstUsrs[Role].NumUsrs = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get list of users",
"%s",
Query)))
2014-12-01 23:55:08 +01:00
{
2016-06-23 13:10:43 +02:00
if (Gbl.Usrs.LstUsrs[Role].NumUsrs > Cfg_MAX_USRS_IN_LIST)
2014-12-01 23:55:08 +01:00
{
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_The_list_of_X_users_is_too_large_to_be_displayed,
Gbl.Usrs.LstUsrs[Role].NumUsrs);
2014-12-01 23:55:08 +01:00
Abort = true;
}
else
{
/***** Allocate memory for the list of users *****/
2016-06-23 13:10:43 +02:00
Usr_AllocateUsrsList (Role);
2014-12-01 23:55:08 +01:00
2016-06-21 10:32:06 +02:00
/***** Get list of users *****/
2014-12-01 23:55:08 +01:00
for (NumUsr = 0;
2016-06-23 13:10:43 +02:00
NumUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs;
2014-12-01 23:55:08 +01:00
NumUsr++)
{
2016-06-21 10:32:06 +02:00
/* Get next user */
2014-12-01 23:55:08 +01:00
row = mysql_fetch_row (mysql_res);
2016-07-25 20:24:07 +02:00
/*
2016-07-26 01:03:41 +02:00
row[ 0]: usr_data.UsrCod
row[ 1]: usr_data.EncryptedUsrCod
2017-01-27 01:02:52 +01:00
row[ 2]: usr_data.Password (used to check if a teacher can edit user's data)
row[ 3]: usr_data.Surname1
row[ 4]: usr_data.Surname2
row[ 5]: usr_data.FirstName
row[ 6]: usr_data.Sex
row[ 7]: usr_data.Photo
row[ 8]: usr_data.PhotoVisibility
2017-03-01 14:53:18 +01:00
row[ 9]: usr_data.CtyCod
row[10]: usr_data.InsCod
row[11]: crs_users.Role (only if Scope == HieLvl_CRS)
row[12]: crs_users.Accepted (only if Scope == HieLvl_CRS)
2016-07-25 20:24:07 +02:00
*/
UsrInList = &Gbl.Usrs.LstUsrs[Role].Lst[NumUsr];
/* Get user's code (row[0]) */
UsrInList->UsrCod = Str_ConvertStrCodToLongCod (row[0]);
/* Get encrypted user's code (row[1]), encrypted password (row[2]),
surname 1 (row[3]), surname 2 (row[4]), first name (row[5]), */
Str_Copy (UsrInList->EnUsrCod,row[1],sizeof (UsrInList->EnUsrCod) - 1);
Str_Copy (UsrInList->Password,row[2],sizeof (UsrInList->Password) - 1);
Str_Copy (UsrInList->Surname1,row[3],sizeof (UsrInList->Surname1) - 1);
Str_Copy (UsrInList->Surname2,row[4],sizeof (UsrInList->Surname2) - 1);
Str_Copy (UsrInList->FrstName,row[5],sizeof (UsrInList->FrstName) - 1);
2016-07-25 20:24:07 +02:00
2017-01-27 01:02:52 +01:00
/* Get user's sex (row[6]) */
UsrInList->Sex = Usr_GetSexFromStr (row[6]);
2016-07-25 20:24:07 +02:00
2017-01-27 01:02:52 +01:00
/* Get user's photo (row[7]) */
Str_Copy (UsrInList->Photo ,row[7],sizeof (UsrInList->Photo ) - 1);
2016-07-25 20:24:07 +02:00
2017-01-27 01:02:52 +01:00
/* Get user's photo visibility (row[8]) */
UsrInList->PhotoVisibility = Pri_GetVisibilityFromStr (row[8]);
2016-07-25 20:24:07 +02:00
/* Get user's country code (row[9])
and user's institution code (row[10]) */
UsrInList->CtyCod = Str_ConvertStrCodToLongCod (row[ 9]);
2017-03-01 14:53:18 +01:00
UsrInList->InsCod = Str_ConvertStrCodToLongCod (row[10]);
2016-07-25 20:24:07 +02:00
2017-03-30 11:20:06 +02:00
/* Get user's role and acceptance of enrolment in course(s)
(row[11], row[12] if Scope == HieLvl_CRS) */
2016-06-27 13:57:01 +02:00
switch (Role)
{
2017-05-18 19:13:41 +02:00
case Rol_UNK: // Here Rol_UNK means any user
2016-06-27 13:57:01 +02:00
switch (Scope)
{
case HieLvl_UNK: // Unknown
Err_WrongScopeExit ();
2016-06-27 13:57:01 +02:00
break;
case HieLvl_SYS: // System
2016-07-26 01:03:41 +02:00
// Query result has not a column with the acceptation
2017-05-18 19:13:41 +02:00
UsrInList->RoleInCurrentCrsDB = Rol_UNK;
if (Enr_DB_GetNumCrssOfUsr (UsrInList->UsrCod))
UsrInList->Accepted = (Enr_DB_GetNumCrssOfUsrNotAccepted (UsrInList->UsrCod) == 0);
2016-06-27 13:57:01 +02:00
else
2016-07-25 20:24:07 +02:00
UsrInList->Accepted = false;
2016-06-27 13:57:01 +02:00
break;
case HieLvl_CTY: // Country
case HieLvl_INS: // Institution
case HieLvl_CTR: // Center
case HieLvl_DEG: // Degree
2016-07-26 01:03:41 +02:00
// Query result has not a column with the acceptation
2017-05-18 19:13:41 +02:00
UsrInList->RoleInCurrentCrsDB = Rol_UNK;
UsrInList->Accepted = (Enr_DB_GetNumCrssOfUsrNotAccepted (UsrInList->UsrCod) == 0);
2016-06-27 13:57:01 +02:00
break;
case HieLvl_CRS: // Course
2016-07-26 01:03:41 +02:00
// Query result has a column with the acceptation
2017-03-01 14:53:18 +01:00
UsrInList->RoleInCurrentCrsDB = Rol_ConvertUnsignedStrToRole (row[11]);
UsrInList->Accepted = (row[12][0] == 'Y');
2016-06-27 13:57:01 +02:00
break;
}
break;
case Rol_GST: // Guests have no courses,...
// ...so they have not accepted...
// ...inscription in any course
case Rol_DEG_ADM: // Any admin (degree, center, institution or system)
2017-05-18 19:13:41 +02:00
UsrInList->RoleInCurrentCrsDB = Rol_UNK;
2016-07-25 20:24:07 +02:00
UsrInList->Accepted = false;
2016-06-27 13:57:01 +02:00
break;
2017-05-18 19:13:41 +02:00
case Rol_STD:
2017-05-23 00:40:03 +02:00
case Rol_NET:
2017-05-18 19:13:41 +02:00
case Rol_TCH:
2016-06-27 13:57:01 +02:00
switch (Scope)
{
case HieLvl_UNK: // Unknown
Err_WrongScopeExit ();
2016-06-27 13:57:01 +02:00
break;
case HieLvl_SYS: // System
case HieLvl_CTY: // Country
case HieLvl_INS: // Institution
case HieLvl_CTR: // Center
case HieLvl_DEG: // Degree
2016-07-26 01:03:41 +02:00
// Query result has not a column with the acceptation
2017-05-18 19:13:41 +02:00
UsrInList->RoleInCurrentCrsDB = Rol_UNK;
UsrInList->Accepted = (Enr_DB_GetNumCrssOfUsrWithARoleNotAccepted (UsrInList->UsrCod,Role) == 0);
2016-06-27 13:57:01 +02:00
break;
case HieLvl_CRS: // Course
2016-07-26 01:03:41 +02:00
// Query result has a column with the acceptation
2017-03-01 14:53:18 +01:00
UsrInList->RoleInCurrentCrsDB = Rol_ConvertUnsignedStrToRole (row[11]);
UsrInList->Accepted = (row[12][0] == 'Y');
2016-06-27 13:57:01 +02:00
break;
}
break;
default:
Err_WrongRoleExit ();
2016-06-27 13:57:01 +02:00
break;
2016-06-21 10:32:06 +02:00
}
2014-12-01 23:55:08 +01:00
/* By default, users are not removed */
2016-07-25 20:24:07 +02:00
UsrInList->Remove = false;
2014-12-01 23:55:08 +01:00
}
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
if (Abort)
Err_ShowErrorAndExit (NULL);
2014-12-01 23:55:08 +01:00
}
2016-07-25 20:55:25 +02:00
/*****************************************************************************/
/********************** Copy user's basic data from list *********************/
/*****************************************************************************/
void Usr_CopyBasicUsrDataFromList (struct Usr_Data *UsrDat,
const struct Usr_InList *UsrInList)
2016-07-25 20:55:25 +02:00
{
UsrDat->UsrCod = UsrInList->UsrCod;
Str_Copy (UsrDat->EnUsrCod,UsrInList->EnUsrCod,sizeof (UsrDat->EnUsrCod) - 1);
Str_Copy (UsrDat->Surname1,UsrInList->Surname1,sizeof (UsrDat->Surname1) - 1);
Str_Copy (UsrDat->Surname2,UsrInList->Surname2,sizeof (UsrDat->Surname2) - 1);
Str_Copy (UsrDat->FrstName,UsrInList->FrstName,sizeof (UsrDat->FrstName) - 1);
UsrDat->Sex = UsrInList->Sex;
Str_Copy (UsrDat->Photo ,UsrInList->Photo ,sizeof (UsrDat->Photo ) - 1);
UsrDat->PhotoVisibility = UsrInList->PhotoVisibility;
UsrDat->CtyCod = UsrInList->CtyCod;
UsrDat->InsCod = UsrInList->InsCod;
UsrDat->Roles.InCurrentCrs = UsrInList->RoleInCurrentCrsDB;
UsrDat->Accepted = UsrInList->Accepted;
2016-07-25 20:55:25 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********************** Allocate space for list of users *********************/
/*****************************************************************************/
2016-06-23 13:10:43 +02:00
static void Usr_AllocateUsrsList (Rol_Role_t Role)
2014-12-01 23:55:08 +01:00
{
2016-06-23 13:10:43 +02:00
if (Gbl.Usrs.LstUsrs[Role].NumUsrs)
if ((Gbl.Usrs.LstUsrs[Role].Lst = calloc (Gbl.Usrs.LstUsrs[Role].NumUsrs,
sizeof (*Gbl.Usrs.LstUsrs[Role].Lst))) == NULL)
Err_NotEnoughMemoryExit ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************* Free space used for list of users *********************/
/*****************************************************************************/
2016-06-23 13:10:43 +02:00
void Usr_FreeUsrsList (Rol_Role_t Role)
2014-12-01 23:55:08 +01:00
{
2016-06-23 13:10:43 +02:00
if (Gbl.Usrs.LstUsrs[Role].NumUsrs)
2014-12-01 23:55:08 +01:00
{
/***** Free the list itself *****/
2016-06-23 13:10:43 +02:00
if (Gbl.Usrs.LstUsrs[Role].Lst)
2014-12-01 23:55:08 +01:00
{
2019-11-06 19:45:20 +01:00
free (Gbl.Usrs.LstUsrs[Role].Lst);
2016-06-23 13:10:43 +02:00
Gbl.Usrs.LstUsrs[Role].Lst = NULL;
2014-12-01 23:55:08 +01:00
}
/***** Reset number of users *****/
2016-06-23 13:10:43 +02:00
Gbl.Usrs.LstUsrs[Role].NumUsrs = 0;
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/******** Show form to confirm that I want to see a big list of users ********/
/*****************************************************************************/
2019-04-11 09:55:35 +02:00
bool Usr_GetIfShowBigList (unsigned NumUsrs,
void (*FuncPars) (void *Args),void *Args,
2019-04-11 09:55:35 +02:00
const char *OnSubmit)
2014-12-01 23:55:08 +01:00
{
bool ShowBigList;
/***** If list of users is too big... *****/
2016-07-04 12:50:17 +02:00
if (NumUsrs > Cfg_MIN_NUM_USERS_TO_CONFIRM_SHOW_BIG_LIST)
{
/***** Get parameter with user's confirmation
to see a big list of users *****/
if (!(ShowBigList = Par_GetParBool ("ShowBigList")))
2020-03-26 02:54:30 +01:00
Usr_PutButtonToConfirmIWantToSeeBigList (NumUsrs,
FuncPars,Args,
2020-03-26 02:54:30 +01:00
OnSubmit);
2016-07-04 12:50:17 +02:00
return ShowBigList;
}
else
2014-12-01 23:55:08 +01:00
return true; // List is not too big ==> show it
}
/*****************************************************************************/
/******** Show form to confirm that I want to see a big list of users ********/
/*****************************************************************************/
2019-04-11 09:55:35 +02:00
static void Usr_PutButtonToConfirmIWantToSeeBigList (unsigned NumUsrs,
void (*FuncPars) (void *Args),void *Args,
2019-04-11 09:55:35 +02:00
const char *OnSubmit)
2014-12-01 23:55:08 +01:00
{
2017-05-25 14:25:22 +02:00
extern const char *Txt_The_list_of_X_users_is_too_large_to_be_displayed;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Show_anyway;
2017-05-25 14:25:22 +02:00
/***** Show alert and button to confirm that I want to see the big list *****/
Usr_FuncParsBigList = FuncPars; // Used to pass pointer to function
2019-02-17 01:14:55 +01:00
Ale_ShowAlertAndButton (Gbl.Action.Act,Usr_USER_LIST_SECTION_ID,OnSubmit,
Usr_PutParsConfirmIWantToSeeBigList,Args,
2019-02-17 01:14:55 +01:00
Btn_CONFIRM_BUTTON,Txt_Show_anyway,
Ale_WARNING,Txt_The_list_of_X_users_is_too_large_to_be_displayed,
NumUsrs);
2017-05-25 14:25:22 +02:00
}
2014-12-01 23:55:08 +01:00
static void Usr_PutParsConfirmIWantToSeeBigList (void *Args)
2017-05-25 14:25:22 +02:00
{
Grp_PutParsCodGrps ();
Set_PutParsPrefsAboutUsrList ();
if (Usr_FuncParsBigList)
Usr_FuncParsBigList (Args);
Par_PutParChar ("ShowBigList",'Y');
2016-07-04 12:50:17 +02:00
}
2019-11-15 03:34:48 +01:00
/*****************************************************************************/
/************ Create list of selected users with one given user **************/
/*****************************************************************************/
void Usr_CreateListSelectedUsrsCodsAndFillWithOtherUsr (struct Usr_SelectedUsrs *SelectedUsrs)
2019-11-15 03:34:48 +01:00
{
/***** Create list of user codes and put encrypted user code in it *****/
if (!SelectedUsrs->List[Rol_UNK])
{
if ((SelectedUsrs->List[Rol_UNK] =
malloc (Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64 + 1)) == NULL)
Err_NotEnoughMemoryExit ();
Str_Copy (SelectedUsrs->List[Rol_UNK],Gbl.Usrs.Other.UsrDat.EnUsrCod,
2019-11-15 03:34:48 +01:00
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
SelectedUsrs->Filled = true;
}
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************* Write parameter with the list of users selected ***************/
/*****************************************************************************/
void Usr_PutParSelectedUsrsCods (struct Usr_SelectedUsrs *SelectedUsrs)
2014-12-01 23:55:08 +01:00
{
char *ParName;
2019-11-15 03:34:48 +01:00
2017-05-09 10:32:54 +02:00
/***** Put a parameter indicating that a list of several users is present *****/
Par_PutParChar ("MultiUsrs",'Y');
2017-05-09 10:32:54 +02:00
/***** Put a parameter with the encrypted user codes of several users *****/
2019-11-15 03:34:48 +01:00
/* Build name of the parameter.
Sometimes a unique action needs several distinct lists of users,
so, it's necessary to use distinct names for the parameters. */
Usr_BuildParName (&ParName,Usr_ParUsrCod[Rol_UNK],SelectedUsrs->ParSuffix);
2019-11-15 03:34:48 +01:00
/* Put the parameter *****/
2014-12-01 23:55:08 +01:00
if (Gbl.Session.IsOpen)
Ses_InsertParInDB (ParName,SelectedUsrs->List[Rol_UNK]);
2014-12-01 23:55:08 +01:00
else
Par_PutParString (NULL,ParName,SelectedUsrs->List[Rol_UNK]);
2019-04-25 02:58:42 +02:00
2019-11-15 03:34:48 +01:00
/***** Free allocated memory for parameter name *****/
free (ParName);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************* Get list of selected users ************************/
/*****************************************************************************/
void Usr_GetListsSelectedEncryptedUsrsCods (struct Usr_SelectedUsrs *SelectedUsrs)
2014-12-01 23:55:08 +01:00
{
2019-11-03 13:19:32 +01:00
extern const char *Par_SEPARATOR_PARAM_MULTIPLE;
char *ParName;
2014-12-01 23:55:08 +01:00
unsigned Length;
2017-05-26 20:11:24 +02:00
Rol_Role_t Role;
2014-12-01 23:55:08 +01:00
2019-11-15 03:34:48 +01:00
if (!SelectedUsrs->Filled) // Get list only if not already got
2014-12-01 23:55:08 +01:00
{
2019-11-15 03:34:48 +01:00
/***** Build name of the parameter.
Sometimes a unique action needs several distinct lists of users,
so, it's necessary to use distinct names for the parameters. *****/
Usr_BuildParName (&ParName,Usr_ParUsrCod[Rol_UNK],SelectedUsrs->ParSuffix);
2019-11-15 03:34:48 +01:00
2019-03-11 13:33:34 +01:00
/***** Get possible list of all selected users *****/
2019-11-15 03:34:48 +01:00
Usr_AllocateListSelectedEncryptedUsrCods (SelectedUsrs,Rol_UNK);
2019-03-11 13:33:34 +01:00
if (Gbl.Session.IsOpen) // If the session is open, get parameter from DB
2017-05-26 20:11:24 +02:00
{
Ses_DB_GetPar (ParName,SelectedUsrs->List[Rol_UNK],
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS);
2019-11-15 03:34:48 +01:00
Str_ChangeFormat (Str_FROM_FORM,Str_TO_TEXT,SelectedUsrs->List[Rol_UNK],
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS,
Str_REMOVE_SPACES);
2019-03-11 13:33:34 +01:00
}
else
Par_GetParMultiToText (ParName,SelectedUsrs->List[Rol_UNK],
2017-05-26 20:11:24 +02:00
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS);
2019-11-15 10:48:20 +01:00
/***** Free allocated memory for parameter name *****/
free (ParName);
2019-11-15 10:48:20 +01:00
2019-03-11 13:33:34 +01:00
/***** Get list of selected users for each possible role *****/
2019-11-14 08:59:11 +01:00
for (Role = Rol_TCH; // From the highest possible role of selected users...
2019-03-11 13:33:34 +01:00
Role >= Rol_GST; // ...downto the lowest possible role of selected users
Role--)
if (Usr_ParUsrCod[Role])
2017-05-26 20:11:24 +02:00
{
2019-11-15 10:48:20 +01:00
/* Build name of the parameter */
Usr_BuildParName (&ParName,Usr_ParUsrCod[Role],SelectedUsrs->ParSuffix);
2019-11-15 10:48:20 +01:00
2019-03-11 13:33:34 +01:00
/* Get parameter with selected users with this role */
2019-11-15 03:34:48 +01:00
Usr_AllocateListSelectedEncryptedUsrCods (SelectedUsrs,Role);
Par_GetParMultiToText (ParName,SelectedUsrs->List[Role],
2019-03-11 13:33:34 +01:00
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS);
2019-11-15 10:48:20 +01:00
/* Free allocated memory for parameter name */
free (ParName);
2019-11-15 10:48:20 +01:00
2019-03-11 13:33:34 +01:00
/* Add selected users with this role
to the list with all selected users */
2019-11-15 03:34:48 +01:00
if (SelectedUsrs->List[Role][0])
2019-03-11 13:33:34 +01:00
{
2019-11-15 03:34:48 +01:00
if (SelectedUsrs->List[Rol_UNK][0])
if ((Length = strlen (SelectedUsrs->List[Rol_UNK])) <
2019-03-11 13:33:34 +01:00
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS)
{
2019-11-15 03:34:48 +01:00
SelectedUsrs->List[Rol_UNK][Length ] = Par_SEPARATOR_PARAM_MULTIPLE[0];
SelectedUsrs->List[Rol_UNK][Length + 1] = '\0';
2019-03-11 13:33:34 +01:00
}
2019-11-15 03:34:48 +01:00
Str_Concat (SelectedUsrs->List[Rol_UNK],SelectedUsrs->List[Role],
2019-03-11 13:33:34 +01:00
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS);
}
2017-05-26 20:11:24 +02:00
}
2019-03-11 13:33:34 +01:00
/***** List is filled *****/
2019-11-15 03:34:48 +01:00
SelectedUsrs->Filled = true;
}
}
static void Usr_BuildParName (char **ParName,
const char *ParRoot,
const char *ParSuffix)
2019-11-15 03:34:48 +01:00
{
/* Build name of the parameter.
Sometimes a unique action needs several distinct lists of users,
so, it's necessary to use distinct names for the parameters. */
if (ParSuffix)
2019-11-15 03:34:48 +01:00
{
if (asprintf (ParName,"%s%s",ParRoot,ParSuffix) < 0)
Err_NotEnoughMemoryExit ();
2019-11-15 03:34:48 +01:00
}
else
{
if (asprintf (ParName,"%s",ParRoot) < 0)
Err_NotEnoughMemoryExit ();
2019-03-11 13:33:34 +01:00
}
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*** Get list of recipients of a message written explicitely by the sender ***/
/*****************************************************************************/
// Returns true if no errors
bool Usr_GetListMsgRecipientsWrittenExplicitelyBySender (bool WriteErrorMsgs)
{
2019-11-03 13:19:32 +01:00
extern const char *Par_SEPARATOR_PARAM_MULTIPLE;
2014-12-01 23:55:08 +01:00
extern const char *Txt_There_is_no_user_with_nickname_X;
extern const char *Txt_There_is_no_user_with_email_X;
extern const char *Txt_There_are_more_than_one_user_with_the_ID_X_Please_type_a_nick_or_email;
2016-11-16 23:19:52 +01:00
extern const char *Txt_There_is_no_user_with_ID_nick_or_email_X;
2014-12-01 23:55:08 +01:00
extern const char *Txt_The_ID_nickname_or_email_X_is_not_valid;
2016-07-04 17:40:34 +02:00
size_t LengthSelectedUsrsCods;
size_t LengthUsrCod;
2014-12-01 23:55:08 +01:00
const char *Ptr;
char UsrIDNickOrEmail[Cns_MAX_BYTES_USR_LOGIN + 1];
struct Usr_Data UsrDat;
struct Usr_ListUsrCods ListUsrCods;
2014-12-01 23:55:08 +01:00
bool Error = false;
2019-03-11 13:33:34 +01:00
/***** Get list of selected encrypted users's codes if not already got.
This list is necessary to add encrypted user's codes at the end. *****/
2019-11-15 03:34:48 +01:00
Usr_GetListsSelectedEncryptedUsrsCods (&Gbl.Usrs.Selected);
2019-03-11 13:33:34 +01:00
LengthSelectedUsrsCods = strlen (Gbl.Usrs.Selected.List[Rol_UNK]);
2014-12-01 23:55:08 +01:00
/***** Allocate memory for the lists of recipients written explicetely *****/
Usr_AllocateListOtherRecipients ();
/***** Get recipients written explicetely *****/
Par_GetParText ("OtherRecipients",Gbl.Usrs.ListOtherRecipients,
Msg_MAX_BYTES_LIST_OTHER_RECIPIENTS);
2014-12-01 23:55:08 +01:00
/***** Add encrypted users' IDs to the list with all selected users *****/
if (Gbl.Usrs.ListOtherRecipients[0])
{
/* Initialize structure with user's data */
Usr_UsrDataConstructor (&UsrDat);
/* Get next plain user's ID or nickname */
Ptr = Gbl.Usrs.ListOtherRecipients;
while (*Ptr)
{
/* Find next string in text until comma or semicolon (leading and trailing spaces are removed) */
Str_GetNextStringUntilComma (&Ptr,UsrIDNickOrEmail,sizeof (UsrIDNickOrEmail) - 1);
2014-12-01 23:55:08 +01:00
/* Check if string is plain user's ID or nickname and get encrypted user's ID */
if (UsrIDNickOrEmail[0])
{
/***** Reset default list of users' codes *****/
ListUsrCods.NumUsrs = 0;
ListUsrCods.Lst = NULL;
if (Nck_CheckIfNickWithArrIsValid (UsrIDNickOrEmail)) // 1: It's a nickname
2014-12-01 23:55:08 +01:00
{
if ((UsrDat.UsrCod = Nck_GetUsrCodFromNickname (UsrIDNickOrEmail)) > 0)
{
ListUsrCods.NumUsrs = 1;
Usr_AllocateListUsrCods (&ListUsrCods);
2017-03-12 12:52:40 +01:00
ListUsrCods.Lst[0] = UsrDat.UsrCod;
2014-12-01 23:55:08 +01:00
}
else
{
if (WriteErrorMsgs)
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_There_is_no_user_with_nickname_X,
UsrIDNickOrEmail);
2014-12-01 23:55:08 +01:00
Error = true;
}
}
2016-11-16 23:19:52 +01:00
else if (Mai_CheckIfEmailIsValid (UsrIDNickOrEmail)) // 2: It's an email
2014-12-01 23:55:08 +01:00
{
if ((UsrDat.UsrCod = Mai_DB_GetUsrCodFromEmail (UsrIDNickOrEmail)) > 0)
2014-12-01 23:55:08 +01:00
{
ListUsrCods.NumUsrs = 1;
Usr_AllocateListUsrCods (&ListUsrCods);
ListUsrCods.Lst[0] = Gbl.Usrs.Other.UsrDat.UsrCod;
}
else
{
if (WriteErrorMsgs)
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_There_is_no_user_with_email_X,
UsrIDNickOrEmail);
2014-12-01 23:55:08 +01:00
Error = true;
}
}
2016-11-16 23:19:52 +01:00
else // 3: It's not a nickname nor email
2014-12-01 23:55:08 +01:00
{
// Users' IDs are always stored internally in capitals and without leading zeros
Str_RemoveLeadingZeros (UsrIDNickOrEmail);
Str_ConvertToUpperText (UsrIDNickOrEmail);
if (ID_CheckIfUsrIDIsValid (UsrIDNickOrEmail))
{
// It seems a user's ID
/***** Allocate space for the list *****/
ID_ReallocateListIDs (&UsrDat,1);
2017-01-15 18:02:52 +01:00
Str_Copy (UsrDat.IDs.List[0].ID,UsrIDNickOrEmail,
sizeof (UsrDat.IDs.List[0].ID) - 1);
2014-12-01 23:55:08 +01:00
/***** Check if a user exists having this user's ID *****/
if (ID_GetListUsrCodsFromUsrID (&UsrDat,NULL,&ListUsrCods,false))
{
if (ListUsrCods.NumUsrs > 1) // Two or more user share the same user's ID
{// TODO: Consider forbid IDs here
if (WriteErrorMsgs)
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_ERROR,Txt_There_are_more_than_one_user_with_the_ID_X_Please_type_a_nick_or_email,
UsrIDNickOrEmail);
2014-12-01 23:55:08 +01:00
Error = true;
}
}
else // No users found
{
if (WriteErrorMsgs)
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_ERROR,Txt_There_is_no_user_with_ID_nick_or_email_X,
UsrIDNickOrEmail);
2014-12-01 23:55:08 +01:00
Error = true;
}
}
2016-11-16 23:19:52 +01:00
else // String is not a valid user's nickname, email or ID
2014-12-01 23:55:08 +01:00
{
if (WriteErrorMsgs)
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_WARNING,Txt_The_ID_nickname_or_email_X_is_not_valid,
UsrIDNickOrEmail);
2014-12-01 23:55:08 +01:00
Error = true;
}
}
if (ListUsrCods.NumUsrs == 1) // Only if user is valid
{
/* Get user's data */
Usr_GetUsrDataFromUsrCod (&UsrDat, // Really only EncryptedUsrCod is needed
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS);
2014-12-01 23:55:08 +01:00
/* Find if encrypted user's code is already in list */
if (!Usr_FindEncryptedUsrCodInListOfSelectedEncryptedUsrCods (UsrDat.EnUsrCod,&Gbl.Usrs.Selected)) // If not in list ==> add it
2014-12-01 23:55:08 +01:00
{
LengthUsrCod = strlen (UsrDat.EnUsrCod);
2017-03-12 12:52:40 +01:00
2014-12-01 23:55:08 +01:00
/* Add encrypted user's code to list of users */
2017-03-12 12:52:40 +01:00
if (LengthSelectedUsrsCods == 0) // First user in list
2014-12-01 23:55:08 +01:00
{
2017-03-12 12:52:40 +01:00
if (LengthUsrCod < Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS)
{
/* Add user */
2019-03-11 13:33:34 +01:00
Str_Copy (Gbl.Usrs.Selected.List[Rol_UNK],
UsrDat.EnUsrCod,
2017-03-12 12:52:40 +01:00
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS);
LengthSelectedUsrsCods = LengthUsrCod;
}
2014-12-01 23:55:08 +01:00
}
2017-03-12 12:52:40 +01:00
else // Not first user in list
2016-07-04 17:40:34 +02:00
{
2017-03-12 12:52:40 +01:00
if (LengthSelectedUsrsCods + (1 + LengthUsrCod) <
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS)
2014-12-01 23:55:08 +01:00
{
2017-03-12 12:52:40 +01:00
/* Add separator */
2019-11-03 13:19:32 +01:00
Gbl.Usrs.Selected.List[Rol_UNK][LengthSelectedUsrsCods] = Par_SEPARATOR_PARAM_MULTIPLE[0];
2017-03-12 12:52:40 +01:00
LengthSelectedUsrsCods++;
/* Add user */
2019-03-11 13:33:34 +01:00
Str_Copy (Gbl.Usrs.Selected.List[Rol_UNK] + LengthSelectedUsrsCods,
UsrDat.EnUsrCod,
2017-03-12 12:52:40 +01:00
Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS);
LengthSelectedUsrsCods += LengthUsrCod;
2014-12-01 23:55:08 +01:00
}
2016-07-04 17:40:34 +02:00
}
2014-12-01 23:55:08 +01:00
}
}
/***** Free list of users' codes *****/
Usr_FreeListUsrCods (&ListUsrCods);
}
}
/* Free memory used for user's data */
Usr_UsrDataDestructor (&UsrDat);
}
return Error;
}
/*****************************************************************************/
/************** Find if encrypted user's code is yet in list *****************/
/*****************************************************************************/
2019-11-15 10:48:20 +01:00
// Returns true if EncryptedUsrCodToFind is in list
2014-12-01 23:55:08 +01:00
bool Usr_FindEncryptedUsrCodInListOfSelectedEncryptedUsrCods (const char *EncryptedUsrCodToFind,
struct Usr_SelectedUsrs *SelectedUsrs)
2014-12-01 23:55:08 +01:00
{
const char *Ptr;
2017-03-07 01:56:41 +01:00
char EncryptedUsrCod[Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64 + 1];
2014-12-01 23:55:08 +01:00
2019-11-15 10:48:20 +01:00
if (SelectedUsrs->List[Rol_UNK])
2014-12-01 23:55:08 +01:00
{
2019-11-15 10:48:20 +01:00
Ptr = SelectedUsrs->List[Rol_UNK];
2015-09-30 23:10:15 +02:00
while (*Ptr)
{
Par_GetNextStrUntilSeparParMult (&Ptr,EncryptedUsrCod,
2017-03-13 14:22:36 +01:00
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
2015-09-30 23:10:15 +02:00
if (!strcmp (EncryptedUsrCodToFind,EncryptedUsrCod))
return true; // Found!
}
2014-12-01 23:55:08 +01:00
}
2015-09-30 23:10:15 +02:00
return false; // List not allocated or user not found
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2019-11-14 02:29:18 +01:00
/******* Check if there are valid users in list of encrypted user codes ******/
/*****************************************************************************/
bool Usr_CheckIfThereAreUsrsInListOfSelectedEncryptedUsrCods (struct Usr_SelectedUsrs *SelectedUsrs)
2019-11-14 02:29:18 +01:00
{
const char *Ptr;
struct Usr_Data UsrDat;
2019-11-14 02:29:18 +01:00
2019-11-15 03:34:48 +01:00
/***** Loop over the list to check if there are valid users *****/
Ptr = SelectedUsrs->List[Rol_UNK];
2019-11-14 02:29:18 +01:00
while (*Ptr)
{
Par_GetNextStrUntilSeparParMult (&Ptr,UsrDat.EnUsrCod,
2019-11-14 02:29:18 +01:00
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat);
if (UsrDat.UsrCod > 0)
return true;
}
return false;
}
/*****************************************************************************/
/******** Count number of valid users in list of encrypted user codes ********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
unsigned Usr_CountNumUsrsInListOfSelectedEncryptedUsrCods (struct Usr_SelectedUsrs *SelectedUsrs)
2014-12-01 23:55:08 +01:00
{
const char *Ptr;
unsigned NumUsrs = 0;
struct Usr_Data UsrDat;
2014-12-01 23:55:08 +01:00
2019-11-15 03:34:48 +01:00
/***** Loop over the list to count the number of users *****/
Ptr = SelectedUsrs->List[Rol_UNK];
2014-12-01 23:55:08 +01:00
while (*Ptr)
{
Par_GetNextStrUntilSeparParMult (&Ptr,UsrDat.EnUsrCod,
2017-03-13 14:22:36 +01:00
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
2014-12-01 23:55:08 +01:00
Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat);
if (UsrDat.UsrCod > 0)
NumUsrs++;
}
return NumUsrs;
}
/*****************************************************************************/
/****************** Allocate memory for list of students *********************/
/*****************************************************************************/
2017-05-23 18:15:59 +02:00
// Role = Rol_UNK here means all users
2014-12-01 23:55:08 +01:00
static void Usr_AllocateListSelectedEncryptedUsrCods (struct Usr_SelectedUsrs *SelectedUsrs,
2019-11-15 03:34:48 +01:00
Rol_Role_t Role)
2014-12-01 23:55:08 +01:00
{
2019-11-15 03:34:48 +01:00
if (!SelectedUsrs->List[Role])
2014-12-01 23:55:08 +01:00
{
2019-11-15 03:34:48 +01:00
if ((SelectedUsrs->List[Role] =
malloc (Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS + 1)) == NULL)
Err_NotEnoughMemoryExit ();
2019-11-15 03:34:48 +01:00
SelectedUsrs->List[Role][0] = '\0';
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
2019-11-15 10:48:20 +01:00
/******* Free memory used by lists of selected encrypted users' codes ********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2017-05-23 18:15:59 +02:00
// Role = Rol_UNK here means all users
2014-12-01 23:55:08 +01:00
void Usr_FreeListsSelectedEncryptedUsrsCods (struct Usr_SelectedUsrs *SelectedUsrs)
2014-12-01 23:55:08 +01:00
{
2017-05-23 18:15:59 +02:00
Rol_Role_t Role;
2019-11-15 03:34:48 +01:00
if (SelectedUsrs->Filled) // Only if lists are filled
2019-03-11 13:33:34 +01:00
{
/***** Free lists *****/
2019-12-15 20:02:34 +01:00
for (Role = (Rol_Role_t) 0;
Role <= (Rol_Role_t) (Rol_NUM_ROLES - 1);
2019-03-11 13:33:34 +01:00
Role++)
2019-11-15 03:34:48 +01:00
if (SelectedUsrs->List[Role])
2019-03-11 13:33:34 +01:00
{
2019-11-15 03:34:48 +01:00
free (SelectedUsrs->List[Role]);
SelectedUsrs->List[Role] = NULL;
2019-03-11 13:33:34 +01:00
}
/***** Mark lists as empty *****/
2019-11-15 03:34:48 +01:00
SelectedUsrs->Filled = false;
2019-03-11 13:33:34 +01:00
// Lists of encrypted codes of users selected from form
// are now marked as not filled
}
2014-12-01 23:55:08 +01:00
}
2019-11-13 21:31:06 +01:00
/*****************************************************************************/
/************* Get list of users selected to show their projects *************/
/*****************************************************************************/
void Usr_GetListSelectedUsrCods (struct Usr_SelectedUsrs *SelectedUsrs,
2019-11-15 03:34:48 +01:00
unsigned NumUsrsInList,
long **LstSelectedUsrCods)
2019-11-13 21:31:06 +01:00
{
unsigned NumUsr;
const char *Ptr;
struct Usr_Data UsrDat;
2019-11-13 21:31:06 +01:00
/***** Create list of user codes *****/
if ((*LstSelectedUsrCods = calloc (NumUsrsInList,
sizeof (**LstSelectedUsrCods))) == NULL)
Err_NotEnoughMemoryExit ();
2019-11-13 21:31:06 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2019-11-15 03:34:48 +01:00
/***** Loop over the list getting users' codes *****/
for (NumUsr = 0, Ptr = SelectedUsrs->List[Rol_UNK];
2019-11-13 21:31:06 +01:00
NumUsr < NumUsrsInList && *Ptr;
NumUsr++)
{
Par_GetNextStrUntilSeparParMult (&Ptr,UsrDat.EnUsrCod,
2019-11-13 21:31:06 +01:00
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat);
(*LstSelectedUsrCods)[NumUsr] = UsrDat.UsrCod;
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
void Usr_FreeListSelectedUsrCods (long *LstSelectedUsrCods)
{
if (LstSelectedUsrCods)
free (LstSelectedUsrCods);
}
/*****************************************************************************/
/******** Create subquery string with users' codes separated by commas *******/
/******** from list of users' codes *******/
/*****************************************************************************/
void Usr_CreateSubqueryUsrCods (long LstSelectedUsrCods[],
unsigned NumUsrsInList,
char **UsrsSubQuery)
2019-11-13 21:31:06 +01:00
{
char SubQueryOneUsr[1 + Cns_MAX_DECIMAL_DIGITS_LONG + 1];
unsigned NumUsr;
size_t MaxLength;
2019-11-14 02:29:18 +01:00
/***** Allocate space for subquery *****/
MaxLength = (size_t) NumUsrsInList * (size_t) (1 + Cns_MAX_DECIMAL_DIGITS_LONG);
if ((*UsrsSubQuery = malloc (MaxLength + 1)) == NULL)
Err_NotEnoughMemoryExit ();
(*UsrsSubQuery)[0] = '\0';
2019-11-13 21:31:06 +01:00
2019-11-14 02:29:18 +01:00
/***** Build subquery *****/
for (NumUsr = 0;
NumUsr < NumUsrsInList;
NumUsr++)
if (NumUsr)
{
snprintf (SubQueryOneUsr,sizeof (SubQueryOneUsr),",%ld",
2019-11-14 02:29:18 +01:00
LstSelectedUsrCods[NumUsr]);
Str_Concat (*UsrsSubQuery,SubQueryOneUsr,MaxLength);
2019-11-14 02:29:18 +01:00
}
else
snprintf (*UsrsSubQuery,sizeof (SubQueryOneUsr),"%ld",
2019-11-14 02:29:18 +01:00
LstSelectedUsrCods[NumUsr]);
2019-11-13 21:31:06 +01:00
}
2019-11-14 02:29:18 +01:00
void Usr_FreeSubqueryUsrCods (char *SubQueryUsrs)
2019-11-13 21:31:06 +01:00
{
2019-11-14 02:29:18 +01:00
free (SubQueryUsrs);
2019-11-13 21:31:06 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********** Allocate memory for list of users's IDs or nicknames *************/
/*****************************************************************************/
static void Usr_AllocateListOtherRecipients (void)
{
if (!Gbl.Usrs.ListOtherRecipients)
{
if ((Gbl.Usrs.ListOtherRecipients = malloc (Msg_MAX_BYTES_LIST_OTHER_RECIPIENTS + 1)) == NULL)
Err_NotEnoughMemoryExit ();
2014-12-01 23:55:08 +01:00
Gbl.Usrs.ListOtherRecipients[0] = '\0';
}
}
/*****************************************************************************/
/****************** Free memory for the list of nicknames ********************/
/*****************************************************************************/
void Usr_FreeListOtherRecipients (void)
{
if (Gbl.Usrs.ListOtherRecipients)
{
2019-11-06 19:45:20 +01:00
free (Gbl.Usrs.ListOtherRecipients);
2014-12-01 23:55:08 +01:00
Gbl.Usrs.ListOtherRecipients = NULL;
}
}
/*****************************************************************************/
2015-04-11 14:38:15 +02:00
/*************************** Selection of list type **************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
void Usr_ShowFormsToSelectUsrListType (void (*FuncPars) (void *Args),void *Args)
2014-12-01 23:55:08 +01:00
{
Set_BeginSettingsHead ();
Set_BeginOneSettingSelector ();
2016-12-23 22:19:03 +01:00
/***** Select Set_USR_LIST_AS_CLASS_PHOTO *****/
Set_BeginPref (Gbl.Usrs.Me.ListType == Set_USR_LIST_AS_CLASS_PHOTO);
Set_FormToSelectUsrListType (FuncPars,Args,
Set_USR_LIST_AS_CLASS_PHOTO);
/* Number of columns in the class photo */
Frm_BeginFormAnchor (Gbl.Action.Act, // Repeat current action
Usr_USER_LIST_SECTION_ID);
Grp_PutParsCodGrps ();
Set_PutParUsrListType (Set_USR_LIST_AS_CLASS_PHOTO);
Set_PutParListWithPhotos ();
Usr_PutSelectorNumColsClassPhoto ();
if (FuncPars)
FuncPars (Args);
Frm_EndForm ();
Set_EndPref ();
2014-12-01 23:55:08 +01:00
2017-01-29 21:41:08 +01:00
/***** Select Usr_LIST_AS_LISTING *****/
Set_BeginPref (Gbl.Usrs.Me.ListType == Set_USR_LIST_AS_LISTING);
Set_FormToSelectUsrListType (FuncPars,Args,
Set_USR_LIST_AS_LISTING);
/* See the photos in list? */
Frm_BeginFormAnchor (Gbl.Action.Act, // Repeat current action
Usr_USER_LIST_SECTION_ID);
Grp_PutParsCodGrps ();
Set_PutParUsrListType (Set_USR_LIST_AS_LISTING);
if (FuncPars)
FuncPars (Args);
Usr_PutCheckboxListWithPhotos ();
Frm_EndForm ();
Set_EndPref ();
2016-12-23 22:19:03 +01:00
2019-03-26 11:53:21 +01:00
Set_EndOneSettingSelector ();
Set_EndSettingsHead ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************* Put a radio element to select a users' list type **************/
/*****************************************************************************/
static void Set_FormToSelectUsrListType (void (*FuncPars) (void *Args),void *Args,
Set_ShowUsrsType_t ListType)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_USR_LIST_TYPES[Set_NUM_USR_LIST_TYPES];
2014-12-01 23:55:08 +01:00
2019-10-20 22:00:28 +02:00
/***** Begin form *****/
Frm_BeginFormAnchor (Gbl.Action.Act, // Repeat current action
2019-04-11 14:45:31 +02:00
Usr_USER_LIST_SECTION_ID);
Grp_PutParsCodGrps ();
Set_PutParUsrListType (ListType);
Set_PutParListWithPhotos ();
if (FuncPars)
FuncPars (Args);
/***** Link and image *****/
HTM_BUTTON_Submit_Begin (Txt_USR_LIST_TYPES[ListType],
"class=\"BT_LINK FORM_IN_%s NOWRAP\"%s",
The_GetSuffix (),
Gbl.Action.Act == ActReqMsgUsr ? " onsubmit=\"CopyMessageToHiddenFields();\"" :
"");
Ico_PutIcon (Usr_IconsClassPhotoOrList[ListType],Ico_BLACK,
Txt_USR_LIST_TYPES[ListType],"ICO20x20");
HTM_TxtF ("&nbsp;%s",Txt_USR_LIST_TYPES[ListType]);
HTM_BUTTON_End ();
2017-05-25 13:49:16 +02:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************** List users to select some of them **********************/
/*****************************************************************************/
2019-04-10 19:19:34 +02:00
void Usr_PutFormToSelectUsrsToGoToAct (struct Usr_SelectedUsrs *SelectedUsrs,
2020-03-26 02:54:30 +01:00
Act_Action_t NextAction,
void (*FuncPars) (void *Args),void *Args,
2019-04-11 23:15:40 +02:00
const char *Title,
2019-04-10 19:19:34 +02:00
const char *HelpLink,
2019-12-09 11:50:03 +01:00
const char *TxtButton,
bool PutFormDateRange)
2019-04-10 19:19:34 +02:00
{
2019-04-11 23:15:40 +02:00
extern const char *Txt_Select_users;
2019-12-09 11:50:03 +01:00
extern const char *Txt_Users;
2019-04-10 19:19:34 +02:00
unsigned NumTotalUsrs;
2020-02-26 19:35:33 +01:00
static const Dat_SetHMS SetHMS[Dat_NUM_START_END_TIME] =
{
[Dat_STR_TIME] = Dat_HMS_DO_NOT_SET,
[Dat_END_TIME] = Dat_HMS_DO_NOT_SET
2020-02-26 19:35:33 +01:00
};
2019-04-10 19:19:34 +02:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Title,
NULL,NULL,
HelpLink,Box_NOT_CLOSABLE);
2019-04-11 23:15:40 +02:00
/***** Get and update type of list,
number of columns in class photo
and preference about view photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2019-04-10 19:19:34 +02:00
/***** Get groups to show ******/
Grp_GetParCodsSeveralGrpsToShowUsrs ();
2019-04-10 19:19:34 +02:00
/***** Get and order lists of users from this course *****/
Usr_GetListUsrs (HieLvl_CRS,Rol_STD);
Usr_GetListUsrs (HieLvl_CRS,Rol_NET);
Usr_GetListUsrs (HieLvl_CRS,Rol_TCH);
NumTotalUsrs = Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs +
Gbl.Usrs.LstUsrs[Rol_NET].NumUsrs +
Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs;
2019-04-10 19:19:34 +02:00
/***** Draw class photos to select users *****/
Box_BoxBegin (NULL,Txt_Select_users,
NULL,NULL,
NULL,Box_NOT_CLOSABLE);
2019-04-10 19:19:34 +02:00
/***** Show form to select the groups *****/
Grp_ShowFormToSelectSeveralGroups (FuncPars,Args,
Grp_MY_GROUPS);
2019-04-10 19:19:34 +02:00
/***** Begin section with user list *****/
HTM_SECTION_Begin (Usr_USER_LIST_SECTION_ID);
2019-04-10 19:19:34 +02:00
if (NumTotalUsrs)
{
if (Usr_GetIfShowBigList (NumTotalUsrs,
FuncPars,Args,
NULL))
{
/***** Form to select type of list used for select several users *****/
Usr_ShowFormsToSelectUsrListType (FuncPars,Args);
2019-04-10 19:19:34 +02:00
/***** Link to register students *****/
Enr_CheckStdsAndPutButtonToRegisterStdsInCurrentCrs ();
2019-04-10 19:19:34 +02:00
/***** Form to select users and select date range ****/
/* Begin form */
Frm_BeginForm (NextAction);
2019-11-13 09:49:52 +01:00
/* Hidden parameters */
Grp_PutParsCodGrps ();
if (NextAction == ActAdmAsgWrkCrs)
{
Gbl.FileBrowser.FullTree = true; // By default, show all files
Brw_PutParFullTreeIfSelected (&Gbl.FileBrowser.FullTree);
}
if (FuncPars)
FuncPars (Args);
2019-04-10 19:19:34 +02:00
HTM_TABLE_BeginCenterPadding (2);
2019-12-09 11:50:03 +01:00
/* Put list of users to select some of them */
HTM_TR_Begin (NULL);
2019-12-09 11:50:03 +01:00
HTM_TD_Begin ("class=\"RT FORM_IN_%s\"",
The_GetSuffix ());
HTM_TxtColon (Txt_Users);
HTM_TD_End ();
2019-12-09 11:50:03 +01:00
HTM_TD_Begin ("class=\"LT FORM_IN_%s\"",
The_GetSuffix ());
HTM_TABLE_BeginCenterPadding (2);
Usr_ListUsersToSelect (Rol_TCH,SelectedUsrs);
Usr_ListUsersToSelect (Rol_NET,SelectedUsrs);
Usr_ListUsersToSelect (Rol_STD,SelectedUsrs);
HTM_TABLE_End ();
HTM_TD_End ();
2019-12-09 11:50:03 +01:00
HTM_TR_End ();
2019-12-09 11:50:03 +01:00
/* Starting and ending dates in the search */
if (PutFormDateRange)
Dat_PutFormStartEndClientLocalDateTimesWithYesterdayToday (SetHMS);
2019-12-09 11:50:03 +01:00
HTM_TABLE_End ();
2019-04-10 19:19:34 +02:00
/***** Send button *****/
Btn_PutConfirmButton (TxtButton);
2019-04-10 19:19:34 +02:00
/***** End form *****/
Frm_EndForm ();
}
}
else // NumTotalUsrs == 0
/***** Show warning indicating no users found *****/
Usr_ShowWarningNoUsersFound (Rol_UNK);
2019-04-10 19:19:34 +02:00
/***** End section with user list *****/
HTM_SECTION_End ();
2019-04-10 19:19:34 +02:00
/***** End box *****/
Box_BoxEnd ();
2019-04-10 19:19:34 +02:00
/***** Free memory for users' list *****/
Usr_FreeUsrsList (Rol_TCH);
Usr_FreeUsrsList (Rol_NET);
Usr_FreeUsrsList (Rol_STD);
2019-04-10 19:19:34 +02:00
/***** Free memory for list of selected groups *****/
Grp_FreeListCodSelectedGrps ();
2019-04-11 23:15:40 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2019-04-10 19:19:34 +02:00
}
void Usr_GetSelectedUsrsAndGoToAct (struct Usr_SelectedUsrs *SelectedUsrs,
2020-04-06 16:00:06 +02:00
void (*FuncWhenUsrsSelected) (void *ArgsSelected),void *ArgsSelected,
void (*FuncWhenNoUsrsSelected) (void *ArgsNoSelected),void *ArgsNoSelected)
2019-04-11 09:55:35 +02:00
{
extern const char *Txt_You_must_select_one_ore_more_users;
/***** Get lists of the selected users if not already got *****/
2019-11-15 03:34:48 +01:00
Usr_GetListsSelectedEncryptedUsrsCods (SelectedUsrs);
2019-04-11 09:55:35 +02:00
/***** Check number of users *****/
2019-11-15 03:34:48 +01:00
if (Usr_CheckIfThereAreUsrsInListOfSelectedEncryptedUsrCods (SelectedUsrs)) // If some users are selected...
2020-04-06 16:00:06 +02:00
FuncWhenUsrsSelected (ArgsSelected);
2019-04-11 09:55:35 +02:00
else // If no users are selected...
{
// ...write warning alert
Ale_ShowAlert (Ale_WARNING,Txt_You_must_select_one_ore_more_users);
// ...and show again the form
2020-04-06 16:00:06 +02:00
FuncWhenNoUsrsSelected (ArgsNoSelected);
2019-04-11 09:55:35 +02:00
}
/***** Free memory used by list of selected users' codes *****/
2019-11-15 03:34:48 +01:00
Usr_FreeListsSelectedEncryptedUsrsCods (SelectedUsrs);
2019-04-11 09:55:35 +02:00
}
2019-04-10 19:19:34 +02:00
/*****************************************************************************/
/*********** List users with a given role to select some of them *************/
/*****************************************************************************/
2014-12-01 23:55:08 +01:00
void Usr_ListUsersToSelect (Rol_Role_t Role,struct Usr_SelectedUsrs *SelectedUsrs)
2014-12-01 23:55:08 +01:00
{
/***** If there are no users, don't list anything *****/
2016-06-23 13:51:37 +02:00
if (!Gbl.Usrs.LstUsrs[Role].NumUsrs)
return;
2014-12-01 23:55:08 +01:00
/***** Draw the classphoto/list *****/
switch (Gbl.Usrs.Me.ListType)
{
case Set_USR_LIST_AS_CLASS_PHOTO:
2017-05-24 03:12:57 +02:00
Usr_DrawClassPhoto (Usr_CLASS_PHOTO_SEL,
2019-11-15 03:34:48 +01:00
Role,SelectedUsrs,true);
2014-12-01 23:55:08 +01:00
break;
case Set_USR_LIST_AS_LISTING:
2019-11-15 03:34:48 +01:00
Usr_ListUsrsForSelection (Role,SelectedUsrs);
2014-12-01 23:55:08 +01:00
break;
2017-01-29 21:41:08 +01:00
default:
break;
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
2016-12-26 16:58:49 +01:00
/******** Put a row, in a classphoto or a list, to select all users **********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2019-11-15 03:34:48 +01:00
static void Usr_PutCheckboxToSelectAllUsers (Rol_Role_t Role,
struct Usr_SelectedUsrs *SelectedUsrs)
2014-12-01 23:55:08 +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-01 23:55:08 +01:00
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
char *ParName;
2014-12-01 23:55:08 +01:00
Usr_Sex_t Sex;
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-12 00:07:52 +02:00
HTM_TH_Span_Begin (HTM_HEAD_LEFT,1,Usr_GetColumnsForSelectUsrs (),"BG_HIGHLIGHT");
2019-10-12 00:07:52 +02:00
HTM_LABEL_Begin (NULL);
if (Usr_NameSelUnsel[Role] && Usr_ParUsrCod[Role])
{
Usr_BuildParName (&ParName,Usr_ParUsrCod[Role],SelectedUsrs->ParSuffix);
HTM_INPUT_CHECKBOX (Usr_NameSelUnsel[Role],HTM_DONT_SUBMIT_ON_CHANGE,
"value=\"\" onclick=\"togglecheckChildren(this,'%s')\"",
ParName);
free (ParName);
}
else
Err_WrongRoleExit ();
Sex = Usr_GetSexOfUsrsLst (Role);
HTM_TxtColon (Gbl.Usrs.LstUsrs[Role].NumUsrs == 1 ? Txt_ROLES_SINGUL_Abc[Role][Sex] :
Txt_ROLES_PLURAL_Abc[Role][Sex]);
HTM_LABEL_End ();
2019-10-12 00:07:52 +02:00
HTM_TH_End ();
2019-10-12 00:07:52 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************** Get sex of a list of users ***********************/
/*****************************************************************************/
2016-06-23 13:10:43 +02:00
static Usr_Sex_t Usr_GetSexOfUsrsLst (Rol_Role_t Role)
2014-12-01 23:55:08 +01:00
{
Usr_Sex_t Sex;
unsigned NumUsr;
/***** If no users, sex is undefined *****/
2016-06-23 13:10:43 +02:00
if (Gbl.Usrs.LstUsrs[Role].NumUsrs == 0)
2014-12-01 23:55:08 +01:00
return Usr_SEX_UNKNOWN;
/***** Initialize sex to that of first user in list *****/
2016-06-23 13:10:43 +02:00
Sex = Gbl.Usrs.LstUsrs[Role].Lst[0].Sex;
2014-12-01 23:55:08 +01:00
/***** Search if there is one user at least with different sex than the first one *****/
for (NumUsr = 1;
2016-06-23 13:10:43 +02:00
NumUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs;
2014-12-01 23:55:08 +01:00
NumUsr++)
2016-06-23 13:10:43 +02:00
if (Gbl.Usrs.LstUsrs[Role].Lst[NumUsr].Sex != Sex)
2014-12-01 23:55:08 +01:00
return Usr_SEX_UNKNOWN;
return Sex;
}
/*****************************************************************************/
/**** Get number of table columns, in classphoto or list, to select users ****/
/*****************************************************************************/
unsigned Usr_GetColumnsForSelectUsrs (void)
{
return (Gbl.Usrs.Me.ListType == Set_USR_LIST_AS_CLASS_PHOTO) ? Gbl.Usrs.ClassPhoto.Cols :
(Gbl.Usrs.Listing.WithPhotos ? 1 + Usr_NUM_MAIN_FIELDS_DATA_USR :
Usr_NUM_MAIN_FIELDS_DATA_USR);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******* Put a checkbox, in a classphoto or a list, to select a user *********/
/*****************************************************************************/
2017-05-30 17:34:49 +02:00
static void Usr_PutCheckboxToSelectUser (Rol_Role_t Role,
const char *EncryptedUsrCod,
2019-11-15 03:34:48 +01:00
bool UsrIsTheMsgSender,
struct Usr_SelectedUsrs *SelectedUsrs)
2014-12-01 23:55:08 +01:00
{
2015-09-30 23:10:15 +02:00
bool CheckboxChecked;
char *ParName;
2015-09-30 23:10:15 +02:00
if (Usr_NameSelUnsel[Role] && Usr_ParUsrCod[Role])
2017-05-23 00:40:03 +02:00
{
2017-05-26 20:11:24 +02:00
/***** Check box must be checked? *****/
if (UsrIsTheMsgSender)
CheckboxChecked = true;
else
/* Check if user is in lists of selected users */
CheckboxChecked = Usr_FindEncryptedUsrCodInListOfSelectedEncryptedUsrCods (EncryptedUsrCod,SelectedUsrs);
2017-05-26 20:11:24 +02:00
/***** Check box *****/
Usr_BuildParName (&ParName,Usr_ParUsrCod[Role],SelectedUsrs->ParSuffix);
HTM_INPUT_CHECKBOX (ParName,HTM_DONT_SUBMIT_ON_CHANGE,
2019-11-04 20:41:35 +01:00
"value=\"%s\"%s onclick=\"checkParent(this,'%s')\"",
EncryptedUsrCod,
2020-03-12 13:53:37 +01:00
CheckboxChecked ? " checked=\"checked\"" :
"",
2019-11-04 20:41:35 +01:00
Usr_NameSelUnsel[Role]);
free (ParName);
2017-05-23 00:40:03 +02:00
}
2014-12-01 23:55:08 +01:00
else
Err_WrongRoleExit ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********* Put a checkbox to select whether list users with photos ***********/
/*****************************************************************************/
2015-10-02 01:04:28 +02:00
static void Usr_PutCheckboxListWithPhotos (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_Display_photos;
Par_PutParChar ("WithPhotosExists",'Y');
2014-12-01 23:55:08 +01:00
/***** Put checkbox to select whether list users with photos *****/
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ());
HTM_INPUT_CHECKBOX ("WithPhotos",HTM_SUBMIT_ON_CHANGE,
"value=\"Y\"%s",
Gbl.Usrs.Listing.WithPhotos ? " checked=\"checked\"" :
"");
HTM_Txt (Txt_Display_photos);
2019-11-02 12:59:31 +01:00
HTM_LABEL_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*********************** Set field names of user's data **********************/
/*****************************************************************************/
2016-06-16 14:34:17 +02:00
void Usr_SetUsrDatMainFieldNames (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_No_INDEX;
extern const char *Txt_Photo;
extern const char *Txt_ID;
extern const char *Txt_Surname_1;
extern const char *Txt_Surname_2;
extern const char *Txt_First_name;
extern const char *Txt_Institution;
/***** Initialize field names *****/
Usr_UsrDatMainFieldNames[0] = "&nbsp;";
Usr_UsrDatMainFieldNames[1] = Txt_No_INDEX;
Usr_UsrDatMainFieldNames[2] = Txt_Photo;
Usr_UsrDatMainFieldNames[3] = Txt_ID;
Usr_UsrDatMainFieldNames[4] = Txt_Surname_1;
Usr_UsrDatMainFieldNames[5] = Txt_Surname_2;
Usr_UsrDatMainFieldNames[6] = Txt_First_name;
2016-07-25 16:08:25 +02:00
Usr_UsrDatMainFieldNames[7] = Txt_Institution;
2014-12-01 23:55:08 +01:00
}
2016-06-16 18:32:12 +02:00
/*****************************************************************************/
/************ Write header with main field names of user's data **************/
/*****************************************************************************/
void Usr_WriteHeaderFieldsUsrDat (bool PutCheckBoxToSelectUsr)
{
unsigned NumCol;
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2016-06-16 18:32:12 +02:00
/***** First column used for selection *****/
if (PutCheckBoxToSelectUsr)
HTM_TH_Span (NULL,HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
2016-06-16 18:32:12 +02:00
/***** Columns for user's data fields *****/
for (NumCol = 0;
NumCol < Usr_NUM_MAIN_FIELDS_DATA_USR;
NumCol++)
if (NumCol != 2 || Gbl.Usrs.Listing.WithPhotos) // Skip photo column if I don't want this column
HTM_TH_Span (Usr_UsrDatMainFieldNames[NumCol],HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
2016-06-16 18:32:12 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2016-06-16 18:32:12 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************************** List guests' main data ***************************/
/*****************************************************************************/
static void Usr_ListMainDataGsts (bool PutCheckBoxToSelectUsr)
{
unsigned NumUsr;
struct Usr_Data UsrDat;
2014-12-01 23:55:08 +01:00
2017-05-18 19:13:41 +02:00
if (Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs)
2014-12-01 23:55:08 +01:00
{
2017-05-24 03:12:57 +02:00
/***** Initialize field names *****/
Usr_SetUsrDatMainFieldNames ();
/***** Put a row to select all users *****/
if (PutCheckBoxToSelectUsr)
2019-11-15 03:34:48 +01:00
Usr_PutCheckboxToSelectAllUsers (Rol_GST,&Gbl.Usrs.Selected);
2017-05-24 03:12:57 +02:00
2014-12-01 23:55:08 +01:00
/***** Heading row with column names *****/
2016-06-16 18:32:12 +02:00
Usr_WriteHeaderFieldsUsrDat (PutCheckBoxToSelectUsr); // Columns for the data
2014-12-01 23:55:08 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** List guests' data *****/
for (NumUsr = 0, The_ResetRowColor ();
NumUsr < Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs;
NumUsr++, The_ChangeRowColor ())
{
/* Copy user's basic data from list */
Usr_CopyBasicUsrDataFromList (&UsrDat,&Gbl.Usrs.LstUsrs[Rol_GST].Lst[NumUsr]);
2016-06-16 11:28:20 +02:00
/* Get list of user's IDs */
ID_GetListIDsFromUsrCod (&UsrDat);
2016-07-25 21:08:53 +02:00
/* Show row for this guest */
Usr_WriteRowUsrMainData (NumUsr + 1,&UsrDat,true,Rol_GST,
&Gbl.Usrs.Selected);
}
2014-12-01 23:55:08 +01:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
2017-05-18 19:13:41 +02:00
else // Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs == 0
2017-05-29 21:34:43 +02:00
/***** Show warning indicating no guests found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_GST);
2014-12-01 23:55:08 +01:00
2016-06-23 13:10:43 +02:00
/***** Free memory for guests list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_GST);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************************** List main students' data ************************/
/*****************************************************************************/
static void Usr_ListMainDataStds (bool PutCheckBoxToSelectUsr)
{
unsigned NumUsr;
char *GroupNames;
struct Usr_Data UsrDat;
2014-12-01 23:55:08 +01:00
/***** Initialize field names *****/
Usr_SetUsrDatMainFieldNames ();
GroupNames = NULL; // To avoid warning
2017-05-18 19:13:41 +02:00
if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs)
2014-12-01 23:55:08 +01:00
{
/***** Allocate memory for the string with the list of group names where student belongs to *****/
if ((GroupNames = malloc (Gbl.Crs.Grps.GrpTypes.NumGrpsTotal *
(Grp_MAX_BYTES_GROUP_NAME + 3))) == NULL)
Err_NotEnoughMemoryExit ();
2014-12-01 23:55:08 +01:00
2019-10-20 22:00:28 +02:00
/***** Begin table with list of students *****/
2014-12-01 23:55:08 +01:00
if (!Gbl.Usrs.ClassPhoto.AllGroups)
{
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
HTM_TD_Begin ("colspan=\"%u\" class=\"TIT CM\"",
1 + Usr_NUM_MAIN_FIELDS_DATA_USR);
Grp_WriteNamesOfSelectedGrps ();
HTM_TD_End ();
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
}
2017-05-24 03:12:57 +02:00
/***** Put a row to select all users *****/
if (PutCheckBoxToSelectUsr)
2019-11-15 03:34:48 +01:00
Usr_PutCheckboxToSelectAllUsers (Rol_STD,&Gbl.Usrs.Selected);
2017-05-24 03:12:57 +02:00
2014-12-01 23:55:08 +01:00
/***** Heading row with column names *****/
2016-06-16 18:32:12 +02:00
Usr_WriteHeaderFieldsUsrDat (PutCheckBoxToSelectUsr); // Columns for the data
2014-12-01 23:55:08 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** List students' data *****/
for (NumUsr = 0, The_ResetRowColor ();
2017-05-18 19:13:41 +02:00
NumUsr < Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs;
NumUsr++, The_ChangeRowColor ())
2014-12-01 23:55:08 +01:00
{
2016-07-25 20:55:25 +02:00
/* Copy user's basic data from list */
2017-05-18 19:13:41 +02:00
Usr_CopyBasicUsrDataFromList (&UsrDat,&Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumUsr]);
2016-06-16 11:28:20 +02:00
2016-07-25 20:55:25 +02:00
/* Get list of user's IDs */
ID_GetListIDsFromUsrCod (&UsrDat);
2016-07-27 14:58:26 +02:00
/* Show row for this student */
2017-05-30 17:34:49 +02:00
Usr_WriteRowUsrMainData (NumUsr + 1,&UsrDat,
2019-11-15 03:34:48 +01:00
PutCheckBoxToSelectUsr,Rol_STD,
&Gbl.Usrs.Selected);
2014-12-01 23:55:08 +01:00
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
/***** Free memory used by the string with the list of group names where student belongs to *****/
2019-11-06 19:45:20 +01:00
free (GroupNames);
2014-12-01 23:55:08 +01:00
}
2017-05-18 19:13:41 +02:00
else // Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs == 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-01 23:55:08 +01:00
/***** Free memory for students list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_STD);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************** List main teachers' data *************************/
/*****************************************************************************/
2017-05-24 03:12:57 +02:00
// Role can be:
// - Rol_NET
// - Rol_TCH
2014-12-01 23:55:08 +01:00
2019-11-15 03:34:48 +01:00
static void Usr_ListMainDataTchs (Rol_Role_t Role,
bool PutCheckBoxToSelectUsr)
2014-12-01 23:55:08 +01:00
{
unsigned NumCol;
unsigned NumUsr;
struct Usr_Data UsrDat;
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
if (Gbl.Usrs.LstUsrs[Role].NumUsrs)
2014-12-01 23:55:08 +01:00
{
2017-05-24 03:12:57 +02:00
/***** Put a row to select all users *****/
if (PutCheckBoxToSelectUsr)
2019-11-15 03:34:48 +01:00
Usr_PutCheckboxToSelectAllUsers (Role,&Gbl.Usrs.Selected);
2014-12-01 23:55:08 +01:00
/***** Heading row with column names *****/
/* Begin row */
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2014-12-01 23:55:08 +01:00
/* First column used for selection */
if (PutCheckBoxToSelectUsr)
HTM_TH_Span (NULL,HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
2014-12-01 23:55:08 +01:00
/* Columns for the data */
for (NumCol = 0;
NumCol < Usr_NUM_MAIN_FIELDS_DATA_USR;
NumCol++)
if (NumCol != 2 || Gbl.Usrs.Listing.WithPhotos) // Skip photo column if I don't want this column
HTM_TH_Span (Usr_UsrDatMainFieldNames[NumCol],HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
2014-12-01 23:55:08 +01:00
/* End row */
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2016-07-25 21:08:53 +02:00
/***** List teachers' data *****/
for (NumUsr = 0, The_ResetRowColor ();
2017-05-24 03:12:57 +02:00
NumUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs;
NumUsr++, The_ChangeRowColor ())
2014-12-01 23:55:08 +01:00
{
2016-07-25 20:55:25 +02:00
/* Copy user's basic data from list */
2017-05-24 03:12:57 +02:00
Usr_CopyBasicUsrDataFromList (&UsrDat,&Gbl.Usrs.LstUsrs[Role].Lst[NumUsr]);
2016-06-16 11:28:20 +02:00
2016-07-25 20:55:25 +02:00
/* Get list of user's IDs */
ID_GetListIDsFromUsrCod (&UsrDat);
2016-07-27 14:58:26 +02:00
/* Show row for this teacher */
2017-05-30 17:34:49 +02:00
Usr_WriteRowUsrMainData (NumUsr + 1,&UsrDat,
2019-11-15 03:34:48 +01:00
PutCheckBoxToSelectUsr,Role,
&Gbl.Usrs.Selected);
2014-12-01 23:55:08 +01:00
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
}
/*****************************************************************************/
/***************************** List guests' data *****************************/
/*****************************************************************************/
void Usr_ListAllDataGsts (void)
{
extern const char *Txt_Photo;
extern const char *Txt_ID;
extern const char *Txt_Surname_1;
extern const char *Txt_Surname_2;
extern const char *Txt_First_name;
extern const char *Txt_Institution;
2016-07-25 16:08:25 +02:00
extern const char *Txt_Email;
extern const char *Txt_Center;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Department;
extern const char *Txt_Office;
extern const char *Txt_Phone;
extern const char *Txt_Date_of_birth;
unsigned NumColumnsCommonCard;
unsigned NumCol;
unsigned NumUsr;
struct Usr_Data UsrDat;
2016-07-25 16:08:25 +02:00
const char *FieldNames[Usr_NUM_ALL_FIELDS_DATA_GST];
2014-12-01 23:55:08 +01:00
/***** Initialize field names *****/
FieldNames[ 0] = Txt_Photo;
FieldNames[ 1] = Txt_ID;
FieldNames[ 2] = Txt_Surname_1;
FieldNames[ 3] = Txt_Surname_2;
FieldNames[ 4] = Txt_First_name;
2016-07-27 14:58:26 +02:00
FieldNames[ 5] = Txt_Email;
FieldNames[ 6] = Txt_Institution;
FieldNames[ 7] = Txt_Center;
2014-12-01 23:55:08 +01:00
FieldNames[ 8] = Txt_Department;
FieldNames[ 9] = Txt_Office;
FieldNames[10] = Txt_Phone;
2020-04-29 02:34:54 +02:00
FieldNames[11] = Txt_Phone;
2014-12-01 23:55:08 +01:00
FieldNames[12] = Txt_Phone;
2020-04-29 02:34:54 +02:00
FieldNames[13] = Txt_Date_of_birth;
2014-12-01 23:55:08 +01:00
/***** Get and update type of list,
number of columns in class photo
2019-03-26 11:53:21 +01:00
and preference about viewing photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2014-12-01 23:55:08 +01:00
/***** Get scope *****/
Sco_SetScopesForListingGuests ();
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeUsr");
2014-12-01 23:55:08 +01:00
2017-01-28 17:17:35 +01:00
/****** Get list of guests ******/
2014-12-01 23:55:08 +01:00
Usr_GetGstsLst (Gbl.Scope.Current);
2017-05-18 19:13:41 +02:00
if (Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs)
2014-12-01 23:55:08 +01:00
{
/***** Set number of columns *****/
2016-07-25 16:08:25 +02:00
NumColumnsCommonCard = Usr_NUM_ALL_FIELDS_DATA_GST;
2014-12-01 23:55:08 +01:00
2019-10-20 22:00:28 +02:00
/***** Begin table with list of guests *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginWide ();
2017-05-01 12:36:24 +02:00
/* Begin row */
HTM_TR_Begin (NULL);
2014-12-01 23:55:08 +01:00
/* Columns for the data */
for (NumCol = (Gbl.Usrs.Listing.WithPhotos ? 0 :
1);
NumCol < NumColumnsCommonCard;
NumCol++)
HTM_TH_Span (FieldNames[NumCol],HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
2014-12-01 23:55:08 +01:00
/* End row */
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2014-12-01 23:55:08 +01:00
/***** List guests' data *****/
for (NumUsr = 0, The_ResetRowColor ();
NumUsr < Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs; )
{
UsrDat.UsrCod = Gbl.Usrs.LstUsrs[Rol_GST].Lst[NumUsr].UsrCod;
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS))
{
UsrDat.Accepted = false; // Guests have no courses,...
// ...so they have not accepted...
// ...inscription in any course
NumUsr++;
Usr_WriteRowGstAllData (&UsrDat);
2016-06-16 11:28:20 +02:00
The_ChangeRowColor ();
}
}
2014-12-01 23:55:08 +01:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End table *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2014-12-01 23:55:08 +01:00
}
2017-05-18 19:13:41 +02:00
else // Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs == 0
2017-05-29 21:34:43 +02:00
/***** Show warning indicating no guests found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_GST);
2014-12-01 23:55:08 +01:00
2016-06-23 13:10:43 +02:00
/***** Free memory for guests list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_GST);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************************** List students' data ***************************/
/*****************************************************************************/
void Usr_ListAllDataStds (void)
{
extern const char *Txt_Photo;
extern const char *Txt_ID;
extern const char *Txt_Surname_1;
extern const char *Txt_Surname_2;
extern const char *Txt_First_name;
extern const char *Txt_Institution;
2016-07-25 16:08:25 +02:00
extern const char *Txt_Email;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Phone;
extern const char *Txt_Date_of_birth;
extern const char *Txt_Group;
2014-12-12 18:50:36 +01:00
extern const char *Txt_RECORD_FIELD_VISIBILITY_RECORD[Rec_NUM_TYPES_VISIBILITY];
unsigned NumColsCommonRecord;
unsigned NumColsRecordAndGroups;
unsigned NumColsTotal;
2014-12-01 23:55:08 +01:00
unsigned NumCol;
unsigned NumUsr;
char *GroupNames;
unsigned NumGrpTyp,NumField;
struct Usr_Data UsrDat;
2014-12-01 23:55:08 +01:00
const char *FieldNames[Usr_NUM_ALL_FIELDS_DATA_STD];
2017-01-16 01:51:01 +01:00
size_t Length;
2014-12-01 23:55:08 +01:00
/***** Initialize field names *****/
2020-04-29 02:34:54 +02:00
FieldNames[0] = Txt_Photo;
FieldNames[1] = Txt_ID;
FieldNames[2] = Txt_Surname_1;
FieldNames[3] = Txt_Surname_2;
FieldNames[4] = Txt_First_name;
FieldNames[5] = Txt_Email;
FieldNames[6] = Txt_Institution;
FieldNames[7] = Txt_Phone;
FieldNames[8] = Txt_Phone;
FieldNames[9] = Txt_Date_of_birth;
2014-12-01 23:55:08 +01:00
GroupNames = NULL; // To avoid warning
/***** Get and update type of list,
number of columns in class photo
2019-03-26 11:53:21 +01:00
and preference about viewing photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2014-12-01 23:55:08 +01:00
/***** Get scope *****/
Sco_SetScopesForListingStudents ();
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeUsr");
2014-12-01 23:55:08 +01:00
2016-11-27 12:45:42 +01:00
/***** If the scope is the current course... *****/
if (Gbl.Scope.Current == HieLvl_CRS)
2016-11-27 12:45:42 +01:00
{
/* Get list of groups types and groups in current course
This is necessary to show columns with group selection */
Grp_GetListGrpTypesInCurrentCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS);
2016-11-27 12:45:42 +01:00
/* Get groups to show */
2016-11-25 03:21:02 +01:00
Grp_GetParCodsSeveralGrpsToShowUsrs ();
2016-11-27 12:45:42 +01:00
}
2016-11-25 03:21:02 +01:00
2017-01-28 17:17:35 +01:00
/****** Get list of students in current course ******/
2017-05-25 19:57:34 +02:00
Usr_GetListUsrs (Gbl.Scope.Current,Rol_STD);
2014-12-01 23:55:08 +01:00
2017-05-18 19:13:41 +02:00
if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs)
2014-12-01 23:55:08 +01:00
{
if (Gbl.Scope.Current == HieLvl_CRS)
2014-12-01 23:55:08 +01:00
/***** Get list of record fields in current course *****/
Rec_GetListRecordFieldsInCurrentCrs ();
/***** Set number of columns *****/
NumColsCommonRecord = Usr_NUM_ALL_FIELDS_DATA_STD;
if (Gbl.Scope.Current == HieLvl_CRS)
2014-12-01 23:55:08 +01:00
{
NumColsRecordAndGroups = NumColsCommonRecord + Gbl.Crs.Grps.GrpTypes.NumGrpTypes;
NumColsTotal = NumColsRecordAndGroups + Gbl.Crs.Records.LstFields.Num;
2014-12-01 23:55:08 +01:00
}
else
NumColsTotal = NumColsRecordAndGroups = NumColsCommonRecord;
2014-12-01 23:55:08 +01:00
/***** Allocate memory for the string with the list of group names where student belongs to *****/
if (Gbl.Scope.Current == HieLvl_CRS)
2017-01-16 01:51:01 +01:00
{
Length = (size_t) (Grp_MAX_BYTES_GROUP_NAME + 2) *
(size_t) Gbl.Crs.Grps.GrpTypes.NumGrpsTotal;
if ((GroupNames = malloc (Length + 1)) == NULL)
Err_NotEnoughMemoryExit ();
2017-01-16 01:51:01 +01:00
}
2014-12-01 23:55:08 +01:00
2019-10-20 22:00:28 +02:00
/***** Begin table with list of students *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginWide ();
2014-12-01 23:55:08 +01:00
if (!Gbl.Usrs.ClassPhoto.AllGroups)
{
HTM_TR_Begin (NULL);
HTM_TD_Begin ("colspan=\"%u\" class=\"TIT CM\"",NumColsTotal);
Grp_WriteNamesOfSelectedGrps ();
HTM_TD_End ();
HTM_TR_End ();
}
2014-12-01 23:55:08 +01:00
/***** Heading row with column names *****/
/* Begin row */
HTM_TR_Begin (NULL);
2014-12-01 23:55:08 +01:00
/* 1. Columns for the data */
for (NumCol = (Gbl.Usrs.Listing.WithPhotos ? 0 :
1);
NumCol < NumColsCommonRecord;
NumCol++)
HTM_TH_Span (FieldNames[NumCol],HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
/* 2. Columns for the groups */
if (Gbl.Scope.Current == HieLvl_CRS)
{
if (Gbl.Crs.Grps.GrpTypes.NumGrpTypes)
for (NumGrpTyp = 0;
NumGrpTyp < Gbl.Crs.Grps.GrpTypes.NumGrpTypes;
NumGrpTyp++)
if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) // If current course tiene groups of este type
{
HTM_TH_Span_Begin (HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
HTM_TxtF ("%s&nbsp;%s",
Txt_Group,
Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].GrpTypName);
HTM_TH_End ();
}
if (Gbl.Crs.Records.LstFields.Num)
{
/* 3. Names of record fields that depend on the course */
for (NumField = 0;
NumField < Gbl.Crs.Records.LstFields.Num;
NumField++)
HTM_TH_Span (Gbl.Crs.Records.LstFields.Lst[NumField].Name,HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
/* 4. Visibility type for the record fields that depend on the course, in other row */
HTM_TR_End ();
HTM_TR_Begin (NULL);
for (NumCol = 0;
NumCol < NumColsRecordAndGroups;
NumCol++)
if (NumCol != 1 || Gbl.Usrs.Listing.WithPhotos) // Skip photo column if I don't want it in listing
{
HTM_TD_Begin ("class=\"LM BG_HIGHLIGHT\"");
HTM_TD_End ();
}
for (NumField = 0;
NumField < Gbl.Crs.Records.LstFields.Num;
NumField++)
{
HTM_TH_Span_Begin (HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
HTM_TxtF ("(%s)",
Txt_RECORD_FIELD_VISIBILITY_RECORD[Gbl.Crs.Records.LstFields.Lst[NumField].Visibility]);
HTM_TH_End ();
}
}
}
2014-12-01 23:55:08 +01:00
/* End row */
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2014-12-01 23:55:08 +01:00
/***** List students' data *****/
for (NumUsr = 0, The_ResetRowColor ();
NumUsr < Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs; )
{
UsrDat.UsrCod = Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumUsr].UsrCod;
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS))
{
UsrDat.Accepted = Gbl.Usrs.LstUsrs[Rol_STD].Lst[NumUsr].Accepted;
NumUsr++;
Usr_WriteRowStdAllData (&UsrDat,GroupNames);
2016-06-16 11:28:20 +02:00
The_ChangeRowColor ();
}
}
2014-12-01 23:55:08 +01:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End table *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2014-12-01 23:55:08 +01:00
/***** Free memory used by the string with the list of group names where student belongs to *****/
if (Gbl.Scope.Current == HieLvl_CRS)
2019-11-06 19:45:20 +01:00
free (GroupNames);
2014-12-01 23:55:08 +01:00
}
2017-05-18 19:13:41 +02:00
else // Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs == 0
2017-05-29 21:34:43 +02:00
/***** Show warning indicating no students found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_STD);
2014-12-01 23:55:08 +01:00
/***** Free memory for list of selected groups *****/
Grp_FreeListCodSelectedGrps ();
/***** Free memory for students list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_STD);
2014-12-01 23:55:08 +01:00
/***** Free list of groups types and groups in current course *****/
Grp_FreeListGrpTypesAndGrps ();
}
/*****************************************************************************/
/*************** List users (of current course) for selection ****************/
/*****************************************************************************/
2019-11-15 03:34:48 +01:00
static void Usr_ListUsrsForSelection (Rol_Role_t Role,
struct Usr_SelectedUsrs *SelectedUsrs)
2014-12-01 23:55:08 +01:00
{
unsigned NumUsr;
struct Usr_Data UsrDat;
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
if (Gbl.Usrs.LstUsrs[Role].NumUsrs)
{
/***** Initialize field names *****/
Usr_SetUsrDatMainFieldNames ();
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Put a row to select all users *****/
2019-11-15 03:34:48 +01:00
Usr_PutCheckboxToSelectAllUsers (Role,SelectedUsrs);
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Heading row with column names *****/
Usr_WriteHeaderFieldsUsrDat (true); // Columns for the data
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** List users' data *****/
for (NumUsr = 0, The_ResetRowColor ();
2017-05-24 03:12:57 +02:00
NumUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs; )
2016-06-23 13:51:37 +02:00
{
2017-05-24 03:12:57 +02:00
UsrDat.UsrCod = Gbl.Usrs.LstUsrs[Role].Lst[NumUsr].UsrCod;
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS))
2017-05-24 03:12:57 +02:00
{
UsrDat.Accepted = Gbl.Usrs.LstUsrs[Role].Lst[NumUsr].Accepted;
2019-11-15 03:34:48 +01:00
Usr_WriteRowUsrMainData (++NumUsr,&UsrDat,true,Role,SelectedUsrs);
2016-06-16 11:28:20 +02:00
The_ChangeRowColor ();
2017-05-24 03:12:57 +02:00
}
2016-06-23 13:51:37 +02:00
}
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************** List all teachers' data **************************/
/*****************************************************************************/
void Usr_ListAllDataTchs (void)
{
extern const char *Txt_Photo;
extern const char *Txt_ID;
extern const char *Txt_Surname_1;
extern const char *Txt_Surname_2;
extern const char *Txt_First_name;
extern const char *Txt_Institution;
2016-07-25 16:08:25 +02:00
extern const char *Txt_Email;
extern const char *Txt_Center;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Department;
extern const char *Txt_Office;
extern const char *Txt_Phone;
2017-05-26 01:12:15 +02:00
unsigned NumUsrs;
2014-12-01 23:55:08 +01:00
unsigned NumColumns;
const char *FieldNames[Usr_NUM_ALL_FIELDS_DATA_TCH];
/***** Initialize field names *****/
FieldNames[ 0] = Txt_Photo;
FieldNames[ 1] = Txt_ID;
FieldNames[ 2] = Txt_Surname_1;
FieldNames[ 3] = Txt_Surname_2;
FieldNames[ 4] = Txt_First_name;
2016-07-27 14:58:26 +02:00
FieldNames[ 5] = Txt_Email;
FieldNames[ 6] = Txt_Institution;
FieldNames[ 7] = Txt_Center;
2014-12-01 23:55:08 +01:00
FieldNames[ 8] = Txt_Department;
FieldNames[ 9] = Txt_Office;
FieldNames[10] = Txt_Phone;
/***** Get and update type of list,
number of columns in class photo
2019-03-26 11:53:21 +01:00
and preference about viewing photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2014-12-01 23:55:08 +01:00
/***** Get scope *****/
Gbl.Scope.Allowed = 1 << HieLvl_SYS |
1 << HieLvl_CTY |
1 << HieLvl_INS |
1 << HieLvl_CTR |
1 << HieLvl_DEG |
1 << HieLvl_CRS;
Gbl.Scope.Default = HieLvl_CRS;
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeUsr");
2014-12-01 23:55:08 +01:00
2017-01-28 17:17:35 +01:00
/***** Get list of teachers *****/
2017-05-26 01:12:15 +02:00
Usr_GetListUsrs (Gbl.Scope.Current,Rol_NET); // Non-editing teachers
Usr_GetListUsrs (Gbl.Scope.Current,Rol_TCH); // Teachers
if (Gbl.Scope.Current == HieLvl_CRS)
2017-05-30 18:24:26 +02:00
NumUsrs = Gbl.Usrs.LstUsrs[Rol_NET].NumUsrs +
Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs;
else
NumUsrs = Enr_GetNumUsrsInCrss (Gbl.Scope.Current,
(Gbl.Scope.Current == HieLvl_CTY ? Gbl.Hierarchy.Cty.CtyCod :
(Gbl.Scope.Current == HieLvl_INS ? Gbl.Hierarchy.Ins.InsCod :
(Gbl.Scope.Current == HieLvl_CTR ? Gbl.Hierarchy.Ctr.CtrCod :
(Gbl.Scope.Current == HieLvl_DEG ? Gbl.Hierarchy.Deg.DegCod :
(Gbl.Scope.Current == HieLvl_CRS ? Gbl.Hierarchy.Crs.CrsCod :
-1L))))),
2020-01-08 23:49:04 +01:00
1 << Rol_NET |
1 << Rol_TCH);
2014-12-01 23:55:08 +01:00
2017-05-26 01:12:15 +02:00
if (NumUsrs)
2014-12-01 23:55:08 +01:00
{
/***** Initialize number of columns *****/
NumColumns = Usr_NUM_ALL_FIELDS_DATA_TCH;
2019-10-20 22:00:28 +02:00
/***** Begin table with lists of teachers *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginWide ();
2017-05-01 12:36:24 +02:00
/***** List teachers and non-editing teachers *****/
Usr_ListRowsAllDataTchs (Rol_TCH,FieldNames,NumColumns);
Usr_ListRowsAllDataTchs (Rol_NET,FieldNames,NumColumns);
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End table *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2014-12-01 23:55:08 +01:00
}
2017-05-29 21:34:43 +02:00
else // NumUsrs == 0
2017-02-09 19:27:18 +01:00
/***** Show warning indicating no teachers found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_TCH);
2014-12-01 23:55:08 +01:00
2017-05-26 19:25:41 +02:00
/***** Free memory for teachers lists *****/
Usr_FreeUsrsList (Rol_TCH); // Teachers
Usr_FreeUsrsList (Rol_NET); // Non-editing teachers
2014-12-01 23:55:08 +01:00
}
2017-05-26 01:12:15 +02:00
/*****************************************************************************/
/*********************** List all teachers' data rows ************************/
/*****************************************************************************/
static void Usr_ListRowsAllDataTchs (Rol_Role_t Role,
const char *FieldNames[Usr_NUM_ALL_FIELDS_DATA_TCH],
unsigned NumColumns)
{
unsigned NumCol;
struct Usr_Data UsrDat;
2017-05-26 01:12:15 +02:00
unsigned NumUsr;
/***** Heading row *****/
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-12 00:07:52 +02:00
for (NumCol = (Gbl.Usrs.Listing.WithPhotos ? 0 :
1);
NumCol < NumColumns;
NumCol++)
HTM_TH_Span (FieldNames[NumCol],HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
2019-10-12 00:07:52 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2017-05-26 01:12:15 +02:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** List data of teachers *****/
for (NumUsr = 0, The_ResetRowColor ();
2017-05-26 01:12:15 +02:00
NumUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs; )
{
UsrDat.UsrCod = Gbl.Usrs.LstUsrs[Role].Lst[NumUsr].UsrCod;
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS))
2017-05-26 01:12:15 +02:00
{
UsrDat.Accepted = Gbl.Usrs.LstUsrs[Role].Lst[NumUsr].Accepted;
NumUsr++;
Usr_WriteRowTchAllData (&UsrDat);
The_ChangeRowColor ();
2017-05-26 01:12:15 +02:00
}
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/****************************** List users found *****************************/
/*****************************************************************************/
// Returns number of users found
2017-05-22 20:37:46 +02:00
unsigned Usr_ListUsrsFound (Rol_Role_t Role,
const char SearchQuery[Sch_MAX_BYTES_SEARCH_QUERY + 1])
2014-12-01 23:55:08 +01:00
{
2016-06-27 12:35:15 +02:00
extern const char *Txt_user[Usr_NUM_SEXS];
extern const char *Txt_users[Usr_NUM_SEXS];
2014-12-01 23:55:08 +01:00
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2015-03-12 14:45:40 +01:00
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2014-12-01 23:55:08 +01:00
extern const char *Txt_ROLES_PLURAL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2016-06-29 18:27:49 +02:00
unsigned NumUsrs;
2014-12-01 23:55:08 +01:00
unsigned NumUsr;
char *Title;
struct Usr_Data UsrDat;
2016-06-29 18:27:49 +02:00
Usr_Sex_t Sex;
struct Usr_InList *UsrInList;
2014-12-01 23:55:08 +01:00
/***** Initialize field names *****/
Usr_SetUsrDatMainFieldNames ();
2016-06-24 15:31:09 +02:00
/***** Create temporary table with candidate users *****/
// Search is faster (aproximately x2) using temporary tables
Usr_DB_CreateTmpTableAndSearchCandidateUsrs (SearchQuery);
2016-06-24 15:31:09 +02:00
2016-06-21 10:32:06 +02:00
/***** Search for users *****/
2016-06-24 15:31:09 +02:00
Usr_SearchListUsrs (Role);
2016-06-23 13:10:43 +02:00
if ((NumUsrs = Gbl.Usrs.LstUsrs[Role].NumUsrs))
2014-12-01 23:55:08 +01:00
{
2019-10-26 02:19:42 +02:00
/***** Begin box and table *****/
2014-12-01 23:55:08 +01:00
/* Number of users found */
2016-06-23 13:10:43 +02:00
Sex = Usr_GetSexOfUsrsLst (Role);
if (asprintf (&Title,"%u %s",NumUsrs,
(Role == Rol_UNK) ? (NumUsrs == 1 ? Txt_user[Sex] :
Txt_users[Sex]) :
(NumUsrs == 1 ? Txt_ROLES_SINGUL_abc[Role][Sex] :
Txt_ROLES_PLURAL_abc[Role][Sex])) < 0)
Err_NotEnoughMemoryExit ();
Box_BoxTableBegin (NULL,Title,NULL,NULL,NULL,Box_NOT_CLOSABLE,2);
free (Title);
2014-12-01 23:55:08 +01:00
/***** Heading row with column names *****/
Gbl.Usrs.Listing.WithPhotos = true;
Usr_WriteHeaderFieldsUsrDat (false); // Columns for the data
2014-12-01 23:55:08 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2014-12-01 23:55:08 +01:00
/***** List data of users *****/
for (NumUsr = 0, The_ResetRowColor ();
NumUsr < NumUsrs;
NumUsr++, The_ChangeRowColor ())
{
UsrInList = &Gbl.Usrs.LstUsrs[Role].Lst[NumUsr];
2016-07-25 20:24:07 +02:00
/* Copy user's basic data from list */
Usr_CopyBasicUsrDataFromList (&UsrDat,UsrInList);
2016-07-25 20:24:07 +02:00
/* Get list of user's IDs */
ID_GetListIDsFromUsrCod (&UsrDat);
2016-07-25 20:24:07 +02:00
/* Write data of this user */
Usr_WriteRowUsrMainData (NumUsr + 1,&UsrDat,false,Role,
&Gbl.Usrs.Selected);
2016-07-25 20:24:07 +02:00
/* Write all courses this user belongs to */
if (Role != Rol_GST && // Guests do not belong to any course
Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM) // Only admins can view the courses
{
HTM_TR_Begin (NULL);
2019-10-07 21:15:14 +02:00
HTM_TD_Begin ("colspan=\"2\" class=\"%s\"",
The_GetColorRows ());
HTM_TD_End ();
HTM_TD_Begin ("colspan=\"%u\" class=\"%s\"",
Usr_NUM_MAIN_FIELDS_DATA_USR-2,
The_GetColorRows ());
if (Role == Rol_UNK)
{
Crs_GetAndWriteCrssOfAUsr (&UsrDat,Rol_TCH);
Crs_GetAndWriteCrssOfAUsr (&UsrDat,Rol_NET);
Crs_GetAndWriteCrssOfAUsr (&UsrDat,Rol_STD);
}
else
Crs_GetAndWriteCrssOfAUsr (&UsrDat,Role);
HTM_TD_End ();
2019-10-07 21:15:14 +02:00
HTM_TR_End ();
2016-09-08 22:53:04 +02:00
}
2016-07-25 20:24:07 +02:00
}
2016-06-16 11:28:20 +02:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
2019-11-25 23:18:08 +01:00
Box_BoxTableEnd ();
2014-12-01 23:55:08 +01:00
}
/***** Free memory for teachers list *****/
2016-06-23 13:10:43 +02:00
Usr_FreeUsrsList (Role);
2014-12-01 23:55:08 +01:00
2016-06-29 18:27:49 +02:00
/***** Drop temporary table with candidate users *****/
Usr_DB_DropTmpTableWithCandidateUsrs ();
2016-06-24 15:31:09 +02:00
2014-12-01 23:55:08 +01:00
return NumUsrs;
}
/*****************************************************************************/
/**************************** List administrators ****************************/
/*****************************************************************************/
void Usr_ListDataAdms (void)
{
2016-11-20 20:03:47 +01:00
extern const char *Hlp_USERS_Administrators;
2015-04-12 18:01:06 +02:00
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2016-03-28 00:31:49 +02:00
extern const char *Txt_Scope;
2014-12-01 23:55:08 +01:00
extern const char *Txt_No_INDEX;
extern const char *Txt_Photo;
extern const char *Txt_ID;
extern const char *Txt_Surname_1;
extern const char *Txt_Surname_2;
extern const char *Txt_First_name;
extern const char *Txt_Email;
extern const char *Txt_Institution;
unsigned NumCol;
unsigned NumUsr;
struct Usr_Data UsrDat;
2014-12-01 23:55:08 +01:00
const char *FieldNames[Usr_NUM_MAIN_FIELDS_DATA_ADM];
2015-09-12 14:12:40 +02:00
/***** Put contextual links *****/
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2015-09-12 14:12:40 +02:00
{
2017-05-29 12:09:51 +02:00
case Rol_TCH:
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
2019-10-24 09:46:20 +02:00
/***** Contextual menu *****/
Mnu_ContextMenuBegin ();
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
{
Usr_PutLinkToSeeGuests (); // List guests
Dup_PutLinkToListDupUsrs (); // List possible duplicate users
}
Enr_PutLinkToAdminOneUsr (ActReqMdfOneOth); // Admin one user
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
Enr_PutLinkToRemOldUsrs (); // Remove old users
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuEnd ();
2017-05-29 12:09:51 +02:00
break;
default:
break;
2015-09-12 14:12:40 +02:00
}
2014-12-01 23:55:08 +01:00
/***** Initialize field names *****/
FieldNames[0] = Txt_No_INDEX;
FieldNames[1] = Txt_Photo;
FieldNames[2] = Txt_ID;
FieldNames[3] = Txt_Surname_1;
FieldNames[4] = Txt_Surname_2;
FieldNames[5] = Txt_First_name;
2016-07-25 16:08:25 +02:00
FieldNames[6] = Txt_Institution;
2014-12-01 23:55:08 +01:00
/***** Get and update type of list,
number of columns in class photo
2019-03-26 11:53:21 +01:00
and preference about viewing photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2014-12-01 23:55:08 +01:00
/***** Get scope *****/
Gbl.Scope.Allowed = 1 << HieLvl_SYS |
1 << HieLvl_CTY |
1 << HieLvl_INS |
1 << HieLvl_CTR |
1 << HieLvl_DEG;
Gbl.Scope.Default = HieLvl_DEG;
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeUsr");
2014-12-01 23:55:08 +01:00
2017-01-28 17:17:35 +01:00
/***** Get list of administrators *****/
Adm_GetAdmsLst (Gbl.Scope.Current);
2016-03-28 00:31:49 +02:00
2019-10-26 02:19:42 +02:00
/***** Begin box with list of administrators *****/
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_ROLES_PLURAL_Abc[Rol_DEG_ADM][Usr_SEX_UNKNOWN],
NULL,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Administrators,Box_NOT_CLOSABLE);
2016-03-28 00:31:49 +02:00
/***** Form to select scope *****/
HTM_DIV_Begin ("class=\"CM\"");
Frm_BeginForm (ActLstOth);
Set_PutParListWithPhotos ();
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ());
HTM_TxtColonNBSP (Txt_Scope);
Sco_PutSelectorScope ("ScopeUsr",HTM_SUBMIT_ON_CHANGE);
HTM_LABEL_End ();
Frm_EndForm ();
2019-10-23 20:07:56 +02:00
HTM_DIV_End ();
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.LstUsrs[Rol_DEG_ADM].NumUsrs)
{
/****** Show photos? *****/
HTM_DIV_Begin ("class=\"PREF_CONT\"");
HTM_DIV_Begin ("class=\"PREF_OFF\"");
Frm_BeginForm (ActLstOth);
Sco_PutParCurrentScope (&Gbl.Scope.Current);
Usr_PutCheckboxListWithPhotos ();
Frm_EndForm ();
HTM_DIV_End ();
HTM_DIV_End ();
2019-10-12 00:07:52 +02:00
/***** Heading row with column names *****/
HTM_TABLE_Begin (NULL);
HTM_TR_Begin (NULL);
2019-10-12 00:07:52 +02:00
for (NumCol = 0;
NumCol < Usr_NUM_MAIN_FIELDS_DATA_ADM;
NumCol++)
if (NumCol != 1 || Gbl.Usrs.Listing.WithPhotos) // Skip photo column if I don't want this column
HTM_TH_Span (FieldNames[NumCol],HTM_HEAD_LEFT,1,1,"BG_HIGHLIGHT");
2014-12-01 23:55:08 +01:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2016-06-16 11:28:20 +02:00
/***** List data of administrators *****/
for (NumUsr = 0, The_ResetRowColor ();
NumUsr < Gbl.Usrs.LstUsrs[Rol_DEG_ADM].NumUsrs; )
{
UsrDat.UsrCod = Gbl.Usrs.LstUsrs[Rol_DEG_ADM].Lst[NumUsr].UsrCod;
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS))
{
UsrDat.Accepted = Gbl.Usrs.LstUsrs[Rol_DEG_ADM].Lst[NumUsr].Accepted;
Usr_WriteRowAdmData (++NumUsr,&UsrDat);
2014-12-01 23:55:08 +01:00
The_ChangeRowColor ();
}
}
2014-12-01 23:55:08 +01:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
/***** End table *****/
HTM_TABLE_End ();
}
else // Gbl.Usrs.LstUsrs[Rol_DEG_ADM].NumUsrs == 0
/***** Show warning indicating no admins found *****/
Usr_ShowWarningNoUsersFound (Rol_DEG_ADM);
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2016-03-28 00:31:49 +02:00
2016-06-23 13:10:43 +02:00
/***** Free memory for administrators list *****/
Usr_FreeUsrsList (Rol_DEG_ADM);
2014-12-01 23:55:08 +01:00
}
2015-09-17 16:54:02 +02:00
/*****************************************************************************/
/********** Put a link (form) to show list or class photo of guests **********/
/*****************************************************************************/
static void Usr_PutLinkToSeeAdmins (void)
{
2019-03-06 22:07:24 +01:00
extern const char *Rol_Icons[Rol_NUM_ROLES];
2016-06-15 13:40:16 +02:00
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2015-09-17 16:54:02 +02:00
/***** Put form to list admins *****/
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkIconText (ActLstOth,NULL,
NULL,NULL,
Rol_Icons[Rol_DEG_ADM],Ico_BLACK,
Txt_ROLES_PLURAL_Abc[Rol_DEG_ADM][Usr_SEX_UNKNOWN],NULL);
2015-09-17 16:54:02 +02:00
}
/*****************************************************************************/
/********** Put a link (form) to show list or class photo of guests **********/
/*****************************************************************************/
static void Usr_PutLinkToSeeGuests (void)
{
2016-06-15 13:40:16 +02:00
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2015-09-17 16:54:02 +02:00
/***** Put form to list guests *****/
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkIconText (ActLstGst,NULL,
NULL,NULL,
"users.svg",Ico_BLACK,
Txt_ROLES_PLURAL_Abc[Rol_GST][Usr_SEX_UNKNOWN],NULL);
2015-09-17 16:54:02 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********************* Show list or class photo of guests ********************/
/*****************************************************************************/
void Usr_SeeGuests (void)
{
2016-11-20 20:03:47 +01:00
extern const char *Hlp_USERS_Guests;
2015-04-11 23:46:21 +02:00
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2016-03-28 00:18:41 +02:00
extern const char *Txt_Scope;
2019-03-12 13:23:46 +01:00
bool ICanChooseOption[Usr_LIST_USRS_NUM_OPTIONS];
bool PutForm;
2014-12-01 23:55:08 +01:00
2019-10-24 09:46:20 +02:00
/***** Contextual menu *****/
Mnu_ContextMenuBegin ();
Usr_PutLinkToSeeAdmins (); // List admins
Enr_PutLinkToAdminOneUsr (ActReqMdfOneOth); // Admin one user
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
Enr_PutLinkToRemOldUsrs (); // Remove old users
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuEnd ();
2015-09-12 14:12:40 +02:00
2014-12-01 23:55:08 +01:00
/***** Get and update type of list,
number of columns in class photo
and preference about view photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2014-12-01 23:55:08 +01:00
/***** Get scope *****/
Sco_SetScopesForListingGuests ();
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeUsr");
2014-12-01 23:55:08 +01:00
2017-01-28 17:17:35 +01:00
/***** Get list of guests in current scope *****/
2014-12-01 23:55:08 +01:00
Usr_GetGstsLst (Gbl.Scope.Current);
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_ROLES_PLURAL_Abc[Rol_GST][Usr_SEX_UNKNOWN],
2020-04-09 21:36:21 +02:00
Usr_PutIconsListGsts,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Guests,Box_NOT_CLOSABLE);
2017-05-24 03:12:57 +02:00
/***** Form to select scope *****/
if (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
{
HTM_DIV_Begin ("class=\"CM\"");
Frm_BeginForm (ActLstGst);
Set_PutParsPrefsAboutUsrList ();
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",
The_GetSuffix ());
HTM_TxtColonNBSP (Txt_Scope);
Sco_PutSelectorScope ("ScopeUsr",HTM_SUBMIT_ON_CHANGE);
HTM_LABEL_End ();
Frm_EndForm ();
HTM_DIV_End ();
}
2014-12-01 23:55:08 +01:00
/***** Begin section with user list *****/
HTM_SECTION_Begin (Usr_USER_LIST_SECTION_ID);
2016-03-18 22:17:35 +01:00
if (Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs)
{
if (Usr_GetIfShowBigList (Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs,
Sco_PutParCurrentScope,&Gbl.Scope.Current,
NULL))
{
/***** Form to select type of list of users *****/
Usr_ShowFormsToSelectUsrListType (Sco_PutParCurrentScope,&Gbl.Scope.Current);
/***** Draw a class photo with guests *****/
if (Gbl.Usrs.Me.ListType == Set_USR_LIST_AS_CLASS_PHOTO)
Lay_WriteHeaderClassPhoto (false,true,
(Gbl.Scope.Current == HieLvl_CTR ||
Gbl.Scope.Current == HieLvl_INS) ? Gbl.Hierarchy.Ins.InsCod :
-1L,
-1L,
-1L);
/* Set options allowed */
PutForm = Usr_SetOptionsListUsrsAllowed (Rol_GST,ICanChooseOption);
/* Begin form */
if (PutForm)
Frm_BeginForm (ActDoActOnSevGst);
/* Begin table */
HTM_TABLE_BeginWide ();
/* Draw the classphoto/list */
switch (Gbl.Usrs.Me.ListType)
{
case Set_USR_LIST_AS_CLASS_PHOTO:
Usr_DrawClassPhoto (Usr_CLASS_PHOTO_SEL_SEE,
Rol_GST,&Gbl.Usrs.Selected,
PutForm); // Put checkbox to select users?
break;
case Set_USR_LIST_AS_LISTING:
Usr_ListMainDataGsts (PutForm); // Put checkbox to select users?
break;
default:
break;
}
2014-12-01 23:55:08 +01:00
/* End table */
HTM_TABLE_End ();
2015-10-02 01:04:28 +02:00
/***** Which action, show records, follow...? *****/
if (PutForm)
{
Usr_PutOptionsListUsrs (ICanChooseOption);
Frm_EndForm ();
}
}
}
else // Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs == 0
/***** Show warning indicating no guests found *****/
Usr_ShowWarningNoUsersFound (Rol_GST);
2017-05-25 19:57:34 +02:00
/***** End section with user list *****/
HTM_SECTION_End ();
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2017-05-24 03:12:57 +02:00
2016-06-23 13:10:43 +02:00
/***** Free memory for guests list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_GST);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************** Show list or class photo of students *******************/
/*****************************************************************************/
void Usr_SeeStudents (void)
{
2016-11-18 00:17:53 +01:00
extern const char *Hlp_USERS_Students;
2015-04-11 23:46:21 +02:00
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2016-03-28 01:02:34 +02:00
extern const char *Txt_Scope;
2019-03-12 13:23:46 +01:00
bool ICanChooseOption[Usr_LIST_USRS_NUM_OPTIONS];
bool PutForm;
2014-12-01 23:55:08 +01:00
2015-09-12 14:12:40 +02:00
/***** Put contextual links *****/
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2014-12-01 23:55:08 +01:00
{
2017-05-29 12:09:51 +02:00
case Rol_STD:
case Rol_TCH:
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
2019-10-24 09:46:20 +02:00
/***** Contextual menu *****/
Mnu_ContextMenuBegin ();
Enr_PutLinkToAdminOneUsr (ActReqMdfOneStd); // Admin one student
if (Gbl.Hierarchy.Level == HieLvl_CRS && // Course selected
Gbl.Usrs.Me.Role.Logged != Rol_STD) // Teacher or admin
{
Enr_PutLinkToAdminSeveralUsrs (Rol_STD); // Admin several students
Rec_PutLinkToEditRecordFields (); // Edit record fields
}
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuEnd ();
2017-05-29 12:09:51 +02:00
break;
default:
break;
2014-12-01 23:55:08 +01:00
}
/***** Get and update type of list,
number of columns in class photo
and preference about view photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2014-12-01 23:55:08 +01:00
/***** Get scope *****/
Sco_SetScopesForListingStudents ();
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeUsr");
2014-12-01 23:55:08 +01:00
2016-11-25 03:21:02 +01:00
/***** Get groups to show ******/
if (Gbl.Scope.Current == HieLvl_CRS)
2016-11-25 03:21:02 +01:00
Grp_GetParCodsSeveralGrpsToShowUsrs ();
2017-01-28 17:17:35 +01:00
/***** Get list of students *****/
2017-05-25 19:57:34 +02:00
Usr_GetListUsrs (Gbl.Scope.Current,Rol_STD);
2016-11-25 03:21:02 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_ROLES_PLURAL_Abc[Rol_STD][Usr_SEX_UNKNOWN],
2020-04-09 21:36:21 +02:00
Usr_PutIconsListStds,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Students,Box_NOT_CLOSABLE);
2016-11-24 22:28:11 +01:00
/***** Form to select scope *****/
switch (Gbl.Usrs.Me.Role.Logged)
{
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
case Rol_SYS_ADM:
HTM_DIV_Begin ("class=\"CM\"");
Frm_BeginForm (ActLstStd);
Set_PutParsPrefsAboutUsrList ();
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",
The_GetSuffix ());
HTM_TxtColonNBSP (Txt_Scope);
Sco_PutSelectorScope ("ScopeUsr",HTM_SUBMIT_ON_CHANGE);
HTM_LABEL_End ();
Frm_EndForm ();
HTM_DIV_End ();
break;
default:
break;
}
2017-05-24 03:12:57 +02:00
/***** Form to select groups *****/
if (Gbl.Scope.Current == HieLvl_CRS)
Grp_ShowFormToSelectSeveralGroups (Sco_PutParCurrentScope,&Gbl.Scope.Current,
Grp_MY_GROUPS);
2017-05-25 11:04:38 +02:00
/***** Begin section with user list *****/
HTM_SECTION_Begin (Usr_USER_LIST_SECTION_ID);
2014-12-01 23:55:08 +01:00
if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs)
{
if (Usr_GetIfShowBigList (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs,
Sco_PutParCurrentScope,&Gbl.Scope.Current,
NULL))
{
/***** Form to select type of list of users *****/
Usr_ShowFormsToSelectUsrListType (Sco_PutParCurrentScope,&Gbl.Scope.Current);
/***** Draw a class photo with students of the course *****/
if (Gbl.Usrs.Me.ListType == Set_USR_LIST_AS_CLASS_PHOTO)
Lay_WriteHeaderClassPhoto (false,true,
(Gbl.Scope.Current == HieLvl_CRS ||
Gbl.Scope.Current == HieLvl_DEG ||
Gbl.Scope.Current == HieLvl_CTR ||
Gbl.Scope.Current == HieLvl_INS) ? Gbl.Hierarchy.Ins.InsCod :
-1L,
(Gbl.Scope.Current == HieLvl_CRS ||
Gbl.Scope.Current == HieLvl_DEG) ? Gbl.Hierarchy.Deg.DegCod :
-1L,
Gbl.Scope.Current == HieLvl_CRS ? Gbl.Hierarchy.Crs.CrsCod :
-1L);
2014-12-01 23:55:08 +01:00
/* Set options allowed */
PutForm = Usr_SetOptionsListUsrsAllowed (Rol_STD,ICanChooseOption);
2016-03-18 22:17:35 +01:00
/* Begin form */
if (PutForm)
{
Frm_BeginForm (ActDoActOnSevStd);
Grp_PutParsCodGrps ();
}
2014-12-01 23:55:08 +01:00
/* Begin table */
HTM_TABLE_BeginWide ();
2015-10-02 01:04:28 +02:00
/* Draw the classphoto/list */
switch (Gbl.Usrs.Me.ListType)
{
case Set_USR_LIST_AS_CLASS_PHOTO:
Usr_DrawClassPhoto (Usr_CLASS_PHOTO_SEL_SEE,
Rol_STD,&Gbl.Usrs.Selected,
PutForm); // Put checkbox to select users?
break;
case Set_USR_LIST_AS_LISTING:
Usr_ListMainDataStds (PutForm); // Put checkbox to select users?
break;
default:
break;
}
/* End table */
HTM_TABLE_End ();
/***** Which action, show records, follow...? *****/
if (PutForm)
{
Usr_PutOptionsListUsrs (ICanChooseOption);
Frm_EndForm ();
}
}
}
else // Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs == 0
/***** Show warning indicating no students found *****/
Usr_ShowWarningNoUsersFound (Rol_STD);
2015-10-02 01:04:28 +02:00
/***** End section with user list *****/
HTM_SECTION_End ();
2017-05-25 11:04:38 +02:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2016-11-24 22:28:11 +01:00
2014-12-01 23:55:08 +01:00
/***** Free memory for students list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_STD);
2014-12-01 23:55:08 +01:00
/***** Free memory for list of selected groups *****/
Grp_FreeListCodSelectedGrps ();
}
/*****************************************************************************/
/******************** Show list or class photo of teachers *******************/
/*****************************************************************************/
void Usr_SeeTeachers (void)
{
2016-11-18 00:17:53 +01:00
extern const char *Hlp_USERS_Teachers;
2015-04-11 23:46:21 +02:00
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
2016-03-28 00:44:24 +02:00
extern const char *Txt_Scope;
2017-05-24 03:12:57 +02:00
unsigned NumUsrs;
2019-03-12 13:23:46 +01:00
bool ICanChooseOption[Usr_LIST_USRS_NUM_OPTIONS];
bool PutForm;
2014-12-01 23:55:08 +01:00
2015-09-12 14:12:40 +02:00
/***** Put contextual links *****/
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2015-09-12 14:12:40 +02:00
{
2017-05-29 12:09:51 +02:00
case Rol_NET:
case Rol_TCH:
case Rol_DEG_ADM:
case Rol_CTR_ADM:
case Rol_INS_ADM:
2017-05-29 22:07:43 +02:00
case Rol_SYS_ADM:
2019-10-24 09:46:20 +02:00
/***** Contextual menu *****/
Mnu_ContextMenuBegin ();
Enr_PutLinkToAdminOneUsr (ActReqMdfOneTch); // Admin one teacher
if (Gbl.Hierarchy.Level == HieLvl_CRS && // Course selected
Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM) // I am logged as admin
{
Enr_PutLinkToAdminSeveralUsrs (Rol_NET); // Admin several non-editing teachers
Enr_PutLinkToAdminSeveralUsrs (Rol_TCH); // Admin several teachers
}
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuEnd ();
2017-05-29 12:09:51 +02:00
break;
default:
break;
2015-09-12 14:12:40 +02:00
}
2014-12-01 23:55:08 +01:00
/***** Get and update type of list,
number of columns in class photo
and preference about view photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2014-12-01 23:55:08 +01:00
/***** Get scope *****/
Gbl.Scope.Allowed = 1 << HieLvl_SYS |
1 << HieLvl_CTY |
1 << HieLvl_INS |
1 << HieLvl_CTR |
1 << HieLvl_DEG |
1 << HieLvl_CRS;
Gbl.Scope.Default = HieLvl_CRS;
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeUsr");
2014-12-01 23:55:08 +01:00
2017-05-30 18:24:26 +02:00
/***** Get groups to show ******/
if (Gbl.Scope.Current == HieLvl_CRS)
2017-05-30 18:24:26 +02:00
Grp_GetParCodsSeveralGrpsToShowUsrs ();
2017-05-24 03:12:57 +02:00
/***** Get lists of teachers *****/
2017-05-25 19:57:34 +02:00
Usr_GetListUsrs (Gbl.Scope.Current,Rol_NET); // Non-editing teachers
Usr_GetListUsrs (Gbl.Scope.Current,Rol_TCH); // Teachers
if (Gbl.Scope.Current == HieLvl_CRS)
2017-05-30 18:24:26 +02:00
NumUsrs = Gbl.Usrs.LstUsrs[Rol_NET].NumUsrs +
Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs;
else
NumUsrs = Enr_GetNumUsrsInCrss (Gbl.Scope.Current,
(Gbl.Scope.Current == HieLvl_CTY ? Gbl.Hierarchy.Cty.CtyCod :
(Gbl.Scope.Current == HieLvl_INS ? Gbl.Hierarchy.Ins.InsCod :
(Gbl.Scope.Current == HieLvl_CTR ? Gbl.Hierarchy.Ctr.CtrCod :
(Gbl.Scope.Current == HieLvl_DEG ? Gbl.Hierarchy.Deg.DegCod :
(Gbl.Scope.Current == HieLvl_CRS ? Gbl.Hierarchy.Crs.CrsCod :
-1L))))),
2020-01-08 23:49:04 +01:00
1 << Rol_NET |
1 << Rol_TCH);
2014-12-01 23:55:08 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_ROLES_PLURAL_Abc[Rol_TCH][Usr_SEX_UNKNOWN],
2020-04-09 21:36:21 +02:00
Usr_PutIconsListTchs,NULL,
2017-06-12 15:03:29 +02:00
Hlp_USERS_Teachers,Box_NOT_CLOSABLE);
2016-03-28 00:44:24 +02:00
/***** Form to select scope *****/
HTM_DIV_Begin ("class=\"CM\"");
Frm_BeginForm (ActLstTch);
Set_PutParsPrefsAboutUsrList ();
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",
The_GetSuffix ());
HTM_TxtColonNBSP (Txt_Scope);
Sco_PutSelectorScope ("ScopeUsr",HTM_SUBMIT_ON_CHANGE);
HTM_LABEL_End ();
Frm_EndForm ();
HTM_DIV_End ();
2016-03-28 00:44:24 +02:00
/***** Form to select groups *****/
if (Gbl.Scope.Current == HieLvl_CRS)
Grp_ShowFormToSelectSeveralGroups (Sco_PutParCurrentScope,&Gbl.Scope.Current,
Grp_MY_GROUPS);
2017-05-30 18:24:26 +02:00
/***** Begin section with user list *****/
HTM_SECTION_Begin (Usr_USER_LIST_SECTION_ID);
2017-05-25 19:57:34 +02:00
if (NumUsrs)
{
if (Usr_GetIfShowBigList (NumUsrs,
Sco_PutParCurrentScope,&Gbl.Scope.Current,
NULL))
{
/***** Form to select type of list of users *****/
Usr_ShowFormsToSelectUsrListType (Sco_PutParCurrentScope,&Gbl.Scope.Current);
/***** Draw a class photo with teachers of the course *****/
if (Gbl.Usrs.Me.ListType == Set_USR_LIST_AS_CLASS_PHOTO)
Lay_WriteHeaderClassPhoto (false,true,
(Gbl.Scope.Current == HieLvl_CRS ||
Gbl.Scope.Current == HieLvl_DEG ||
Gbl.Scope.Current == HieLvl_CTR ||
Gbl.Scope.Current == HieLvl_INS) ? Gbl.Hierarchy.Ins.InsCod :
-1L,
(Gbl.Scope.Current == HieLvl_CRS ||
Gbl.Scope.Current == HieLvl_DEG) ? Gbl.Hierarchy.Deg.DegCod :
-1L,
Gbl.Scope.Current == HieLvl_CRS ? Gbl.Hierarchy.Crs.CrsCod :
-1L);
/* Set options allowed */
PutForm = Usr_SetOptionsListUsrsAllowed (Rol_TCH,ICanChooseOption);
/* Begin form */
if (PutForm)
{
Frm_BeginForm (ActDoActOnSevTch);
Grp_PutParsCodGrps ();
}
2014-12-01 23:55:08 +01:00
/* Begin table */
HTM_TABLE_BeginWide ();
2016-03-18 22:17:35 +01:00
/***** Draw the classphoto/list *****/
switch (Gbl.Usrs.Me.ListType)
{
case Set_USR_LIST_AS_CLASS_PHOTO:
/* List teachers and non-editing teachers */
Usr_DrawClassPhoto (Usr_CLASS_PHOTO_SEL_SEE,
Rol_TCH,&Gbl.Usrs.Selected,
PutForm); // Put checkbox to select users?
Usr_DrawClassPhoto (Usr_CLASS_PHOTO_SEL_SEE,
Rol_NET,&Gbl.Usrs.Selected,
PutForm); // Put checkbox to select users?
break;
case Set_USR_LIST_AS_LISTING:
/* Initialize field names */
Usr_SetUsrDatMainFieldNames ();
/* List teachers and non-editing teachers */
Usr_ListMainDataTchs (Rol_TCH,
PutForm); // Put checkbox to select users?
Usr_ListMainDataTchs (Rol_NET,
PutForm); // Put checkbox to select users?
break;
default:
break;
}
2014-12-01 23:55:08 +01:00
/* End table */
HTM_TABLE_End ();
2015-10-02 01:04:28 +02:00
/***** Which action, show records, follow...? *****/
if (PutForm)
{
Usr_PutOptionsListUsrs (ICanChooseOption);
Frm_EndForm ();
}
}
}
else // NumUsrs == 0
/***** Show warning indicating no teachers found *****/
Usr_ShowWarningNoUsersFound (Rol_TCH);
2017-02-09 19:27:18 +01:00
/***** End section with user list *****/
HTM_SECTION_End ();
2017-05-25 19:57:34 +02:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2017-05-24 03:12:57 +02:00
/***** Free memory for teachers lists *****/
Usr_FreeUsrsList (Rol_TCH); // Teachers
Usr_FreeUsrsList (Rol_NET); // Non-editing teachers
2017-05-30 18:24:26 +02:00
/***** Free memory for list of selected groups *****/
Grp_FreeListCodSelectedGrps ();
2014-12-01 23:55:08 +01:00
}
2019-03-11 00:51:54 +01:00
/*****************************************************************************/
2019-03-12 13:23:46 +01:00
/**************** Set allowed options to do with several users ***************/
2019-03-11 00:51:54 +01:00
/*****************************************************************************/
2019-03-12 13:23:46 +01:00
// Returns true if any option is allowed
2019-03-11 00:51:54 +01:00
2019-03-12 13:23:46 +01:00
static bool Usr_SetOptionsListUsrsAllowed (Rol_Role_t UsrsRole,
bool ICanChooseOption[Usr_LIST_USRS_NUM_OPTIONS])
2019-03-11 00:51:54 +01:00
{
2019-03-12 09:27:04 +01:00
Usr_ListUsrsOption_t Opt;
2019-03-12 13:23:46 +01:00
bool OptionsAllowed;
2019-03-11 13:33:34 +01:00
2019-03-12 09:27:04 +01:00
/***** Check which options I can choose *****/
/* Set default (I can not choose options) */
for (Opt = (Usr_ListUsrsOption_t) 1; // Skip unknown option
Opt <= (Usr_ListUsrsOption_t) (Usr_LIST_USRS_NUM_OPTIONS - 1);
Opt++)
ICanChooseOption[Opt] = false;
2019-03-11 00:51:54 +01:00
2019-03-12 09:27:04 +01:00
/* Activate some options depending on users' role, on my role, etc. */
2019-03-11 14:16:55 +01:00
switch (UsrsRole)
2019-03-11 00:51:54 +01:00
{
case Rol_GST:
2019-03-12 09:27:04 +01:00
ICanChooseOption[Usr_OPTION_RECORDS] = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM);
2019-03-11 00:51:54 +01:00
break;
case Rol_STD:
2019-03-12 09:27:04 +01:00
ICanChooseOption[Usr_OPTION_RECORDS] =
ICanChooseOption[Usr_OPTION_MESSAGE] =
2019-03-12 12:51:54 +01:00
ICanChooseOption[Usr_OPTION_FOLLOW] =
ICanChooseOption[Usr_OPTION_UNFOLLOW] = (Gbl.Scope.Current == HieLvl_CRS &&
2019-03-12 12:51:54 +01:00
(Gbl.Usrs.Me.Role.Logged == Rol_STD ||
Gbl.Usrs.Me.Role.Logged == Rol_NET ||
Gbl.Usrs.Me.Role.Logged == Rol_TCH ||
2019-03-12 09:27:04 +01:00
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM));
ICanChooseOption[Usr_OPTION_HOMEWORK] =
2019-04-11 21:37:11 +02:00
ICanChooseOption[Usr_OPTION_ATTENDANCE] =
ICanChooseOption[Usr_OPTION_EMAIL] = (Gbl.Scope.Current == HieLvl_CRS &&
2019-03-12 12:51:54 +01:00
(Gbl.Usrs.Me.Role.Logged == Rol_NET ||
Gbl.Usrs.Me.Role.Logged == Rol_TCH ||
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM));
2019-03-11 00:51:54 +01:00
break;
case Rol_TCH:
2019-03-12 09:27:04 +01:00
ICanChooseOption[Usr_OPTION_RECORDS] =
ICanChooseOption[Usr_OPTION_MESSAGE] =
2019-04-11 21:37:11 +02:00
ICanChooseOption[Usr_OPTION_EMAIL] =
2019-03-12 12:51:54 +01:00
ICanChooseOption[Usr_OPTION_FOLLOW] =
ICanChooseOption[Usr_OPTION_UNFOLLOW] = (Gbl.Scope.Current == HieLvl_CRS &&
2019-03-12 12:51:54 +01:00
(Gbl.Usrs.Me.Role.Logged == Rol_STD ||
Gbl.Usrs.Me.Role.Logged == Rol_NET ||
Gbl.Usrs.Me.Role.Logged == Rol_TCH ||
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM));
ICanChooseOption[Usr_OPTION_HOMEWORK] = (Gbl.Scope.Current == HieLvl_CRS &&
2019-03-12 12:51:54 +01:00
(Gbl.Usrs.Me.Role.Logged == Rol_NET ||
Gbl.Usrs.Me.Role.Logged == Rol_TCH ||
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM));
2019-03-11 00:51:54 +01:00
break;
default:
2019-03-12 09:27:04 +01:00
return false;
2019-03-11 00:51:54 +01:00
}
2019-03-12 13:23:46 +01:00
/***** Count allowed options *****/
OptionsAllowed = false;
for (Opt = (Usr_ListUsrsOption_t) 1; // Skip unknown option
!OptionsAllowed &&
Opt <= (Usr_ListUsrsOption_t) (Usr_LIST_USRS_NUM_OPTIONS - 1);
Opt++)
if (ICanChooseOption[Opt])
OptionsAllowed = true;
return OptionsAllowed;
}
/*****************************************************************************/
/*************** Put different options to do with several users **************/
/*****************************************************************************/
// Returns true if at least one action can be shown
static void Usr_PutOptionsListUsrs (const bool ICanChooseOption[Usr_LIST_USRS_NUM_OPTIONS])
{
extern const char *Txt_View_records;
extern const char *Txt_View_homework;
extern const char *Txt_View_attendance;
extern const char *Txt_Send_message;
extern const char *Txt_Create_email_message;
extern const char *Txt_Follow;
extern const char *Txt_Unfollow;
extern const char *Txt_Continue;
static const char **Label[Usr_LIST_USRS_NUM_OPTIONS] =
2019-03-12 13:23:46 +01:00
{
2019-11-22 01:04:03 +01:00
[Usr_OPTION_UNKNOWN ] = NULL,
[Usr_OPTION_RECORDS ] = &Txt_View_records,
[Usr_OPTION_HOMEWORK ] = &Txt_View_homework,
[Usr_OPTION_ATTENDANCE] = &Txt_View_attendance,
[Usr_OPTION_MESSAGE ] = &Txt_Send_message,
[Usr_OPTION_EMAIL ] = &Txt_Create_email_message,
[Usr_OPTION_FOLLOW ] = &Txt_Follow,
[Usr_OPTION_UNFOLLOW ] = &Txt_Unfollow,
2019-03-12 13:23:46 +01:00
};
Usr_ListUsrsOption_t Opt;
/***** Get the selected option from form *****/
Gbl.Usrs.Selected.Option = Usr_GetListUsrsOption (Usr_LIST_USRS_DEFAULT_OPTION);
2019-03-12 09:27:04 +01:00
/***** Write list of options *****/
/* Begin list of options */
HTM_UL_Begin ("class=\"LIST_LEFT FORM_IN_%s\"",The_GetSuffix ());
2019-03-11 00:51:54 +01:00
/* Show option items */
for (Opt = (Usr_ListUsrsOption_t) 1; // Skip unknown option
Opt <= (Usr_ListUsrsOption_t) (Usr_LIST_USRS_NUM_OPTIONS - 1);
Opt++)
if (ICanChooseOption[Opt])
Usr_ShowOneListUsrsOption (Opt,*Label[Opt]);
2019-03-12 01:46:40 +01:00
2019-03-12 09:27:04 +01:00
/* End list of options */
2019-10-26 02:19:42 +02:00
HTM_UL_End ();
2019-03-11 00:51:54 +01:00
2019-03-12 13:23:46 +01:00
/***** Put button to confirm *****/
Btn_PutConfirmButton (Txt_Continue);
2019-03-11 00:51:54 +01:00
}
/*****************************************************************************/
/************ Put start/end of action to register/remove one user ************/
/*****************************************************************************/
2019-03-12 09:27:04 +01:00
static void Usr_ShowOneListUsrsOption (Usr_ListUsrsOption_t ListUsrsAction,
const char *Label)
2019-03-11 00:51:54 +01:00
{
2019-10-26 22:49:13 +02:00
HTM_LI_Begin (NULL);
HTM_LABEL_Begin (NULL);
HTM_INPUT_RADIO ("ListUsrsAction",HTM_DONT_SUBMIT_ON_CLICK,
"value=\"%u\"%s",
(unsigned) ListUsrsAction,
ListUsrsAction == Gbl.Usrs.Selected.Option ? " checked=\"checked\"" :
"");
HTM_Txt (Label);
HTM_LABEL_End ();
2019-10-26 22:49:13 +02:00
HTM_LI_End ();
2019-03-11 00:51:54 +01:00
}
/*****************************************************************************/
/********************** Do action on several students ************************/
/*****************************************************************************/
2019-03-11 13:33:34 +01:00
void Usr_DoActionOnSeveralUsrs1 (void)
2019-03-11 00:51:54 +01:00
{
extern const char *Txt_You_must_select_one_ore_more_users;
/***** Get parameters from form *****/
/* Get list of selected users */
2019-11-15 03:34:48 +01:00
Usr_GetListsSelectedEncryptedUsrsCods (&Gbl.Usrs.Selected);
2019-03-11 00:51:54 +01:00
2019-11-14 02:29:18 +01:00
/* Check if there are selected users */
2019-11-15 03:34:48 +01:00
if (Usr_CheckIfThereAreUsrsInListOfSelectedEncryptedUsrCods (&Gbl.Usrs.Selected))
2019-11-14 17:53:50 +01:00
{
/* Get the action to do */
Gbl.Usrs.Selected.Option = Usr_GetListUsrsOption (Usr_OPTION_UNKNOWN);
2019-03-11 00:51:54 +01:00
2019-11-14 17:53:50 +01:00
/***** Change action depending on my selection *****/
Gbl.Action.Original = Gbl.Action.Act; // To check if action changes
2019-03-11 00:51:54 +01:00
2019-11-14 17:53:50 +01:00
switch (Gbl.Usrs.Selected.Option)
{
case Usr_OPTION_RECORDS:
switch (Gbl.Action.Act)
{
case ActDoActOnSevGst:
Gbl.Action.Act = ActSeeRecSevGst;
break;
case ActDoActOnSevStd:
Gbl.Action.Act = ActSeeRecSevStd;
break;
case ActDoActOnSevTch:
Gbl.Action.Act = ActSeeRecSevTch;
break;
default:
break;
}
break;
case Usr_OPTION_HOMEWORK:
switch (Gbl.Action.Act)
{
case ActDoActOnSevStd:
case ActDoActOnSevTch:
Gbl.Action.Act = ActAdmAsgWrkCrs;
break;
default:
break;
}
break;
case Usr_OPTION_ATTENDANCE:
switch (Gbl.Action.Act)
{
case ActDoActOnSevStd:
Gbl.Action.Act = ActSeeLstUsrAtt;
break;
default:
break;
}
break;
case Usr_OPTION_MESSAGE:
switch (Gbl.Action.Act)
{
case ActDoActOnSevStd:
case ActDoActOnSevTch:
Gbl.Action.Act = ActReqMsgUsr;
break;
default:
break;
}
break;
case Usr_OPTION_EMAIL:
switch (Gbl.Action.Act)
{
case ActDoActOnSevStd:
Gbl.Action.Act = ActMaiUsr;
break;
default:
break;
}
break;
case Usr_OPTION_FOLLOW:
switch (Gbl.Action.Act)
{
case ActDoActOnSevStd:
Gbl.Action.Act = ActReqFolSevStd;
break;
case ActDoActOnSevTch:
Gbl.Action.Act = ActReqFolSevTch;
break;
default:
break;
}
break;
case Usr_OPTION_UNFOLLOW:
switch (Gbl.Action.Act)
{
case ActDoActOnSevStd:
Gbl.Action.Act = ActReqUnfSevStd;
break;
case ActDoActOnSevTch:
Gbl.Action.Act = ActReqUnfSevTch;
break;
default:
break;
}
break;
default:
break;
}
2019-03-12 01:46:40 +01:00
2019-11-14 17:53:50 +01:00
if (Gbl.Action.Act == Gbl.Action.Original) // Fail, no change in action
Ale_CreateAlert (Ale_ERROR,NULL,"Wrong action.");
else // Success, action has changed
Tab_SetCurrentTab ();
2019-03-11 13:33:34 +01:00
}
2019-11-14 17:53:50 +01:00
else // If no users selected...
Ale_CreateAlert (Ale_WARNING,NULL, // ...write warning notice
Txt_You_must_select_one_ore_more_users);
2019-03-11 13:33:34 +01:00
}
void Usr_DoActionOnSeveralUsrs2 (void)
{
/***** Show possible alerts *****/
Ale_ShowAlerts (NULL);
2019-03-12 09:27:04 +01:00
/***** If success, action has changed.
No change in action means an error in form has happened,
so show again the form to selected users *****/
2019-03-11 13:33:34 +01:00
switch (Gbl.Action.Act)
{
case ActDoActOnSevGst:
Usr_SeeGuests ();
break;
case ActDoActOnSevStd:
Usr_SeeStudents ();
break;
case ActDoActOnSevTch:
Usr_SeeTeachers ();
break;
2019-03-12 09:27:04 +01:00
default:
break;
2019-03-11 00:51:54 +01:00
}
2019-11-14 17:53:50 +01:00
/***** Free memory used by list of selected users' codes *****/
2019-11-15 03:34:48 +01:00
Usr_FreeListsSelectedEncryptedUsrsCods (&Gbl.Usrs.Selected);
2019-03-11 13:33:34 +01:00
}
2019-03-11 00:51:54 +01:00
2019-03-11 13:33:34 +01:00
/*****************************************************************************/
/*************** Get action to do with list of selected users ****************/
/*****************************************************************************/
2019-03-12 09:27:04 +01:00
static Usr_ListUsrsOption_t Usr_GetListUsrsOption (Usr_ListUsrsOption_t DefaultAction)
2019-03-11 13:33:34 +01:00
{
return (Usr_ListUsrsOption_t) Par_GetParUnsignedLong ("ListUsrsAction",
0,
Usr_LIST_USRS_NUM_OPTIONS - 1,
(unsigned long) DefaultAction);
2019-03-11 00:51:54 +01:00
}
2016-11-07 01:23:17 +01:00
/*****************************************************************************/
/***************** Put contextual icons in list of guests ********************/
/*****************************************************************************/
2020-04-09 21:36:21 +02:00
static void Usr_PutIconsListGsts (__attribute__((unused)) void *Args)
2016-11-07 01:23:17 +01:00
{
2020-04-09 21:36:21 +02:00
switch (Gbl.Usrs.Me.ListType)
2016-11-07 01:23:17 +01:00
{
case Set_USR_LIST_AS_CLASS_PHOTO:
2020-04-09 21:36:21 +02:00
if (Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs)
/***** Put icon to print guests *****/
Usr_PutIconToPrintGsts ();
break;
case Set_USR_LIST_AS_LISTING:
2020-04-09 21:36:21 +02:00
/***** Put icon to show all data of guests *****/
Usr_PutIconToShowGstsAllData ();
break;
default:
break;
2020-03-26 02:54:30 +01:00
}
2020-04-09 21:36:21 +02:00
/***** Put icon to show a figure *****/
Fig_PutIconToShowFigure (Fig_USERS);
2016-11-07 01:23:17 +01:00
}
2016-11-07 00:46:13 +01:00
/*****************************************************************************/
/**************** Put contextual icons in list of students *******************/
/*****************************************************************************/
2020-04-09 21:36:21 +02:00
static void Usr_PutIconsListStds (__attribute__((unused)) void *Args)
2016-11-07 00:46:13 +01:00
{
2020-04-13 16:39:15 +02:00
switch (Gbl.Usrs.Me.ListType)
2016-11-07 00:46:13 +01:00
{
case Set_USR_LIST_AS_CLASS_PHOTO:
2020-04-13 16:39:15 +02:00
if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs)
/***** Put icon to print students *****/
Usr_PutIconToPrintStds ();
break;
case Set_USR_LIST_AS_LISTING:
2020-04-13 16:39:15 +02:00
/***** Put icon to show all data of students *****/
Usr_PutIconToShowStdsAllData ();
break;
default:
break;
2020-03-26 02:54:30 +01:00
}
2020-04-13 16:39:15 +02:00
/***** Put icon to show a figure *****/
Fig_PutIconToShowFigure (Fig_USERS);
2016-11-07 01:01:21 +01:00
}
/*****************************************************************************/
/**************** Put contextual icons in list of teachers *******************/
/*****************************************************************************/
2020-04-09 21:36:21 +02:00
static void Usr_PutIconsListTchs (__attribute__((unused)) void *Args)
2016-11-07 01:01:21 +01:00
{
2020-04-13 16:39:15 +02:00
switch (Gbl.Usrs.Me.ListType)
2016-11-07 01:01:21 +01:00
{
case Set_USR_LIST_AS_CLASS_PHOTO:
2020-04-13 16:39:15 +02:00
if (Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs)
/***** Put icon to print teachers *****/
Usr_PutIconToPrintTchs ();
break;
case Set_USR_LIST_AS_LISTING:
2020-04-13 16:39:15 +02:00
/***** Put icon to show all data of teachers *****/
Usr_PutIconToShowTchsAllData ();
break;
default:
break;
2020-03-26 02:54:30 +01:00
}
2020-04-13 16:39:15 +02:00
/***** Put icon to show a figure *****/
Fig_PutIconToShowFigure (Fig_USERS);
2016-11-07 00:46:13 +01:00
}
2016-03-18 21:28:45 +01:00
/*****************************************************************************/
/***************** Functions used to print lists of users ********************/
/*****************************************************************************/
static void Usr_PutIconToPrintGsts (void)
{
2020-03-26 02:54:30 +01:00
Ico_PutContextualIconToPrint (ActPrnGstPho,
Usr_ShowGstsAllDataPars,NULL);
2016-03-18 21:28:45 +01:00
}
static void Usr_PutIconToPrintStds (void)
{
2020-03-26 02:54:30 +01:00
Ico_PutContextualIconToPrint (ActPrnStdPho,
Usr_ShowStdsAllDataPars,NULL);
2016-03-18 21:28:45 +01:00
}
static void Usr_PutIconToPrintTchs (void)
{
2020-03-26 02:54:30 +01:00
Ico_PutContextualIconToPrint (ActPrnTchPho,
Usr_ShowTchsAllDataPars,NULL);
2016-03-18 21:28:45 +01:00
}
2016-11-27 14:10:31 +01:00
/*****************************************************************************/
/**************** Functions used to list all data of users *******************/
/*****************************************************************************/
2016-03-18 21:28:45 +01:00
static void Usr_PutIconToShowGstsAllData (void)
{
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkOnlyIcon (ActLstGstAll,NULL,
Usr_ShowGstsAllDataPars,NULL,
"table.svg",Ico_BLACK);
2016-03-18 21:28:45 +01:00
}
static void Usr_PutIconToShowStdsAllData (void)
{
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkOnlyIcon (ActLstStdAll,NULL,
Usr_ShowStdsAllDataPars,NULL,
"table.svg",Ico_BLACK);
2016-03-18 21:28:45 +01:00
}
static void Usr_PutIconToShowTchsAllData (void)
{
2020-03-26 02:54:30 +01:00
Lay_PutContextualLinkOnlyIcon (ActLstTchAll,NULL,
Usr_ShowTchsAllDataPars,NULL,
"table.svg",Ico_BLACK);
2016-03-18 21:28:45 +01:00
}
static void Usr_ShowGstsAllDataPars (__attribute__((unused)) void *Args)
2016-03-18 21:28:45 +01:00
{
Set_PutParListWithPhotos ();
2016-03-18 21:28:45 +01:00
}
static void Usr_ShowStdsAllDataPars (__attribute__((unused)) void *Args)
2016-03-18 21:28:45 +01:00
{
Grp_PutParsCodGrps ();
Set_PutParListWithPhotos ();
2016-03-18 21:28:45 +01:00
}
static void Usr_ShowTchsAllDataPars (__attribute__((unused)) void *Args)
2016-03-18 21:28:45 +01:00
{
Sco_PutParCurrentScope (&Gbl.Scope.Current);
Set_PutParListWithPhotos ();
2016-03-18 21:28:45 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************* Draw class photo with guests ready to be printed **************/
/*****************************************************************************/
void Usr_SeeGstClassPhotoPrn (void)
{
/***** Get and update type of list,
number of columns in class photo
and preference about view photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2014-12-01 23:55:08 +01:00
/***** Get scope *****/
Sco_SetScopesForListingGuests ();
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeUsr");
2014-12-01 23:55:08 +01:00
2017-01-28 17:17:35 +01:00
/***** Get list of guests *****/
2014-12-01 23:55:08 +01:00
Usr_GetGstsLst (Gbl.Scope.Current);
2017-05-18 19:13:41 +02:00
if (Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs)
2014-12-01 23:55:08 +01:00
{
/***** Draw the guests' class photo *****/
2016-03-18 22:17:35 +01:00
Lay_WriteHeaderClassPhoto (true,true,
(Gbl.Scope.Current == HieLvl_CTR ||
Gbl.Scope.Current == HieLvl_INS) ? Gbl.Hierarchy.Ins.InsCod :
-1L,
2014-12-01 23:55:08 +01:00
-1L,-1L);
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginWide ();
Usr_DrawClassPhoto (Usr_CLASS_PHOTO_PRN,
Rol_GST,&Gbl.Usrs.Selected,false);
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2014-12-01 23:55:08 +01:00
}
2017-05-29 21:34:43 +02:00
else // Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs
/***** Show warning indicating no guests found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_GST);
2014-12-01 23:55:08 +01:00
2016-06-23 13:10:43 +02:00
/***** Free memory for guests list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_GST);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************** Draw class photo with students ready to print **************/
/*****************************************************************************/
void Usr_SeeStdClassPhotoPrn (void)
{
/***** Get and update type of list,
number of columns in class photo
and preference about view photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2014-12-01 23:55:08 +01:00
/***** Get scope *****/
Sco_SetScopesForListingStudents ();
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeUsr");
2014-12-01 23:55:08 +01:00
/****** Get groups to show ******/
Grp_GetParCodsSeveralGrpsToShowUsrs ();
2017-01-28 17:17:35 +01:00
/***** Get list of students *****/
2017-05-25 19:57:34 +02:00
Usr_GetListUsrs (Gbl.Scope.Current,Rol_STD);
2014-12-01 23:55:08 +01:00
2017-05-18 19:13:41 +02:00
if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs)
2014-12-01 23:55:08 +01:00
{
/***** Draw the students' class photo *****/
2016-03-18 22:17:35 +01:00
Lay_WriteHeaderClassPhoto (true,true,
(Gbl.Scope.Current == HieLvl_CRS ||
Gbl.Scope.Current == HieLvl_DEG ||
Gbl.Scope.Current == HieLvl_CTR ||
Gbl.Scope.Current == HieLvl_INS) ? Gbl.Hierarchy.Ins.InsCod :
-1L,
(Gbl.Scope.Current == HieLvl_CRS ||
Gbl.Scope.Current == HieLvl_DEG) ? Gbl.Hierarchy.Deg.DegCod :
-1L,
Gbl.Scope.Current == HieLvl_CRS ? Gbl.Hierarchy.Crs.CrsCod :
-1L);
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginWide ();
Usr_DrawClassPhoto (Usr_CLASS_PHOTO_PRN,
Rol_STD,&Gbl.Usrs.Selected,false);
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2014-12-01 23:55:08 +01:00
}
2017-05-29 21:34:43 +02:00
else // Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs == 0
/***** Show warning indicating no students found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_STD);
2014-12-01 23:55:08 +01:00
/***** Free memory for students list *****/
2017-05-18 19:13:41 +02:00
Usr_FreeUsrsList (Rol_STD);
2014-12-01 23:55:08 +01:00
/***** Free memory for list of selected groups *****/
Grp_FreeListCodSelectedGrps ();
}
/*****************************************************************************/
/**************** Draw class photo with teachers ready to print **************/
/*****************************************************************************/
void Usr_SeeTchClassPhotoPrn (void)
{
2017-05-26 19:25:41 +02:00
unsigned NumUsrs;
2014-12-01 23:55:08 +01:00
/***** Get and update type of list,
number of columns in class photo
and preference about view photos *****/
Set_GetAndUpdatePrefsAboutUsrList ();
2014-12-01 23:55:08 +01:00
/***** Get scope *****/
Gbl.Scope.Allowed = 1 << HieLvl_SYS |
1 << HieLvl_CTY |
1 << HieLvl_INS |
1 << HieLvl_CTR |
1 << HieLvl_DEG |
1 << HieLvl_CRS;
Gbl.Scope.Default = HieLvl_CRS;
2016-06-24 20:34:58 +02:00
Sco_GetScope ("ScopeUsr");
2014-12-01 23:55:08 +01:00
2017-05-30 19:42:10 +02:00
/****** Get groups to show ******/
Grp_GetParCodsSeveralGrpsToShowUsrs ();
2017-01-28 17:17:35 +01:00
/***** Get list of teachers *****/
2017-05-26 19:25:41 +02:00
Usr_GetListUsrs (Gbl.Scope.Current,Rol_NET); // Non-editing teachers
Usr_GetListUsrs (Gbl.Scope.Current,Rol_TCH); // Teachers
if (Gbl.Scope.Current == HieLvl_CRS)
2017-05-30 18:24:26 +02:00
NumUsrs = Gbl.Usrs.LstUsrs[Rol_NET].NumUsrs +
Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs;
else
NumUsrs = Enr_GetNumUsrsInCrss (Gbl.Scope.Current,
(Gbl.Scope.Current == HieLvl_CTY ? Gbl.Hierarchy.Cty.CtyCod :
(Gbl.Scope.Current == HieLvl_INS ? Gbl.Hierarchy.Ins.InsCod :
(Gbl.Scope.Current == HieLvl_CTR ? Gbl.Hierarchy.Ctr.CtrCod :
(Gbl.Scope.Current == HieLvl_DEG ? Gbl.Hierarchy.Deg.DegCod :
(Gbl.Scope.Current == HieLvl_CRS ? Gbl.Hierarchy.Crs.CrsCod :
-1L))))),
2020-01-08 23:49:04 +01:00
1 << Rol_NET |
1 << Rol_TCH);
2014-12-01 23:55:08 +01:00
2017-05-26 19:25:41 +02:00
if (NumUsrs)
2014-12-01 23:55:08 +01:00
{
/***** Draw the teachers' class photo *****/
2016-03-18 22:17:35 +01:00
Lay_WriteHeaderClassPhoto (true,true,
(Gbl.Scope.Current == HieLvl_CRS ||
Gbl.Scope.Current == HieLvl_DEG ||
Gbl.Scope.Current == HieLvl_CTR ||
Gbl.Scope.Current == HieLvl_INS) ? Gbl.Hierarchy.Ins.InsCod :
-1L,
(Gbl.Scope.Current == HieLvl_CRS ||
Gbl.Scope.Current == HieLvl_DEG) ? Gbl.Hierarchy.Deg.DegCod :
-1L,
Gbl.Scope.Current == HieLvl_CRS ? Gbl.Hierarchy.Crs.CrsCod :
-1L);
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginWide ();
2017-05-26 19:25:41 +02:00
/* List teachers and non-editing teachers */
Usr_DrawClassPhoto (Usr_CLASS_PHOTO_PRN,
Rol_TCH,&Gbl.Usrs.Selected,false);
Usr_DrawClassPhoto (Usr_CLASS_PHOTO_PRN,
Rol_NET,&Gbl.Usrs.Selected,false);
2017-05-26 19:25:41 +02:00
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2014-12-01 23:55:08 +01:00
}
2017-05-29 21:34:43 +02:00
else // NumUsrs == 0
2017-02-09 19:27:18 +01:00
/***** Show warning indicating no teachers found *****/
2017-05-18 19:13:41 +02:00
Usr_ShowWarningNoUsersFound (Rol_TCH);
2014-12-01 23:55:08 +01:00
2017-05-26 19:25:41 +02:00
/***** Free memory for teachers lists *****/
Usr_FreeUsrsList (Rol_TCH); // Teachers
Usr_FreeUsrsList (Rol_NET); // Non-editing teachers
2017-05-30 19:42:10 +02:00
/***** Free memory for list of selected groups *****/
Grp_FreeListCodSelectedGrps ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****************** Draw class photo with students or teachers ***************/
/*****************************************************************************/
static void Usr_DrawClassPhoto (Usr_ClassPhotoType_t ClassPhotoType,
2019-11-15 03:34:48 +01:00
Rol_Role_t Role,
struct Usr_SelectedUsrs *SelectedUsrs,
2019-11-15 03:34:48 +01:00
bool PutCheckBoxToSelectUsr)
2014-12-01 23:55:08 +01:00
{
static const char *ClassPhoto[Usr_NUM_CLASS_PHOTO_TYPE][PhoSha_NUM_SHAPES] =
{
[Usr_CLASS_PHOTO_SEL ][PhoSha_SHAPE_CIRCLE ] = "PHOTOC21x28",
[Usr_CLASS_PHOTO_SEL ][PhoSha_SHAPE_ELLIPSE ] = "PHOTOE21x28",
[Usr_CLASS_PHOTO_SEL ][PhoSha_SHAPE_OVAL ] = "PHOTOO21x28",
[Usr_CLASS_PHOTO_SEL ][PhoSha_SHAPE_RECTANGLE] = "PHOTOR21x28",
[Usr_CLASS_PHOTO_SEL_SEE][PhoSha_SHAPE_CIRCLE ] = "PHOTOC45x60",
[Usr_CLASS_PHOTO_SEL_SEE][PhoSha_SHAPE_ELLIPSE ] = "PHOTOE45x60",
[Usr_CLASS_PHOTO_SEL_SEE][PhoSha_SHAPE_OVAL ] = "PHOTOO45x60",
[Usr_CLASS_PHOTO_SEL_SEE][PhoSha_SHAPE_RECTANGLE] = "PHOTOR45x60",
[Usr_CLASS_PHOTO_PRN ][PhoSha_SHAPE_CIRCLE ] = "PHOTOC45x60",
[Usr_CLASS_PHOTO_PRN ][PhoSha_SHAPE_ELLIPSE ] = "PHOTOE45x60",
[Usr_CLASS_PHOTO_PRN ][PhoSha_SHAPE_OVAL ] = "PHOTOO45x60",
[Usr_CLASS_PHOTO_PRN ][PhoSha_SHAPE_RECTANGLE] = "PHOTOR45x60",
};
2014-12-01 23:55:08 +01:00
unsigned NumUsr;
bool TRIsOpen = false;
bool UsrIsTheMsgSender;
struct Usr_Data UsrDat;
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
if (Gbl.Usrs.LstUsrs[Role].NumUsrs)
2014-12-01 23:55:08 +01:00
{
2017-05-24 03:12:57 +02:00
/***** Put a row to select all users *****/
if (PutCheckBoxToSelectUsr)
2019-11-15 03:34:48 +01:00
Usr_PutCheckboxToSelectAllUsers (Role,SelectedUsrs);
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Loop for showing users photos, names and place of birth *****/
for (NumUsr = 0;
NumUsr < Gbl.Usrs.LstUsrs[Role].NumUsrs; )
{
if ((NumUsr % Gbl.Usrs.ClassPhoto.Cols) == 0)
{
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2017-05-24 03:12:57 +02:00
TRIsOpen = true;
}
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/* Copy user's basic data from list */
Usr_CopyBasicUsrDataFromList (&UsrDat,&Gbl.Usrs.LstUsrs[Role].Lst[NumUsr]);
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/* Get list of user's IDs */
ID_GetListIDsFromUsrCod (&UsrDat);
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Begin user's cell *****/
if (ClassPhotoType == Usr_CLASS_PHOTO_SEL &&
UsrDat.UsrCod == Gbl.Usrs.Other.UsrDat.UsrCod)
{
UsrIsTheMsgSender = true;
HTM_TD_Begin ("class=\"CLASSPHOTO CLASSPHOTO_%s CB LIGHT_GREEN\"",
The_GetSuffix ());
2017-05-24 03:12:57 +02:00
}
else
2019-10-10 21:21:24 +02:00
{
2017-05-24 03:12:57 +02:00
UsrIsTheMsgSender = false;
HTM_TD_Begin ("class=\"CLASSPHOTO CLASSPHOTO_%s CB\"",
The_GetSuffix ());
2019-10-10 21:21:24 +02:00
}
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Checkbox to select this user *****/
if (PutCheckBoxToSelectUsr)
Usr_PutCheckboxToSelectUser (Role,UsrDat.EnUsrCod,UsrIsTheMsgSender,
2019-11-15 03:34:48 +01:00
SelectedUsrs);
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Show photo *****/
Pho_ShowUsrPhotoIfAllowed (&UsrDat,
ClassPhoto[ClassPhotoType][Gbl.Prefs.PhotoShape],Pho_ZOOM);
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Photo foot *****/
HTM_DIV_Begin ("class=\"CLASSPHOTO_CAPTION CLASSPHOTO_%s\"",
The_GetSuffix ());
2014-12-01 23:55:08 +01:00
/* Name */
if (UsrDat.FrstName[0])
HTM_Txt (UsrDat.FrstName);
else
HTM_NBSP ();
HTM_BR ();
if (UsrDat.Surname1[0])
HTM_Txt (UsrDat.Surname1);
else
HTM_NBSP ();
HTM_BR ();
if (UsrDat.Surname2[0])
HTM_Txt (UsrDat.Surname2);
else
HTM_NBSP ();
2017-03-03 21:06:34 +01:00
2019-10-23 20:07:56 +02:00
HTM_DIV_End ();
2014-12-01 23:55:08 +01:00
2017-06-12 14:16:33 +02:00
/***** End user's cell *****/
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2017-05-24 03:12:57 +02:00
if ((++NumUsr % Gbl.Usrs.ClassPhoto.Cols) == 0)
{
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2017-05-24 03:12:57 +02:00
TRIsOpen = false;
}
2016-07-26 01:51:48 +02:00
}
2017-05-24 03:12:57 +02:00
if (TRIsOpen)
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
2017-05-24 03:12:57 +02:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************** Write selector of columns in class photo ******************/
/*****************************************************************************/
void Usr_PutSelectorNumColsClassPhoto (void)
{
extern const char *Txt_columns;
unsigned Cols;
/***** Begin label *****/
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",The_GetSuffix ());
/***** Begin selector *****/
HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE,NULL,
"name=\"ColsClassPhoto\" class=\"INPUT_%s\"",
The_GetSuffix ());
/***** Put a row in selector for every number of columns *****/
for (Cols = 1;
Cols <= Usr_CLASS_PHOTO_COLS_MAX;
Cols++)
HTM_OPTION (HTM_Type_UNSIGNED,&Cols,
Cols == Gbl.Usrs.ClassPhoto.Cols ? HTM_OPTION_SELECTED :
HTM_OPTION_UNSELECTED,
HTM_OPTION_ENABLED,
"%u",Cols);
/***** End selector *****/
HTM_SELECT_End ();
HTM_Txt (Txt_columns);
/***** End label *****/
2019-11-02 12:59:31 +01:00
HTM_LABEL_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********** Build the relative path of a user from his user's code ***********/
/*****************************************************************************/
void Usr_ConstructPathUsr (long UsrCod,char PathUsr[PATH_MAX + 1])
2014-12-01 23:55:08 +01:00
{
2017-01-28 15:58:46 +01:00
char PathAboveUsr[PATH_MAX + 1];
char PathUsrTmp[PATH_MAX + 1 + Cns_MAX_DECIMAL_DIGITS_LONG + 1];
2014-12-01 23:55:08 +01:00
/***** Path for users *****/
2019-03-20 01:36:36 +01:00
Fil_CreateDirIfNotExists (Cfg_PATH_USR_PRIVATE);
2014-12-01 23:55:08 +01:00
/***** Path above user's ID *****/
snprintf (PathAboveUsr,sizeof (PathAboveUsr),"%s/%02u",
2019-03-20 01:36:36 +01:00
Cfg_PATH_USR_PRIVATE,(unsigned) (UsrCod % 100));
2014-12-01 23:55:08 +01:00
Fil_CreateDirIfNotExists (PathAboveUsr);
/***** Path for user *****/
snprintf (PathUsrTmp,sizeof (PathUsrTmp),"%s/%ld",PathAboveUsr,UsrCod);
if (strlen (PathUsrTmp) <= PATH_MAX)
Str_Copy (PathUsr,PathUsrTmp,PATH_MAX);
else
Err_PathTooLongExit ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************** Show warning "no users found" ************************/
/*****************************************************************************/
2017-05-18 19:13:41 +02:00
// Use Rol_UNK type to display "no users found"
2014-12-01 23:55:08 +01:00
void Usr_ShowWarningNoUsersFound (Rol_Role_t Role)
{
extern const char *Txt_No_users_found[Rol_NUM_ROLES];
2017-05-29 21:34:43 +02:00
extern const char *Txt_Register_students;
extern const char *Txt_Register_teacher;
2014-12-01 23:55:08 +01:00
2017-05-30 18:24:26 +02:00
if (Gbl.Usrs.ClassPhoto.AllGroups && // All groups selected
Role == Rol_STD && // No students found
2017-06-04 18:18:54 +02:00
Gbl.Usrs.Me.Role.Logged == Rol_TCH) // Course selected and I am logged as teacher
2017-05-29 21:34:43 +02:00
/***** Show alert and button to enrol students *****/
2020-03-26 02:54:30 +01:00
Ale_ShowAlertAndButton (ActReqEnrSevStd,NULL,NULL,
NULL,NULL,
2019-02-17 01:14:55 +01:00
Btn_CREATE_BUTTON,Txt_Register_students,
Ale_WARNING,Txt_No_users_found[Rol_STD]);
2017-05-29 21:34:43 +02:00
2017-05-30 18:24:26 +02:00
else if (Gbl.Usrs.ClassPhoto.AllGroups && // All groups selected
Role == Rol_TCH && // No teachers found
Gbl.Hierarchy.Level == HieLvl_CRS && // Course selected
2017-06-04 18:18:54 +02:00
Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM) // I am an administrator
2017-05-29 21:34:43 +02:00
/***** Show alert and button to enrol students *****/
2020-03-26 02:54:30 +01:00
Ale_ShowAlertAndButton (ActReqMdfOneTch,NULL,NULL,
NULL,NULL,
2019-02-17 01:14:55 +01:00
Btn_CREATE_BUTTON,Txt_Register_teacher,
Ale_WARNING,Txt_No_users_found[Rol_TCH]);
2017-05-29 14:14:31 +02:00
else
/***** Show alert *****/
2019-02-16 19:29:27 +01:00
Ale_ShowAlert (Ale_INFO,Txt_No_users_found[Role]);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2017-05-25 19:57:34 +02:00
/****************** Get total number of users in platform ********************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
unsigned Usr_GetTotalNumberOfUsers (void)
2014-12-01 23:55:08 +01:00
{
long Cod;
unsigned Roles;
/***** Get number of users with events from database *****/
switch (Gbl.Scope.Current)
{
case HieLvl_SYS:
return (unsigned) DB_GetNumRowsTable ("usr_data"); // All users in platform
case HieLvl_CTY:
case HieLvl_INS:
case HieLvl_CTR:
case HieLvl_DEG:
case HieLvl_CRS:
Cod = (Gbl.Scope.Current == HieLvl_CTY ? Gbl.Hierarchy.Cty.CtyCod :
(Gbl.Scope.Current == HieLvl_INS ? Gbl.Hierarchy.Ins.InsCod :
(Gbl.Scope.Current == HieLvl_CTR ? Gbl.Hierarchy.Ctr.CtrCod :
(Gbl.Scope.Current == HieLvl_DEG ? Gbl.Hierarchy.Deg.DegCod :
Gbl.Hierarchy.Crs.CrsCod))));
Roles = (1 << Rol_STD) |
(1 << Rol_NET) |
(1 << Rol_TCH);
return Enr_GetCachedNumUsrsInCrss (Gbl.Scope.Current,Cod,Roles); // All users in courses
default:
Err_WrongScopeExit ();
return 0; // Not reached
}
2017-05-25 19:57:34 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/******************** Write the author of a message/post/ ********************/
/*****************************************************************************/
// Input: UsrDat must hold user's data
void Usr_WriteAuthor (struct Usr_Data *UsrDat,
Cns_DisabledOrEnabled_t DisabledOrEnabled)
{
extern const char *Txt_Unknown_or_without_photo;
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC30x40",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE30x40",
[PhoSha_SHAPE_OVAL ] = "PHOTOO30x40",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR30x40",
};
bool WriteAuthor;
/***** Write author name or don't write it? *****/
WriteAuthor = false;
if (DisabledOrEnabled == Cns_ENABLED)
if (UsrDat->UsrCod > 0)
WriteAuthor = true;
/***** Begin table and row *****/
HTM_TABLE_BeginPadding (2);
HTM_TR_Begin (NULL);
/***** Begin first column with author's photo
(if author has a web page, put a link to it) *****/
HTM_TD_Begin ("class=\"CT\" style=\"width:30px;\"");
if (WriteAuthor)
Pho_ShowUsrPhotoIfAllowed (UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
else
Ico_PutIcon ("usr_bl.jpg",Ico_UNCHANGED,Txt_Unknown_or_without_photo,
ClassPhoto[Gbl.Prefs.PhotoShape]);
HTM_TD_End ();
/***** Second column with user name
(if author has a web page, put a link to it) *****/
if (WriteAuthor)
{
HTM_TD_Begin ("class=\"LT\"");
HTM_DIV_Begin ("class=\"AUTHOR_2_LINES\""); // Limited width
Usr_WriteFirstNameBRSurnames (UsrDat);
HTM_DIV_End ();
}
else
HTM_TD_Begin ("class=\"LM\"");
HTM_TD_End ();
/***** End row and table *****/
HTM_TR_End ();
HTM_TABLE_End ();
}
2017-03-04 01:59:27 +01:00
/*****************************************************************************/
/********************* Write the author of an assignment *********************/
/*****************************************************************************/
void Usr_WriteAuthor1Line (long UsrCod,Cns_HiddenOrVisible_t HiddenOrVisible)
2017-03-04 01:59:27 +01:00
{
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC15x20",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE15x20",
[PhoSha_SHAPE_OVAL ] = "PHOTOO15x20",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR15x20",
};
static const char *MsgClass[Cns_NUM_HIDDEN_VISIBLE] =
{
[Cns_HIDDEN ] = "MSG_AUT_LIGHT",
[Cns_VISIBLE] = "MSG_AUT",
};
2017-03-04 01:59:27 +01:00
bool ShowPhoto = false;
char PhotoURL[Cns_MAX_BYTES_WWW + 1];
struct Usr_Data UsrDat;
2017-03-04 01:59:27 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** Get data of author *****/
UsrDat.UsrCod = UsrCod;
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS))
2017-03-04 01:59:27 +01:00
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (&UsrDat,PhotoURL);
/***** Show photo *****/
Pho_ShowUsrPhoto (&UsrDat,ShowPhoto ? PhotoURL :
NULL,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
2017-03-04 01:59:27 +01:00
/***** Write name *****/
HTM_DIV_Begin ("class=\"AUTHOR_1_LINE %s_%s\"",
MsgClass[HiddenOrVisible],The_GetSuffix ());
HTM_Txt (UsrDat.FullName);
2019-10-23 20:07:56 +02:00
HTM_DIV_End ();
2017-03-04 01:59:27 +01:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
2019-09-22 19:50:24 +02:00
/*****************************************************************************/
/*************** Show a table cell with the data of a user *******************/
/*****************************************************************************/
void Usr_ShowTableCellWithUsrData (struct Usr_Data *UsrDat,unsigned NumRows)
2019-09-22 19:50:24 +02:00
{
static const Act_Action_t NextAction[Rol_NUM_ROLES] =
{
[Rol_STD] = ActSeeRecOneStd,
[Rol_NET] = ActSeeRecOneTch,
[Rol_TCH] = ActSeeRecOneTch,
};
static const char *ClassPhoto[PhoSha_NUM_SHAPES] =
{
[PhoSha_SHAPE_CIRCLE ] = "PHOTOC45x60",
[PhoSha_SHAPE_ELLIPSE ] = "PHOTOE45x60",
[PhoSha_SHAPE_OVAL ] = "PHOTOO45x60",
[PhoSha_SHAPE_RECTANGLE] = "PHOTOR45x60",
};
2019-09-22 19:50:24 +02:00
2020-05-20 03:12:21 +02:00
/***** Show user's photo *****/
2019-09-22 19:50:24 +02:00
if (NumRows)
HTM_TD_Begin ("rowspan=\"%u\" class=\"LT LINE_BOTTOM %s\"",
NumRows + 1,The_GetColorRows ());
2019-10-10 00:49:39 +02:00
else
HTM_TD_Begin ("class=\"LT LINE_BOTTOM %s\"",The_GetColorRows ());
Pho_ShowUsrPhotoIfAllowed (UsrDat,
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM);
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2019-09-22 19:50:24 +02:00
2020-05-20 03:12:21 +02:00
/***** User's IDs and name *****/
/* Begin cell */
2019-09-22 19:50:24 +02:00
if (NumRows)
HTM_TD_Begin ("rowspan=\"%u\" class=\"LT LINE_BOTTOM %s\"",
NumRows + 1,The_GetColorRows ());
2019-10-10 00:49:39 +02:00
else
HTM_TD_Begin ("class=\"LT LINE_BOTTOM %s\"",The_GetColorRows ());
2020-05-20 03:12:21 +02:00
/* Action to go to user's record depending on role in course */
if (!NextAction[UsrDat->Roles.InCurrentCrs])
2020-05-20 03:12:21 +02:00
/* Begin div */
HTM_DIV_Begin ("class=\"MSG_AUT_%s\"",The_GetSuffix ());
2020-05-20 03:12:21 +02:00
else
{
/* Begin form to go to user's record card */
Frm_BeginForm (NextAction[UsrDat->Roles.InCurrentCrs]);
Usr_PutParUsrCodEncrypted (UsrDat->EnUsrCod);
HTM_BUTTON_Submit_Begin (UsrDat->FullName,
"class=\"LT BT_LINK MSG_AUT_%s\"",
The_GetSuffix ());
2020-05-20 03:12:21 +02:00
}
/* User's ID */
2019-09-22 19:50:24 +02:00
ID_WriteUsrIDs (UsrDat,NULL);
2020-05-20 03:12:21 +02:00
/* User's name */
2019-11-09 21:08:20 +01:00
HTM_BR ();
2019-11-10 12:36:37 +01:00
HTM_Txt (UsrDat->Surname1);
2019-09-22 19:50:24 +02:00
if (UsrDat->Surname2[0])
2019-11-11 10:59:24 +01:00
HTM_TxtF ("&nbsp;%s",UsrDat->Surname2);
if (UsrDat->FrstName[0])
2019-11-09 21:03:02 +01:00
{
2019-11-11 00:15:44 +01:00
HTM_Comma ();
2019-11-09 21:08:20 +01:00
HTM_BR ();
HTM_Txt (UsrDat->FrstName);
2019-11-09 21:03:02 +01:00
}
2019-09-22 19:50:24 +02:00
if (!NextAction[UsrDat->Roles.InCurrentCrs])
2020-05-20 03:12:21 +02:00
/* End div */
HTM_DIV_End ();
else
{
/* End form */
HTM_BUTTON_End ();
2020-05-20 03:12:21 +02:00
Frm_EndForm ();
}
/* End cell */
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2019-09-22 19:50:24 +02:00
}
2019-11-11 15:46:54 +01:00
/*****************************************************************************/
/********** Show a setting selector for me / selected users / all ************/
/*****************************************************************************/
void Usr_PutWhoIcon (Usr_Who_t Who)
{
2019-11-12 00:31:41 +01:00
extern const char *Txt_WHO[Usr_NUM_WHO];
static const char *Icon[Usr_NUM_WHO] =
{
[Usr_WHO_UNKNOWN ] = NULL,
[Usr_WHO_ME ] = NULL,
[Usr_WHO_SELECTED] = "search.svg",
[Usr_WHO_FOLLOWED] = "user-check.svg",
[Usr_WHO_ALL ] = "users.svg",
};
2019-11-12 00:31:41 +01:00
2019-11-11 15:46:54 +01:00
switch (Who)
{
2019-11-12 00:31:41 +01:00
case Usr_WHO_UNKNOWN:
break;
2019-11-11 15:46:54 +01:00
case Usr_WHO_ME:
HTM_INPUT_IMAGE (Gbl.Usrs.Me.PhotoURL[0] ? Gbl.Usrs.Me.PhotoURL :
Cfg_URL_ICON_PUBLIC,
Gbl.Usrs.Me.PhotoURL[0] ? NULL :
"usr_bl.jpg",
2019-11-12 00:31:41 +01:00
Txt_WHO[Who],
"class=\"ICO_HIGHLIGHT PHOTOR15x20\"");
2019-11-11 15:46:54 +01:00
break;
2019-11-12 00:31:41 +01:00
case Usr_WHO_SELECTED:
case Usr_WHO_FOLLOWED:
2019-11-11 15:46:54 +01:00
case Usr_WHO_ALL:
HTM_INPUT_IMAGE (Cfg_URL_ICON_PUBLIC,Icon[Who],Txt_WHO[Who],
"class=\"ICO_HIGHLIGHT ICOx20 ICO_%s_%s\"",
Ico_GetPreffix (Ico_BLACK),The_GetSuffix ());
break;
2021-02-08 20:38:12 +01:00
default:
Err_WrongWhoExit ();
break;
2019-11-11 15:46:54 +01:00
}
}
2019-11-12 00:31:41 +01:00
/*****************************************************************************/
/*************** Put hidden param for which users are involved ***************/
/*****************************************************************************/
void Usr_PutParWho (Usr_Who_t Who)
2019-11-12 00:31:41 +01:00
{
Par_PutParUnsigned (NULL,"Who",(unsigned) Who);
2019-11-12 00:31:41 +01:00
}
/*****************************************************************************/
/*************** Get hidden param for which users are involved ***************/
/*****************************************************************************/
Usr_Who_t Usr_GetParWho (void)
2019-11-12 00:31:41 +01:00
{
return (Usr_Who_t) Par_GetParUnsignedLong ("Who",
1,
Usr_NUM_WHO - 1,
Usr_WHO_UNKNOWN);
2019-11-12 00:31:41 +01:00
}
/*****************************************************************************/
/********************** Show stats about number of users *********************/
/*****************************************************************************/
void Usr_GetAndShowUsersStats (void)
{
extern const char *Hlp_ANALYTICS_Figures_users;
extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES];
extern const char *Txt_Users;
extern const char *Txt_Number_of_users;
extern const char *Txt_Average_number_of_courses_to_which_a_user_belongs;
extern const char *Txt_Average_number_of_users_belonging_to_a_course;
/***** Begin box and table *****/
Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_USERS],
NULL,NULL,
Hlp_ANALYTICS_Figures_users,Box_NOT_CLOSABLE,2);
/***** Write heading *****/
HTM_TR_Begin (NULL);
HTM_TH (Txt_Users ,HTM_HEAD_RIGHT);
HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT);
HTM_TH (Txt_Average_number_of_courses_to_which_a_user_belongs,HTM_HEAD_RIGHT);
HTM_TH (Txt_Average_number_of_users_belonging_to_a_course ,HTM_HEAD_RIGHT);
HTM_TR_End ();
/***** Figures *****/
Usr_GetAndShowNumUsrsInCrss (Rol_STD); // Students
Usr_GetAndShowNumUsrsInCrss (Rol_NET); // Non-editing teachers
Usr_GetAndShowNumUsrsInCrss (Rol_TCH); // Teachers
Usr_GetAndShowNumUsrsInCrss (Rol_UNK); // Any user in courses
/***** Separator *****/
HTM_TR_Begin (NULL);
HTM_TH_Span (NULL,HTM_HEAD_CENTER,1,4,"SEPAR_ROW");
HTM_TR_End ();
Usr_GetAndShowNumUsrsNotBelongingToAnyCrs (); // Users not beloging to any course
/***** End table and box *****/
Box_BoxTableEnd ();
}
/*****************************************************************************/
/**************** Get and show number of users in courses ********************/
/*****************************************************************************/
// Rol_UNK means any role in courses
static void Usr_GetAndShowNumUsrsInCrss (Rol_Role_t Role)
{
extern const char *Txt_Total;
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
long Cod = Sco_GetCurrentCod ();
const char *Class;
unsigned Roles;
/***** Initializations depending on role *****/
if (Role == Rol_UNK)
{
Class = "RB LINE_TOP DAT_STRONG";
Roles = (1 << Rol_STD) |
(1 << Rol_NET) |
(1 << Rol_TCH);
}
else
{
Class = "RB DAT";
Roles = (1 << Role);
}
/***** Write the total number of users *****/
HTM_TR_Begin (NULL);
HTM_TD_Begin ("class=\"%s_%s\"",Class,The_GetSuffix ());
HTM_Txt ((Role == Rol_UNK) ? Txt_Total :
Txt_ROLES_PLURAL_Abc[Role][Usr_SEX_UNKNOWN]);
HTM_TD_End ();
/* Number of users in courses */
HTM_TD_Begin ("class=\"%s_%s\"",Class,The_GetSuffix ());
HTM_Unsigned (Enr_GetCachedNumUsrsInCrss (Gbl.Scope.Current,Cod,Roles));
HTM_TD_End ();
HTM_TD_Begin ("class=\"%s_%s\"",Class,The_GetSuffix ());
HTM_Double2Decimals (Enr_GetCachedAverageNumCrssPerUsr (Gbl.Scope.Current,Cod,Role));
HTM_TD_End ();
HTM_TD_Begin ("class=\"%s_%s\"",Class,The_GetSuffix ());
HTM_Double2Decimals (Enr_GetCachedAverageNumUsrsPerCrs (Gbl.Scope.Current,Cod,Role));
HTM_TD_End ();
HTM_TR_End ();
}
/*****************************************************************************/
/**************** Get and show number of users in courses ********************/
/*****************************************************************************/
static void Usr_GetAndShowNumUsrsNotBelongingToAnyCrs (void)
{
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
char *Class;
if (asprintf (&Class,"RB DAT_%s",The_GetSuffix ()) < 0)
Err_NotEnoughMemoryExit ();
/***** Write the total number of users not belonging to any course *****/
HTM_TR_Begin (NULL);
HTM_TD_Begin ("class=\"%s\"",Class);
HTM_Txt (Txt_ROLES_PLURAL_Abc[Rol_GST][Usr_SEX_UNKNOWN]);
HTM_TD_End ();
HTM_TD_Begin ("class=\"%s\"",Class);
HTM_Unsigned (Enr_GetCachedNumUsrsNotBelongingToAnyCrs ());
HTM_TD_End ();
HTM_TD_Begin ("class=\"%s\"",Class);
HTM_Double2Decimals (0.0);
HTM_TD_End ();
HTM_TD_Begin ("class=\"%s\"",Class);
HTM_Double2Decimals (0.0);
HTM_TD_End ();
HTM_TR_End ();
free (Class);
}
/*****************************************************************************/
/****************************** Show users' ranking **************************/
/*****************************************************************************/
void Usr_GetAndShowUsersRanking (void)
{
extern const char *Hlp_ANALYTICS_Figures_ranking;
extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES];
extern const char *Txt_Clicks;
extern const char *Txt_Clicks_per_day;
extern const char *Txt_Timeline;
extern const char *Txt_Downloads;
extern const char *Txt_Forums;
extern const char *Txt_Messages;
extern const char *Txt_Followers;
/***** Begin box and table *****/
Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_USERS_RANKING],
NULL,NULL,
Hlp_ANALYTICS_Figures_ranking,Box_NOT_CLOSABLE,2);
/***** Write heading *****/
HTM_TR_Begin (NULL);
HTM_TH (Txt_Clicks ,HTM_HEAD_CENTER);
HTM_TH (Txt_Clicks_per_day,HTM_HEAD_CENTER);
HTM_TH (Txt_Timeline ,HTM_HEAD_CENTER);
HTM_TH (Txt_Followers ,HTM_HEAD_CENTER);
HTM_TH (Txt_Downloads ,HTM_HEAD_CENTER);
HTM_TH (Txt_Forums ,HTM_HEAD_CENTER);
HTM_TH (Txt_Messages ,HTM_HEAD_CENTER);
HTM_TR_End ();
/***** Rankings *****/
HTM_TR_Begin (NULL);
HTM_TD_Begin ("class=\"LT\"");
Prf_GetAndShowRankingClicks ();
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
Prf_GetAndShowRankingClicksPerDay ();
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
Prf_GetAndShowRankingTimelinePubs ();
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
Fol_GetAndShowRankingFollowers ();
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
Prf_GetAndShowRankingFileViews ();
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
Prf_GetAndShowRankingForPsts ();
HTM_TD_End ();
HTM_TD_Begin ("class=\"LT\"");
Prf_GetAndShowRankingMsgsSnt ();
HTM_TD_End ();
HTM_TR_End ();
/***** End table and box *****/
Box_BoxTableEnd ();
}