From 58a8de40045062eefa43b9280cee5664357ca1de Mon Sep 17 00:00:00 2001 From: acanas Date: Wed, 3 Nov 2021 21:31:16 +0100 Subject: [PATCH] Version 21.50: Nov 03, 2021 Queries moved to module swad_user_database and other modules. --- swad_API.c | 2 +- swad_ID.c | 2 +- swad_account.c | 2 +- swad_admin.c | 8 +- swad_admin_database.c | 18 + swad_admin_database.h | 1 + swad_attendance.c | 12 +- swad_browser.c | 14 +- swad_center.c | 112 +++ swad_center.h | 6 + swad_center_database.c | 108 +- swad_center_database.h | 5 +- swad_changelog.h | 3 +- swad_chat.c | 2 +- swad_country.c | 81 ++ swad_country.h | 4 + swad_course.c | 10 +- swad_degree.c | 144 +++ swad_degree.h | 9 + swad_degree_database.c | 125 ++- swad_degree_database.h | 6 +- swad_duplicate.c | 9 +- swad_enrolment.c | 282 +++++- swad_enrolment.h | 13 + swad_enrolment_database.c | 650 +++++++++++- swad_enrolment_database.h | 24 +- swad_exam_result.c | 6 +- swad_figure.c | 7 +- swad_follow.c | 6 +- swad_global.c | 10 +- swad_global.h | 3 +- swad_group.c | 4 +- swad_institution.c | 112 +++ swad_institution.h | 6 + swad_institution_database.c | 22 + swad_institution_database.h | 1 + swad_mail.c | 4 +- swad_match_result.c | 6 +- swad_message.c | 3 +- swad_photo.c | 18 +- swad_privacy.c | 5 +- swad_profile.c | 11 +- swad_profile_database.c | 29 +- swad_profile_database.h | 2 + swad_record.c | 14 +- swad_report.c | 7 +- swad_role.c | 13 +- swad_setting.c | 301 ++++++ swad_setting.h | 20 + swad_setting_database.c | 71 +- swad_setting_database.h | 5 +- swad_statistic.c | 2 +- swad_survey.c | 2 +- swad_test_print.c | 2 +- swad_text.c | 9 +- swad_user.c | 1888 ++--------------------------------- swad_user.h | 72 +- swad_zip.c | 2 +- 58 files changed, 2207 insertions(+), 2108 deletions(-) diff --git a/swad_API.c b/swad_API.c index 19550aaa..854c9446 100644 --- a/swad_API.c +++ b/swad_API.c @@ -3149,7 +3149,7 @@ int swad__sendAttendanceUsers (struct soap *soap, if (Usr_DB_ChkIfUsrCodExists (UsrDat.UsrCod)) // The user must belong to course, // but it's not necessary he/she belongs to groups associated to the event - if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) { /* Mark user as present */ Att_RegUsrInAttEventNotChangingComments (Event.AttCod,UsrDat.UsrCod); diff --git a/swad_ID.c b/swad_ID.c index 1b054c63..08494865 100644 --- a/swad_ID.c +++ b/swad_ID.c @@ -918,7 +918,7 @@ void ID_ConfirmOtherUsrID (void) check if he/she has accepted */ if (Gbl.Hierarchy.Level == HieLvl_CRS) if (Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs == Rol_STD) - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); if (ID_ICanSeeOtherUsrIDs (&Gbl.Usrs.Other.UsrDat)) ICanConfirm = true; diff --git a/swad_account.c b/swad_account.c index 545c6bec..97641312 100644 --- a/swad_account.c +++ b/swad_account.c @@ -1041,7 +1041,7 @@ void Acc_CompletelyEliminateAccount (struct UsrData *UsrDat, UsrDat->FullName); /***** Remove user from tables of banned users *****/ - Usr_DB_RemoveUsrFromBanned (UsrDat->UsrCod); + Prf_DB_RemoveUsrFromBanned (UsrDat->UsrCod); Msg_DB_RemoveUsrFromBanned (UsrDat->UsrCod); /***** Delete thread read status for this user *****/ diff --git a/swad_admin.c b/swad_admin.c index b2260dd3..f77071f5 100644 --- a/swad_admin.c +++ b/swad_admin.c @@ -150,7 +150,7 @@ static void Adm_ReqAddAdm (HieLvl_Level_t Scope,long Cod, (Scope == HieLvl_INS && Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)); if (ICanRegister) { - if (Usr_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod,Scope,Cod)) // User is already an administrator of current institution/center/degree + if (Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod,Scope,Cod)) // User is already an administrator of current institution/center/degree { Ale_ShowAlert (Ale_INFO,Txt_THE_USER_X_is_already_an_administrator_of_Y, Gbl.Usrs.Other.UsrDat.FullName,InsCtrDegName); @@ -254,7 +254,7 @@ static void Adm_RegisterAdmin (struct UsrData *UsrDat, extern const char *Txt_THE_USER_X_has_been_enroled_as_administrator_of_Y; /***** Check if user was and administrator of current institution/center/degree *****/ - if (Usr_DB_CheckIfUsrIsAdm (UsrDat->UsrCod,Scope,Cod)) + if (Adm_DB_CheckIfUsrIsAdm (UsrDat->UsrCod,Scope,Cod)) Ale_ShowAlert (Ale_SUCCESS,Txt_THE_USER_X_is_already_an_administrator_of_Y, UsrDat->FullName,InsCtrDegName); else // User was not administrator of current institution/center/degree @@ -353,7 +353,7 @@ static void Adm_ReqRemOrRemAdm (Enr_ReqDelOrDelUsr_t ReqDelOrDelUsr, if (ICanRemove) { /* Check if the other user is an admin of the current institution/center/degree */ - if (Usr_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod,Scope,Cod)) + if (Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod,Scope,Cod)) { // The other user is an administrator of current institution/center/degree ==> ask for removing or remove her/him switch (ReqDelOrDelUsr) { @@ -433,7 +433,7 @@ static void Adm_EffectivelyRemAdm (struct UsrData *UsrDat, extern const char *Txt_THE_USER_X_has_been_removed_as_administrator_of_Y; extern const char *Txt_THE_USER_X_is_not_an_administrator_of_Y; - if (Usr_DB_CheckIfUsrIsAdm (UsrDat->UsrCod,Scope,Cod)) // User is administrator of current institution/center/degree + if (Adm_DB_CheckIfUsrIsAdm (UsrDat->UsrCod,Scope,Cod)) // User is administrator of current institution/center/degree { /***** Remove user as administrator of institution, center or degree *****/ Adm_DB_RemAdmin (UsrDat->UsrCod,Scope,Cod); diff --git a/swad_admin_database.c b/swad_admin_database.c index 80c17a52..9e2c44b9 100644 --- a/swad_admin_database.c +++ b/swad_admin_database.c @@ -94,6 +94,24 @@ unsigned Adm_DB_GetAdmsCurrentScopeExceptMe (MYSQL_RES **mysql_res) Gbl.Usrs.Me.UsrDat.UsrCod); } +/*****************************************************************************/ +/***** Check if a user is an administrator of a degree/center/institution ****/ +/*****************************************************************************/ + +bool Adm_DB_CheckIfUsrIsAdm (long UsrCod,HieLvl_Level_t Scope,long Cod) + { + /***** Get if a user is administrator of a degree from database *****/ + return (DB_QueryCOUNT ("can not check if a user is administrator", + "SELECT COUNT(*)" + " FROM usr_admins" + " WHERE UsrCod=%ld" + " AND Scope='%s'" + " AND Cod=%ld", + UsrCod, + Sco_GetDBStrFromScope (Scope), + Cod) != 0); + } + /*****************************************************************************/ /***** Remove user as administrator of an institution, center or degree ******/ /*****************************************************************************/ diff --git a/swad_admin_database.h b/swad_admin_database.h index cfc5bd68..c2944dba 100644 --- a/swad_admin_database.h +++ b/swad_admin_database.h @@ -44,6 +44,7 @@ void Adm_DB_InsertAdmin (long UsrCod,HieLvl_Level_t Scope,long Cod); unsigned Adm_DB_GetAdmsCurrentScopeExceptMe (MYSQL_RES **mysql_res); +bool Adm_DB_CheckIfUsrIsAdm (long UsrCod,HieLvl_Level_t Scope,long Cod); void Adm_DB_RemAdmin (long UsrCod,HieLvl_Level_t Scope,long Cod); void Adm_DB_RemUsrAsAdmin (long UsrCod); diff --git a/swad_attendance.c b/swad_attendance.c index d1b6864e..4afefb76 100644 --- a/swad_attendance.c +++ b/swad_attendance.c @@ -1521,7 +1521,7 @@ static void Att_ListAttOnlyMeAsStudent (struct Att_Event *Event) extern const char *Txt_Save_changes; /***** Get my setting about photos in users' list for current course *****/ - Usr_GetMyPrefAboutListWithPhotosFromDB (); + Set_GetMyPrefAboutListWithPhotosFromDB (); /***** List students (only me) *****/ /* Begin box */ @@ -1607,7 +1607,7 @@ static void Att_ListAttStudents (struct Att_Events *Events, if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs) { /***** Get my preference about photos in users' list for current course *****/ - Usr_GetMyPrefAboutListWithPhotosFromDB (); + Set_GetMyPrefAboutListWithPhotosFromDB (); /***** Initialize structure with user's data *****/ Usr_UsrDataConstructor (&UsrDat); @@ -2297,7 +2297,7 @@ static void Att_ListOrPrintMyAttendanceCrs (Att_TypeOfView_t TypeOfView) Att_ListEventsToSelect (&Events,TypeOfView); /***** Get my preference about photos in users' list for current course *****/ - Usr_GetMyPrefAboutListWithPhotosFromDB (); + Set_GetMyPrefAboutListWithPhotosFromDB (); /***** Show table with attendances for every student in list *****/ Att_ListUsrsAttendanceTable (&Events,TypeOfView,1,&Gbl.Usrs.Me.UsrDat.UsrCod); @@ -2412,7 +2412,7 @@ static void Att_ListOrPrintUsrsAttendanceCrs (void *TypeOfView) Att_ListEventsToSelect (&Events,*((Att_TypeOfView_t *) TypeOfView)); /***** Get my preference about photos in users' list for current course *****/ - Usr_GetMyPrefAboutListWithPhotosFromDB (); + Set_GetMyPrefAboutListWithPhotosFromDB (); /***** Show table with attendances for every student in list *****/ Att_ListUsrsAttendanceTable (&Events,*((Att_TypeOfView_t *) TypeOfView), @@ -2839,7 +2839,7 @@ static void Att_ListUsrsAttendanceTable (const struct Att_Events *Events, Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) if (Usr_CheckIfICanViewAtt (&UsrDat)) { - UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); + UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); Att_WriteRowUsrSeveralAttEvents (Events,NumUsr,&UsrDat); } } @@ -3063,7 +3063,7 @@ static void Att_ListStdsWithAttEventsDetails (const struct Att_Events *Events, Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) if (Usr_CheckIfICanViewAtt (&UsrDat)) { - UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); + UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); Att_ListAttEventsForAStd (Events,NumUsr,&UsrDat); } } diff --git a/swad_browser.c b/swad_browser.c index f669a424..bff6a70e 100644 --- a/swad_browser.c +++ b/swad_browser.c @@ -3052,7 +3052,7 @@ static void Brw_ShowFileBrowsersAsgWrkCrs (void) if (Usr_CheckIfICanViewAsgWrk (&Gbl.Usrs.Other.UsrDat)) { Gbl.Usrs.Other.UsrDat.Accepted = - Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); /***** Show a row with the data of the owner of the works *****/ HTM_TR_Begin (NULL); @@ -3701,7 +3701,7 @@ static void Brw_UpdateLastAccess (void) if (Gbl.Action.Act == ActChgToSeeDocCrs || Gbl.Action.Act == ActChgToAdmDocCrs || Gbl.Action.Act == ActChgToAdmTch) // Update group of last access to a documents/teachers zone only when user changes zone - Set_DB_UpdateGrpLastAccZone ("LastDowGrpCod",-1L); + Set_DB_UpdateGrpMyLastAccZone ("LastDowGrpCod",-1L); break; case Brw_SHOW_DOC_GRP: case Brw_ADMI_DOC_GRP: @@ -3709,27 +3709,27 @@ static void Brw_UpdateLastAccess (void) if (Gbl.Action.Act == ActChgToSeeDocCrs || Gbl.Action.Act == ActChgToAdmDocCrs || Gbl.Action.Act == ActChgToAdmTch) // Update group of last access to a documents/teachers zone only when user changes zone - Set_DB_UpdateGrpLastAccZone ("LastDowGrpCod",Gbl.Crs.Grps.GrpCod); + Set_DB_UpdateGrpMyLastAccZone ("LastDowGrpCod",Gbl.Crs.Grps.GrpCod); break; case Brw_ADMI_SHR_CRS: if (Gbl.Action.Act == ActChgToAdmSha) // Update group of last access to a shared files zone only when user changes zone - Set_DB_UpdateGrpLastAccZone ("LastComGrpCod",-1L); + Set_DB_UpdateGrpMyLastAccZone ("LastComGrpCod",-1L); break; case Brw_ADMI_SHR_GRP: if (Gbl.Action.Act == ActChgToAdmSha) // Update group of last access to a shared files zone only when user changes zone - Set_DB_UpdateGrpLastAccZone ("LastComGrpCod",Gbl.Crs.Grps.GrpCod); + Set_DB_UpdateGrpMyLastAccZone ("LastComGrpCod",Gbl.Crs.Grps.GrpCod); break; case Brw_SHOW_MRK_CRS: case Brw_ADMI_MRK_CRS: if (Gbl.Action.Act == ActChgToSeeMrk || Gbl.Action.Act == ActChgToAdmMrk) // Update group of last access to a marks zone only when user changes zone - Set_DB_UpdateGrpLastAccZone ("LastAssGrpCod",-1L); + Set_DB_UpdateGrpMyLastAccZone ("LastAssGrpCod",-1L); break; case Brw_SHOW_MRK_GRP: case Brw_ADMI_MRK_GRP: if (Gbl.Action.Act == ActChgToSeeMrk || Gbl.Action.Act == ActChgToAdmMrk) // Update group of last access to a marks zone only when user changes zone - Set_DB_UpdateGrpLastAccZone ("LastAssGrpCod",Gbl.Crs.Grps.GrpCod); + Set_DB_UpdateGrpMyLastAccZone ("LastAssGrpCod",Gbl.Crs.Grps.GrpCod); break; default: break; diff --git a/swad_center.c b/swad_center.c index 253c3330..0aac4ee0 100644 --- a/swad_center.c +++ b/swad_center.c @@ -2015,3 +2015,115 @@ bool Ctr_GetIfMapIsAvailable (const struct Ctr_Center *Ctr) return (bool) (Ctr->Coord.Latitude || Ctr->Coord.Longitude); } + +/*****************************************************************************/ +/***** Get all my centers (those of my courses) and store them in a list *****/ +/*****************************************************************************/ + +void Ctr_GetMyCenters (void) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumCtr; + unsigned NumCtrs; + long CtrCod; + + /***** If my centers are yet filled, there's nothing to do *****/ + if (!Gbl.Usrs.Me.MyCtrs.Filled) + { + Gbl.Usrs.Me.MyCtrs.Num = 0; + + /***** Get my centers from database *****/ + NumCtrs = Ctr_DB_GetCtrsFromUsr (&mysql_res, + Gbl.Usrs.Me.UsrDat.UsrCod,-1L); + for (NumCtr = 0; + NumCtr < NumCtrs; + NumCtr++) + { + /* Get next center */ + row = mysql_fetch_row (mysql_res); + + /* Get center code */ + if ((CtrCod = Str_ConvertStrCodToLongCod (row[0])) > 0) + { + if (Gbl.Usrs.Me.MyCtrs.Num == Ctr_MAX_CENTERS_PER_USR) + Err_ShowErrorAndExit ("Maximum number of centers of a user exceeded."); + + Gbl.Usrs.Me.MyCtrs.Ctrs[Gbl.Usrs.Me.MyCtrs.Num].CtrCod = CtrCod; + Gbl.Usrs.Me.MyCtrs.Ctrs[Gbl.Usrs.Me.MyCtrs.Num].MaxRole = Rol_ConvertUnsignedStrToRole (row[1]); + + Gbl.Usrs.Me.MyCtrs.Num++; + } + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + /***** Set boolean that indicates that my centers are yet filled *****/ + Gbl.Usrs.Me.MyCtrs.Filled = true; + } + } + +/*****************************************************************************/ +/************************ Free the list of my centers ************************/ +/*****************************************************************************/ + +void Ctr_FreeMyCenters (void) + { + if (Gbl.Usrs.Me.MyCtrs.Filled) + { + /***** Reset list *****/ + Gbl.Usrs.Me.MyCtrs.Filled = false; + Gbl.Usrs.Me.MyCtrs.Num = 0; + } + } + +/*****************************************************************************/ +/*********************** Check if I belong to a center ***********************/ +/*****************************************************************************/ + +bool Ctr_CheckIfIBelongToCtr (long CtrCod) + { + unsigned NumMyCtr; + + /***** Fill the list with the centers I belong to *****/ + Ctr_GetMyCenters (); + + /***** Check if the center passed as parameter is any of my centers *****/ + for (NumMyCtr = 0; + NumMyCtr < Gbl.Usrs.Me.MyCtrs.Num; + NumMyCtr++) + if (Gbl.Usrs.Me.MyCtrs.Ctrs[NumMyCtr].CtrCod == CtrCod) + return true; + return false; + } + +/*****************************************************************************/ +/******************* Check if a user belongs to a center *********************/ +/*****************************************************************************/ + +void Ctr_FlushCacheUsrBelongsToCtr (void) + { + Gbl.Cache.UsrBelongsToCtr.UsrCod = -1L; + Gbl.Cache.UsrBelongsToCtr.CtrCod = -1L; + Gbl.Cache.UsrBelongsToCtr.Belongs = false; + } + +bool Ctr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod) + { + /***** 1. Fast check: Trivial case *****/ + if (UsrCod <= 0 || + CtrCod <= 0) + return false; + + /***** 2. Fast check: If cached... *****/ + if (UsrCod == Gbl.Cache.UsrBelongsToCtr.UsrCod && + CtrCod == Gbl.Cache.UsrBelongsToCtr.CtrCod) + return Gbl.Cache.UsrBelongsToCtr.Belongs; + + /***** 3. Slow check: Get is user belongs to center from database *****/ + Gbl.Cache.UsrBelongsToCtr.UsrCod = UsrCod; + Gbl.Cache.UsrBelongsToCtr.CtrCod = CtrCod; + Gbl.Cache.UsrBelongsToCtr.Belongs = Ctr_DB_CheckIfUsrBelongsToCtr (UsrCod,CtrCod); + return Gbl.Cache.UsrBelongsToCtr.Belongs; + } diff --git a/swad_center.h b/swad_center.h index fb3790a2..fd398ae8 100644 --- a/swad_center.h +++ b/swad_center.h @@ -147,4 +147,10 @@ void Ctr_ListCtrsFound (MYSQL_RES **mysql_res,unsigned NumCtrs); bool Ctr_GetIfMapIsAvailable (const struct Ctr_Center *Ctr); +void Ctr_GetMyCenters (void); +void Ctr_FreeMyCenters (void); +bool Ctr_CheckIfIBelongToCtr (long CtrCod); +void Ctr_FlushCacheUsrBelongsToCtr (void); +bool Ctr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod); + #endif diff --git a/swad_center_database.c b/swad_center_database.c index 2276142b..ca9869fb 100644 --- a/swad_center_database.c +++ b/swad_center_database.c @@ -514,50 +514,6 @@ unsigned Ctr_DB_GetNumCtrsWithUsrs (Rol_Role_t Role, SubQuery,(unsigned) Role); } -/*****************************************************************************/ -/***************** Get the centers of a user from database *******************/ -/*****************************************************************************/ -// Returns the number of rows of the result - -unsigned Ctr_DB_GetCtrsFromUsr (MYSQL_RES **mysql_res,long UsrCod,long InsCod) - { - /***** Get from database the centers a user belongs to *****/ - if (InsCod > 0) - return (unsigned) - DB_QuerySELECT (mysql_res,"can not check the centers a user belongs to", - "SELECT ctr_centers.CtrCod," // row[0] - "MAX(crs_users.Role)" // row[1] - " FROM crs_users," - "crs_courses," - "deg_degrees," - "ctr_centers" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.CrsCod=crs_courses.CrsCod" - " AND crs_courses.DegCod=deg_degrees.DegCod" - " AND deg_degrees.CtrCod=ctr_centers.CtrCod" - " AND ctr_centers.InsCod=%ld" - " GROUP BY ctr_centers.CtrCod" - " ORDER BY ctr_centers.ShortName", - UsrCod, - InsCod); - else - return (unsigned) - DB_QuerySELECT (mysql_res,"can not check the centers a user belongs to", - "SELECT deg_degrees.CtrCod," // row[0] - "MAX(crs_users.Role)" // row[1] - " FROM crs_users," - "crs_courses," - "deg_degrees," - "ctr_centers" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.CrsCod=crs_courses.CrsCod" - " AND crs_courses.DegCod=deg_degrees.DegCod" - " AND deg_degrees.CtrCod=ctr_centers.CtrCod" - " GROUP BY ctr_centers.CtrCod" - " ORDER BY ctr_centers.ShortName", - UsrCod); - } - /*****************************************************************************/ /******************* Update institution in table of centers ******************/ /*****************************************************************************/ @@ -774,6 +730,70 @@ unsigned Ctr_DB_GetCtrsWithCoordsInCurrentIns (MYSQL_RES **mysql_res) Gbl.Hierarchy.Ins.InsCod); } +/*****************************************************************************/ +/***************** Get the centers of a user from database *******************/ +/*****************************************************************************/ +// Returns the number of rows of the result + +unsigned Ctr_DB_GetCtrsFromUsr (MYSQL_RES **mysql_res,long UsrCod,long InsCod) + { + /***** Get from database the centers a user belongs to *****/ + if (InsCod > 0) + return (unsigned) + DB_QuerySELECT (mysql_res,"can not check the centers a user belongs to", + "SELECT ctr_centers.CtrCod," // row[0] + "MAX(crs_users.Role)" // row[1] + " FROM crs_users," + "crs_courses," + "deg_degrees," + "ctr_centers" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.CrsCod=crs_courses.CrsCod" + " AND crs_courses.DegCod=deg_degrees.DegCod" + " AND deg_degrees.CtrCod=ctr_centers.CtrCod" + " AND ctr_centers.InsCod=%ld" + " GROUP BY ctr_centers.CtrCod" + " ORDER BY ctr_centers.ShortName", + UsrCod, + InsCod); + else + return (unsigned) + DB_QuerySELECT (mysql_res,"can not check the centers a user belongs to", + "SELECT deg_degrees.CtrCod," // row[0] + "MAX(crs_users.Role)" // row[1] + " FROM crs_users," + "crs_courses," + "deg_degrees," + "ctr_centers" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.CrsCod=crs_courses.CrsCod" + " AND crs_courses.DegCod=deg_degrees.DegCod" + " AND deg_degrees.CtrCod=ctr_centers.CtrCod" + " GROUP BY ctr_centers.CtrCod" + " ORDER BY ctr_centers.ShortName", + UsrCod); + } + +/*****************************************************************************/ +/******************* Check if a user belongs to a center *********************/ +/*****************************************************************************/ + +bool Ctr_DB_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod) + { + return (DB_QueryCOUNT ("can not check if a user belongs to a center", + "SELECT COUNT(DISTINCT deg_degrees.CtrCod)" + " FROM crs_users," + "crs_courses," + "deg_degrees" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.Accepted='Y'" // Only if user accepted + " AND crs_users.CrsCod=crs_courses.CrsCod" + " AND crs_courses.DegCod=deg_degrees.DegCod" + " AND deg_degrees.CtrCod=%ld", + UsrCod, + CtrCod) != 0); + } + /*****************************************************************************/ /****************************** Remove a center ******************************/ /*****************************************************************************/ diff --git a/swad_center_database.h b/swad_center_database.h index e4ea3bd7..a866378f 100644 --- a/swad_center_database.h +++ b/swad_center_database.h @@ -71,8 +71,6 @@ unsigned Ctr_DB_GetNumCtrsWithCrss (HieLvl_Level_t Scope,long Cod); unsigned Ctr_DB_GetNumCtrsWithUsrs (Rol_Role_t Role, HieLvl_Level_t Scope,long Cod); -unsigned Ctr_DB_GetCtrsFromUsr (MYSQL_RES **mysql_res,long UsrCod,long InsCod); - void Ctr_DB_UpdateCtrIns (long CtrCod,long NewInsCod); void Ctr_DB_UpdateCtrPlc (long CtrCod,long NewPlcCod); void Ctr_DB_UpdateCtrName (long CtrCod,const char *FieldName,const char *NewCtrName); @@ -89,6 +87,9 @@ void Ctr_DB_GetCoordAndZoomInCurrentIns (struct Map_Coordinates *Coord,unsigned unsigned Ctr_DB_GetCtrsWithCoords (MYSQL_RES **mysql_res); unsigned Ctr_DB_GetCtrsWithCoordsInCurrentIns (MYSQL_RES **mysql_res); +unsigned Ctr_DB_GetCtrsFromUsr (MYSQL_RES **mysql_res,long UsrCod,long InsCod); +bool Ctr_DB_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod); + void Ctr_DB_RemoveCenter (long CtrCod); #endif diff --git a/swad_changelog.h b/swad_changelog.h index ca3c3ffb..8d7f67dc 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo. */ -#define Log_PLATFORM_VERSION "SWAD 21.49 (2021-11-03)" +#define Log_PLATFORM_VERSION "SWAD 21.50 (2021-11-03)" #define CSS_FILE "swad20.45.css" #define JS_FILE "swad20.69.1.js" /* TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams + Version 21.50: Nov 03, 2021 Queries moved to module swad_user_database and other modules. (321696 lines) Version 21.49: Nov 03, 2021 New module swad_user_database for database queries related to users. (321615 lines) Version 21.48: Nov 03, 2021 New module swad_timetable_database for database queries related to timetables. (321438 lines) Version 21.47.5: Oct 30, 2021 Queries moved to module swad_questions_database. (321308 lines) diff --git a/swad_chat.c b/swad_chat.c index 061a1ce7..651bc00f 100644 --- a/swad_chat.c +++ b/swad_chat.c @@ -406,7 +406,7 @@ void Cht_OpenChatWindow (void) /***** Fill the lists with the degrees and courses I belong to *****/ Deg_GetMyDegrees (); - Crs_GetMyCourses (); + Enr_GetMyCourses (); /***** Build my user's name *****/ Str_Copy (UsrName,Gbl.Usrs.Me.UsrDat.Surname1,sizeof (UsrName) - 1); diff --git a/swad_country.c b/swad_country.c index a9b00353..dcb09b2b 100644 --- a/swad_country.c +++ b/swad_country.c @@ -1888,3 +1888,84 @@ static void Cty_FormToGoToMap (struct Cty_Countr *Cty) Txt_Map); } } + +/*****************************************************************************/ +/**** Get all my countries (those of my courses) and store them in a list ****/ +/*****************************************************************************/ + +void Cty_GetMyCountrs (void) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumCty; + unsigned NumCtys; + long CtyCod; + + /***** If my countries are yet filled, there's nothing to do *****/ + if (!Gbl.Usrs.Me.MyCtys.Filled) + { + Gbl.Usrs.Me.MyCtys.Num = 0; + + /***** Get my institutions from database *****/ + NumCtys = Cty_DB_GetCtysFromUsr (&mysql_res,Gbl.Usrs.Me.UsrDat.UsrCod); + for (NumCty = 0; + NumCty < NumCtys; + NumCty++) + { + /* Get next country */ + row = mysql_fetch_row (mysql_res); + + /* Get country code */ + if ((CtyCod = Str_ConvertStrCodToLongCod (row[0])) > 0) + { + if (Gbl.Usrs.Me.MyCtys.Num == Cty_MAX_COUNTRS_PER_USR) + Err_ShowErrorAndExit ("Maximum number of countries of a user exceeded."); + + Gbl.Usrs.Me.MyCtys.Ctys[Gbl.Usrs.Me.MyCtys.Num].CtyCod = CtyCod; + Gbl.Usrs.Me.MyCtys.Ctys[Gbl.Usrs.Me.MyCtys.Num].MaxRole = Rol_ConvertUnsignedStrToRole (row[1]); + + Gbl.Usrs.Me.MyCtys.Num++; + } + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + /***** Set boolean that indicates that my institutions are yet filled *****/ + Gbl.Usrs.Me.MyCtys.Filled = true; + } + } + +/*****************************************************************************/ +/************************ Free the list of my countries ************************/ +/*****************************************************************************/ + +void Cty_FreeMyCountrs (void) + { + if (Gbl.Usrs.Me.MyCtys.Filled) + { + /***** Reset list *****/ + Gbl.Usrs.Me.MyCtys.Filled = false; + Gbl.Usrs.Me.MyCtys.Num = 0; + } + } + +/*****************************************************************************/ +/********************** Check if I belong to a country **********************/ +/*****************************************************************************/ + +bool Cty_CheckIfIBelongToCty (long CtyCod) + { + unsigned NumMyCty; + + /***** Fill the list with the institutions I belong to *****/ + Cty_GetMyCountrs (); + + /***** Check if the country passed as parameter is any of my countries *****/ + for (NumMyCty = 0; + NumMyCty < Gbl.Usrs.Me.MyCtys.Num; + NumMyCty++) + if (Gbl.Usrs.Me.MyCtys.Ctys[NumMyCty].CtyCod == CtyCod) + return true; + return false; + } diff --git a/swad_country.h b/swad_country.h index 7128b24b..cbcfea81 100644 --- a/swad_country.h +++ b/swad_country.h @@ -123,4 +123,8 @@ unsigned Cty_GetCachedNumCtysWithUsrs (Rol_Role_t Role); void Cty_ListCtysFound (MYSQL_RES **mysql_res,unsigned NumCtys); +void Cty_GetMyCountrs (void); +void Cty_FreeMyCountrs (void); +bool Cty_CheckIfIBelongToCty (long CtyCod); + #endif diff --git a/swad_course.c b/swad_course.c index 5f78bbfc..d31ee611 100644 --- a/swad_course.c +++ b/swad_course.c @@ -790,7 +790,7 @@ void Crs_WriteSelectorMyCoursesInBreadcrumb (void) /***** Fill the list with the courses I belong to, if not filled *****/ if (Gbl.Usrs.Me.Logged) - Crs_GetMyCourses (); + Enr_GetMyCourses (); /***** Begin form *****/ Frm_BeginFormGoTo (Gbl.Usrs.Me.MyCrss.Num ? ActSeeCrsInf : @@ -977,7 +977,7 @@ static bool Crs_ListCoursesOfAYearForSeeing (unsigned Year) } /* Check if this course is one of my courses */ - BgColor = (Crs_CheckIfIBelongToCrs (Crs->CrsCod)) ? "LIGHT_BLUE" : + BgColor = (Enr_CheckIfIBelongToCrs (Crs->CrsCod)) ? "LIGHT_BLUE" : Gbl.ColorRows[Gbl.RowEvenOdd]; HTM_TR_Begin (NULL); @@ -2190,7 +2190,7 @@ void Crs_ContEditAfterChgCrs (void) PutButtonToRequestRegistration = true; break; case Rol_USR: - PutButtonToRequestRegistration = !Crs_CheckIfUsrBelongsToCrs (Gbl.Usrs.Me.UsrDat.UsrCod, + PutButtonToRequestRegistration = !Enr_CheckIfUsrBelongsToCrs (Gbl.Usrs.Me.UsrDat.UsrCod, Crs_EditingCrs->CrsCod, false); break; @@ -2198,7 +2198,7 @@ void Crs_ContEditAfterChgCrs (void) case Rol_NET: case Rol_TCH: if (Crs_EditingCrs->CrsCod != Gbl.Hierarchy.Crs.CrsCod) - PutButtonToRequestRegistration = !Crs_CheckIfUsrBelongsToCrs (Gbl.Usrs.Me.UsrDat.UsrCod, + PutButtonToRequestRegistration = !Enr_CheckIfUsrBelongsToCrs (Gbl.Usrs.Me.UsrDat.UsrCod, Crs_EditingCrs->CrsCod, false); break; @@ -2269,7 +2269,7 @@ static void Crs_PutButtonToRegisterInCrs (void) void Crs_ReqSelectOneOfMyCourses (void) { /***** Fill the list with the courses I belong to, if not filled *****/ - Crs_GetMyCourses (); + Enr_GetMyCourses (); /***** Select one of my courses *****/ if (Gbl.Usrs.Me.MyCrss.Num) diff --git a/swad_degree.c b/swad_degree.c index 0aa6daf3..41e9e40b 100644 --- a/swad_degree.c +++ b/swad_degree.c @@ -1939,3 +1939,147 @@ static void Deg_EditingDegreeDestructor (void) Deg_EditingDeg = NULL; } } + +/*****************************************************************************/ +/***** Get all my degrees (those of my courses) and store them in a list *****/ +/*****************************************************************************/ + +void Deg_GetMyDegrees (void) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumDeg; + unsigned NumDegs; + long DegCod; + + /***** If my degrees are yet filled, there's nothing to do *****/ + if (!Gbl.Usrs.Me.MyDegs.Filled) + { + Gbl.Usrs.Me.MyDegs.Num = 0; + + /***** Get my degrees from database *****/ + NumDegs = Deg_DB_GetDegsFromUsr (&mysql_res, + Gbl.Usrs.Me.UsrDat.UsrCod,-1L); + for (NumDeg = 0; + NumDeg < NumDegs; + NumDeg++) + { + /* Get next degree */ + row = mysql_fetch_row (mysql_res); + + /* Get degree code */ + if ((DegCod = Str_ConvertStrCodToLongCod (row[0])) > 0) + { + if (Gbl.Usrs.Me.MyDegs.Num == Deg_MAX_DEGREES_PER_USR) + Err_ShowErrorAndExit ("Maximum number of degrees of a user exceeded."); + + Gbl.Usrs.Me.MyDegs.Degs[Gbl.Usrs.Me.MyDegs.Num].DegCod = DegCod; + Gbl.Usrs.Me.MyDegs.Degs[Gbl.Usrs.Me.MyDegs.Num].MaxRole = Rol_ConvertUnsignedStrToRole (row[1]); + + Gbl.Usrs.Me.MyDegs.Num++; + } + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + /***** Set boolean that indicates that my degrees are yet filled *****/ + Gbl.Usrs.Me.MyDegs.Filled = true; + } + } + +/*****************************************************************************/ +/************************ Free the list of my degrees ************************/ +/*****************************************************************************/ + +void Deg_FreeMyDegrees (void) + { + if (Gbl.Usrs.Me.MyDegs.Filled) + { + /***** Reset list *****/ + Gbl.Usrs.Me.MyDegs.Filled = false; + Gbl.Usrs.Me.MyDegs.Num = 0; + } + } + +/*****************************************************************************/ +/*********************** Check if I belong to a degree ***********************/ +/*****************************************************************************/ + +bool Deg_CheckIfIBelongToDeg (long DegCod) + { + unsigned NumMyDeg; + + /***** Fill the list with the degrees I belong to *****/ + Deg_GetMyDegrees (); + + /***** Check if the degree passed as parameter is any of my degrees *****/ + for (NumMyDeg = 0; + NumMyDeg < Gbl.Usrs.Me.MyDegs.Num; + NumMyDeg++) + if (Gbl.Usrs.Me.MyDegs.Degs[NumMyDeg].DegCod == DegCod) + return true; + return false; + } + +/*****************************************************************************/ +/********* Get the degree in which a user is enroled in more courses *********/ +/*****************************************************************************/ + +void Deg_GetUsrMainDeg (long UsrCod, + char ShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1], + Rol_Role_t *MaxRole) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + + /***** Get the degree in which a user is enroled in more courses *****/ + if (Deg_DB_GetUsrMainDeg (&mysql_res,UsrCod)) + { + row = mysql_fetch_row (mysql_res); + + /* Get degree name (row[0]) */ + Str_Copy (ShrtName,row[0],Cns_HIERARCHY_MAX_BYTES_SHRT_NAME); + + /* Get maximum role (row[1]) */ + *MaxRole = Rol_ConvertUnsignedStrToRole (row[1]); + } + else // User is not enroled in any course + { + ShrtName[0] = '\0'; + *MaxRole = Rol_UNK; + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + } + +/*****************************************************************************/ +/******************* Check if a user belongs to a degree *********************/ +/*****************************************************************************/ + +void Deg_FlushCacheUsrBelongsToDeg (void) + { + Gbl.Cache.UsrBelongsToDeg.UsrCod = -1L; + Gbl.Cache.UsrBelongsToDeg.DegCod = -1L; + Gbl.Cache.UsrBelongsToDeg.Belongs = false; + } + +bool Deg_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod) + { + /***** 1. Fast check: Trivial case *****/ + if (UsrCod <= 0 || + DegCod <= 0) + return false; + + /***** 2. Fast check: If cached... *****/ + if (UsrCod == Gbl.Cache.UsrBelongsToDeg.UsrCod && + DegCod == Gbl.Cache.UsrBelongsToDeg.DegCod) + return Gbl.Cache.UsrBelongsToDeg.Belongs; + + /***** 3. Slow check: Get if user belongs to degree from database *****/ + Gbl.Cache.UsrBelongsToDeg.UsrCod = UsrCod; + Gbl.Cache.UsrBelongsToDeg.DegCod = DegCod; + Gbl.Cache.UsrBelongsToDeg.Belongs = Deg_DB_CheckIfUsrBelongsToDeg (UsrCod,DegCod); + return Gbl.Cache.UsrBelongsToDeg.Belongs; + } diff --git a/swad_degree.h b/swad_degree.h index 290023ac..95b4a800 100644 --- a/swad_degree.h +++ b/swad_degree.h @@ -147,4 +147,13 @@ unsigned Deg_GetCachedNumDegsWithUsrs (Rol_Role_t Role); void Deg_ListDegsFound (MYSQL_RES **mysql_res,unsigned NumCrss); +void Deg_GetMyDegrees (void); +void Deg_FreeMyDegrees (void); +bool Deg_CheckIfIBelongToDeg (long DegCod); +void Deg_GetUsrMainDeg (long UsrCod, + char ShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1], + Rol_Role_t *MaxRole); +void Deg_FlushCacheUsrBelongsToDeg (void); +bool Deg_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod); + #endif diff --git a/swad_degree_database.c b/swad_degree_database.c index c0428d70..e78d52af 100644 --- a/swad_degree_database.c +++ b/swad_degree_database.c @@ -552,45 +552,6 @@ unsigned Deg_DB_GetNumDegsWithUsrs (Rol_Role_t Role, SubQuery,(unsigned) Role); } -/*****************************************************************************/ -/***************** Get the degrees of a user from database *******************/ -/*****************************************************************************/ -// Returns the number of rows of the result - -unsigned Deg_DB_GetDegsFromUsr (MYSQL_RES **mysql_res,long UsrCod,long CtrCod) - { - if (CtrCod > 0) - return (unsigned) - DB_QuerySELECT (mysql_res,"can not check the degrees a user belongs to", - "SELECT deg_degrees.DegCod," // row[0] - "MAX(crs_users.Role)" // row[1] - " FROM crs_users," - "crs_courses," - "deg_degrees" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.CrsCod=crs_courses.CrsCod" - " AND crs_courses.DegCod=deg_degrees.DegCod" - " AND deg_degrees.CtrCod=%ld" - " GROUP BY deg_degrees.DegCod" - " ORDER BY deg_degrees.ShortName", - UsrCod, - CtrCod); - else - return (unsigned) - DB_QuerySELECT (mysql_res,"can not check the degrees a user belongs to", - "SELECT deg_degrees.DegCod," // row[0] - "MAX(crs_users.Role)" // row[1] - " FROM crs_users," - "crs_courses," - "deg_degrees" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.CrsCod=crs_courses.CrsCod" - " AND crs_courses.DegCod=deg_degrees.DegCod" - " GROUP BY deg_degrees.DegCod" - " ORDER BY deg_degrees.ShortName", - UsrCod); - } - /*****************************************************************************/ /******************** Get number of degrees in a country *********************/ /*****************************************************************************/ @@ -726,6 +687,92 @@ void Deg_DB_UpdateDegStatus (long DegCod,Deg_Status_t NewStatus) DegCod); } +/*****************************************************************************/ +/***************** Get the degrees of a user from database *******************/ +/*****************************************************************************/ +// Returns the number of rows of the result + +unsigned Deg_DB_GetDegsFromUsr (MYSQL_RES **mysql_res,long UsrCod,long CtrCod) + { + if (CtrCod > 0) + return (unsigned) + DB_QuerySELECT (mysql_res,"can not check the degrees a user belongs to", + "SELECT deg_degrees.DegCod," // row[0] + "MAX(crs_users.Role)" // row[1] + " FROM crs_users," + "crs_courses," + "deg_degrees" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.CrsCod=crs_courses.CrsCod" + " AND crs_courses.DegCod=deg_degrees.DegCod" + " AND deg_degrees.CtrCod=%ld" + " GROUP BY deg_degrees.DegCod" + " ORDER BY deg_degrees.ShortName", + UsrCod, + CtrCod); + else + return (unsigned) + DB_QuerySELECT (mysql_res,"can not check the degrees a user belongs to", + "SELECT deg_degrees.DegCod," // row[0] + "MAX(crs_users.Role)" // row[1] + " FROM crs_users," + "crs_courses," + "deg_degrees" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.CrsCod=crs_courses.CrsCod" + " AND crs_courses.DegCod=deg_degrees.DegCod" + " GROUP BY deg_degrees.DegCod" + " ORDER BY deg_degrees.ShortName", + UsrCod); + } + +/*****************************************************************************/ +/********* Get the degree in which a user is enroled in more courses *********/ +/*****************************************************************************/ + +unsigned Deg_DB_GetUsrMainDeg (MYSQL_RES **mysql_res,long UsrCod) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get user's main degree", + "SELECT deg_degrees.ShortName," // row[0] + "main_degree.MaxRole" // row[1] + " FROM deg_degrees," + + // The second table contain only one row with the main degree + " (SELECT crs_courses.DegCod AS DegCod," + "MAX(crs_users.Role) AS MaxRole," + "COUNT(*) AS N" + " FROM crs_users," + "crs_courses" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.CrsCod=crs_courses.CrsCod" + " GROUP BY crs_courses.DegCod" + " ORDER BY N DESC" // Ordered by number of courses in which user is enroled + " LIMIT 1)" // We need only the main degree + " AS main_degree" + + " WHERE deg_degrees.DegCod=main_degree.DegCod", + UsrCod); + } + +/*****************************************************************************/ +/******************* Check if a user belongs to a degree *********************/ +/*****************************************************************************/ + +bool Deg_DB_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod) + { + return (DB_QueryCOUNT ("can not check if a user belongs to a degree", + "SELECT COUNT(DISTINCT crs_courses.DegCod)" + " FROM crs_users," + "crs_courses" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.Accepted='Y'" // Only if user accepted + " AND crs_users.CrsCod=crs_courses.CrsCod" + " AND crs_courses.DegCod=%ld", + UsrCod, + DegCod) != 0); + } + /*****************************************************************************/ /*************************** Remove the degree type **************************/ /*****************************************************************************/ diff --git a/swad_degree_database.h b/swad_degree_database.h index ce31e4b8..260e8d3e 100644 --- a/swad_degree_database.h +++ b/swad_degree_database.h @@ -73,8 +73,6 @@ unsigned Deg_DB_GetNumDegsWithCrss (HieLvl_Level_t Scope,long Cod); unsigned Deg_DB_GetNumDegsWithUsrs (Rol_Role_t Role, HieLvl_Level_t Scope,long Cod); -unsigned Deg_DB_GetDegsFromUsr (MYSQL_RES **mysql_res,long UsrCod,long CtrCod); - unsigned Deg_DB_GetNumDegsInCty (long CtyCod); unsigned Deg_DB_GetNumDegsInIns (long InsCod); unsigned Deg_DB_GetNumDegsInCtr (long CtrCod); @@ -88,6 +86,10 @@ void Deg_DB_UpdateDegTyp (long DegCod,long NewDegTypCod); void Deg_DB_UpdateDegWWW (long DegCod,const char NewWWW[Cns_MAX_BYTES_WWW + 1]); void Deg_DB_UpdateDegStatus (long DegCod,Deg_Status_t NewStatus); +unsigned Deg_DB_GetDegsFromUsr (MYSQL_RES **mysql_res,long UsrCod,long CtrCod); +unsigned Deg_DB_GetUsrMainDeg (MYSQL_RES **mysql_res,long UsrCod); +bool Deg_DB_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod); + void Deg_DB_RemoveDegTyp (long DegTypCod); void Deg_DB_RemoveDeg (long DegCod); diff --git a/swad_duplicate.c b/swad_duplicate.c index 6e628b43..47f86992 100644 --- a/swad_duplicate.c +++ b/swad_duplicate.c @@ -31,6 +31,7 @@ #include "swad_duplicate.h" #include "swad_duplicate_database.h" #include "swad_enrolment.h" +#include "swad_enrolment_database.h" #include "swad_error.h" #include "swad_form.h" #include "swad_global.h" @@ -166,8 +167,8 @@ void Dup_ListDuplicateUsrs (void) Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) { /* Get if user has accepted all his/her courses */ - if (Usr_DB_GetNumCrssOfUsr (UsrDat.UsrCod) != 0) - UsrDat.Accepted = (Usr_DB_GetNumCrssOfUsrNotAccepted (UsrDat.UsrCod) == 0); + if (Enr_DB_GetNumCrssOfUsr (UsrDat.UsrCod) != 0) + UsrDat.Accepted = (Enr_DB_GetNumCrssOfUsrNotAccepted (UsrDat.UsrCod) == 0); else UsrDat.Accepted = false; @@ -283,8 +284,8 @@ static void Dup_ListSimilarUsrs (void) Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) { /* Get if user has accepted all his/her courses */ - if (Usr_DB_GetNumCrssOfUsr (UsrDat.UsrCod) != 0) - UsrDat.Accepted = (Usr_DB_GetNumCrssOfUsrNotAccepted (UsrDat.UsrCod) == 0); + if (Enr_DB_GetNumCrssOfUsr (UsrDat.UsrCod) != 0) + UsrDat.Accepted = (Enr_DB_GetNumCrssOfUsrNotAccepted (UsrDat.UsrCod) == 0); else UsrDat.Accepted = false; diff --git a/swad_enrolment.c b/swad_enrolment.c index ce077cef..c7dd6215 100644 --- a/swad_enrolment.c +++ b/swad_enrolment.c @@ -33,6 +33,7 @@ #include "swad_account.h" #include "swad_account_database.h" #include "swad_admin.h" +#include "swad_admin_database.h" #include "swad_announcement.h" #include "swad_attendance_database.h" #include "swad_box.h" @@ -1364,25 +1365,25 @@ bool Enr_PutActionsRegRemOneUsr (bool ItsMe) /***** Check if the other user belongs to the current course *****/ if (Gbl.Hierarchy.Level == HieLvl_CRS) - UsrBelongsToCrs = Usr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat); + UsrBelongsToCrs = Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat); if (Gbl.Hierarchy.Ins.InsCod > 0) { /***** Check if the other user is administrator of the current institution *****/ - UsrIsInsAdmin = Usr_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod, + UsrIsInsAdmin = Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod, HieLvl_INS, Gbl.Hierarchy.Ins.InsCod); if (Gbl.Hierarchy.Ctr.CtrCod > 0) { /***** Check if the other user is administrator of the current center *****/ - UsrIsCtrAdmin = Usr_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod, + UsrIsCtrAdmin = Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod, HieLvl_CTR, Gbl.Hierarchy.Ctr.CtrCod); if (Gbl.Hierarchy.Deg.DegCod > 0) /***** Check if the other user is administrator of the current degree *****/ - UsrIsDegAdmin = Usr_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod, + UsrIsDegAdmin = Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Other.UsrDat.UsrCod, HieLvl_DEG, Gbl.Hierarchy.Deg.DegCod); } @@ -1694,7 +1695,7 @@ static void Enr_RegisterUsr (struct UsrData *UsrDat,Rol_Role_t RegRemRole, /***** Register user in current course in database *****/ if (Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected { - if (Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) { if (RegRemRole != UsrDat->Roles.InCurrentCrs) // The role must be updated /* Modify role */ @@ -1981,7 +1982,7 @@ void Enr_AskIfRejectSignUp (void) Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) { // User's data exist... - if (Usr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat)) { /* User already belongs to this course */ Ale_ShowAlert (Ale_WARNING,Txt_THE_USER_X_is_already_enroled_in_the_course_Y, @@ -2040,7 +2041,7 @@ void Enr_RejectSignUp (void) Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) { // User's data exist... - if (Usr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat)) { /* User already belongs to this course */ Ale_ShowAlert (Ale_WARNING,Txt_THE_USER_X_is_already_enroled_in_the_course_Y, @@ -2236,7 +2237,7 @@ static void Enr_ShowEnrolmentRequestsGivenRoles (unsigned RolesSelected) DesiredRole = Rol_ConvertUnsignedStrToRole (row[3]); if (UsrExists) - UsrBelongsToCrs = Crs_CheckIfUsrBelongsToCrs (UsrDat.UsrCod, + UsrBelongsToCrs = Enr_CheckIfUsrBelongsToCrs (UsrDat.UsrCod, Crs.CrsCod, false); else @@ -2658,9 +2659,9 @@ static void Enr_ShowFormToEditOtherUsr (void) if (Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected { /* Check if this user belongs to the current course */ - if (Usr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat)) { - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); if (Gbl.Usrs.Other.UsrDat.Accepted) Ale_ShowAlert (Ale_INFO,Txt_THE_USER_X_is_already_enroled_in_the_course_Y, Gbl.Usrs.Other.UsrDat.FullName,Gbl.Hierarchy.Crs.FullName); @@ -2834,7 +2835,7 @@ void Enr_CreateNewUsr1 (void) /***** Register user in current course in database *****/ if (Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected { - if (Usr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat)) { OldRole = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs; // Remember old role before changing it if (NewRole != OldRole) // The role must be updated @@ -2953,7 +2954,7 @@ void Enr_ModifyUsr1 (void) NewRole = Rec_GetRoleFromRecordForm (); /***** Register user in current course in database *****/ - if (Usr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Other.UsrDat)) { OldRole = Gbl.Usrs.Other.UsrDat.Roles.InCurrentCrs; // Remember old role before changing it if (NewRole != OldRole) // The role must be updated @@ -3135,7 +3136,7 @@ static void Enr_AskIfRemoveUsrFromCrs (struct UsrData *UsrDat) bool ItsMe; Act_Action_t NextAction; - if (Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) { ItsMe = Usr_ItsMe (Gbl.Usrs.Other.UsrDat.UsrCod); @@ -3193,7 +3194,7 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat, extern const char *Txt_THE_USER_X_has_been_removed_from_the_course_Y; bool ItsMe = Usr_ItsMe (UsrDat->UsrCod); - if (Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) { /***** Remove user from all attendance events in course *****/ Att_DB_RemoveUsrFromCrsAttEvents (UsrDat->UsrCod,Crs->CrsCod); @@ -3243,7 +3244,7 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat, /* Fill the list with the courses I belong to */ Gbl.Usrs.Me.MyCrss.Filled = false; - Crs_GetMyCourses (); + Enr_GetMyCourses (); /* Set my roles */ Gbl.Usrs.Me.Role.FromSession = @@ -3273,3 +3274,254 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat, if (QuietOrVerbose == Cns_VERBOSE) Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission (); } + +/*****************************************************************************/ +/*************** Get all my courses and store them in a list *****************/ +/*****************************************************************************/ + +void Enr_GetMyCourses (void) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumCrss; + unsigned NumCrs; + long CrsCod; + + /***** Trivial check 1: if my courses are already filled, there's nothing to do *****/ + if (Gbl.Usrs.Me.MyCrss.Filled) + return; + + /***** Trivial check 2: if user's code is not set, don't query database *****/ + if (Gbl.Usrs.Me.UsrDat.UsrCod <= 0) + return; + + /***** Remove temporary table with my courses *****/ + Enr_DB_DropTmpTableMyCourses (); + + /***** Create temporary table with my courses *****/ + Enr_DB_CreateTmpTableMyCourses (); + + /***** Get my courses from database *****/ + NumCrss = Enr_DB_GetMyCourses (&mysql_res); + for (NumCrs = 0; + NumCrs < NumCrss; + NumCrs++) + { + /* Get next course */ + row = mysql_fetch_row (mysql_res); + + /* Get course code (row[0]) */ + if ((CrsCod = Str_ConvertStrCodToLongCod (row[0])) > 0) + { + if (Gbl.Usrs.Me.MyCrss.Num == Crs_MAX_COURSES_PER_USR) + Err_ShowErrorAndExit ("Maximum number of courses of a user exceeded."); + + Gbl.Usrs.Me.MyCrss.Crss[Gbl.Usrs.Me.MyCrss.Num].CrsCod = CrsCod; + + /* Get role (row[1]) and degree code (row[2]) */ + Gbl.Usrs.Me.MyCrss.Crss[Gbl.Usrs.Me.MyCrss.Num].Role = Rol_ConvertUnsignedStrToRole (row[1]); + Gbl.Usrs.Me.MyCrss.Crss[Gbl.Usrs.Me.MyCrss.Num].DegCod = Str_ConvertStrCodToLongCod (row[2]); + + Gbl.Usrs.Me.MyCrss.Num++; + } + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + /***** Set boolean that indicates that my courses are already filled *****/ + Gbl.Usrs.Me.MyCrss.Filled = true; + } + +/*****************************************************************************/ +/************************ Free the list of my courses ************************/ +/*****************************************************************************/ + +void Enr_FreeMyCourses (void) + { + if (Gbl.Usrs.Me.MyCrss.Filled) + { + /***** Reset list *****/ + Gbl.Usrs.Me.MyCrss.Filled = false; + Gbl.Usrs.Me.MyCrss.Num = 0; + + /***** Remove temporary table with my courses *****/ + Enr_DB_DropTmpTableMyCourses (); + } + } + +/*****************************************************************************/ +/*********************** Check if I belong to a course ***********************/ +/*****************************************************************************/ + +bool Enr_CheckIfIBelongToCrs (long CrsCod) + { + unsigned NumMyCrs; + + /***** Fill the list with the courses I belong to *****/ + Enr_GetMyCourses (); + + /***** Check if the course passed as parameter is any of my courses *****/ + for (NumMyCrs = 0; + NumMyCrs < Gbl.Usrs.Me.MyCrss.Num; + NumMyCrs++) + if (Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].CrsCod == CrsCod) + return true; + + return false; + } + +/*****************************************************************************/ +/******************** Check if a user belongs to a course ********************/ +/*****************************************************************************/ + +void Enr_FlushCacheUsrBelongsToCrs (void) + { + Gbl.Cache.UsrBelongsToCrs.UsrCod = -1L; + Gbl.Cache.UsrBelongsToCrs.CrsCod = -1L; + Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses = false; + Gbl.Cache.UsrBelongsToCrs.Belongs = false; + } + +bool Enr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod, + bool CountOnlyAcceptedCourses) + { + /***** 1. Fast check: Trivial cases *****/ + if (UsrCod <= 0 || + CrsCod <= 0) + return false; + + /***** 2. Fast check: If cached... *****/ + if (UsrCod == Gbl.Cache.UsrBelongsToCrs.UsrCod && + CrsCod == Gbl.Cache.UsrBelongsToCrs.CrsCod && + CountOnlyAcceptedCourses == Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses) + return Gbl.Cache.UsrBelongsToCrs.Belongs; + + /***** 3. Slow check: Get if user belongs to course from database *****/ + Gbl.Cache.UsrBelongsToCrs.UsrCod = UsrCod; + Gbl.Cache.UsrBelongsToCrs.CrsCod = CrsCod; + Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses = CountOnlyAcceptedCourses; + Gbl.Cache.UsrBelongsToCrs.Belongs = Enr_DB_CheckIfUsrBelongsToCrs (UsrCod,CrsCod, + CountOnlyAcceptedCourses); + return Gbl.Cache.UsrBelongsToCrs.Belongs; + } + +/*****************************************************************************/ +/***** Check if user belongs (no matter if he/she has accepted or not) *******/ +/***** to the current course *******/ +/*****************************************************************************/ + +void Enr_FlushCacheUsrBelongsToCurrentCrs (void) + { + Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = -1L; + Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = false; + } + +bool Enr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat) + { + /***** 1. Fast check: Trivial cases *****/ + if (UsrDat->UsrCod <= 0 || + Gbl.Hierarchy.Crs.CrsCod <= 0) + return false; + + /***** 2. Fast check: If cached... *****/ + if (UsrDat->UsrCod == Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod) + return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs; + + /***** 3. Fast check: If we know role of user in the current course *****/ + if (UsrDat->Roles.InCurrentCrs != Rol_UNK) + { + Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod; + Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = UsrDat->Roles.InCurrentCrs == Rol_STD || + UsrDat->Roles.InCurrentCrs == Rol_NET || + UsrDat->Roles.InCurrentCrs == Rol_TCH; + return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs; + } + + /***** 4. Fast / slow check: Get if user belongs to current course *****/ + Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod; + Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = Enr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod, + Gbl.Hierarchy.Crs.CrsCod, + false); + return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs; + } + +/*****************************************************************************/ +/***** Check if user belongs (no matter if he/she has accepted or not) *******/ +/***** to the current course *******/ +/*****************************************************************************/ + +void Enr_FlushCacheUsrHasAcceptedInCurrentCrs (void) + { + Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod = -1L; + Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted = false; + } + +bool Enr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat) + { + /***** 1. Fast check: Trivial cases *****/ + if (UsrDat->UsrCod <= 0 || + Gbl.Hierarchy.Crs.CrsCod <= 0) + return false; + + /***** 2. Fast check: If cached... *****/ + if (UsrDat->UsrCod == Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod) + return Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted; + + /***** 3. Fast / slow check: Get if user belongs to current course + and has accepted *****/ + Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod = UsrDat->UsrCod; + Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted = Enr_CheckIfUsrBelongsToCrs (UsrDat->UsrCod, + Gbl.Hierarchy.Crs.CrsCod, + true); + return Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted; + } + +/*****************************************************************************/ +/*************** Check if a user belongs to any of my courses ****************/ +/*****************************************************************************/ + +void Enr_FlushCacheUsrSharesAnyOfMyCrs (void) + { + Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = -1L; + Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = false; + } + +bool Enr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat) + { + bool ItsMe; + + /***** 1. Fast check: Am I logged? *****/ + if (!Gbl.Usrs.Me.Logged) + return false; + + /***** 2. Fast check: It is a valid user code? *****/ + if (UsrDat->UsrCod <= 0) + return false; + + /***** 3. Fast check: It's me? *****/ + ItsMe = Usr_ItsMe (UsrDat->UsrCod); + if (ItsMe) + return true; + + /***** 4. Fast check: Is already calculated if user shares any course with me? *****/ + if (UsrDat->UsrCod == Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod) + return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs; + + /***** 5. Fast check: Is course selected and we both belong to it? *****/ + if (Gbl.Usrs.Me.IBelongToCurrentCrs) + if (Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) // Course selected and we both belong to it + return true; + + /***** 6. Fast/slow check: Does he/she belong to any course? *****/ + Rol_GetRolesInAllCrss (UsrDat); + if (!(UsrDat->Roles.InCrss & ((1 << Rol_STD) | // Any of his/her roles is student + (1 << Rol_NET) | // or non-editing teacher + (1 << Rol_TCH)))) // or teacher? + return false; + + /***** 7. Slow check: Get if user shares any course with me from database *****/ + Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = UsrDat->UsrCod; + Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = Enr_DB_CheckIfUsrSharesAnyOfMyCrs (UsrDat->UsrCod); + return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs; + } diff --git a/swad_enrolment.h b/swad_enrolment.h index c0bb06c5..b616bc57 100644 --- a/swad_enrolment.h +++ b/swad_enrolment.h @@ -141,4 +141,17 @@ void Enr_CreateNewUsr2 (void); void Enr_ModifyUsr1 (void); void Enr_ModifyUsr2 (void); +void Enr_GetMyCourses (void); +void Enr_FreeMyCourses (void); +bool Enr_CheckIfIBelongToCrs (long CrsCod); +void Enr_FlushCacheUsrBelongsToCrs (void); +bool Enr_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod, + bool CountOnlyAcceptedCourses);; +void Enr_FlushCacheUsrBelongsToCurrentCrs (void); +bool Enr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat); +void Enr_FlushCacheUsrHasAcceptedInCurrentCrs (void); +bool Enr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat); +void Enr_FlushCacheUsrSharesAnyOfMyCrs (void); +bool Enr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat); + #endif diff --git a/swad_enrolment_database.c b/swad_enrolment_database.c index 1931af36..ef325805 100644 --- a/swad_enrolment_database.c +++ b/swad_enrolment_database.c @@ -92,6 +92,145 @@ void Enr_DB_AcceptUsrInCrs (long UsrCod,long CrsCod) UsrCod); } +/*****************************************************************************/ +/******************** Create temporary table with my courses *****************/ +/*****************************************************************************/ + +void Enr_DB_CreateTmpTableMyCourses (void) + { + DB_Query ("can not create temporary table", + "CREATE TEMPORARY TABLE IF NOT EXISTS my_courses_tmp" + " (CrsCod INT NOT NULL," + "Role TINYINT NOT NULL," + "DegCod INT NOT NULL," + "UNIQUE INDEX(CrsCod,Role,DegCod)) ENGINE=MEMORY" + " SELECT crs_users.CrsCod," + "crs_users.Role," + "crs_courses.DegCod" + " FROM crs_users," + "crs_courses," + "deg_degrees" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.CrsCod=crs_courses.CrsCod" + " AND crs_courses.DegCod=deg_degrees.DegCod" + " ORDER BY deg_degrees.ShortName," + "crs_courses.ShortName", + Gbl.Usrs.Me.UsrDat.UsrCod); + } + +/*****************************************************************************/ +/************************* Get my courses from database **********************/ +/*****************************************************************************/ + +unsigned Enr_DB_GetMyCourses (MYSQL_RES **mysql_res) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get which courses you belong to", + "SELECT CrsCod," // row[0] + "Role," // row[1] + "DegCod" // row[2] + " FROM my_courses_tmp"); + } + +/*****************************************************************************/ +/********************* Drop temporary table with my courses ******************/ +/*****************************************************************************/ + +void Enr_DB_DropTmpTableMyCourses (void) + { + DB_Query ("can not remove temporary table", + "DROP TEMPORARY TABLE IF EXISTS my_courses_tmp"); + } + +/*****************************************************************************/ +/******************** Check if a user belongs to a course ********************/ +/*****************************************************************************/ + +bool Enr_DB_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod, + bool CountOnlyAcceptedCourses) + { + const char *SubQuery = (CountOnlyAcceptedCourses ? " AND crs_users.Accepted='Y'" : // Only if user accepted + ""); + + return (DB_QueryCOUNT ("can not check if a user belongs to a course", + "SELECT COUNT(*)" + " FROM crs_users" + " WHERE CrsCod=%ld" + " AND UsrCod=%ld" + "%s", + CrsCod, + UsrCod, + SubQuery) != 0); + } + +/*****************************************************************************/ +/*************** Check if a user belongs to any of my courses ****************/ +/*****************************************************************************/ + +bool Enr_DB_CheckIfUsrSharesAnyOfMyCrs (long UsrCod) + { + /* Fill the list with the courses I belong to (if not already filled) */ + Enr_GetMyCourses (); + + /* Check if user shares any course with me */ + return (DB_QueryCOUNT ("can not check if a user shares any course with you", + "SELECT COUNT(*)" + " FROM crs_users" + " WHERE UsrCod=%ld" + " AND CrsCod IN" + " (SELECT CrsCod" + " FROM my_courses_tmp)", + UsrCod) != 0); + } + +/*****************************************************************************/ +/*** Check if a user belongs to any of my courses but has a different role ***/ +/*****************************************************************************/ + +bool Enr_DB_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod) + { + bool UsrSharesAnyOfMyCrsWithDifferentRole; + + /***** 1. Fast check: Am I logged? *****/ + if (!Gbl.Usrs.Me.Logged) + return false; + + /***** 2. Slow check: Get if user shares any course with me + with a different role, from database *****/ + /* Fill the list with the courses I belong to (if not already filled) */ + Enr_GetMyCourses (); + + /* Remove temporary table if exists */ + DB_Query ("can not remove temporary tables", + "DROP TEMPORARY TABLE IF EXISTS usr_courses_tmp"); + + /* Create temporary table with all user's courses for a role */ + DB_Query ("can not create temporary table", + "CREATE TEMPORARY TABLE IF NOT EXISTS usr_courses_tmp " + "(CrsCod INT NOT NULL,Role TINYINT NOT NULL," + "UNIQUE INDEX(CrsCod,Role)) ENGINE=MEMORY" + " SELECT CrsCod," + "Role" + " FROM crs_users" + " WHERE UsrCod=%ld", + UsrCod); + + /* Get if a user shares any course with me from database */ + UsrSharesAnyOfMyCrsWithDifferentRole = + (DB_QueryCOUNT ("can not check if a user shares any course with you", + "SELECT COUNT(*)" + " FROM my_courses_tmp," + "usr_courses_tmp" + " WHERE my_courses_tmp.CrsCod=usr_courses_tmp.CrsCod" + " AND my_courses_tmp.Role<>usr_courses_tmp.Role") != 0); + + /* Remove temporary table if exists */ + DB_Query ("can not remove temporary tables", + "DROP TEMPORARY TABLE IF EXISTS usr_courses_tmp"); + + return UsrSharesAnyOfMyCrsWithDifferentRole; + } + /*****************************************************************************/ /******** Get the user's code of a random student from current course ********/ /*****************************************************************************/ @@ -158,6 +297,445 @@ unsigned Enr_DB_GetTchsFromCurrentCrsExceptMe (MYSQL_RES **mysql_res) (unsigned) Rol_TCH); } +/*****************************************************************************/ +/********************* Get number of courses of a user ***********************/ +/*****************************************************************************/ + +unsigned Enr_DB_GetNumCrssOfUsr (long UsrCod) + { + return (unsigned) + DB_QueryCOUNT ("can not get the number of courses of a user", + "SELECT COUNT(*)" + " FROM crs_users" + " WHERE UsrCod=%ld", + UsrCod); + } + +/*****************************************************************************/ +/*************** Get number of courses of a user not accepted ****************/ +/*****************************************************************************/ + +unsigned Enr_DB_GetNumCrssOfUsrNotAccepted (long UsrCod) + { + return (unsigned) + DB_QueryCOUNT ("can not get the number of courses of a user", + "SELECT COUNT(*)" + " FROM crs_users" + " WHERE UsrCod=%ld" + " AND Accepted='N'", + UsrCod); + } + +/*****************************************************************************/ +/********* Get number of courses in with a user have a given role ************/ +/*****************************************************************************/ + +unsigned Enr_DB_GetNumCrssOfUsrWithARole (long UsrCod,Rol_Role_t Role) + { + return (unsigned) + DB_QueryCOUNT ("can not get the number of courses of a user with a role", + "SELECT COUNT(*)" + " FROM crs_users" + " WHERE UsrCod=%ld" + " AND Role=%u", + UsrCod, + (unsigned) Role); + } + +/*****************************************************************************/ +/********* Get number of courses in with a user have a given role ************/ +/*****************************************************************************/ + +unsigned Enr_DB_GetNumCrssOfUsrWithARoleNotAccepted (long UsrCod,Rol_Role_t Role) + { + return (unsigned) + DB_QueryCOUNT ("can not get the number of courses of a user with a role", + "SELECT COUNT(*)" + " FROM crs_users" + " WHERE UsrCod=%ld" + " AND Role=%u" + " AND Accepted='N'", + UsrCod, + (unsigned) Role); + } + +/*****************************************************************************/ +/****** Get number of users with some given roles in courses of a user *******/ +/*****************************************************************************/ + +#define Enr_DB_MAX_BYTES_ROLES_STR (Rol_NUM_ROLES * (Cns_MAX_DECIMAL_DIGITS_UINT + 1)) +unsigned Enr_DB_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole, + unsigned OthersRoles) + { + Rol_Role_t Role; + char UnsignedStr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; + char OthersRolesStr[Enr_DB_MAX_BYTES_ROLES_STR + 1]; + char SubQueryRole[64]; + unsigned NumUsrs; + // This query can be made in a unique, but slower, query + // The temporary table achieves speedup from ~2s to few ms + + /***** Remove temporary table if exists *****/ + DB_Query ("can not remove temporary tables", + "DROP TEMPORARY TABLE IF EXISTS usr_courses_tmp"); + + /***** Create temporary table with all user's courses + as student/non-editing teacher/teacher *****/ + switch (UsrRole) + { + case Rol_STD: // Student + sprintf (SubQueryRole," AND Role=%u", + (unsigned) Rol_STD); + break; + case Rol_NET: // Non-editing teacher + sprintf (SubQueryRole," AND Role=%u", + (unsigned) Rol_NET); + break; + case Rol_TCH: // or teacher + sprintf (SubQueryRole," AND Role=%u", + (unsigned) Rol_TCH); + break; + default: + SubQueryRole[0] = '\0'; + Err_WrongRoleExit (); + break; + } + DB_Query ("can not create temporary table", + "CREATE TEMPORARY TABLE IF NOT EXISTS usr_courses_tmp" + " (CrsCod INT NOT NULL,UNIQUE INDEX (CrsCod))" + " ENGINE=MEMORY" + " SELECT CrsCod" + " FROM crs_users" + " WHERE UsrCod=%ld" + "%s", + UsrCod,SubQueryRole); + + /***** Get the number of students/teachers in a course from database ******/ + OthersRolesStr[0] = '\0'; + for (Role = Rol_STD; // First possible role in a course + Role <= Rol_TCH; // Last possible role in a course + Role++) + if ((OthersRoles & (1 << Role))) + { + sprintf (UnsignedStr,"%u",(unsigned) Role); + if (OthersRolesStr[0]) // Not empty + Str_Concat (OthersRolesStr,",",sizeof (OthersRolesStr) - 1); + Str_Concat (OthersRolesStr,UnsignedStr,sizeof (OthersRolesStr) - 1); + } + NumUsrs = (unsigned) + DB_QueryCOUNT ("can not get number of users", + "SELECT COUNT(DISTINCT crs_users.UsrCod)" + " FROM crs_users," + "usr_courses_tmp" + " WHERE crs_users.CrsCod=usr_courses_tmp.CrsCod" + " AND crs_users.Role IN (%s)", + OthersRolesStr); + + /***** Remove temporary table *****/ + DB_Query ("can not remove temporary tables", + "DROP TEMPORARY TABLE IF EXISTS usr_courses_tmp"); + + return NumUsrs; + } + +/*****************************************************************************/ +/************ Get average number of courses with users of a type *************/ +/*****************************************************************************/ + +double Enr_DB_GetAverageNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) + { + switch (Scope) + { + case HieLvl_SYS: + if (Role == Rol_UNK) // Any user + return DB_QuerySELECTDouble ("can not get number of users per course", + "SELECT AVG(NumUsrs)" + " FROM (SELECT COUNT(UsrCod) AS NumUsrs" + " FROM crs_users" + " GROUP BY CrsCod) AS NumUsrsTable"); + else + return DB_QuerySELECTDouble ("can not get number of users per course", + "SELECT AVG(NumUsrs)" + " FROM (SELECT COUNT(UsrCod) AS NumUsrs" + " FROM crs_users" + " WHERE Role=%u GROUP BY CrsCod) AS NumUsrsTable", + (unsigned) Role); + case HieLvl_CTY: + if (Role == Rol_UNK) // Any user + return DB_QuerySELECTDouble ("can not get number of users per course", + "SELECT AVG(NumUsrs)" + " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" + " FROM ins_instits," + "ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ins_instits.CtyCod=%ld" + " AND ins_instits.InsCod=ctr_centers.InsCod" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " GROUP BY crs_users.CrsCod) AS NumUsrsTable", + Cod); + else + return DB_QuerySELECTDouble ("can not get number of users per course", + "SELECT AVG(NumUsrs)" + " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" + " FROM ins_instits," + "ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ins_instits.CtyCod=%ld" + " AND ins_instits.InsCod=ctr_centers.InsCod" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role=%u" + " GROUP BY crs_users.CrsCod) AS NumUsrsTable", + Cod, + (unsigned) Role); + case HieLvl_INS: + if (Role == Rol_UNK) // Any user + return DB_QuerySELECTDouble ("can not get number of users per course", + "SELECT AVG(NumUsrs)" + " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" + " FROM ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ctr_centers.InsCod=%ld" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " GROUP BY crs_users.CrsCod) AS NumUsrsTable", + Cod); + else + return DB_QuerySELECTDouble ("can not get number of users per course", + "SELECT AVG(NumUsrs)" + " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" + " FROM ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ctr_centers.InsCod=%ld" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role=%u" + " GROUP BY crs_users.CrsCod) AS NumUsrsTable", + Cod, + (unsigned) Role); + case HieLvl_CTR: + if (Role == Rol_UNK) // Any user + return DB_QuerySELECTDouble ("can not get number of users per course", + "SELECT AVG(NumUsrs)" + " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" + " FROM deg_degrees," + "crs_courses," + "crs_users" + " WHERE deg_degrees.CtrCod=%ld" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " GROUP BY crs_users.CrsCod) AS NumUsrsTable", + Cod); + else + return DB_QuerySELECTDouble ("can not get number of users per course", + "SELECT AVG(NumUsrs)" + " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" + " FROM deg_degrees," + "crs_courses," + "crs_users" + " WHERE deg_degrees.CtrCod=%ld" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role=%u" + " GROUP BY crs_users.CrsCod) AS NumUsrsTable", + Cod, + (unsigned) Role); + case HieLvl_DEG: + if (Role == Rol_UNK) // Any user + return DB_QuerySELECTDouble ("can not get number of users per course", + "SELECT AVG(NumUsrs)" + " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" + " FROM crs_courses," + "crs_users" + " WHERE crs_courses.DegCod=%ld" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " GROUP BY crs_users.CrsCod) AS NumUsrsTable", + Cod); + else + return DB_QuerySELECTDouble ("can not get number of users per course", + "SELECT AVG(NumUsrs)" + " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" + " FROM crs_courses," + "crs_users" + " WHERE crs_courses.DegCod=%ld" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role=%u" + " GROUP BY crs_users.CrsCod) AS NumUsrsTable", + Cod, + (unsigned) Role); + case HieLvl_CRS: + return (double) Usr_GetNumUsrsInCrss (HieLvl_CRS,Cod, + Role == Rol_UNK ? 1 << Rol_STD | + 1 << Rol_NET | + 1 << Rol_TCH : // Any user + 1 << Role); + + default: + Err_WrongScopeExit (); + return 0.0; // Not reached + } + } + +/*****************************************************************************/ +/************ Get average number of courses with users of a role *************/ +/*****************************************************************************/ + +double Enr_DB_GetAverageNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) + { + switch (Scope) + { + case HieLvl_SYS: + if (Role == Rol_UNK) // Any user + return DB_QuerySELECTDouble ("can not get number of courses per user", + "SELECT AVG(NumCrss)" + " FROM (SELECT COUNT(CrsCod) AS NumCrss" + " FROM crs_users" + " GROUP BY UsrCod) AS NumCrssTable"); + else + return DB_QuerySELECTDouble ("can not get number of courses per user", + "SELECT AVG(NumCrss)" + " FROM (SELECT COUNT(CrsCod) AS NumCrss" + " FROM crs_users" + " WHERE Role=%u" + " GROUP BY UsrCod) AS NumCrssTable", + (unsigned) Role); + case HieLvl_CTY: + if (Role == Rol_UNK) // Any user + return DB_QuerySELECTDouble ("can not get number of courses per user", + "SELECT AVG(NumCrss)" + " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" + " FROM ins_instits," + "ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ins_instits.CtyCod=%ld" + " AND ins_instits.InsCod=ctr_centers.InsCod" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " GROUP BY crs_users.UsrCod) AS NumCrssTable", + Cod); + else + return DB_QuerySELECTDouble ("can not get number of courses per user", + "SELECT AVG(NumCrss)" + " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" + " FROM ins_instits," + "ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ins_instits.CtyCod=%ld" + " AND ins_instits.InsCod=ctr_centers.InsCod" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role=%u" + " GROUP BY crs_users.UsrCod) AS NumCrssTable", + Cod, + (unsigned) Role); + case HieLvl_INS: + if (Role == Rol_UNK) // Any user + return DB_QuerySELECTDouble ("can not get number of courses per user", + "SELECT AVG(NumCrss)" + " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" + " FROM ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ctr_centers.InsCod=%ld" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " GROUP BY crs_users.UsrCod) AS NumCrssTable", + Cod); + else + return DB_QuerySELECTDouble ("can not get number of courses per user", + "SELECT AVG(NumCrss)" + " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" + " FROM ctr_centers," + "deg_degrees," + "crs_courses," + "crs_users" + " WHERE ctr_centers.InsCod=%ld" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role=%u" + " GROUP BY crs_users.UsrCod) AS NumCrssTable", + Cod, + (unsigned) Role); + case HieLvl_CTR: + if (Role == Rol_UNK) // Any user + return DB_QuerySELECTDouble ("can not get number of courses per user", + "SELECT AVG(NumCrss)" + " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" + " FROM deg_degrees," + "crs_courses," + "crs_users" + " WHERE deg_degrees.CtrCod=%ld" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " GROUP BY crs_users.UsrCod) AS NumCrssTable", + Cod); + else + return DB_QuerySELECTDouble ("can not get number of courses per user", + "SELECT AVG(NumCrss)" + " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" + " FROM deg_degrees," + "crs_courses," + "crs_users" + " WHERE deg_degrees.CtrCod=%ld" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role=%u" + " GROUP BY crs_users.UsrCod) AS NumCrssTable", + Cod, + (unsigned) Role); + case HieLvl_DEG: + if (Role == Rol_UNK) // Any user + return DB_QuerySELECTDouble ("can not get number of courses per user", + "SELECT AVG(NumCrss)" + " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" + " FROM crs_courses," + "crs_users" + " WHERE crs_courses.DegCod=%ld" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " GROUP BY crs_users.UsrCod) AS NumCrssTable", + Cod); + else + return DB_QuerySELECTDouble ("can not get number of courses per user", + "SELECT AVG(NumCrss)" + " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" + " FROM crs_courses," + "crs_users" + " WHERE crs_courses.DegCod=%ld" + " AND crs_courses.CrsCod=crs_users.CrsCod" + " AND crs_users.Role=%u" + " GROUP BY crs_users.UsrCod) AS NumCrssTable", + Cod, + (unsigned) Role); + case HieLvl_CRS: + return 1.0; + default: + Err_WrongScopeExit (); + return 0.0; // Not reached + } + } + /*****************************************************************************/ /************************** Remove user from course **************************/ /*****************************************************************************/ @@ -196,6 +774,42 @@ void Enr_DB_RemAllUsrsFromCrs (long CrsCod) CrsCod); } +/*****************************************************************************/ +/************ Create my enrolment request in the current course **************/ +/*****************************************************************************/ + +long Enr_DB_CreateMyEnrolmentRequestInCurrentCrs (Rol_Role_t NewRole) + { + return + DB_QueryINSERTandReturnCode ("can not save enrolment request", + "INSERT INTO crs_requests" + " (CrsCod,UsrCod,Role,RequestTime)" + " VALUES" + " (%ld,%ld,%u,NOW())", + Gbl.Hierarchy.Crs.CrsCod, + Gbl.Usrs.Me.UsrDat.UsrCod, + (unsigned) NewRole); + } + +/*****************************************************************************/ +/************* Update my enrolment request in the current course *************/ +/*****************************************************************************/ + +void Enr_DB_UpdateMyEnrolmentRequestInCurrentCrs (long ReqCod,Rol_Role_t NewRole) + { + DB_QueryUPDATE ("can not update enrolment request", + "UPDATE crs_requests" + " SET Role=%u," + "RequestTime=NOW()" + " WHERE ReqCod=%ld" + " AND CrsCod=%ld" + " AND UsrCod=%ld", + (unsigned) NewRole, + ReqCod, + Gbl.Hierarchy.Crs.CrsCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + } + /*****************************************************************************/ /********* Set a user's acceptation to true in the current course ************/ /*****************************************************************************/ @@ -761,42 +1375,6 @@ long Enr_DB_GetUsrEnrolmentRequestInCrs (long UsrCod,long CrsCod) UsrCod); } -/*****************************************************************************/ -/************ Create my enrolment request in the current course **************/ -/*****************************************************************************/ - -long Enr_DB_CreateMyEnrolmentRequestInCurrentCrs (Rol_Role_t NewRole) - { - return - DB_QueryINSERTandReturnCode ("can not save enrolment request", - "INSERT INTO crs_requests" - " (CrsCod,UsrCod,Role,RequestTime)" - " VALUES" - " (%ld,%ld,%u,NOW())", - Gbl.Hierarchy.Crs.CrsCod, - Gbl.Usrs.Me.UsrDat.UsrCod, - (unsigned) NewRole); - } - -/*****************************************************************************/ -/************* Update my enrolment request in the current course *************/ -/*****************************************************************************/ - -void Enr_DB_UpdateMyEnrolmentRequestInCurrentCrs (long ReqCod,Rol_Role_t NewRole) - { - DB_QueryUPDATE ("can not update enrolment request", - "UPDATE crs_requests" - " SET Role=%u," - "RequestTime=NOW()" - " WHERE ReqCod=%ld" - " AND CrsCod=%ld" - " AND UsrCod=%ld", - (unsigned) NewRole, - ReqCod, - Gbl.Hierarchy.Crs.CrsCod, - Gbl.Usrs.Me.UsrDat.UsrCod); - } - /*****************************************************************************/ /************************** Remove enrolment request *************************/ /*****************************************************************************/ diff --git a/swad_enrolment_database.h b/swad_enrolment_database.h index 52cc6d3c..f36768b7 100644 --- a/swad_enrolment_database.h +++ b/swad_enrolment_database.h @@ -42,24 +42,44 @@ /****************************** Public prototypes ****************************/ /*****************************************************************************/ +//------------------------------ Users in courses ----------------------------- void Enr_DB_InsertUsrInCurrentCrs (long UsrCod,long CrsCod,Rol_Role_t NewRole, Enr_KeepOrSetAccepted_t KeepOrSetAccepted); void Enr_DB_AcceptUsrInCrs (long UsrCod,long CrsCod); +void Enr_DB_CreateTmpTableMyCourses (void); +unsigned Enr_DB_GetMyCourses (MYSQL_RES **mysql_res); +void Enr_DB_DropTmpTableMyCourses (void); + +bool Enr_DB_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod, + bool CountOnlyAcceptedCourses); +bool Enr_DB_CheckIfUsrSharesAnyOfMyCrs (long UsrCod); +bool Enr_DB_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod); long Enr_DB_GetRamdomStdFromCrs (long CrsCod); unsigned Enr_DB_GetUsrsFromCurrentCrs (MYSQL_RES **mysql_res); unsigned Enr_DB_GetUsrsFromCurrentCrsExceptMe (MYSQL_RES **mysql_res); unsigned Enr_DB_GetTchsFromCurrentCrsExceptMe (MYSQL_RES **mysql_res); +unsigned Enr_DB_GetNumCrssOfUsr (long UsrCod); +unsigned Enr_DB_GetNumCrssOfUsrNotAccepted (long UsrCod); +unsigned Enr_DB_GetNumCrssOfUsrWithARole (long UsrCod,Rol_Role_t Role); +unsigned Enr_DB_GetNumCrssOfUsrWithARoleNotAccepted (long UsrCod,Rol_Role_t Role); +unsigned Enr_DB_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole, + unsigned OthersRoles); +double Enr_DB_GetAverageNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); +double Enr_DB_GetAverageNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); void Enr_DB_RemUsrFromCrs (long UsrCod,long CrsCod); void Enr_DB_RemUsrFromAllCrss (long UsrCod); void Enr_DB_RemAllUsrsFromCrs (long CrsCod); +//-------------------------- Enrolment requests ------------------------------- +long Enr_DB_CreateMyEnrolmentRequestInCurrentCrs (Rol_Role_t NewRole); +void Enr_DB_UpdateMyEnrolmentRequestInCurrentCrs (long ReqCod,Rol_Role_t NewRole); + unsigned Enr_DB_GetEnrolmentRequests (MYSQL_RES **mysql_res,unsigned RolesSelected); unsigned Enr_DB_GetEnrolmentRequestByCod (MYSQL_RES **mysql_res,long ReqCod); long Enr_DB_GetUsrEnrolmentRequestInCrs (long UsrCod,long CrsCod); -long Enr_DB_CreateMyEnrolmentRequestInCurrentCrs (Rol_Role_t NewRole); -void Enr_DB_UpdateMyEnrolmentRequestInCurrentCrs (long ReqCod,Rol_Role_t NewRole); + void Enr_DB_RemRequest (long ReqCod); void Enr_DB_RemCrsRequests (long CrsCod); void Enr_DB_RemUsrRequests (long UsrCod); diff --git a/swad_exam_result.c b/swad_exam_result.c index 3954769b..763286dd 100644 --- a/swad_exam_result.c +++ b/swad_exam_result.c @@ -382,7 +382,7 @@ static void ExaRes_ListAllResultsInSelectedExams (struct Exa_Exams *Exams) if (Usr_CheckIfICanViewTstExaMchResult (&Gbl.Usrs.Other.UsrDat)) { /***** Show sessions results *****/ - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); ExaRes_ShowResults (Exams,Usr_OTHER,-1L,-1L,ExamsSelectedCommas); } } @@ -453,7 +453,7 @@ static void ExaRes_ListAllResultsInExa (struct Exa_Exams *Exams,long ExaCod) if (Usr_CheckIfICanViewTstExaMchResult (&Gbl.Usrs.Other.UsrDat)) { /***** Show sessions results *****/ - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); ExaRes_ShowResults (Exams,Usr_OTHER,-1L,ExaCod,NULL); } @@ -530,7 +530,7 @@ static void ExaRes_ListAllResultsInSes (struct Exa_Exams *Exams,long SesCod) if (Usr_CheckIfICanViewTstExaMchResult (&Gbl.Usrs.Other.UsrDat)) { /***** Show sessions results *****/ - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); ExaRes_ShowResults (Exams,Usr_OTHER,SesCod,-1L,NULL); } diff --git a/swad_figure.c b/swad_figure.c index 3926de61..d013d122 100644 --- a/swad_figure.c +++ b/swad_figure.c @@ -65,6 +65,7 @@ #include "swad_project.h" #include "swad_project_database.h" #include "swad_role.h" +#include "swad_setting.h" #include "swad_survey.h" #include "swad_survey_database.h" #include "swad_test.h" @@ -978,7 +979,7 @@ static void Fig_GetAndShowInstitutionsStats (void) Hlp_ANALYTICS_Figures_institutions,Box_NOT_CLOSABLE); /***** Form to select type of list used to display degree photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); Figures.Scope = Gbl.Scope.Current; Figures.FigureType = Fig_INSTITS; Usr_ShowFormsToSelectUsrListType (Fig_PutHiddenParamFigures,&Figures); @@ -1171,7 +1172,7 @@ static void Fig_ShowInss (MYSQL_RES **mysql_res,unsigned NumInss, /* Draw the classphoto/list */ switch (Gbl.Usrs.Me.ListType) { - case Usr_LIST_AS_CLASS_PHOTO: + case Set_USR_LIST_AS_CLASS_PHOTO: /***** Draw institutions as a class photo *****/ for (NumIns = 0; NumIns < NumInss;) @@ -1202,7 +1203,7 @@ static void Fig_ShowInss (MYSQL_RES **mysql_res,unsigned NumInss, HTM_TR_End (); break; - case Usr_LIST_AS_LISTING: + case Set_USR_LIST_AS_LISTING: /***** Draw institutions as a list *****/ HTM_TR_Begin (NULL); HTM_TH_Empty (1); diff --git a/swad_follow.c b/swad_follow.c index 11e79486..a03d7d30 100644 --- a/swad_follow.c +++ b/swad_follow.c @@ -973,7 +973,7 @@ static void Fol_GetFollowedFromSelectedUsrs (unsigned *NumFollowed, if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat, Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) // Get from the database the data of the student - if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) { /* Check if I follow this user, and update number of users */ if (Fol_DB_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, @@ -1021,7 +1021,7 @@ void Fol_FollowUsrs () if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat, // Get user's data from database Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) - if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) /* If I don't follow this user ==> follow him/her */ if (!Fol_DB_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, UsrDat.UsrCod)) @@ -1070,7 +1070,7 @@ void Fol_UnfollowUsrs (void) if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat, // Get user's data from database Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) - if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) /* If I follow this user ==> unfollow him/her */ if (Fol_DB_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, UsrDat.UsrCod)) diff --git a/swad_global.c b/swad_global.c index c070141f..f4529bee 100644 --- a/swad_global.c +++ b/swad_global.c @@ -335,10 +335,10 @@ void Gbl_InitializeGlobals (void) Ins_FlushCacheUsrBelongsToIns (); Ctr_FlushCacheUsrBelongsToCtr (); Deg_FlushCacheUsrBelongsToDeg (); - Crs_FlushCacheUsrBelongsToCrs (); - Usr_FlushCacheUsrBelongsToCurrentCrs (); - Usr_FlushCacheUsrHasAcceptedInCurrentCrs (); - Usr_FlushCacheUsrSharesAnyOfMyCrs (); + Enr_FlushCacheUsrBelongsToCrs (); + Enr_FlushCacheUsrBelongsToCurrentCrs (); + Enr_FlushCacheUsrHasAcceptedInCurrentCrs (); + Enr_FlushCacheUsrSharesAnyOfMyCrs (); Rol_FlushCacheMyRoleInCurrentCrs (); Rol_FlushCacheRoleUsrInCrs (); Prj_FlushCacheMyRolesInProject (); @@ -359,7 +359,7 @@ void Gbl_Cleanup (void) !Gbl.WebService.IsWebService && Act_GetBrowserTab (Gbl.Action.Act) == Act_BRW_1ST_TAB) Ses_DB_RemoveParam (); - Crs_FreeMyCourses (); + Enr_FreeMyCourses (); Deg_FreeMyDegrees (); Ctr_FreeMyCenters (); Ins_FreeMyInstits (); diff --git a/swad_global.h b/swad_global.h index 415bfd5c..a7e95727 100644 --- a/swad_global.h +++ b/swad_global.h @@ -59,6 +59,7 @@ #include "swad_record.h" #include "swad_search.h" #include "swad_session.h" +#include "swad_setting.h" /*****************************************************************************/ /***************************** Public constants ******************************/ @@ -313,7 +314,7 @@ struct Globals long DegCod; } Crss[Crs_MAX_COURSES_PER_USR]; } MyCrss; - Usr_ShowUsrsType_t ListType; // My preference about user's list type + Set_ShowUsrsType_t ListType; // My preference about user's list type unsigned NumFollowers; // Number of users who follow me unsigned NumFollowing; // Number of users I follow } Me; // The user logged diff --git a/swad_group.c b/swad_group.c index 5888b46d..a37ffb54 100644 --- a/swad_group.c +++ b/swad_group.c @@ -392,7 +392,7 @@ void Grp_ShowFormToSelectSeveralGroups (void (*FuncParams) (void *Args),void *Ar depending on the groups selected *****/ Frm_BeginFormAnchor (Gbl.Action.Act, // Repeat current action Usr_USER_LIST_SECTION_ID); - Usr_PutParamsPrefsAboutUsrList (); + Set_PutParamsPrefsAboutUsrList (); if (FuncParams) FuncParams (Args); @@ -3059,7 +3059,7 @@ bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat) return Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares; /***** 7. Fast / slow check: Does he/she belong to the current course? *****/ - if (!Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) + if (!Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) { Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod = UsrDat->UsrCod; Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares = false; diff --git a/swad_institution.c b/swad_institution.c index c55bef25..9ca03030 100644 --- a/swad_institution.c +++ b/swad_institution.c @@ -1982,3 +1982,115 @@ static void Ins_FormToGoToMap (struct Ins_Instit *Ins) Txt_Map); } } + +/*****************************************************************************/ +/** Get all my institutions (those of my courses) and store them in a list ***/ +/*****************************************************************************/ + +void Ins_GetMyInstits (void) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumIns; + unsigned NumInss; + long InsCod; + + /***** If my institutions are yet filled, there's nothing to do *****/ + if (!Gbl.Usrs.Me.MyInss.Filled) + { + Gbl.Usrs.Me.MyInss.Num = 0; + + /***** Get my institutions from database *****/ + NumInss = Ins_DB_GetInssFromUsr (&mysql_res, + Gbl.Usrs.Me.UsrDat.UsrCod,-1L); + for (NumIns = 0; + NumIns < NumInss; + NumIns++) + { + /* Get next institution */ + row = mysql_fetch_row (mysql_res); + + /* Get institution code */ + if ((InsCod = Str_ConvertStrCodToLongCod (row[0])) > 0) + { + if (Gbl.Usrs.Me.MyInss.Num == Ins_MAX_INSTITS_PER_USR) + Err_ShowErrorAndExit ("Maximum number of institutions of a user exceeded."); + + Gbl.Usrs.Me.MyInss.Inss[Gbl.Usrs.Me.MyInss.Num].InsCod = InsCod; + Gbl.Usrs.Me.MyInss.Inss[Gbl.Usrs.Me.MyInss.Num].MaxRole = Rol_ConvertUnsignedStrToRole (row[1]); + + Gbl.Usrs.Me.MyInss.Num++; + } + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + /***** Set boolean that indicates that my institutions are yet filled *****/ + Gbl.Usrs.Me.MyInss.Filled = true; + } + } + +/*****************************************************************************/ +/********************* Free the list of my institutions **********************/ +/*****************************************************************************/ + +void Ins_FreeMyInstits (void) + { + if (Gbl.Usrs.Me.MyInss.Filled) + { + /***** Reset list *****/ + Gbl.Usrs.Me.MyInss.Filled = false; + Gbl.Usrs.Me.MyInss.Num = 0; + } + } + +/*****************************************************************************/ +/******************** Check if I belong to an institution ********************/ +/*****************************************************************************/ + +bool Ins_CheckIfIBelongToIns (long InsCod) + { + unsigned NumMyIns; + + /***** Fill the list with the institutions I belong to *****/ + Ins_GetMyInstits (); + + /***** Check if the institution passed as parameter is any of my institutions *****/ + for (NumMyIns = 0; + NumMyIns < Gbl.Usrs.Me.MyInss.Num; + NumMyIns++) + if (Gbl.Usrs.Me.MyInss.Inss[NumMyIns].InsCod == InsCod) + return true; + return false; + } + +/*****************************************************************************/ +/**************** Check if a user belongs to an institution ******************/ +/*****************************************************************************/ + +void Ins_FlushCacheUsrBelongsToIns (void) + { + Gbl.Cache.UsrBelongsToIns.UsrCod = -1L; + Gbl.Cache.UsrBelongsToIns.InsCod = -1L; + Gbl.Cache.UsrBelongsToIns.Belongs = false; + } + +bool Ins_CheckIfUsrBelongsToIns (long UsrCod,long InsCod) + { + /***** 1. Fast check: Trivial case *****/ + if (UsrCod <= 0 || + InsCod <= 0) + return false; + + /***** 2. Fast check: If cached... *****/ + if (UsrCod == Gbl.Cache.UsrBelongsToIns.UsrCod && + InsCod != Gbl.Cache.UsrBelongsToIns.InsCod) + return Gbl.Cache.UsrBelongsToIns.Belongs; + + /***** 3. Slow check: Get is user belongs to institution from database *****/ + Gbl.Cache.UsrBelongsToIns.UsrCod = UsrCod; + Gbl.Cache.UsrBelongsToIns.InsCod = InsCod; + Gbl.Cache.UsrBelongsToIns.Belongs = Ins_DB_CheckIfUsrBelongsToIns (UsrCod,InsCod); + return Gbl.Cache.UsrBelongsToIns.Belongs; + } diff --git a/swad_institution.h b/swad_institution.h index 18332fc0..49fc709e 100644 --- a/swad_institution.h +++ b/swad_institution.h @@ -135,4 +135,10 @@ unsigned Ins_GetCachedNumInssWithUsrs (Rol_Role_t Role); void Ins_ListInssFound (MYSQL_RES **mysql_res,unsigned NumInss); +void Ins_GetMyInstits (void); +void Ins_FreeMyInstits (void); +bool Ins_CheckIfIBelongToIns (long InsCod); +void Ins_FlushCacheUsrBelongsToIns (void); +bool Ins_CheckIfUsrBelongsToIns (long UsrCod,long InsCod); + #endif diff --git a/swad_institution_database.c b/swad_institution_database.c index 05cf2a33..89fceef5 100644 --- a/swad_institution_database.c +++ b/swad_institution_database.c @@ -800,6 +800,28 @@ unsigned Ins_DB_GetInssFromUsr (MYSQL_RES **mysql_res,long UsrCod,long CtyCod) UsrCod); } +/*****************************************************************************/ +/**************** Check if a user belongs to an institution ******************/ +/*****************************************************************************/ + +bool Ins_DB_CheckIfUsrBelongsToIns (long UsrCod,long InsCod) + { + return (DB_QueryCOUNT ("can not check if a user belongs to an institution", + "SELECT COUNT(DISTINCT ctr_centers.InsCod)" + " FROM crs_users," + "crs_courses," + "deg_degrees," + "ctr_centers" + " WHERE crs_users.UsrCod=%ld" + " AND crs_users.Accepted='Y'" // Only if user accepted + " AND crs_users.CrsCod=crs_courses.CrsCod" + " AND crs_courses.DegCod=deg_degrees.DegCod" + " AND deg_degrees.CtrCod=ctr_centers.CtrCod" + " AND ctr_centers.InsCod=%ld", + UsrCod, + InsCod) != 0); + } + /*****************************************************************************/ /***************************** Remove institution ****************************/ /*****************************************************************************/ diff --git a/swad_institution_database.h b/swad_institution_database.h index 38a29848..0ab62cf4 100644 --- a/swad_institution_database.h +++ b/swad_institution_database.h @@ -81,6 +81,7 @@ unsigned Ins_DB_GetNumInnsWithUsrs (Rol_Role_t Role, HieLvl_Level_t Scope,long Cod); unsigned Ins_DB_GetInssFromUsr (MYSQL_RES **mysql_res,long UsrCod,long CtyCod); +bool Ins_DB_CheckIfUsrBelongsToIns (long UsrCod,long InsCod); void Ins_DB_RemoveInstitution (long InsCod); diff --git a/swad_mail.c b/swad_mail.c index 22849433..50da19d8 100644 --- a/swad_mail.c +++ b/swad_mail.c @@ -840,7 +840,7 @@ static void Mai_ListEmails (__attribute__((unused)) void *Args) NumUsrsWithEmail++; /* Check if users has accepted inscription in current course */ - UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); + UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); if (UsrDat.Accepted) // If student has email and has accepted { @@ -1676,7 +1676,7 @@ bool Mai_ICanSeeOtherUsrEmail (const struct UsrData *UsrDat) case Rol_TCH: /* If I am a teacher in the current course, I can see the email of confirmed students and teachers */ - return Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat) && // A user belonging to the current course + return Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat) && // A user belonging to the current course UsrDat->Accepted; // who accepted registration case Rol_DEG_ADM: /* If I am an administrator of current degree, diff --git a/swad_match_result.c b/swad_match_result.c index 6ae860e3..8fce18ab 100644 --- a/swad_match_result.c +++ b/swad_match_result.c @@ -319,7 +319,7 @@ static void MchRes_ListAllMchResultsInSelectedGames (struct Gam_Games *Games) if (Usr_CheckIfICanViewTstExaMchResult (&Gbl.Usrs.Other.UsrDat)) { /***** Show matches results *****/ - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); MchRes_ShowMchResults (Games,Usr_OTHER,-1L,-1L,GamesSelectedCommas); } } @@ -419,7 +419,7 @@ static void MchRes_ListAllMchResultsInGam (struct Gam_Games *Games,long GamCod) if (Usr_CheckIfICanViewTstExaMchResult (&Gbl.Usrs.Other.UsrDat)) { /***** Show matches results *****/ - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); MchRes_ShowMchResults (Games,Usr_OTHER,-1L,GamCod,NULL); } @@ -494,7 +494,7 @@ static void MchRes_ListAllMchResultsInMch (struct Gam_Games *Games,long MchCod) if (Usr_CheckIfICanViewTstExaMchResult (&Gbl.Usrs.Other.UsrDat)) { /***** Show matches results *****/ - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); MchRes_ShowMchResults (Games,Usr_OTHER,MchCod,-1L,NULL); } diff --git a/swad_message.c b/swad_message.c index 7f1c8d74..175a03ee 100644 --- a/swad_message.c +++ b/swad_message.c @@ -59,6 +59,7 @@ #include "swad_profile.h" #include "swad_profile_database.h" #include "swad_session_database.h" +#include "swad_setting.h" #include "swad_user.h" /*****************************************************************************/ @@ -258,7 +259,7 @@ static void Msg_PutFormMsgUsrs (struct Msg_Messages *Messages, /***** Get and update type of list, number of columns in class photo and preference about view photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get groups to show ******/ Grp_GetParCodsSeveralGrpsToShowUsrs (); diff --git a/swad_photo.c b/swad_photo.c index 6a242d88..89a8a362 100644 --- a/swad_photo.c +++ b/swad_photo.c @@ -166,7 +166,7 @@ bool Pho_ICanChangeOtherUsrPhoto (struct UsrData *UsrDat) /* It's a student in this course, check if he/she has accepted registration */ - UsrDat->Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (UsrDat); + UsrDat->Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (UsrDat); return UsrDat->Accepted; case Rol_DEG_ADM: case Rol_CTR_ADM: @@ -1604,7 +1604,7 @@ static void Pho_ShowOrPrintPhotoDegree (Pho_AvgPhotoSeeOrPrint_t SeeOrPrint) /***** Get and update type of list, number of columns in class photo and preference about view photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); switch (SeeOrPrint) { @@ -1647,10 +1647,10 @@ static void Pho_ShowOrPrintPhotoDegree (Pho_AvgPhotoSeeOrPrint_t SeeOrPrint) /***** Draw the classphoto/list *****/ switch (Gbl.Usrs.Me.ListType) { - case Usr_LIST_AS_CLASS_PHOTO: + case Set_USR_LIST_AS_CLASS_PHOTO: Pho_ShowOrPrintClassPhotoDegrees (&DegPhotos,SeeOrPrint); break; - case Usr_LIST_AS_LISTING: + case Set_USR_LIST_AS_LISTING: Pho_ShowOrPrintListDegrees (&DegPhotos,SeeOrPrint); break; default: @@ -1698,7 +1698,7 @@ static void Pho_PutSelectorForTypeOfAvg (const struct Pho_DegPhotos *DegPhotos) Frm_BeginForm (ActSeePhoDeg); Pho_PutHiddenParamPhotoSize (DegPhotos->HowComputePhotoSize); Pho_PutHiddenParamOrderDegrees (DegPhotos->HowOrderDegrees); - Usr_PutParamsPrefsAboutUsrList (); + Set_PutParamsPrefsAboutUsrList (); HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE, "id=\"AvgType\" name=\"AvgType\""); for (TypeOfAvg = (Pho_AvgPhotoTypeOfAverage_t) 0; @@ -1762,7 +1762,7 @@ static void Pho_PutSelectorForHowComputePhotoSize (const struct Pho_DegPhotos *D Frm_BeginForm (ActSeePhoDeg); Pho_PutHiddenParamTypeOfAvg (DegPhotos->TypeOfAverage); Pho_PutHiddenParamOrderDegrees (DegPhotos->HowOrderDegrees); - Usr_PutParamsPrefsAboutUsrList (); + Set_PutParamsPrefsAboutUsrList (); HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE, "id=\"PhotoSize\" name=\"PhotoSize\""); for (PhoSi = (Pho_HowComputePhotoSize_t) 0; @@ -1826,7 +1826,7 @@ static void Pho_PutSelectorForHowOrderDegrees (const struct Pho_DegPhotos *DegPh Frm_BeginForm (ActSeePhoDeg); Pho_PutHiddenParamTypeOfAvg (DegPhotos->TypeOfAverage); Pho_PutHiddenParamPhotoSize (DegPhotos->HowComputePhotoSize); - Usr_PutParamsPrefsAboutUsrList (); + Set_PutParamsPrefsAboutUsrList (); HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE, "id=\"Order\" name=\"Order\""); for (Order = (Pho_HowOrderDegrees_t) 0; @@ -1882,7 +1882,7 @@ static void Pho_PutLinkToPrintViewOfDegreeStatsParams (void *DegPhotos) Pho_PutHiddenParamTypeOfAvg (((struct Pho_DegPhotos *) DegPhotos)->TypeOfAverage); Pho_PutHiddenParamPhotoSize (((struct Pho_DegPhotos *) DegPhotos)->HowComputePhotoSize); Pho_PutHiddenParamOrderDegrees (((struct Pho_DegPhotos *) DegPhotos)->HowOrderDegrees); - Usr_PutParamsPrefsAboutUsrList (); + Set_PutParamsPrefsAboutUsrList (); } /*****************************************************************************/ @@ -1919,7 +1919,7 @@ static void Pho_PutLinkToCalculateDegreeStats (const struct Pho_DegPhotos *DegPh Pho_PutHiddenParamTypeOfAvg (DegPhotos->TypeOfAverage); Pho_PutHiddenParamPhotoSize (DegPhotos->HowComputePhotoSize); Pho_PutHiddenParamOrderDegrees (DegPhotos->HowOrderDegrees); - Usr_PutParamsPrefsAboutUsrList (); + Set_PutParamsPrefsAboutUsrList (); HTM_BUTTON_Animated_Begin (Txt_Calculate_average_photo_of_THE_DEGREE_X, The_ClassFormLinkInBoxBold[Gbl.Prefs.Theme], diff --git a/swad_privacy.c b/swad_privacy.c index cf7c7dce..cd7be2c4 100644 --- a/swad_privacy.c +++ b/swad_privacy.c @@ -29,6 +29,7 @@ #include "swad_action.h" #include "swad_box.h" +#include "swad_enrolment_database.h" #include "swad_figure.h" #include "swad_form.h" #include "swad_global.h" @@ -259,10 +260,10 @@ bool Pri_ShowingIsAllowed (Pri_Visibility_t Visibility,struct UsrData *UsrDat) // by me and my teachers if I am a student // or me and my students if I am a teacher // Do both users share the same course but whit different role? - return Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (UsrDat->UsrCod); + return Enr_DB_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (UsrDat->UsrCod); case Pri_VISIBILITY_COURSE: // Visible by users sharing courses with me // Do both users share the same course? - return Usr_CheckIfUsrSharesAnyOfMyCrs (UsrDat); + return Enr_CheckIfUsrSharesAnyOfMyCrs (UsrDat); case Pri_VISIBILITY_SYSTEM: // Visible by any user logged in platform return Gbl.Usrs.Me.Logged; case Pri_VISIBILITY_WORLD: // Public, visible by everyone, even unlogged visitors diff --git a/swad_profile.c b/swad_profile.c index 9f21b5be..ba58c7e7 100644 --- a/swad_profile.c +++ b/swad_profile.c @@ -35,6 +35,7 @@ #include "swad_browser_database.h" #include "swad_config.h" #include "swad_database.h" +#include "swad_enrolment_database.h" #include "swad_error.h" #include "swad_figure.h" #include "swad_follow_database.h" @@ -321,7 +322,7 @@ bool Prf_ShowUserProfile (struct UsrData *UsrDat) Gbl.Hierarchy.Crs.CrsCod); /* Get if user has accepted enrolment in current course */ - UsrDat->Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (UsrDat); + UsrDat->Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (UsrDat); } Rec_ShowSharedUsrRecord (Rec_SHA_RECORD_PUBLIC,UsrDat,NULL); @@ -420,7 +421,7 @@ void Prf_ShowDetailsUserProfile (const struct UsrData *UsrDat) /***** Right list *****/ HTM_DIV_Begin ("class=\"PRF_FIG_RIGHT_CONT\""); - UsrIsBannedFromRanking = Usr_DB_CheckIfUsrBanned (UsrDat->UsrCod); + UsrIsBannedFromRanking = Prf_DB_CheckIfUsrBanned (UsrDat->UsrCod); if (!UsrIsBannedFromRanking) { /* Begin right list */ @@ -527,7 +528,7 @@ static void Prf_ShowNumCrssWithRole (const struct UsrData *UsrDat, unsigned NumCrss; /***** Number of courses in which the user has a given role *****/ - NumCrss = Usr_DB_GetNumCrssOfUsrWithARole (UsrDat->UsrCod,Role); + NumCrss = Enr_DB_GetNumCrssOfUsrWithARole (UsrDat->UsrCod,Role); Prf_BeginListItem (Txt_ROLES_SINGUL_Abc[Role][UsrDat->Sex],Rol_Icons[Role]); @@ -535,11 +536,11 @@ static void Prf_ShowNumCrssWithRole (const struct UsrData *UsrDat, if (NumCrss) HTM_TxtF (" (%u %s/%u %s)", - Usr_GetNumUsrsInCrssOfAUsr (UsrDat->UsrCod,Role, + Enr_DB_GetNumUsrsInCrssOfAUsr (UsrDat->UsrCod,Role, (1 << Rol_NET) | (1 << Rol_TCH)), Txt_teachers_ABBREVIATION, - Usr_GetNumUsrsInCrssOfAUsr (UsrDat->UsrCod,Role, + Enr_DB_GetNumUsrsInCrssOfAUsr (UsrDat->UsrCod,Role, (1 << Rol_STD)), Txt_students_ABBREVIATION); diff --git a/swad_profile_database.c b/swad_profile_database.c index 3e1788e1..21223d19 100644 --- a/swad_profile_database.c +++ b/swad_profile_database.c @@ -566,7 +566,9 @@ unsigned Prf_DB_GetRankingClicksPerDay (MYSQL_RES **mysql_res) " AND crs_users.UsrCod=usr_figures.UsrCod" " AND usr_figures.NumClicks>0" " AND usr_figures.FirstClickTime>FROM_UNIXTIME(0)" - " AND usr_figures.UsrCod NOT IN (SELECT UsrCod FROM usr_banned)" + " AND usr_figures.UsrCod NOT IN" + " (SELECT UsrCod" + " FROM usr_banned)" " ORDER BY NumClicksPerDay DESC," "usr_figures.UsrCod" " LIMIT 100", @@ -666,6 +668,19 @@ unsigned Prf_DB_GetUsrFigures (MYSQL_RES **mysql_res,long UsrCod) UsrCod); } +/*****************************************************************************/ +/****************** Check if a user is banned in ranking *********************/ +/*****************************************************************************/ + +bool Prf_DB_CheckIfUsrBanned (long UsrCod) + { + return (DB_QueryCOUNT ("can not check if user is banned", + "SELECT COUNT(*)" + " FROM usr_banned" + " WHERE UsrCod=%ld", + UsrCod) != 0); + } + /*****************************************************************************/ /**************************** Remove user's figures **************************/ /*****************************************************************************/ @@ -677,3 +692,15 @@ void Prf_DB_RemoveUsrFigures (long UsrCod) " WHERE UsrCod=%ld", UsrCod); } + +/*****************************************************************************/ +/**************** Remove user from banned users in ranking *******************/ +/*****************************************************************************/ + +void Prf_DB_RemoveUsrFromBanned (long UsrCod) + { + DB_QueryDELETE ("can not remove user from users banned", + "DELETE FROM usr_banned" + " WHERE UsrCod=%ld", + UsrCod); + } diff --git a/swad_profile_database.h b/swad_profile_database.h index 993f294d..a291b27c 100644 --- a/swad_profile_database.h +++ b/swad_profile_database.h @@ -63,7 +63,9 @@ unsigned Prf_DB_GetRankingNumClicksPerDay (long UsrCod); unsigned Prf_DB_GetNumUsrsWithNumClicksPerDay (void); bool Prf_DB_CheckIfUsrFiguresExists (long UsrCod); unsigned Prf_DB_GetUsrFigures (MYSQL_RES **mysql_res,long UsrCod); +bool Prf_DB_CheckIfUsrBanned (long UsrCod); void Prf_DB_RemoveUsrFigures (long UsrCod); +void Prf_DB_RemoveUsrFromBanned (long UsrCod); #endif diff --git a/swad_record.c b/swad_record.c index 03e61c47..cfc1649f 100644 --- a/swad_record.c +++ b/swad_record.c @@ -971,7 +971,7 @@ static void Rec_ShowRecordOneStdCrs (void) bool ItsMe; /***** Get if student has accepted enrolment in current course *****/ - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); /***** Assign users listing type depending on current action *****/ Gbl.Usrs.Listing.RecsUsrs = Rec_RECORD_USERS_STUDENTS; @@ -1112,11 +1112,11 @@ static void Rec_ListRecordsStds (Rec_SharedRecordViewType_t ShaTypeOfView, if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat, // Get student's data from database Usr_DONT_GET_PREFS, Usr_GET_ROLE_IN_CURRENT_CRS)) - if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) { /* Check if this user has accepted his/her inscription in the current course */ - UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); + UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); /* Begin container for this user */ snprintf (RecordSectionId,sizeof (RecordSectionId),"record_%u",NumUsr); @@ -1206,7 +1206,7 @@ static void Rec_ShowRecordOneTchCrs (void) snprintf (Width,sizeof (Width),"%upx",Rec_RECORD_WIDTH); /***** Get if teacher has accepted enrolment in current course *****/ - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); /***** Assign users listing type depending on current action *****/ Gbl.Usrs.Listing.RecsUsrs = Rec_RECORD_USERS_TEACHERS; @@ -1336,11 +1336,11 @@ static void Rec_ListRecordsTchs (Rec_SharedRecordViewType_t TypeOfView) if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat, // Get teacher's data from database Usr_DONT_GET_PREFS, Usr_GET_ROLE_IN_CURRENT_CRS)) - if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) { /* Check if this user has accepted his/her inscription in the current course */ - UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); + UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&UsrDat); /* Begin container for this user */ snprintf (RecordSectionId,sizeof (RecordSectionId),"record_%u",NumUsr); @@ -1978,7 +1978,7 @@ void Rec_ShowSharedRecordUnmodifiable (struct UsrData *UsrDat) Usr_GetAllUsrDataFromUsrCod (UsrDat, Usr_DONT_GET_PREFS, Usr_GET_ROLE_IN_CURRENT_CRS); - UsrDat->Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (UsrDat); + UsrDat->Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (UsrDat); /***** Show user's record *****/ HTM_DIV_Begin ("class=\"CM\""); diff --git a/swad_report.c b/swad_report.c index 85995622..a5abaaed 100644 --- a/swad_report.c +++ b/swad_report.c @@ -32,6 +32,7 @@ #include "swad_box.h" #include "swad_browser_database.h" #include "swad_database.h" +#include "swad_enrolment_database.h" #include "swad_error.h" #include "swad_form.h" #include "swad_global.h" @@ -896,7 +897,7 @@ static void Rep_GetAndWriteMyCurrentCrss (Rol_Role_t Role, unsigned NumCrs; long CrsCod; - NumCrss = Usr_DB_GetNumCrssOfUsrWithARole (Gbl.Usrs.Me.UsrDat.UsrCod,Role); + NumCrss = Enr_DB_GetNumCrssOfUsrWithARole (Gbl.Usrs.Me.UsrDat.UsrCod,Role); fprintf (Gbl.F.Rep,"
  • "); fprintf (Gbl.F.Rep,Txt_USER_in_COURSE, Txt_ROLES_SINGUL_Abc[Role][Gbl.Usrs.Me.UsrDat.Sex]); @@ -908,11 +909,11 @@ static void Rep_GetAndWriteMyCurrentCrss (Rol_Role_t Role, if (NumCrss) { fprintf (Gbl.F.Rep," (%u %s / %u %s):", - Usr_GetNumUsrsInCrssOfAUsr (Gbl.Usrs.Me.UsrDat.UsrCod,Role, + Enr_DB_GetNumUsrsInCrssOfAUsr (Gbl.Usrs.Me.UsrDat.UsrCod,Role, (1 << Rol_NET) | (1 << Rol_TCH)), Txt_teachers_ABBREVIATION, - Usr_GetNumUsrsInCrssOfAUsr (Gbl.Usrs.Me.UsrDat.UsrCod,Role, + Enr_DB_GetNumUsrsInCrssOfAUsr (Gbl.Usrs.Me.UsrDat.UsrCod,Role, (1 << Rol_STD)), Txt_students_ABBREVIATION); diff --git a/swad_role.c b/swad_role.c index 4ab65c19..7e274a4a 100644 --- a/swad_role.c +++ b/swad_role.c @@ -25,6 +25,7 @@ /*********************************** Headers *********************************/ /*****************************************************************************/ +#include "swad_admin_database.h" #include "swad_connected_database.h" #include "swad_database.h" #include "swad_form.h" @@ -119,18 +120,18 @@ void Rol_SetMyRoles (void) if (Gbl.Hierarchy.Ins.InsCod > 0) { /* Check if I am and administrator of current institution */ - ICanBeInsAdm = Usr_DB_CheckIfUsrIsAdm (Gbl.Usrs.Me.UsrDat.UsrCod, + ICanBeInsAdm = Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Me.UsrDat.UsrCod, HieLvl_INS, Gbl.Hierarchy.Ins.InsCod); if (Gbl.Hierarchy.Ctr.CtrCod > 0) { /* Check if I am and administrator of current center */ - ICanBeCtrAdm = Usr_DB_CheckIfUsrIsAdm (Gbl.Usrs.Me.UsrDat.UsrCod, + ICanBeCtrAdm = Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Me.UsrDat.UsrCod, HieLvl_CTR, Gbl.Hierarchy.Ctr.CtrCod); if (Gbl.Hierarchy.Deg.DegCod > 0) /* Check if I am and administrator of current degree */ - ICanBeDegAdm = Usr_DB_CheckIfUsrIsAdm (Gbl.Usrs.Me.UsrDat.UsrCod, + ICanBeDegAdm = Adm_DB_CheckIfUsrIsAdm (Gbl.Usrs.Me.UsrDat.UsrCod, HieLvl_DEG, Gbl.Hierarchy.Deg.DegCod); } @@ -139,9 +140,9 @@ void Rol_SetMyRoles (void) /***** Check if I belong to current course *****/ if (Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected { - Gbl.Usrs.Me.IBelongToCurrentCrs = Usr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Me.UsrDat); + Gbl.Usrs.Me.IBelongToCurrentCrs = Enr_CheckIfUsrBelongsToCurrentCrs (&Gbl.Usrs.Me.UsrDat); if (Gbl.Usrs.Me.IBelongToCurrentCrs) - Gbl.Usrs.Me.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Me.UsrDat); + Gbl.Usrs.Me.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Me.UsrDat); else Gbl.Usrs.Me.UsrDat.Accepted = false; } @@ -358,7 +359,7 @@ Rol_Role_t Rol_GetMyRoleInCrs (long CrsCod) /***** 3. Slow check: get my role from list of my courses *****/ /* Fill the list with the courses I belong to (if not already filled) */ - Crs_GetMyCourses (); + Enr_GetMyCourses (); /* Check if the current course is any of my courses */ for (NumMyCrs = 0, Role = Rol_UNK; diff --git a/swad_setting.c b/swad_setting.c index fbf91e6a..7635ce87 100644 --- a/swad_setting.c +++ b/swad_setting.c @@ -66,6 +66,15 @@ extern struct Globals Gbl; static void Set_PutIconsToSelectSideCols (void); static void Set_PutIconsSideColumns (__attribute__((unused)) void *Args); +static void Set_GetAndUpdateUsrListType (void); +static void Set_GetUsrListTypeFromForm (void); +static void Set_GetMyUsrListTypeFromDB (void); + +static void Set_GetParamColsClassPhotoFromForm (void); + +static void Set_GetAndUpdatePrefAboutListWithPhotos (void); +static bool Set_GetParamListWithPhotosFromForm (void); + /*****************************************************************************/ /***************************** Edit settings ******************************/ /*****************************************************************************/ @@ -267,6 +276,298 @@ unsigned Set_GetParamSideCols (void) Cfg_DEFAULT_COLUMNS); } +/*****************************************************************************/ +/**************** Put hidden parameters with type of list, *******************/ +/**************** number of columns in class photo *******************/ +/**************** and preference about viewing photos *******************/ +/*****************************************************************************/ + +void Set_PutParamsPrefsAboutUsrList (void) + { + Set_PutParamUsrListType (Gbl.Usrs.Me.ListType); + Set_PutParamColsClassPhoto (); + Set_PutParamListWithPhotos (); + } + +/*****************************************************************************/ +/****************** Get and update type of list, **********************/ +/****************** number of columns in class photo **********************/ +/****************** and preference about viewing photos **********************/ +/*****************************************************************************/ + +void Set_GetAndUpdatePrefsAboutUsrList (void) + { + /***** Get and update type of list *****/ + Set_GetAndUpdateUsrListType (); + + /***** Get and update number of columns in class photo *****/ + Set_GetAndUpdateColsClassPhoto (); + + /***** Get and update preference about viewing photos *****/ + Set_GetAndUpdatePrefAboutListWithPhotos (); + } + +/*****************************************************************************/ +/****************** Get from form the type of users' list ********************/ +/*****************************************************************************/ + +static void Set_GetAndUpdateUsrListType (void) + { + /***** Get type of list used to select users from form *****/ + Set_GetUsrListTypeFromForm (); + + if (Gbl.Usrs.Me.ListType != Set_USR_LIST_UNKNOWN) + /* Save in the database the type of list preferred by me */ + Set_DB_UpdateMyUsrListType (); + else + /* If parameter can't be retrieved from, + get my preference from database */ + Set_GetMyUsrListTypeFromDB (); + } + +/*****************************************************************************/ +/************* Put a hidden parameter with the users' list type **************/ +/*****************************************************************************/ + +void Set_PutParamUsrListType (Set_ShowUsrsType_t ListType) + { + Par_PutHiddenParamUnsigned (NULL,"UsrListType",(unsigned) ListType); + } + +/*****************************************************************************/ +/****************** Get from form the type of users' list ********************/ +/*****************************************************************************/ + +static void Set_GetUsrListTypeFromForm (void) + { + Gbl.Usrs.Me.ListType = (Set_ShowUsrsType_t) + Par_GetParToUnsignedLong ("UsrListType", + 0, + Set_NUM_USR_LIST_TYPES - 1, + (unsigned long) Set_USR_LIST_UNKNOWN); + } + +/*****************************************************************************/ +/************** Get my preference about type of users' list ******************/ +/*****************************************************************************/ + +static void Set_GetMyUsrListTypeFromDB (void) + { + extern const char *Set_DB_StringsUsrListTypes[Set_NUM_USR_LIST_TYPES]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumRows; + Set_ShowUsrsType_t ListType; + + /***** Get type of listing of users from database *****/ + NumRows = (unsigned) + DB_QuerySELECT (&mysql_res,"can not get type of listing of users", + "SELECT UsrListType" // row[0] + " FROM crs_user_settings" + " WHERE UsrCod=%ld" + " AND CrsCod=%ld", + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Hierarchy.Crs.CrsCod); + if (NumRows == 1) // Should be one only row + { + /* Get type of users' listing used to select some of them */ + Gbl.Usrs.Me.ListType = Set_SHOW_USRS_TYPE_DEFAULT; + row = mysql_fetch_row (mysql_res); + if (row[0]) + for (ListType = (Set_ShowUsrsType_t) 0; + ListType <= (Set_ShowUsrsType_t) (Set_NUM_USR_LIST_TYPES - 1); + ListType++) + if (!strcasecmp (row[0],Set_DB_StringsUsrListTypes[ListType])) + { + Gbl.Usrs.Me.ListType = ListType; + break; + } + } + else if (NumRows == 0) // If I am an administrator or superuser + // and I don't belong to current course, + // then the result will be the default + Gbl.Usrs.Me.ListType = Set_SHOW_USRS_TYPE_DEFAULT; + else // Error in database: + // more than one row for a user in course + Err_ShowErrorAndExit ("Error when getting type of listing of users."); + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + } + +/*****************************************************************************/ +/************* Get and update number of columns in class photo ***************/ +/*****************************************************************************/ + +void Set_GetAndUpdateColsClassPhoto (void) + { + /***** Get the number of columns in class photo from form *****/ + Set_GetParamColsClassPhotoFromForm (); + + if (Gbl.Usrs.ClassPhoto.Cols) + /* Save the number of columns into the database */ + Set_DB_UpdateMyColsClassPhoto (); + else + /* If parameter can't be retrieved from form, + get my preference from database */ + Set_GetMyColsClassPhotoFromDB (); + } + +/*****************************************************************************/ +/** Get my prefs. about number of colums in class photo for current course ***/ +/*****************************************************************************/ + +void Set_GetMyColsClassPhotoFromDB (void) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumRows; + + Gbl.Usrs.ClassPhoto.Cols = Usr_CLASS_PHOTO_COLS_DEF; + + /***** If user logged and course selected... *****/ + if (Gbl.Usrs.Me.Logged && + Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected + { + /***** Get number of columns in class photo from database *****/ + NumRows = (unsigned) + DB_QuerySELECT (&mysql_res,"can not get number of columns in class photo", + "SELECT ColsClassPhoto" // row[0] + " FROM crs_user_settings" + " WHERE UsrCod=%ld" + " AND CrsCod=%ld", + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Hierarchy.Crs.CrsCod); + if (NumRows == 1) // Should be one only row + { + /* Get number of columns in class photo */ + row = mysql_fetch_row (mysql_res); + if (row[0]) + if (sscanf (row[0],"%u",&Gbl.Usrs.ClassPhoto.Cols) == 1) + if (Gbl.Usrs.ClassPhoto.Cols < 1 || + Gbl.Usrs.ClassPhoto.Cols > Usr_CLASS_PHOTO_COLS_MAX) + Gbl.Usrs.ClassPhoto.Cols = Usr_CLASS_PHOTO_COLS_DEF; + } + else if (NumRows > 1) // Error in database: + // more than one row for a user in course + Err_ShowErrorAndExit ("Error when getting number of columns" + " in class photo."); + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + } + } + +/*****************************************************************************/ +/****** Put a hidden parameter with the number of colums in class photo ******/ +/*****************************************************************************/ + +void Set_PutParamColsClassPhoto (void) + { + Par_PutHiddenParamUnsigned (NULL,"ColsClassPhoto",Gbl.Usrs.ClassPhoto.Cols); + } + +/*****************************************************************************/ +/************* Get from form the number of colums in class photo *************/ +/*****************************************************************************/ + +static void Set_GetParamColsClassPhotoFromForm (void) + { + Gbl.Usrs.ClassPhoto.Cols = (unsigned) + Par_GetParToUnsignedLong ("ColsClassPhoto", + 1, + Usr_CLASS_PHOTO_COLS_MAX, + 0); + } + +/*****************************************************************************/ +/********** Get and update preference about photos in users' list ************/ +/*****************************************************************************/ + +static void Set_GetAndUpdatePrefAboutListWithPhotos (void) + { + /***** Get my preference about photos in users' list from form *****/ + if (Set_GetParamListWithPhotosFromForm ()) + /* Save preference about photos in users' list into the database */ + Set_DB_UpdateMyPrefAboutListWithPhotosPhoto (); + else + /* If parameter can't be retrieved from form, + get my preference from database */ + Set_GetMyPrefAboutListWithPhotosFromDB (); + } + +/*****************************************************************************/ +/** Put a hidden parameter with the preference about photos in users' list ***/ +/*****************************************************************************/ + +void Set_PutParamListWithPhotos (void) + { + Par_PutHiddenParamChar ("WithPhotosExists",'Y'); + Par_PutHiddenParamChar ("WithPhotos", + Gbl.Usrs.Listing.WithPhotos ? 'Y' : + 'N'); + } + +/*****************************************************************************/ +/********* Get from form the preference about photos in users' list **********/ +/*****************************************************************************/ + +static bool Set_GetParamListWithPhotosFromForm (void) + { + /***** Get if exists parameter with preference about photos in users' list *****/ + if (Par_GetParToBool ("WithPhotosExists")) + { + /***** Parameter with preference about photos in users' list exists, so get it *****/ + Gbl.Usrs.Listing.WithPhotos = Par_GetParToBool ("WithPhotos"); + return true; + } + + Gbl.Usrs.Listing.WithPhotos = Usr_LIST_WITH_PHOTOS_DEF; + return false; + } + +/*****************************************************************************/ +/***** Get my preference about photos in users' list for current course ******/ +/*****************************************************************************/ + +void Set_GetMyPrefAboutListWithPhotosFromDB (void) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumRows; + + Gbl.Usrs.Listing.WithPhotos = Usr_LIST_WITH_PHOTOS_DEF; + + /***** If no user logged or not course selected... *****/ + if (Gbl.Usrs.Me.Logged && Gbl.Hierarchy.Crs.CrsCod) + { + /***** Get if listing of users must show photos from database *****/ + NumRows = (unsigned) + DB_QuerySELECT (&mysql_res,"can not check if listing of users" + " must show photos", + "SELECT ListWithPhotos" // row[0] + " FROM crs_user_settings" + " WHERE UsrCod=%ld" + " AND CrsCod=%ld", + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Hierarchy.Crs.CrsCod); + if (NumRows == 1) // Should be one only row + { + /* Get number of columns in class photo */ + Gbl.Usrs.Listing.WithPhotos = Usr_LIST_WITH_PHOTOS_DEF; + row = mysql_fetch_row (mysql_res); + Gbl.Usrs.Listing.WithPhotos = (row[0][0] == 'Y'); + } + else if (NumRows > 1) // Error in database: + // more than one row for a user in course + Err_ShowErrorAndExit ("Error when checking if listing of users" + " must show photos."); + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + } + } + /*****************************************************************************/ /*********** Head to select one or several settings using icons **************/ /*****************************************************************************/ diff --git a/swad_setting.h b/swad_setting.h index b9dc7a4d..70a7b7b9 100644 --- a/swad_setting.h +++ b/swad_setting.h @@ -33,6 +33,16 @@ /***************************** Public constants ******************************/ /*****************************************************************************/ +// Related with type of list of users +#define Set_NUM_USR_LIST_TYPES 3 +typedef enum + { + Set_USR_LIST_UNKNOWN = 0, + Set_USR_LIST_AS_CLASS_PHOTO = 1, + Set_USR_LIST_AS_LISTING = 2, + } Set_ShowUsrsType_t; +#define Set_SHOW_USRS_TYPE_DEFAULT Set_USR_LIST_AS_CLASS_PHOTO + /*****************************************************************************/ /******************************* Public types ********************************/ /*****************************************************************************/ @@ -49,6 +59,16 @@ void Set_SetSettingsFromIP (void); void Set_ChangeSideCols (void); unsigned Set_GetParamSideCols (void); +//------------------------ My settings on users' list ------------------------- +void Set_PutParamsPrefsAboutUsrList (void); +void Set_GetAndUpdatePrefsAboutUsrList (void); +void Set_PutParamUsrListType (Set_ShowUsrsType_t ListType); +void Set_GetAndUpdateColsClassPhoto (void); +void Set_GetMyColsClassPhotoFromDB (void); +void Set_PutParamColsClassPhoto (void); +void Set_PutParamListWithPhotos (void); +void Set_GetMyPrefAboutListWithPhotosFromDB (void); + void Set_BeginSettingsHead (void); void Set_EndSettingsHead (void); void Set_BeginOneSettingSelector (void); diff --git a/swad_setting_database.c b/swad_setting_database.c index 2e221d56..7b867b97 100644 --- a/swad_setting_database.c +++ b/swad_setting_database.c @@ -35,12 +35,20 @@ extern struct Globals Gbl; /*****************************************************************************/ -/***************************** Private constants *****************************/ +/****************************** Public constants *****************************/ /*****************************************************************************/ +const char *Set_DB_StringsUsrListTypes[Set_NUM_USR_LIST_TYPES] = + { + [Set_USR_LIST_UNKNOWN ] = "", + [Set_USR_LIST_AS_CLASS_PHOTO] = "classphoto", + [Set_USR_LIST_AS_LISTING ] = "list", + }; + /*****************************************************************************/ /***************************** Private prototypes ****************************/ /*****************************************************************************/ + /*****************************************************************************/ /**************** Update my language to the current language *****************/ /*****************************************************************************/ @@ -209,8 +217,6 @@ void Set_DB_UpdateMySettingsAboutNotifyEvents (void) void Set_DB_InsertUsrInCrsSettings (long UsrCod,long CrsCod) { - extern const char *Usr_StringsUsrListTypeInDB[Usr_NUM_USR_LIST_TYPES]; - DB_QueryINSERT ("can not register user in course", "INSERT INTO crs_user_settings" " (UsrCod,CrsCod," @@ -225,7 +231,7 @@ void Set_DB_InsertUsrInCrsSettings (long UsrCod,long CrsCod) UsrCod, CrsCod, (long) (time_t) 0, // The user never accessed to tests in this course - Usr_StringsUsrListTypeInDB[Usr_SHOW_USRS_TYPE_DEFAULT], + Set_DB_StringsUsrListTypes[Set_SHOW_USRS_TYPE_DEFAULT], Usr_CLASS_PHOTO_COLS_DEF, Usr_LIST_WITH_PHOTOS_DEF ? 'Y' : 'N'); @@ -235,7 +241,7 @@ void Set_DB_InsertUsrInCrsSettings (long UsrCod,long CrsCod) /******** Update the group of my last access to a file browser zone **********/ /*****************************************************************************/ -void Set_DB_UpdateGrpLastAccZone (const char *FieldNameDB,long GrpCod) +void Set_DB_UpdateGrpMyLastAccZone (const char *FieldNameDB,long GrpCod) { DB_QueryUPDATE ("can not update the group of the last access to a file browser", "UPDATE crs_user_settings" @@ -247,6 +253,61 @@ void Set_DB_UpdateGrpLastAccZone (const char *FieldNameDB,long GrpCod) Gbl.Hierarchy.Crs.CrsCod); } +/*****************************************************************************/ +/***************** Save my preference about type of users' list **************/ +/*****************************************************************************/ + +void Set_DB_UpdateMyUsrListType (void) + { + DB_QueryUPDATE ("can not update type of listing", + "UPDATE crs_user_settings" + " SET UsrListType='%s'" + " WHERE UsrCod=%ld" + " AND CrsCod=%ld", + Set_DB_StringsUsrListTypes[Gbl.Usrs.Me.ListType], + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/** Save my prefs. about number of colums in class photo for current course **/ +/*****************************************************************************/ + +void Set_DB_UpdateMyColsClassPhoto (void) + { + if (Gbl.Usrs.Me.Logged && + Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected + /***** Update number of colums in class photo for current course *****/ + DB_QueryUPDATE ("can not update number of columns in class photo", + "UPDATE crs_user_settings" + " SET ColsClassPhoto=%u" + " WHERE UsrCod=%ld" + " AND CrsCod=%ld", + Gbl.Usrs.ClassPhoto.Cols, + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/**** Save my preference about photos in users' list for current course ******/ +/*****************************************************************************/ + +void Set_DB_UpdateMyPrefAboutListWithPhotosPhoto (void) + { + if (Gbl.Usrs.Me.Logged && + Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected + /***** Update number of colums in class photo for current course *****/ + DB_QueryUPDATE ("can not update your preference about photos in listing", + "UPDATE crs_user_settings" + " SET ListWithPhotos='%c'" + " WHERE UsrCod=%ld" + " AND CrsCod=%ld", + Gbl.Usrs.Listing.WithPhotos ? 'Y' : + 'N', + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Hierarchy.Crs.CrsCod); + } + /*****************************************************************************/ /****************** Remove a user from a courses setting *********************/ /*****************************************************************************/ diff --git a/swad_setting_database.h b/swad_setting_database.h index 2206b217..7d700522 100644 --- a/swad_setting_database.h +++ b/swad_setting_database.h @@ -55,7 +55,10 @@ void Set_DB_UpdateMySettingsAboutNotifyEvents (void); //-------------------- User settings in the current course -------------------- void Set_DB_InsertUsrInCrsSettings (long UsrCod,long CrsCod); -void Set_DB_UpdateGrpLastAccZone (const char *FieldNameDB,long GrpCod); +void Set_DB_UpdateGrpMyLastAccZone (const char *FieldNameDB,long GrpCod); +void Set_DB_UpdateMyUsrListType (void); +void Set_DB_UpdateMyColsClassPhoto (void); +void Set_DB_UpdateMyPrefAboutListWithPhotosPhoto (void); void Set_DB_RemUsrFromCrsSettings (long UsrCod,long CrsCod); void Set_DB_RemUsrFromAllCrssSettings (long UsrCod); diff --git a/swad_statistic.c b/swad_statistic.c index 31a06785..be94af96 100644 --- a/swad_statistic.c +++ b/swad_statistic.c @@ -265,7 +265,7 @@ static void Sta_PutFormCrsHits (struct Sta_Stats *Stats) /***** Get and update type of list, number of columns in class photo and preference about view photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get groups to show ******/ Grp_GetParCodsSeveralGrpsToShowUsrs (); diff --git a/swad_survey.c b/swad_survey.c index e38f9843..ae7b6899 100644 --- a/swad_survey.c +++ b/swad_survey.c @@ -1195,7 +1195,7 @@ void Svy_GetDataOfSurveyByCod (struct Svy_Survey *Svy) Svy->Status.IBelongToScope = Deg_CheckIfIBelongToDeg (Svy->Cod); break; case HieLvl_CRS: // Course - Svy->Status.IBelongToScope = Crs_CheckIfIBelongToCrs (Svy->Cod) && + Svy->Status.IBelongToScope = Enr_CheckIfIBelongToCrs (Svy->Cod) && Svy_DB_CheckIfICanDoThisSurveyBasedOnGrps (Svy->SvyCod); break; } diff --git a/swad_test_print.c b/swad_test_print.c index 0bd0737e..0da05d94 100644 --- a/swad_test_print.c +++ b/swad_test_print.c @@ -1772,7 +1772,7 @@ static void TstPrn_ShowUsrsPrints (__attribute__((unused)) void *Args) if (Usr_CheckIfICanViewTstExaMchResult (&Gbl.Usrs.Other.UsrDat)) { /***** Show tests *****/ - Gbl.Usrs.Other.UsrDat.Accepted = Usr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); + Gbl.Usrs.Other.UsrDat.Accepted = Enr_CheckIfUsrHasAcceptedInCurrentCrs (&Gbl.Usrs.Other.UsrDat); TstPrn_ShowUsrPrints (&Gbl.Usrs.Other.UsrDat); } } diff --git a/swad_text.c b/swad_text.c index d975c8ae..de0cf8f9 100644 --- a/swad_text.c +++ b/swad_text.c @@ -85,6 +85,7 @@ #include "swad_record.h" #include "swad_role.h" #include "swad_room.h" +#include "swad_setting.h" #include "swad_statistic.h" #include "swad_survey.h" #include "swad_syllabus.h" @@ -55933,12 +55934,12 @@ const char *Txt_X_users_who_have_email = // Warning: it is very important to inc "%u utilizadores que têm email"; #endif -const char *Txt_USR_LIST_TYPES[Usr_NUM_USR_LIST_TYPES] = +const char *Txt_USR_LIST_TYPES[Set_NUM_USR_LIST_TYPES] = { - [Usr_LIST_UNKNOWN] = + [Set_USR_LIST_UNKNOWN] = "" , - [Usr_LIST_AS_CLASS_PHOTO] = + [Set_USR_LIST_AS_CLASS_PHOTO] = #if L==1 // ca "Orla" #elif L==2 // de @@ -55959,7 +55960,7 @@ const char *Txt_USR_LIST_TYPES[Usr_NUM_USR_LIST_TYPES] = "Foto de formatura" #endif , - [Usr_LIST_AS_LISTING] = + [Set_USR_LIST_AS_LISTING] = #if L==1 // ca "Llista" #elif L==2 // de diff --git a/swad_user.c b/swad_user.c index c27291b4..cb8a113e 100644 --- a/swad_user.c +++ b/swad_user.c @@ -51,6 +51,7 @@ #include "swad_department.h" #include "swad_duplicate.h" #include "swad_enrolment.h" +#include "swad_enrolment_database.h" #include "swad_error.h" #include "swad_figure.h" #include "swad_figure_cache.h" @@ -105,22 +106,15 @@ const char *Usr_StringsSexDB[Usr_NUM_SEXS] = [Usr_SEX_ALL ] = "all", }; -const char *Usr_StringsUsrListTypeInDB[Usr_NUM_USR_LIST_TYPES] = - { - [Usr_LIST_UNKNOWN ] = "", - [Usr_LIST_AS_CLASS_PHOTO] = "classphoto", - [Usr_LIST_AS_LISTING ] = "list", - }; - /*****************************************************************************/ /***************************** Private constants *****************************/ /*****************************************************************************/ -static const char *Usr_IconsClassPhotoOrList[Usr_NUM_USR_LIST_TYPES] = +static const char *Usr_IconsClassPhotoOrList[Set_NUM_USR_LIST_TYPES] = { - [Usr_LIST_UNKNOWN ] = "", - [Usr_LIST_AS_CLASS_PHOTO] = "th.svg", - [Usr_LIST_AS_LISTING ] = "list-ol.svg", + [Set_USR_LIST_UNKNOWN ] = "", + [Set_USR_LIST_AS_CLASS_PHOTO] = "th.svg", + [Set_USR_LIST_AS_LISTING ] = "list-ol.svg", }; static const char *Usr_NameSelUnsel[Rol_NUM_ROLES] = @@ -174,8 +168,6 @@ static Usr_Sex_t Usr_GetSexFromStr (const char *Str); static bool Usr_DB_CheckIfMyBirthdayHasNotBeenCongratulated (void); static void Usr_InsertMyBirthday (void); -static void Usr_RemoveTemporaryTableMyCourses (void); - static void Usr_GetParamOtherUsrIDNickOrEMail (void); static bool Usr_ChkUsrAndGetUsrDataFromDirectLogin (void); @@ -220,8 +212,8 @@ static void Usr_AllocateListSelectedEncryptedUsrCods (struct SelectedUsrs *Selec Rol_Role_t Role); static void Usr_AllocateListOtherRecipients (void); -static void Usr_FormToSelectUsrListType (void (*FuncParams) (void *Args),void *Args, - Usr_ShowUsrsType_t ListType); +static void Set_FormToSelectUsrListType (void (*FuncParams) (void *Args),void *Args, + Set_ShowUsrsType_t ListType); static void Usr_PutCheckboxToSelectAllUsers (Rol_Role_t Role, struct SelectedUsrs *SelectedUsrs); static Usr_Sex_t Usr_GetSexOfUsrsLst (Rol_Role_t Role); @@ -240,18 +232,6 @@ static void Usr_ListUsrsForSelection (Rol_Role_t Role, static void Usr_ListRowsAllDataTchs (Rol_Role_t Role, const char *FieldNames[Usr_NUM_ALL_FIELDS_DATA_TCH], unsigned NumColumns); -static void Usr_GetAndUpdateUsrListType (void); -static void Usr_GetUsrListTypeFromForm (void); -static void Usr_GetMyUsrListTypeFromDB (void); -static void Usr_DB_UpdateMyUsrListType (void); - -static void Usr_GetParamColsClassPhotoFromForm (void); -static void Usr_GetMyColsClassPhotoFromDB (void); -static void Usr_DB_UpdateMyColsClassPhoto (void); - -static void Usr_GetAndUpdatePrefAboutListWithPhotos (void); -static bool Usr_GetParamListWithPhotosFromForm (void); -static void Usr_DB_UpdateMyPrefAboutListWithPhotosPhoto (void); static void Usr_PutLinkToSeeAdmins (void); static void Usr_PutLinkToSeeGuests (void); @@ -283,8 +263,6 @@ static void Usr_DrawClassPhoto (Usr_ClassPhotoType_t ClassPhotoType, bool PutCheckBoxToSelectUsr); static FigCch_FigureCached_t Usr_GetFigureNumUsrsInCrss (unsigned Roles); -static double Usr_GetNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); -static double Usr_GetNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); /*****************************************************************************/ /**** Show alert about number of clicks remaining before sending my photo ****/ @@ -912,10 +890,10 @@ void Usr_FlushCachesUsr (void) Ins_FlushCacheUsrBelongsToIns (); Ctr_FlushCacheUsrBelongsToCtr (); Deg_FlushCacheUsrBelongsToDeg (); - Crs_FlushCacheUsrBelongsToCrs (); - Usr_FlushCacheUsrBelongsToCurrentCrs (); - Usr_FlushCacheUsrHasAcceptedInCurrentCrs (); - Usr_FlushCacheUsrSharesAnyOfMyCrs (); + Enr_FlushCacheUsrBelongsToCrs (); + Enr_FlushCacheUsrBelongsToCurrentCrs (); + Enr_FlushCacheUsrHasAcceptedInCurrentCrs (); + Enr_FlushCacheUsrSharesAnyOfMyCrs (); Rol_FlushCacheMyRoleInCurrentCrs (); Rol_FlushCacheRoleUsrInCrs (); Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (); @@ -923,24 +901,6 @@ void Usr_FlushCachesUsr (void) Fol_FlushCacheFollow (); } -/*****************************************************************************/ -/***** Check if a user is an administrator of a degree/center/institution ****/ -/*****************************************************************************/ - -bool Usr_DB_CheckIfUsrIsAdm (long UsrCod,HieLvl_Level_t Scope,long Cod) - { - /***** Get if a user is administrator of a degree from database *****/ - return (DB_QueryCOUNT ("can not check if a user is administrator", - "SELECT COUNT(*)" - " FROM usr_admins" - " WHERE UsrCod=%ld" - " AND Scope='%s'" - " AND Cod=%ld", - UsrCod, - Sco_GetDBStrFromScope (Scope), - Cod) != 0); - } - /*****************************************************************************/ /********************* Check if a user is a superuser ************************/ /*****************************************************************************/ @@ -1052,151 +1012,6 @@ bool Usr_ICanEditOtherUsr (const struct UsrData *UsrDat) } } -/*****************************************************************************/ -/********************* Get number of courses of a user ***********************/ -/*****************************************************************************/ - -unsigned Usr_DB_GetNumCrssOfUsr (long UsrCod) - { - /***** Get the number of courses of a user from database ******/ - return (unsigned) - DB_QueryCOUNT ("can not get the number of courses of a user", - "SELECT COUNT(*)" - " FROM crs_users" - " WHERE UsrCod=%ld", - UsrCod); - } - -/*****************************************************************************/ -/*************** Get number of courses of a user not accepted ****************/ -/*****************************************************************************/ - -unsigned Usr_DB_GetNumCrssOfUsrNotAccepted (long UsrCod) - { - /***** Get the number of courses of a user not accepted from database ******/ - return (unsigned) - DB_QueryCOUNT ("can not get the number of courses of a user", - "SELECT COUNT(*)" - " FROM crs_users" - " WHERE UsrCod=%ld" - " AND Accepted='N'", - UsrCod); - } - -/*****************************************************************************/ -/********* Get number of courses in with a user have a given role ************/ -/*****************************************************************************/ - -unsigned Usr_DB_GetNumCrssOfUsrWithARole (long UsrCod,Rol_Role_t Role) - { - /***** Get the number of courses of a user with a role from database ******/ - return (unsigned) - DB_QueryCOUNT ("can not get the number of courses of a user with a role", - "SELECT COUNT(*)" - " FROM crs_users" - " WHERE UsrCod=%ld" - " AND Role=%u", - UsrCod, - (unsigned) Role); - } - -/*****************************************************************************/ -/********* Get number of courses in with a user have a given role ************/ -/*****************************************************************************/ - -unsigned Usr_DB_GetNumCrssOfUsrWithARoleNotAccepted (long UsrCod,Rol_Role_t Role) - { - /***** Get the number of courses of a user with a role from database ******/ - return (unsigned) - DB_QueryCOUNT ("can not get the number of courses of a user with a role", - "SELECT COUNT(*)" - " FROM crs_users" - " WHERE UsrCod=%ld" - " AND Role=%u" - " AND Accepted='N'", - UsrCod, - (unsigned) Role); - } - -/*****************************************************************************/ -/****** Get number of users with some given roles in courses of a user *******/ -/*****************************************************************************/ - -#define Usr_MAX_BYTES_ROLES_STR (Rol_NUM_ROLES * (Cns_MAX_DECIMAL_DIGITS_UINT + 1)) -unsigned Usr_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole, - unsigned OthersRoles) - { - Rol_Role_t Role; - char UnsignedStr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char OthersRolesStr[Usr_MAX_BYTES_ROLES_STR + 1]; - char SubQueryRole[64]; - unsigned NumUsrs; - // This query can be made in a unique, but slower, query - // The temporary table achieves speedup from ~2s to few ms - - /***** Remove temporary table if exists *****/ - DB_Query ("can not remove temporary tables", - "DROP TEMPORARY TABLE IF EXISTS usr_courses_tmp"); - - /***** Create temporary table with all user's courses - as student/non-editing teacher/teacher *****/ - switch (UsrRole) - { - case Rol_STD: // Student - sprintf (SubQueryRole," AND Role=%u", - (unsigned) Rol_STD); - break; - case Rol_NET: // Non-editing teacher - sprintf (SubQueryRole," AND Role=%u", - (unsigned) Rol_NET); - break; - case Rol_TCH: // or teacher - sprintf (SubQueryRole," AND Role=%u", - (unsigned) Rol_TCH); - break; - default: - SubQueryRole[0] = '\0'; - Err_WrongRoleExit (); - break; - } - DB_Query ("can not create temporary table", - "CREATE TEMPORARY TABLE IF NOT EXISTS usr_courses_tmp" - " (CrsCod INT NOT NULL,UNIQUE INDEX (CrsCod))" - " ENGINE=MEMORY" - " SELECT CrsCod" - " FROM crs_users" - " WHERE UsrCod=%ld" - "%s", - UsrCod,SubQueryRole); - - /***** Get the number of students/teachers in a course from database ******/ - OthersRolesStr[0] = '\0'; - for (Role = Rol_STD; // First possible role in a course - Role <= Rol_TCH; // Last possible role in a course - Role++) - if ((OthersRoles & (1 << Role))) - { - sprintf (UnsignedStr,"%u",(unsigned) Role); - if (OthersRolesStr[0]) // Not empty - Str_Concat (OthersRolesStr,",",sizeof (OthersRolesStr) - 1); - Str_Concat (OthersRolesStr,UnsignedStr,sizeof (OthersRolesStr) - 1); - } - NumUsrs = (unsigned) - DB_QueryCOUNT ("can not get number of users", - "SELECT COUNT(DISTINCT crs_users.UsrCod)" - " FROM crs_users," - "usr_courses_tmp" - " WHERE crs_users.CrsCod=usr_courses_tmp.CrsCod" - " AND crs_users.Role IN (%s)", - OthersRolesStr); - - /***** Remove temporary table *****/ - DB_Query ("can not remove temporary tables", - "DROP TEMPORARY TABLE IF EXISTS usr_courses_tmp"); - - return NumUsrs; - } - /*****************************************************************************/ /************ Check if I can view the record card of a student ***************/ /*****************************************************************************/ @@ -1235,7 +1050,7 @@ bool Usr_CheckIfICanViewRecordStd (const struct UsrData *UsrDat) return true; /***** 8. Fast / slow check: Does he/she belong to the current course? *****/ - if (!Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) + if (!Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) return false; /***** 9. Fast / slow check depending on roles *****/ @@ -1311,7 +1126,7 @@ bool Usr_CheckIfICanViewTstExaMchResult (const struct UsrData *UsrDat) return true; /***** 7. Fast check: Does he/she belong to the current course? *****/ - if (!Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) + if (!Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) return false; /***** 8. Fast / slow check depending on roles *****/ @@ -1348,7 +1163,7 @@ bool Usr_CheckIfICanViewAsgWrk (const struct UsrData *UsrDat) /***** 4. Fast check: Does he/she belong to the current course? *****/ // Only users beloging to course can have files in assignments/works - if (!Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) + if (!Enr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) return false; /***** 5. Fast check: Am I a system admin? *****/ @@ -1443,862 +1258,7 @@ bool Usr_CheckIfICanViewUsrAgenda (struct UsrData *UsrDat) return true; /***** 4. Slow check: Get if user shares any course with me from database *****/ - return Usr_CheckIfUsrSharesAnyOfMyCrs (UsrDat); - } - -/*****************************************************************************/ -/*************** Check if a user belongs to any of my courses ****************/ -/*****************************************************************************/ - -void Usr_FlushCacheUsrSharesAnyOfMyCrs (void) - { - Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = -1L; - Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = false; - } - -bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat) - { - bool ItsMe; - - /***** 1. Fast check: Am I logged? *****/ - if (!Gbl.Usrs.Me.Logged) - return false; - - /***** 2. Fast check: It is a valid user code? *****/ - if (UsrDat->UsrCod <= 0) - return false; - - /***** 3. Fast check: It's me? *****/ - ItsMe = Usr_ItsMe (UsrDat->UsrCod); - if (ItsMe) - return true; - - /***** 4. Fast check: Is already calculated if user shares any course with me? *****/ - if (UsrDat->UsrCod == Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod) - return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs; - - /***** 5. Fast check: Is course selected and we both belong to it? *****/ - if (Gbl.Usrs.Me.IBelongToCurrentCrs) - if (Usr_CheckIfUsrBelongsToCurrentCrs (UsrDat)) // Course selected and we both belong to it - return true; - - /***** 6. Fast/slow check: Does he/she belong to any course? *****/ - Rol_GetRolesInAllCrss (UsrDat); - if (!(UsrDat->Roles.InCrss & ((1 << Rol_STD) | // Any of his/her roles is student - (1 << Rol_NET) | // or non-editing teacher - (1 << Rol_TCH)))) // or teacher? - return false; - - /***** 7. Slow check: Get if user shares any course with me from database *****/ - /* Fill the list with the courses I belong to (if not already filled) */ - Crs_GetMyCourses (); - - /* Check if user shares any course with me */ - Gbl.Cache.UsrSharesAnyOfMyCrs.UsrCod = UsrDat->UsrCod; - Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs = - (DB_QueryCOUNT ("can not check if a user shares any course with you", - "SELECT COUNT(*)" - " FROM crs_users" - " WHERE UsrCod=%ld" - " AND CrsCod IN" - " (SELECT CrsCod" - " FROM my_courses_tmp)", - UsrDat->UsrCod) != 0); - return Gbl.Cache.UsrSharesAnyOfMyCrs.SharesAnyOfMyCrs; - } - -/*****************************************************************************/ -/*** Check if a user belongs to any of my courses but has a different role ***/ -/*****************************************************************************/ - -bool Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod) - { - bool UsrSharesAnyOfMyCrsWithDifferentRole; - - /***** 1. Fast check: Am I logged? *****/ - if (!Gbl.Usrs.Me.Logged) - return false; - - /***** 2. Slow check: Get if user shares any course with me - with a different role, from database *****/ - /* Fill the list with the courses I belong to (if not already filled) */ - Crs_GetMyCourses (); - - /* Remove temporary table if exists */ - DB_Query ("can not remove temporary tables", - "DROP TEMPORARY TABLE IF EXISTS usr_courses_tmp"); - - /* Create temporary table with all user's courses for a role */ - DB_Query ("can not create temporary table", - "CREATE TEMPORARY TABLE IF NOT EXISTS usr_courses_tmp " - "(CrsCod INT NOT NULL,Role TINYINT NOT NULL," - "UNIQUE INDEX(CrsCod,Role)) ENGINE=MEMORY" - " SELECT CrsCod," - "Role" - " FROM crs_users" - " WHERE UsrCod=%ld", - UsrCod); - - /* Get if a user shares any course with me from database */ - UsrSharesAnyOfMyCrsWithDifferentRole = - (DB_QueryCOUNT ("can not check if a user shares any course with you", - "SELECT COUNT(*)" - " FROM my_courses_tmp," - "usr_courses_tmp" - " WHERE my_courses_tmp.CrsCod=usr_courses_tmp.CrsCod" - " AND my_courses_tmp.Role<>usr_courses_tmp.Role") != 0); - - /* Remove temporary table if exists */ - DB_Query ("can not remove temporary tables", - "DROP TEMPORARY TABLE IF EXISTS usr_courses_tmp"); - - return UsrSharesAnyOfMyCrsWithDifferentRole; - } - -/*****************************************************************************/ -/**** Get all my countries (those of my courses) and store them in a list ****/ -/*****************************************************************************/ - -void Cty_GetMyCountrs (void) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumCty; - unsigned NumCtys; - long CtyCod; - - /***** If my countries are yet filled, there's nothing to do *****/ - if (!Gbl.Usrs.Me.MyCtys.Filled) - { - Gbl.Usrs.Me.MyCtys.Num = 0; - - /***** Get my institutions from database *****/ - NumCtys = Cty_DB_GetCtysFromUsr (&mysql_res,Gbl.Usrs.Me.UsrDat.UsrCod); - for (NumCty = 0; - NumCty < NumCtys; - NumCty++) - { - /* Get next country */ - row = mysql_fetch_row (mysql_res); - - /* Get country code */ - if ((CtyCod = Str_ConvertStrCodToLongCod (row[0])) > 0) - { - if (Gbl.Usrs.Me.MyCtys.Num == Cty_MAX_COUNTRS_PER_USR) - Err_ShowErrorAndExit ("Maximum number of countries of a user exceeded."); - - Gbl.Usrs.Me.MyCtys.Ctys[Gbl.Usrs.Me.MyCtys.Num].CtyCod = CtyCod; - Gbl.Usrs.Me.MyCtys.Ctys[Gbl.Usrs.Me.MyCtys.Num].MaxRole = Rol_ConvertUnsignedStrToRole (row[1]); - - Gbl.Usrs.Me.MyCtys.Num++; - } - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - - /***** Set boolean that indicates that my institutions are yet filled *****/ - Gbl.Usrs.Me.MyCtys.Filled = true; - } - } - -/*****************************************************************************/ -/** Get all my institutions (those of my courses) and store them in a list ***/ -/*****************************************************************************/ - -void Ins_GetMyInstits (void) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumIns; - unsigned NumInss; - long InsCod; - - /***** If my institutions are yet filled, there's nothing to do *****/ - if (!Gbl.Usrs.Me.MyInss.Filled) - { - Gbl.Usrs.Me.MyInss.Num = 0; - - /***** Get my institutions from database *****/ - NumInss = Ins_DB_GetInssFromUsr (&mysql_res, - Gbl.Usrs.Me.UsrDat.UsrCod,-1L); - for (NumIns = 0; - NumIns < NumInss; - NumIns++) - { - /* Get next institution */ - row = mysql_fetch_row (mysql_res); - - /* Get institution code */ - if ((InsCod = Str_ConvertStrCodToLongCod (row[0])) > 0) - { - if (Gbl.Usrs.Me.MyInss.Num == Ins_MAX_INSTITS_PER_USR) - Err_ShowErrorAndExit ("Maximum number of institutions of a user exceeded."); - - Gbl.Usrs.Me.MyInss.Inss[Gbl.Usrs.Me.MyInss.Num].InsCod = InsCod; - Gbl.Usrs.Me.MyInss.Inss[Gbl.Usrs.Me.MyInss.Num].MaxRole = Rol_ConvertUnsignedStrToRole (row[1]); - - Gbl.Usrs.Me.MyInss.Num++; - } - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - - /***** Set boolean that indicates that my institutions are yet filled *****/ - Gbl.Usrs.Me.MyInss.Filled = true; - } - } - -/*****************************************************************************/ -/***** Get all my centers (those of my courses) and store them in a list *****/ -/*****************************************************************************/ - -void Ctr_GetMyCenters (void) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumCtr; - unsigned NumCtrs; - long CtrCod; - - /***** If my centers are yet filled, there's nothing to do *****/ - if (!Gbl.Usrs.Me.MyCtrs.Filled) - { - Gbl.Usrs.Me.MyCtrs.Num = 0; - - /***** Get my centers from database *****/ - NumCtrs = Ctr_DB_GetCtrsFromUsr (&mysql_res, - Gbl.Usrs.Me.UsrDat.UsrCod,-1L); - for (NumCtr = 0; - NumCtr < NumCtrs; - NumCtr++) - { - /* Get next center */ - row = mysql_fetch_row (mysql_res); - - /* Get center code */ - if ((CtrCod = Str_ConvertStrCodToLongCod (row[0])) > 0) - { - if (Gbl.Usrs.Me.MyCtrs.Num == Ctr_MAX_CENTERS_PER_USR) - Err_ShowErrorAndExit ("Maximum number of centers of a user exceeded."); - - Gbl.Usrs.Me.MyCtrs.Ctrs[Gbl.Usrs.Me.MyCtrs.Num].CtrCod = CtrCod; - Gbl.Usrs.Me.MyCtrs.Ctrs[Gbl.Usrs.Me.MyCtrs.Num].MaxRole = Rol_ConvertUnsignedStrToRole (row[1]); - - Gbl.Usrs.Me.MyCtrs.Num++; - } - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - - /***** Set boolean that indicates that my centers are yet filled *****/ - Gbl.Usrs.Me.MyCtrs.Filled = true; - } - } - -/*****************************************************************************/ -/***** Get all my degrees (those of my courses) and store them in a list *****/ -/*****************************************************************************/ - -void Deg_GetMyDegrees (void) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumDeg; - unsigned NumDegs; - long DegCod; - - /***** If my degrees are yet filled, there's nothing to do *****/ - if (!Gbl.Usrs.Me.MyDegs.Filled) - { - Gbl.Usrs.Me.MyDegs.Num = 0; - - /***** Get my degrees from database *****/ - NumDegs = Deg_DB_GetDegsFromUsr (&mysql_res, - Gbl.Usrs.Me.UsrDat.UsrCod,-1L); - for (NumDeg = 0; - NumDeg < NumDegs; - NumDeg++) - { - /* Get next degree */ - row = mysql_fetch_row (mysql_res); - - /* Get degree code */ - if ((DegCod = Str_ConvertStrCodToLongCod (row[0])) > 0) - { - if (Gbl.Usrs.Me.MyDegs.Num == Deg_MAX_DEGREES_PER_USR) - Err_ShowErrorAndExit ("Maximum number of degrees of a user exceeded."); - - Gbl.Usrs.Me.MyDegs.Degs[Gbl.Usrs.Me.MyDegs.Num].DegCod = DegCod; - Gbl.Usrs.Me.MyDegs.Degs[Gbl.Usrs.Me.MyDegs.Num].MaxRole = Rol_ConvertUnsignedStrToRole (row[1]); - - Gbl.Usrs.Me.MyDegs.Num++; - } - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - - /***** Set boolean that indicates that my degrees are yet filled *****/ - Gbl.Usrs.Me.MyDegs.Filled = true; - } - } - -/*****************************************************************************/ -/********* Get the degree in which a user is enroled in more courses *********/ -/*****************************************************************************/ - -void Deg_GetUsrMainDeg (long UsrCod, - char ShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1], - Rol_Role_t *MaxRole) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - - /***** Get a random student from current course from database *****/ - if (DB_QuerySELECT (&mysql_res,"can not get user's main degree", - "SELECT deg_degrees.ShortName," // row[0] - "main_degree.MaxRole" // row[1] - " FROM deg_degrees," - - // The second table contain only one row with the main degree - " (SELECT crs_courses.DegCod AS DegCod," - "MAX(crs_users.Role) AS MaxRole," - "COUNT(*) AS N" - " FROM crs_users," - "crs_courses" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.CrsCod=crs_courses.CrsCod" - " GROUP BY crs_courses.DegCod" - " ORDER BY N DESC" // Ordered by number of courses in which user is enroled - " LIMIT 1)" // We need only the main degree - " AS main_degree" - - " WHERE deg_degrees.DegCod=main_degree.DegCod", - UsrCod)) - { - row = mysql_fetch_row (mysql_res); - - /* Get degree name (row[0]) */ - Str_Copy (ShrtName,row[0],Cns_HIERARCHY_MAX_BYTES_SHRT_NAME); - - /* Get maximum role (row[1]) */ - *MaxRole = Rol_ConvertUnsignedStrToRole (row[1]); - } - else // User is not enroled in any course - { - ShrtName[0] = '\0'; - *MaxRole = Rol_UNK; - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - } - -/*****************************************************************************/ -/*************** Get all my courses and store them in a list *****************/ -/*****************************************************************************/ - -void Crs_GetMyCourses (void) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumCrss; - unsigned NumCrs; - long CrsCod; - - /***** Trivial check 1: if my courses are already filled, there's nothing to do *****/ - if (Gbl.Usrs.Me.MyCrss.Filled) - return; - - /***** Trivial check 2: if user's code is not set, don't query database *****/ - if (Gbl.Usrs.Me.UsrDat.UsrCod <= 0) - return; - - /***** Remove temporary table with my courses *****/ - Usr_RemoveTemporaryTableMyCourses (); - - /***** Create temporary table with my courses *****/ - DB_Query ("can not create temporary table", - "CREATE TEMPORARY TABLE IF NOT EXISTS my_courses_tmp" - " (CrsCod INT NOT NULL," - "Role TINYINT NOT NULL," - "DegCod INT NOT NULL," - "UNIQUE INDEX(CrsCod,Role,DegCod)) ENGINE=MEMORY" - " SELECT crs_users.CrsCod," - "crs_users.Role," - "crs_courses.DegCod" - " FROM crs_users," - "crs_courses," - "deg_degrees" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.CrsCod=crs_courses.CrsCod" - " AND crs_courses.DegCod=deg_degrees.DegCod" - " ORDER BY deg_degrees.ShortName," - "crs_courses.ShortName", - Gbl.Usrs.Me.UsrDat.UsrCod); - - /***** Get my courses from database *****/ - NumCrss = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get which courses you belong to", - "SELECT CrsCod," // row[0] - "Role," // row[1] - "DegCod" // row[2] - " FROM my_courses_tmp"); - for (NumCrs = 0; - NumCrs < NumCrss; - NumCrs++) - { - /* Get next course */ - row = mysql_fetch_row (mysql_res); - - /* Get course code */ - if ((CrsCod = Str_ConvertStrCodToLongCod (row[0])) > 0) - { - if (Gbl.Usrs.Me.MyCrss.Num == Crs_MAX_COURSES_PER_USR) - Err_ShowErrorAndExit ("Maximum number of courses of a user exceeded."); - - Gbl.Usrs.Me.MyCrss.Crss[Gbl.Usrs.Me.MyCrss.Num].CrsCod = CrsCod; - Gbl.Usrs.Me.MyCrss.Crss[Gbl.Usrs.Me.MyCrss.Num].Role = Rol_ConvertUnsignedStrToRole (row[1]); - Gbl.Usrs.Me.MyCrss.Crss[Gbl.Usrs.Me.MyCrss.Num].DegCod = Str_ConvertStrCodToLongCod (row[2]); - Gbl.Usrs.Me.MyCrss.Num++; - } - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - - /***** Set boolean that indicates that my courses are already filled *****/ - Gbl.Usrs.Me.MyCrss.Filled = true; - } - -/*****************************************************************************/ -/************************ Free the list of my countries ************************/ -/*****************************************************************************/ - -void Cty_FreeMyCountrs (void) - { - if (Gbl.Usrs.Me.MyCtys.Filled) - { - /***** Reset list *****/ - Gbl.Usrs.Me.MyCtys.Filled = false; - Gbl.Usrs.Me.MyCtys.Num = 0; - } - } - -/*****************************************************************************/ -/********************* Free the list of my institutions **********************/ -/*****************************************************************************/ - -void Ins_FreeMyInstits (void) - { - if (Gbl.Usrs.Me.MyInss.Filled) - { - /***** Reset list *****/ - Gbl.Usrs.Me.MyInss.Filled = false; - Gbl.Usrs.Me.MyInss.Num = 0; - } - } - -/*****************************************************************************/ -/************************ Free the list of my centers ************************/ -/*****************************************************************************/ - -void Ctr_FreeMyCenters (void) - { - if (Gbl.Usrs.Me.MyCtrs.Filled) - { - /***** Reset list *****/ - Gbl.Usrs.Me.MyCtrs.Filled = false; - Gbl.Usrs.Me.MyCtrs.Num = 0; - } - } - -/*****************************************************************************/ -/************************ Free the list of my degrees ************************/ -/*****************************************************************************/ - -void Deg_FreeMyDegrees (void) - { - if (Gbl.Usrs.Me.MyDegs.Filled) - { - /***** Reset list *****/ - Gbl.Usrs.Me.MyDegs.Filled = false; - Gbl.Usrs.Me.MyDegs.Num = 0; - } - } - -/*****************************************************************************/ -/************************ Free the list of my courses ************************/ -/*****************************************************************************/ - -void Crs_FreeMyCourses (void) - { - if (Gbl.Usrs.Me.MyCrss.Filled) - { - /***** Reset list *****/ - Gbl.Usrs.Me.MyCrss.Filled = false; - Gbl.Usrs.Me.MyCrss.Num = 0; - - /***** Remove temporary table with my courses *****/ - Usr_RemoveTemporaryTableMyCourses (); - } - } - -/*****************************************************************************/ -/************************ Free the list of my courses ************************/ -/*****************************************************************************/ - -static void Usr_RemoveTemporaryTableMyCourses (void) - { - char Query[128]; - - /***** Remove temporary table with my courses *****/ - sprintf (Query,"DROP TEMPORARY TABLE IF EXISTS my_courses_tmp"); - if (mysql_query (&Gbl.mysql,Query)) - DB_ExitOnMySQLError ("can not remove temporary table"); - } - -/*****************************************************************************/ -/**************** Check if a user belongs to an institution ******************/ -/*****************************************************************************/ - -void Ins_FlushCacheUsrBelongsToIns (void) - { - Gbl.Cache.UsrBelongsToIns.UsrCod = -1L; - Gbl.Cache.UsrBelongsToIns.InsCod = -1L; - Gbl.Cache.UsrBelongsToIns.Belongs = false; - } - -bool Ins_CheckIfUsrBelongsToIns (long UsrCod,long InsCod) - { - /***** 1. Fast check: Trivial case *****/ - if (UsrCod <= 0 || - InsCod <= 0) - return false; - - /***** 2. Fast check: If cached... *****/ - if (UsrCod == Gbl.Cache.UsrBelongsToIns.UsrCod && - InsCod != Gbl.Cache.UsrBelongsToIns.InsCod) - return Gbl.Cache.UsrBelongsToIns.Belongs; - - /***** 3. Slow check: Get is user belongs to institution from database *****/ - Gbl.Cache.UsrBelongsToIns.UsrCod = UsrCod; - Gbl.Cache.UsrBelongsToIns.InsCod = InsCod; - Gbl.Cache.UsrBelongsToIns.Belongs = - (DB_QueryCOUNT ("can not check if a user belongs to an institution", - "SELECT COUNT(DISTINCT ctr_centers.InsCod)" - " FROM crs_users," - "crs_courses," - "deg_degrees," - "ctr_centers" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.Accepted='Y'" // Only if user accepted - " AND crs_users.CrsCod=crs_courses.CrsCod" - " AND crs_courses.DegCod=deg_degrees.DegCod" - " AND deg_degrees.CtrCod=ctr_centers.CtrCod" - " AND ctr_centers.InsCod=%ld", - UsrCod,InsCod) != 0); - return Gbl.Cache.UsrBelongsToIns.Belongs; - } - -/*****************************************************************************/ -/******************* Check if a user belongs to a center *********************/ -/*****************************************************************************/ - -void Ctr_FlushCacheUsrBelongsToCtr (void) - { - Gbl.Cache.UsrBelongsToCtr.UsrCod = -1L; - Gbl.Cache.UsrBelongsToCtr.CtrCod = -1L; - Gbl.Cache.UsrBelongsToCtr.Belongs = false; - } - -bool Ctr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod) - { - /***** 1. Fast check: Trivial case *****/ - if (UsrCod <= 0 || - CtrCod <= 0) - return false; - - /***** 2. Fast check: If cached... *****/ - if (UsrCod == Gbl.Cache.UsrBelongsToCtr.UsrCod && - CtrCod == Gbl.Cache.UsrBelongsToCtr.CtrCod) - return Gbl.Cache.UsrBelongsToCtr.Belongs; - - /***** 3. Slow check: Get is user belongs to center from database *****/ - Gbl.Cache.UsrBelongsToCtr.UsrCod = UsrCod; - Gbl.Cache.UsrBelongsToCtr.CtrCod = CtrCod; - Gbl.Cache.UsrBelongsToCtr.Belongs = - (DB_QueryCOUNT ("can not check if a user belongs to a center", - "SELECT COUNT(DISTINCT deg_degrees.CtrCod)" - " FROM crs_users," - "crs_courses," - "deg_degrees" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.Accepted='Y'" // Only if user accepted - " AND crs_users.CrsCod=crs_courses.CrsCod" - " AND crs_courses.DegCod=deg_degrees.DegCod" - " AND deg_degrees.CtrCod=%ld", - UsrCod, - CtrCod) != 0); - return Gbl.Cache.UsrBelongsToCtr.Belongs; - } - -/*****************************************************************************/ -/******************* Check if a user belongs to a degree *********************/ -/*****************************************************************************/ - -void Deg_FlushCacheUsrBelongsToDeg (void) - { - Gbl.Cache.UsrBelongsToDeg.UsrCod = -1L; - Gbl.Cache.UsrBelongsToDeg.DegCod = -1L; - Gbl.Cache.UsrBelongsToDeg.Belongs = false; - } - -bool Deg_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod) - { - /***** 1. Fast check: Trivial case *****/ - if (UsrCod <= 0 || - DegCod <= 0) - return false; - - /***** 2. Fast check: If cached... *****/ - if (UsrCod == Gbl.Cache.UsrBelongsToDeg.UsrCod && - DegCod == Gbl.Cache.UsrBelongsToDeg.DegCod) - return Gbl.Cache.UsrBelongsToDeg.Belongs; - - /***** 3. Slow check: Get if user belongs to degree from database *****/ - Gbl.Cache.UsrBelongsToDeg.UsrCod = UsrCod; - Gbl.Cache.UsrBelongsToDeg.DegCod = DegCod; - Gbl.Cache.UsrBelongsToDeg.Belongs = - (DB_QueryCOUNT ("can not check if a user belongs to a degree", - "SELECT COUNT(DISTINCT crs_courses.DegCod)" - " FROM crs_users," - "crs_courses" - " WHERE crs_users.UsrCod=%ld" - " AND crs_users.Accepted='Y'" // Only if user accepted - " AND crs_users.CrsCod=crs_courses.CrsCod" - " AND crs_courses.DegCod=%ld", - UsrCod,DegCod) != 0); - return Gbl.Cache.UsrBelongsToDeg.Belongs; - } - -/*****************************************************************************/ -/******************** Check if a user belongs to a course ********************/ -/*****************************************************************************/ - -void Crs_FlushCacheUsrBelongsToCrs (void) - { - Gbl.Cache.UsrBelongsToCrs.UsrCod = -1L; - Gbl.Cache.UsrBelongsToCrs.CrsCod = -1L; - Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses = false; - Gbl.Cache.UsrBelongsToCrs.Belongs = false; - } - -bool Crs_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod, - bool CountOnlyAcceptedCourses) - { - const char *SubQuery; - - /***** 1. Fast check: Trivial cases *****/ - if (UsrCod <= 0 || - CrsCod <= 0) - return false; - - /***** 2. Fast check: If cached... *****/ - if (UsrCod == Gbl.Cache.UsrBelongsToCrs.UsrCod && - CrsCod == Gbl.Cache.UsrBelongsToCrs.CrsCod && - CountOnlyAcceptedCourses == Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses) - return Gbl.Cache.UsrBelongsToCrs.Belongs; - - /***** 3. Slow check: Get if user belongs to course from database *****/ - SubQuery = (CountOnlyAcceptedCourses ? " AND crs_users.Accepted='Y'" : // Only if user accepted - ""); - Gbl.Cache.UsrBelongsToCrs.UsrCod = UsrCod; - Gbl.Cache.UsrBelongsToCrs.CrsCod = CrsCod; - Gbl.Cache.UsrBelongsToCrs.CountOnlyAcceptedCourses = CountOnlyAcceptedCourses; - Gbl.Cache.UsrBelongsToCrs.Belongs = - (DB_QueryCOUNT ("can not check if a user belongs to a course", - "SELECT COUNT(*)" - " FROM crs_users" - " WHERE CrsCod=%ld" - " AND UsrCod=%ld%s", - CrsCod,UsrCod,SubQuery) != 0); - return Gbl.Cache.UsrBelongsToCrs.Belongs; - } - -/*****************************************************************************/ -/***** Check if user belongs (no matter if he/she has accepted or not) *******/ -/***** to the current course *******/ -/*****************************************************************************/ - -void Usr_FlushCacheUsrBelongsToCurrentCrs (void) - { - Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = -1L; - Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = false; - } - -bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat) - { - /***** 1. Fast check: Trivial cases *****/ - if (UsrDat->UsrCod <= 0 || - Gbl.Hierarchy.Crs.CrsCod <= 0) - return false; - - /***** 2. Fast check: If cached... *****/ - if (UsrDat->UsrCod == Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod) - return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs; - - /***** 3. Fast check: If we know role of user in the current course *****/ - if (UsrDat->Roles.InCurrentCrs != Rol_UNK) - { - Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod; - Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = UsrDat->Roles.InCurrentCrs == Rol_STD || - UsrDat->Roles.InCurrentCrs == Rol_NET || - UsrDat->Roles.InCurrentCrs == Rol_TCH; - return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs; - } - - /***** 4. Fast / slow check: Get if user belongs to current course *****/ - Gbl.Cache.UsrBelongsToCurrentCrs.UsrCod = UsrDat->UsrCod; - Gbl.Cache.UsrBelongsToCurrentCrs.Belongs = Crs_CheckIfUsrBelongsToCrs (UsrDat->UsrCod, - Gbl.Hierarchy.Crs.CrsCod, - false); - return Gbl.Cache.UsrBelongsToCurrentCrs.Belongs; - } - -/*****************************************************************************/ -/***** Check if user belongs (no matter if he/she has accepted or not) *******/ -/***** to the current course *******/ -/*****************************************************************************/ - -void Usr_FlushCacheUsrHasAcceptedInCurrentCrs (void) - { - Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod = -1L; - Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted = false; - } - -bool Usr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat) - { - /***** 1. Fast check: Trivial cases *****/ - if (UsrDat->UsrCod <= 0 || - Gbl.Hierarchy.Crs.CrsCod <= 0) - return false; - - /***** 2. Fast check: If cached... *****/ - if (UsrDat->UsrCod == Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod) - return Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted; - - /***** 3. Fast / slow check: Get if user belongs to current course - and has accepted *****/ - Gbl.Cache.UsrHasAcceptedInCurrentCrs.UsrCod = UsrDat->UsrCod; - Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted = Crs_CheckIfUsrBelongsToCrs (UsrDat->UsrCod, - Gbl.Hierarchy.Crs.CrsCod, - true); - return Gbl.Cache.UsrHasAcceptedInCurrentCrs.Accepted; - } - -/*****************************************************************************/ -/********************** Check if I belong to a country **********************/ -/*****************************************************************************/ - -bool Cty_CheckIfIBelongToCty (long CtyCod) - { - unsigned NumMyCty; - - /***** Fill the list with the institutions I belong to *****/ - Cty_GetMyCountrs (); - - /***** Check if the country passed as parameter is any of my countries *****/ - for (NumMyCty = 0; - NumMyCty < Gbl.Usrs.Me.MyCtys.Num; - NumMyCty++) - if (Gbl.Usrs.Me.MyCtys.Ctys[NumMyCty].CtyCod == CtyCod) - return true; - return false; - } - -/*****************************************************************************/ -/******************** Check if I belong to an institution ********************/ -/*****************************************************************************/ - -bool Ins_CheckIfIBelongToIns (long InsCod) - { - unsigned NumMyIns; - - /***** Fill the list with the institutions I belong to *****/ - Ins_GetMyInstits (); - - /***** Check if the institution passed as parameter is any of my institutions *****/ - for (NumMyIns = 0; - NumMyIns < Gbl.Usrs.Me.MyInss.Num; - NumMyIns++) - if (Gbl.Usrs.Me.MyInss.Inss[NumMyIns].InsCod == InsCod) - return true; - return false; - } - -/*****************************************************************************/ -/*********************** Check if I belong to a center ***********************/ -/*****************************************************************************/ - -bool Ctr_CheckIfIBelongToCtr (long CtrCod) - { - unsigned NumMyCtr; - - /***** Fill the list with the centers I belong to *****/ - Ctr_GetMyCenters (); - - /***** Check if the center passed as parameter is any of my centers *****/ - for (NumMyCtr = 0; - NumMyCtr < Gbl.Usrs.Me.MyCtrs.Num; - NumMyCtr++) - if (Gbl.Usrs.Me.MyCtrs.Ctrs[NumMyCtr].CtrCod == CtrCod) - return true; - return false; - } - -/*****************************************************************************/ -/*********************** Check if I belong to a degree ***********************/ -/*****************************************************************************/ - -bool Deg_CheckIfIBelongToDeg (long DegCod) - { - unsigned NumMyDeg; - - /***** Fill the list with the degrees I belong to *****/ - Deg_GetMyDegrees (); - - /***** Check if the degree passed as parameter is any of my degrees *****/ - for (NumMyDeg = 0; - NumMyDeg < Gbl.Usrs.Me.MyDegs.Num; - NumMyDeg++) - if (Gbl.Usrs.Me.MyDegs.Degs[NumMyDeg].DegCod == DegCod) - return true; - return false; - } - -/*****************************************************************************/ -/*********************** Check if I belong to a course ***********************/ -/*****************************************************************************/ - -bool Crs_CheckIfIBelongToCrs (long CrsCod) - { - unsigned NumMyCrs; - - /***** Fill the list with the courses I belong to *****/ - Crs_GetMyCourses (); - - /***** Check if the course passed as parameter is any of my courses *****/ - for (NumMyCrs = 0; - NumMyCrs < Gbl.Usrs.Me.MyCrss.Num; - NumMyCrs++) - if (Gbl.Usrs.Me.MyCrss.Crss[NumMyCrs].CrsCod == CrsCod) - return true; - - return false; + return Enr_CheckIfUsrSharesAnyOfMyCrs (UsrDat); } /*****************************************************************************/ @@ -5350,8 +4310,8 @@ static void Usr_GetListUsrsFromQuery (char *Query,Rol_Role_t Role,HieLvl_Level_t case HieLvl_SYS: // System // Query result has not a column with the acceptation UsrInList->RoleInCurrentCrsDB = Rol_UNK; - if (Usr_DB_GetNumCrssOfUsr (UsrInList->UsrCod)) - UsrInList->Accepted = (Usr_DB_GetNumCrssOfUsrNotAccepted (UsrInList->UsrCod) == 0); + if (Enr_DB_GetNumCrssOfUsr (UsrInList->UsrCod)) + UsrInList->Accepted = (Enr_DB_GetNumCrssOfUsrNotAccepted (UsrInList->UsrCod) == 0); else UsrInList->Accepted = false; break; @@ -5361,7 +4321,7 @@ static void Usr_GetListUsrsFromQuery (char *Query,Rol_Role_t Role,HieLvl_Level_t case HieLvl_DEG: // Degree // Query result has not a column with the acceptation UsrInList->RoleInCurrentCrsDB = Rol_UNK; - UsrInList->Accepted = (Usr_DB_GetNumCrssOfUsrNotAccepted (UsrInList->UsrCod) == 0); + UsrInList->Accepted = (Enr_DB_GetNumCrssOfUsrNotAccepted (UsrInList->UsrCod) == 0); break; case HieLvl_CRS: // Course // Query result has a column with the acceptation @@ -5392,7 +4352,7 @@ static void Usr_GetListUsrsFromQuery (char *Query,Rol_Role_t Role,HieLvl_Level_t case HieLvl_DEG: // Degree // Query result has not a column with the acceptation UsrInList->RoleInCurrentCrsDB = Rol_UNK; - UsrInList->Accepted = (Usr_DB_GetNumCrssOfUsrWithARoleNotAccepted (UsrInList->UsrCod,Role) == 0); + UsrInList->Accepted = (Enr_DB_GetNumCrssOfUsrWithARoleNotAccepted (UsrInList->UsrCod,Role) == 0); break; case HieLvl_CRS: // Course // Query result has a column with the acceptation @@ -5530,7 +4490,7 @@ static void Usr_PutButtonToConfirmIWantToSeeBigList (unsigned NumUsrs, static void Usr_PutParamsConfirmIWantToSeeBigList (void *Args) { Grp_PutParamsCodGrps (); - Usr_PutParamsPrefsAboutUsrList (); + Set_PutParamsPrefsAboutUsrList (); if (Usr_FuncParamsBigList) Usr_FuncParamsBigList (Args); Par_PutHiddenParamChar ("ShowBigList",'Y'); @@ -6084,19 +5044,19 @@ void Usr_ShowFormsToSelectUsrListType (void (*FuncParams) (void *Args),void *Arg Set_BeginSettingsHead (); Set_BeginOneSettingSelector (); - /***** Select Usr_LIST_AS_CLASS_PHOTO *****/ + /***** Select Set_USR_LIST_AS_CLASS_PHOTO *****/ HTM_DIV_Begin ("class=\"%s\"", - Gbl.Usrs.Me.ListType == Usr_LIST_AS_CLASS_PHOTO ? "PREF_ON" : + Gbl.Usrs.Me.ListType == Set_USR_LIST_AS_CLASS_PHOTO ? "PREF_ON" : "PREF_OFF"); - Usr_FormToSelectUsrListType (FuncParams,Args, - Usr_LIST_AS_CLASS_PHOTO); + Set_FormToSelectUsrListType (FuncParams,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_PutParamsCodGrps (); - Usr_PutParamUsrListType (Usr_LIST_AS_CLASS_PHOTO); - Usr_PutParamListWithPhotos (); + Set_PutParamUsrListType (Set_USR_LIST_AS_CLASS_PHOTO); + Set_PutParamListWithPhotos (); Usr_PutSelectorNumColsClassPhoto (); if (FuncParams) FuncParams (Args); @@ -6105,16 +5065,16 @@ void Usr_ShowFormsToSelectUsrListType (void (*FuncParams) (void *Args),void *Arg /***** Select Usr_LIST_AS_LISTING *****/ HTM_DIV_Begin ("class=\"%s\"", - Gbl.Usrs.Me.ListType == Usr_LIST_AS_LISTING ? "PREF_ON" : + Gbl.Usrs.Me.ListType == Set_USR_LIST_AS_LISTING ? "PREF_ON" : "PREF_OFF"); - Usr_FormToSelectUsrListType (FuncParams,Args, - Usr_LIST_AS_LISTING); + Set_FormToSelectUsrListType (FuncParams,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_PutParamsCodGrps (); - Usr_PutParamUsrListType (Usr_LIST_AS_LISTING); + Set_PutParamUsrListType (Set_USR_LIST_AS_LISTING); if (FuncParams) FuncParams (Args); Usr_PutCheckboxListWithPhotos (); @@ -6129,18 +5089,18 @@ void Usr_ShowFormsToSelectUsrListType (void (*FuncParams) (void *Args),void *Arg /************* Put a radio element to select a users' list type **************/ /*****************************************************************************/ -static void Usr_FormToSelectUsrListType (void (*FuncParams) (void *Args),void *Args, - Usr_ShowUsrsType_t ListType) +static void Set_FormToSelectUsrListType (void (*FuncParams) (void *Args),void *Args, + Set_ShowUsrsType_t ListType) { extern const char *The_ClassFormLinkInBoxNoWrap[The_NUM_THEMES]; - extern const char *Txt_USR_LIST_TYPES[Usr_NUM_USR_LIST_TYPES]; + extern const char *Txt_USR_LIST_TYPES[Set_NUM_USR_LIST_TYPES]; /***** Begin form *****/ Frm_BeginFormAnchor (Gbl.Action.Act, // Repeat current action Usr_USER_LIST_SECTION_ID); Grp_PutParamsCodGrps (); - Usr_PutParamUsrListType (ListType); - Usr_PutParamListWithPhotos (); + Set_PutParamUsrListType (ListType); + Set_PutParamListWithPhotos (); if (FuncParams) FuncParams (Args); @@ -6187,7 +5147,7 @@ void Usr_PutFormToSelectUsrsToGoToAct (struct SelectedUsrs *SelectedUsrs, /***** Get and update type of list, number of columns in class photo and preference about view photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get groups to show ******/ Grp_GetParCodsSeveralGrpsToShowUsrs (); @@ -6329,11 +5289,11 @@ void Usr_ListUsersToSelect (Rol_Role_t Role,struct SelectedUsrs *SelectedUsrs) /***** Draw the classphoto/list *****/ switch (Gbl.Usrs.Me.ListType) { - case Usr_LIST_AS_CLASS_PHOTO: + case Set_USR_LIST_AS_CLASS_PHOTO: Usr_DrawClassPhoto (Usr_CLASS_PHOTO_SEL, Role,SelectedUsrs,true); break; - case Usr_LIST_AS_LISTING: + case Set_USR_LIST_AS_LISTING: Usr_ListUsrsForSelection (Role,SelectedUsrs); break; default: @@ -6410,7 +5370,7 @@ static Usr_Sex_t Usr_GetSexOfUsrsLst (Rol_Role_t Role) unsigned Usr_GetColumnsForSelectUsrs (void) { - return (Gbl.Usrs.Me.ListType == Usr_LIST_AS_CLASS_PHOTO) ? Gbl.Usrs.ClassPhoto.Cols : + 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); } @@ -6751,7 +5711,7 @@ void Usr_ListAllDataGsts (void) /***** Get and update type of list, number of columns in class photo and preference about viewing photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get scope *****/ Sco_SetScopesForListingGuests (); @@ -6862,7 +5822,7 @@ void Usr_ListAllDataStds (void) /***** Get and update type of list, number of columns in class photo and preference about viewing photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get scope *****/ Sco_SetScopesForListingStudents (); @@ -7106,7 +6066,7 @@ void Usr_ListAllDataTchs (void) /***** Get and update type of list, number of columns in class photo and preference about viewing photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get scope *****/ Gbl.Scope.Allowed = 1 << HieLvl_SYS | @@ -7376,7 +6336,7 @@ void Usr_ListDataAdms (void) /***** Get and update type of list, number of columns in class photo and preference about viewing photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get scope *****/ Gbl.Scope.Allowed = 1 << HieLvl_SYS | @@ -7398,7 +6358,7 @@ void Usr_ListDataAdms (void) /***** Form to select scope *****/ HTM_DIV_Begin ("class=\"CM\""); Frm_BeginForm (ActLstOth); - Usr_PutParamListWithPhotos (); + Set_PutParamListWithPhotos (); HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); HTM_TxtColonNBSP (Txt_Scope); Sco_PutSelectorScope ("ScopeUsr",HTM_SUBMIT_ON_CHANGE); @@ -7466,353 +6426,6 @@ void Usr_ListDataAdms (void) Usr_FreeUsrsList (Rol_DEG_ADM); } -/*****************************************************************************/ -/**************** Put hidden parameters with type of list, *******************/ -/**************** number of columns in class photo *******************/ -/**************** and preference about viewing photos *******************/ -/*****************************************************************************/ - -void Usr_PutParamsPrefsAboutUsrList (void) - { - Usr_PutParamUsrListType (Gbl.Usrs.Me.ListType); - Usr_PutParamColsClassPhoto (); - Usr_PutParamListWithPhotos (); - } - -/*****************************************************************************/ -/****************** Get and update type of list, **********************/ -/****************** number of columns in class photo **********************/ -/****************** and preference about viewing photos **********************/ -/*****************************************************************************/ - -void Usr_GetAndUpdatePrefsAboutUsrList (void) - { - /***** Get and update type of list *****/ - Usr_GetAndUpdateUsrListType (); - - /***** Get and update number of columns in class photo *****/ - Usr_GetAndUpdateColsClassPhoto (); - - /***** Get and update preference about viewing photos *****/ - Usr_GetAndUpdatePrefAboutListWithPhotos (); - } - -/*****************************************************************************/ -/****************** Get from form the type of users' list ********************/ -/*****************************************************************************/ - -static void Usr_GetAndUpdateUsrListType (void) - { - /***** Get type of list used to select users from form *****/ - Usr_GetUsrListTypeFromForm (); - - if (Gbl.Usrs.Me.ListType != Usr_LIST_UNKNOWN) - /* Save in the database the type of list preferred by me */ - Usr_DB_UpdateMyUsrListType (); - else - /* If parameter can't be retrieved from, - get my preference from database */ - Usr_GetMyUsrListTypeFromDB (); - } - -/*****************************************************************************/ -/************* Put a hidden parameter with the users' list type **************/ -/*****************************************************************************/ - -void Usr_PutParamUsrListType (Usr_ShowUsrsType_t ListType) - { - Par_PutHiddenParamUnsigned (NULL,"UsrListType",(unsigned) ListType); - } - -/*****************************************************************************/ -/****************** Get from form the type of users' list ********************/ -/*****************************************************************************/ - -static void Usr_GetUsrListTypeFromForm (void) - { - Gbl.Usrs.Me.ListType = (Usr_ShowUsrsType_t) - Par_GetParToUnsignedLong ("UsrListType", - 0, - Usr_NUM_USR_LIST_TYPES - 1, - (unsigned long) Usr_LIST_UNKNOWN); - } - -/*****************************************************************************/ -/************** Get my preference about type of users' list ******************/ -/*****************************************************************************/ - -static void Usr_GetMyUsrListTypeFromDB (void) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumRows; - Usr_ShowUsrsType_t ListType; - - /***** Get type of listing of users from database *****/ - NumRows = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get type of listing of users", - "SELECT UsrListType" // row[0] - " FROM crs_user_settings" - " WHERE UsrCod=%ld" - " AND CrsCod=%ld", - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Hierarchy.Crs.CrsCod); - if (NumRows == 1) // Should be one only row - { - /* Get type of users' listing used to select some of them */ - Gbl.Usrs.Me.ListType = Usr_SHOW_USRS_TYPE_DEFAULT; - row = mysql_fetch_row (mysql_res); - if (row[0]) - for (ListType = (Usr_ShowUsrsType_t) 0; - ListType <= (Usr_ShowUsrsType_t) (Usr_NUM_USR_LIST_TYPES - 1); - ListType++) - if (!strcasecmp (row[0],Usr_StringsUsrListTypeInDB[ListType])) - { - Gbl.Usrs.Me.ListType = ListType; - break; - } - } - else if (NumRows == 0) // If I am an administrator or superuser - // and I don't belong to current course, - // then the result will be the default - Gbl.Usrs.Me.ListType = Usr_SHOW_USRS_TYPE_DEFAULT; - else // Error in database: - // more than one row for a user in course - Err_ShowErrorAndExit ("Error when getting type of listing of users."); - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - } - -/*****************************************************************************/ -/***************** Save my preference about type of users' list **************/ -/*****************************************************************************/ - -static void Usr_DB_UpdateMyUsrListType (void) - { - /***** Update type of users listing *****/ - DB_QueryUPDATE ("can not update type of listing", - "UPDATE crs_user_settings" - " SET UsrListType='%s'" - " WHERE UsrCod=%ld" - " AND CrsCod=%ld", - Usr_StringsUsrListTypeInDB[Gbl.Usrs.Me.ListType], - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Hierarchy.Crs.CrsCod); - } - -/*****************************************************************************/ -/************* Get and update number of columns in class photo ***************/ -/*****************************************************************************/ - -void Usr_GetAndUpdateColsClassPhoto (void) - { - /***** Get the number of columns in class photo from form *****/ - Usr_GetParamColsClassPhotoFromForm (); - - if (Gbl.Usrs.ClassPhoto.Cols) - /* Save the number of columns into the database */ - Usr_DB_UpdateMyColsClassPhoto (); - else - /* If parameter can't be retrieved from form, - get my preference from database */ - Usr_GetMyColsClassPhotoFromDB (); - } - -/*****************************************************************************/ -/****** Put a hidden parameter with the number of colums in class photo ******/ -/*****************************************************************************/ - -void Usr_PutParamColsClassPhoto (void) - { - Par_PutHiddenParamUnsigned (NULL,"ColsClassPhoto",Gbl.Usrs.ClassPhoto.Cols); - } - -/*****************************************************************************/ -/************* Get from form the number of colums in class photo *************/ -/*****************************************************************************/ - -static void Usr_GetParamColsClassPhotoFromForm (void) - { - Gbl.Usrs.ClassPhoto.Cols = (unsigned) - Par_GetParToUnsignedLong ("ColsClassPhoto", - 1, - Usr_CLASS_PHOTO_COLS_MAX, - 0); - } - -/*****************************************************************************/ -/** Get my prefs. about number of colums in class photo for current course ***/ -/*****************************************************************************/ - -static void Usr_GetMyColsClassPhotoFromDB (void) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumRows; - - Gbl.Usrs.ClassPhoto.Cols = Usr_CLASS_PHOTO_COLS_DEF; - - /***** If user logged and course selected... *****/ - if (Gbl.Usrs.Me.Logged && - Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected - { - /***** Get number of columns in class photo from database *****/ - NumRows = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get number of columns in class photo", - "SELECT ColsClassPhoto" // row[0] - " FROM crs_user_settings" - " WHERE UsrCod=%ld" - " AND CrsCod=%ld", - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Hierarchy.Crs.CrsCod); - if (NumRows == 1) // Should be one only row - { - /* Get number of columns in class photo */ - row = mysql_fetch_row (mysql_res); - if (row[0]) - if (sscanf (row[0],"%u",&Gbl.Usrs.ClassPhoto.Cols) == 1) - if (Gbl.Usrs.ClassPhoto.Cols < 1 || - Gbl.Usrs.ClassPhoto.Cols > Usr_CLASS_PHOTO_COLS_MAX) - Gbl.Usrs.ClassPhoto.Cols = Usr_CLASS_PHOTO_COLS_DEF; - } - else if (NumRows > 1) // Error in database: - // more than one row for a user in course - Err_ShowErrorAndExit ("Error when getting number of columns" - " in class photo."); - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - } - } - -/*****************************************************************************/ -/** Save my prefs. about number of colums in class photo for current course **/ -/*****************************************************************************/ - -static void Usr_DB_UpdateMyColsClassPhoto (void) - { - if (Gbl.Usrs.Me.Logged && - Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected - /***** Update number of colums in class photo for current course *****/ - DB_QueryUPDATE ("can not update number of columns in class photo", - "UPDATE crs_user_settings" - " SET ColsClassPhoto=%u" - " WHERE UsrCod=%ld" - " AND CrsCod=%ld", - Gbl.Usrs.ClassPhoto.Cols, - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Hierarchy.Crs.CrsCod); - } - -/*****************************************************************************/ -/********** Get and update preference about photos in users' list ************/ -/*****************************************************************************/ - -static void Usr_GetAndUpdatePrefAboutListWithPhotos (void) - { - /***** Get my preference about photos in users' list from form *****/ - if (Usr_GetParamListWithPhotosFromForm ()) - /* Save preference about photos in users' list into the database */ - Usr_DB_UpdateMyPrefAboutListWithPhotosPhoto (); - else - /* If parameter can't be retrieved from form, - get my preference from database */ - Usr_GetMyPrefAboutListWithPhotosFromDB (); - } - -/*****************************************************************************/ -/** Put a hidden parameter with the preference about photos in users' list ***/ -/*****************************************************************************/ - -void Usr_PutParamListWithPhotos (void) - { - Par_PutHiddenParamChar ("WithPhotosExists",'Y'); - Par_PutHiddenParamChar ("WithPhotos", - Gbl.Usrs.Listing.WithPhotos ? 'Y' : - 'N'); - } - -/*****************************************************************************/ -/********* Get from form the preference about photos in users' list **********/ -/*****************************************************************************/ - -static bool Usr_GetParamListWithPhotosFromForm (void) - { - /***** Get if exists parameter with preference about photos in users' list *****/ - if (Par_GetParToBool ("WithPhotosExists")) - { - /***** Parameter with preference about photos in users' list exists, so get it *****/ - Gbl.Usrs.Listing.WithPhotos = Par_GetParToBool ("WithPhotos"); - return true; - } - - Gbl.Usrs.Listing.WithPhotos = Usr_LIST_WITH_PHOTOS_DEF; - return false; - } - -/*****************************************************************************/ -/***** Get my preference about photos in users' list for current course ******/ -/*****************************************************************************/ - -void Usr_GetMyPrefAboutListWithPhotosFromDB (void) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumRows; - - Gbl.Usrs.Listing.WithPhotos = Usr_LIST_WITH_PHOTOS_DEF; - - /***** If no user logged or not course selected... *****/ - if (Gbl.Usrs.Me.Logged && Gbl.Hierarchy.Crs.CrsCod) - { - /***** Get if listing of users must show photos from database *****/ - NumRows = (unsigned) - DB_QuerySELECT (&mysql_res,"can not check if listing of users" - " must show photos", - "SELECT ListWithPhotos" // row[0] - " FROM crs_user_settings" - " WHERE UsrCod=%ld" - " AND CrsCod=%ld", - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Hierarchy.Crs.CrsCod); - if (NumRows == 1) // Should be one only row - { - /* Get number of columns in class photo */ - Gbl.Usrs.Listing.WithPhotos = Usr_LIST_WITH_PHOTOS_DEF; - row = mysql_fetch_row (mysql_res); - Gbl.Usrs.Listing.WithPhotos = (row[0][0] == 'Y'); - } - else if (NumRows > 1) // Error in database: - // more than one row for a user in course - Err_ShowErrorAndExit ("Error when checking if listing of users" - " must show photos."); - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - } - } - -/*****************************************************************************/ -/**** Save my preference about photos in users' list for current course ******/ -/*****************************************************************************/ - -static void Usr_DB_UpdateMyPrefAboutListWithPhotosPhoto (void) - { - if (Gbl.Usrs.Me.Logged && - Gbl.Hierarchy.Level == HieLvl_CRS) // Course selected - /***** Update number of colums in class photo for current course *****/ - DB_QueryUPDATE ("can not update your preference about photos in listing", - "UPDATE crs_user_settings" - " SET ListWithPhotos='%c'" - " WHERE UsrCod=%ld" - " AND CrsCod=%ld", - Gbl.Usrs.Listing.WithPhotos ? 'Y' : - 'N', - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Hierarchy.Crs.CrsCod); - } - /*****************************************************************************/ /********** Put a link (form) to show list or class photo of guests **********/ /*****************************************************************************/ @@ -7868,7 +6481,7 @@ void Usr_SeeGuests (void) /***** Get and update type of list, number of columns in class photo and preference about view photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get scope *****/ Sco_SetScopesForListingGuests (); @@ -7887,7 +6500,7 @@ void Usr_SeeGuests (void) { HTM_DIV_Begin ("class=\"CM\""); Frm_BeginForm (ActLstGst); - Usr_PutParamsPrefsAboutUsrList (); + Set_PutParamsPrefsAboutUsrList (); HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); HTM_TxtColonNBSP (Txt_Scope); Sco_PutSelectorScope ("ScopeUsr",HTM_SUBMIT_ON_CHANGE); @@ -7909,7 +6522,7 @@ void Usr_SeeGuests (void) Usr_ShowFormsToSelectUsrListType (Sco_PutParamCurrentScope,&Gbl.Scope.Current); /***** Draw a class photo with guests *****/ - if (Gbl.Usrs.Me.ListType == Usr_LIST_AS_CLASS_PHOTO) + 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 : @@ -7930,12 +6543,12 @@ void Usr_SeeGuests (void) /* Draw the classphoto/list */ switch (Gbl.Usrs.Me.ListType) { - case Usr_LIST_AS_CLASS_PHOTO: + 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 Usr_LIST_AS_LISTING: + case Set_USR_LIST_AS_LISTING: Usr_ListMainDataGsts (PutForm); // Put checkbox to select users? break; default: @@ -8007,7 +6620,7 @@ void Usr_SeeStudents (void) /***** Get and update type of list, number of columns in class photo and preference about view photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get scope *****/ Sco_SetScopesForListingStudents (); @@ -8034,7 +6647,7 @@ void Usr_SeeStudents (void) case Rol_SYS_ADM: HTM_DIV_Begin ("class=\"CM\""); Frm_BeginForm (ActLstStd); - Usr_PutParamsPrefsAboutUsrList (); + Set_PutParamsPrefsAboutUsrList (); HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); HTM_TxtColonNBSP (Txt_Scope); Sco_PutSelectorScope ("ScopeUsr",HTM_SUBMIT_ON_CHANGE); @@ -8064,7 +6677,7 @@ void Usr_SeeStudents (void) Usr_ShowFormsToSelectUsrListType (Sco_PutParamCurrentScope,&Gbl.Scope.Current); /***** Draw a class photo with students of the course *****/ - if (Gbl.Usrs.Me.ListType == Usr_LIST_AS_CLASS_PHOTO) + 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 || @@ -8093,12 +6706,12 @@ void Usr_SeeStudents (void) /* Draw the classphoto/list */ switch (Gbl.Usrs.Me.ListType) { - case Usr_LIST_AS_CLASS_PHOTO: + 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 Usr_LIST_AS_LISTING: + case Set_USR_LIST_AS_LISTING: Usr_ListMainDataStds (PutForm); // Put checkbox to select users? break; default: @@ -8174,7 +6787,7 @@ void Usr_SeeTeachers (void) /***** Get and update type of list, number of columns in class photo and preference about view photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get scope *****/ Gbl.Scope.Allowed = 1 << HieLvl_SYS | @@ -8215,7 +6828,7 @@ void Usr_SeeTeachers (void) /***** Form to select scope *****/ HTM_DIV_Begin ("class=\"CM\""); Frm_BeginForm (ActLstTch); - Usr_PutParamsPrefsAboutUsrList (); + Set_PutParamsPrefsAboutUsrList (); HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); HTM_TxtColonNBSP (Txt_Scope); Sco_PutSelectorScope ("ScopeUsr",HTM_SUBMIT_ON_CHANGE); @@ -8241,7 +6854,7 @@ void Usr_SeeTeachers (void) Usr_ShowFormsToSelectUsrListType (Sco_PutParamCurrentScope,&Gbl.Scope.Current); /***** Draw a class photo with teachers of the course *****/ - if (Gbl.Usrs.Me.ListType == Usr_LIST_AS_CLASS_PHOTO) + 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 || @@ -8270,7 +6883,7 @@ void Usr_SeeTeachers (void) /***** Draw the classphoto/list *****/ switch (Gbl.Usrs.Me.ListType) { - case Usr_LIST_AS_CLASS_PHOTO: + 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, @@ -8279,7 +6892,7 @@ void Usr_SeeTeachers (void) Rol_NET,&Gbl.Usrs.Selected, PutForm); // Put checkbox to select users? break; - case Usr_LIST_AS_LISTING: + case Set_USR_LIST_AS_LISTING: /* Initialize field names */ Usr_SetUsrDatMainFieldNames (); @@ -8630,12 +7243,12 @@ static void Usr_PutIconsListGsts (__attribute__((unused)) void *Args) { switch (Gbl.Usrs.Me.ListType) { - case Usr_LIST_AS_CLASS_PHOTO: + case Set_USR_LIST_AS_CLASS_PHOTO: if (Gbl.Usrs.LstUsrs[Rol_GST].NumUsrs) /***** Put icon to print guests *****/ Usr_PutIconToPrintGsts (); break; - case Usr_LIST_AS_LISTING: + case Set_USR_LIST_AS_LISTING: /***** Put icon to show all data of guests *****/ Usr_PutIconToShowGstsAllData (); break; @@ -8655,12 +7268,12 @@ static void Usr_PutIconsListStds (__attribute__((unused)) void *Args) { switch (Gbl.Usrs.Me.ListType) { - case Usr_LIST_AS_CLASS_PHOTO: + case Set_USR_LIST_AS_CLASS_PHOTO: if (Gbl.Usrs.LstUsrs[Rol_STD].NumUsrs) /***** Put icon to print students *****/ Usr_PutIconToPrintStds (); break; - case Usr_LIST_AS_LISTING: + case Set_USR_LIST_AS_LISTING: /***** Put icon to show all data of students *****/ Usr_PutIconToShowStdsAllData (); break; @@ -8680,12 +7293,12 @@ static void Usr_PutIconsListTchs (__attribute__((unused)) void *Args) { switch (Gbl.Usrs.Me.ListType) { - case Usr_LIST_AS_CLASS_PHOTO: + case Set_USR_LIST_AS_CLASS_PHOTO: if (Gbl.Usrs.LstUsrs[Rol_TCH].NumUsrs) /***** Put icon to print teachers *****/ Usr_PutIconToPrintTchs (); break; - case Usr_LIST_AS_LISTING: + case Set_USR_LIST_AS_LISTING: /***** Put icon to show all data of teachers *****/ Usr_PutIconToShowTchsAllData (); break; @@ -8755,19 +7368,19 @@ static void Usr_PutIconToShowTchsAllData (void) static void Usr_ShowGstsAllDataParams (__attribute__((unused)) void *Args) { - Usr_PutParamListWithPhotos (); + Set_PutParamListWithPhotos (); } static void Usr_ShowStdsAllDataParams (__attribute__((unused)) void *Args) { Grp_PutParamsCodGrps (); - Usr_PutParamListWithPhotos (); + Set_PutParamListWithPhotos (); } static void Usr_ShowTchsAllDataParams (__attribute__((unused)) void *Args) { Sco_PutParamCurrentScope (&Gbl.Scope.Current); - Usr_PutParamListWithPhotos (); + Set_PutParamListWithPhotos (); } /*****************************************************************************/ @@ -8779,7 +7392,7 @@ void Usr_SeeGstClassPhotoPrn (void) /***** Get and update type of list, number of columns in class photo and preference about view photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get scope *****/ Sco_SetScopesForListingGuests (); @@ -8818,7 +7431,7 @@ void Usr_SeeStdClassPhotoPrn (void) /***** Get and update type of list, number of columns in class photo and preference about view photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get scope *****/ Sco_SetScopesForListingStudents (); @@ -8871,7 +7484,7 @@ void Usr_SeeTchClassPhotoPrn (void) /***** Get and update type of list, number of columns in class photo and preference about view photos *****/ - Usr_GetAndUpdatePrefsAboutUsrList (); + Set_GetAndUpdatePrefsAboutUsrList (); /***** Get scope *****/ Gbl.Scope.Allowed = 1 << HieLvl_SYS | @@ -9476,330 +8089,10 @@ unsigned Usr_GetCachedNumUsrsNotBelongingToAnyCrs (void) return NumGsts; } -/*****************************************************************************/ -/************ Get average number of courses with users of a role *************/ -/*****************************************************************************/ - -static double Usr_GetNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) - { - /***** Get number of courses per user from database *****/ - switch (Scope) - { - case HieLvl_SYS: - if (Role == Rol_UNK) // Any user - return DB_QuerySELECTDouble ("can not get number of courses per user", - "SELECT AVG(NumCrss)" - " FROM (SELECT COUNT(CrsCod) AS NumCrss" - " FROM crs_users" - " GROUP BY UsrCod) AS NumCrssTable"); - else - return DB_QuerySELECTDouble ("can not get number of courses per user", - "SELECT AVG(NumCrss)" - " FROM (SELECT COUNT(CrsCod) AS NumCrss" - " FROM crs_users" - " WHERE Role=%u" - " GROUP BY UsrCod) AS NumCrssTable", - (unsigned) Role); - case HieLvl_CTY: - if (Role == Rol_UNK) // Any user - return DB_QuerySELECTDouble ("can not get number of courses per user", - "SELECT AVG(NumCrss)" - " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" - " FROM ins_instits," - "ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ins_instits.CtyCod=%ld" - " AND ins_instits.InsCod=ctr_centers.InsCod" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " GROUP BY crs_users.UsrCod) AS NumCrssTable", - Cod); - else - return DB_QuerySELECTDouble ("can not get number of courses per user", - "SELECT AVG(NumCrss)" - " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" - " FROM ins_instits," - "ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ins_instits.CtyCod=%ld" - " AND ins_instits.InsCod=ctr_centers.InsCod" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role=%u" - " GROUP BY crs_users.UsrCod) AS NumCrssTable", - Cod, - (unsigned) Role); - case HieLvl_INS: - if (Role == Rol_UNK) // Any user - return DB_QuerySELECTDouble ("can not get number of courses per user", - "SELECT AVG(NumCrss)" - " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" - " FROM ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ctr_centers.InsCod=%ld" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " GROUP BY crs_users.UsrCod) AS NumCrssTable", - Cod); - else - return DB_QuerySELECTDouble ("can not get number of courses per user", - "SELECT AVG(NumCrss)" - " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" - " FROM ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ctr_centers.InsCod=%ld" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role=%u" - " GROUP BY crs_users.UsrCod) AS NumCrssTable", - Cod, - (unsigned) Role); - case HieLvl_CTR: - if (Role == Rol_UNK) // Any user - return DB_QuerySELECTDouble ("can not get number of courses per user", - "SELECT AVG(NumCrss)" - " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" - " FROM deg_degrees," - "crs_courses," - "crs_users" - " WHERE deg_degrees.CtrCod=%ld" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " GROUP BY crs_users.UsrCod) AS NumCrssTable", - Cod); - else - return DB_QuerySELECTDouble ("can not get number of courses per user", - "SELECT AVG(NumCrss)" - " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" - " FROM deg_degrees," - "crs_courses," - "crs_users" - " WHERE deg_degrees.CtrCod=%ld" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role=%u" - " GROUP BY crs_users.UsrCod) AS NumCrssTable", - Cod, - (unsigned) Role); - case HieLvl_DEG: - if (Role == Rol_UNK) // Any user - return DB_QuerySELECTDouble ("can not get number of courses per user", - "SELECT AVG(NumCrss)" - " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" - " FROM crs_courses," - "crs_users" - " WHERE crs_courses.DegCod=%ld" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " GROUP BY crs_users.UsrCod) AS NumCrssTable", - Cod); - else - return DB_QuerySELECTDouble ("can not get number of courses per user", - "SELECT AVG(NumCrss)" - " FROM (SELECT COUNT(crs_users.CrsCod) AS NumCrss" - " FROM crs_courses," - "crs_users" - " WHERE crs_courses.DegCod=%ld" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role=%u" - " GROUP BY crs_users.UsrCod) AS NumCrssTable", - Cod, - (unsigned) Role); - case HieLvl_CRS: - return 1.0; - default: - Err_WrongScopeExit (); - return 0.0; // Not reached - } - } - -double Usr_GetCachedNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) - { - static const FigCch_FigureCached_t FigureNumCrssPerUsr[Rol_NUM_ROLES] = - { - [Rol_UNK] = FigCch_NUM_CRSS_PER_USR, // Number of courses per user - [Rol_STD] = FigCch_NUM_CRSS_PER_STD, // Number of courses per student - [Rol_NET] = FigCch_NUM_CRSS_PER_NET, // Number of courses per non-editing teacher - [Rol_TCH] = FigCch_NUM_CRSS_PER_TCH, // Number of courses per teacher - }; - double NumCrssPerUsr; - - /***** Get number of courses per user from cache *****/ - if (!FigCch_GetFigureFromCache (FigureNumCrssPerUsr[Role],Scope,Cod, - FigCch_DOUBLE,&NumCrssPerUsr)) - { - /***** Get current number of courses per user from database and update cache *****/ - NumCrssPerUsr = Usr_GetNumCrssPerUsr (Scope,Cod,Role); - FigCch_UpdateFigureIntoCache (FigureNumCrssPerUsr[Role],Scope,Cod, - FigCch_DOUBLE,&NumCrssPerUsr); - } - - return NumCrssPerUsr; - } - /*****************************************************************************/ /************ Get average number of courses with users of a type *************/ /*****************************************************************************/ -static double Usr_GetNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) - { - /***** Get number of users per course from database *****/ - switch (Scope) - { - case HieLvl_SYS: - if (Role == Rol_UNK) // Any user - return DB_QuerySELECTDouble ("can not get number of users per course", - "SELECT AVG(NumUsrs)" - " FROM (SELECT COUNT(UsrCod) AS NumUsrs" - " FROM crs_users" - " GROUP BY CrsCod) AS NumUsrsTable"); - else - return DB_QuerySELECTDouble ("can not get number of users per course", - "SELECT AVG(NumUsrs)" - " FROM (SELECT COUNT(UsrCod) AS NumUsrs" - " FROM crs_users" - " WHERE Role=%u GROUP BY CrsCod) AS NumUsrsTable", - (unsigned) Role); - case HieLvl_CTY: - if (Role == Rol_UNK) // Any user - return DB_QuerySELECTDouble ("can not get number of users per course", - "SELECT AVG(NumUsrs)" - " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" - " FROM ins_instits," - "ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ins_instits.CtyCod=%ld" - " AND ins_instits.InsCod=ctr_centers.InsCod" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " GROUP BY crs_users.CrsCod) AS NumUsrsTable", - Cod); - else - return DB_QuerySELECTDouble ("can not get number of users per course", - "SELECT AVG(NumUsrs)" - " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" - " FROM ins_instits," - "ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ins_instits.CtyCod=%ld" - " AND ins_instits.InsCod=ctr_centers.InsCod" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role=%u" - " GROUP BY crs_users.CrsCod) AS NumUsrsTable", - Cod, - (unsigned) Role); - case HieLvl_INS: - if (Role == Rol_UNK) // Any user - return DB_QuerySELECTDouble ("can not get number of users per course", - "SELECT AVG(NumUsrs)" - " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" - " FROM ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ctr_centers.InsCod=%ld" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " GROUP BY crs_users.CrsCod) AS NumUsrsTable", - Cod); - else - return DB_QuerySELECTDouble ("can not get number of users per course", - "SELECT AVG(NumUsrs)" - " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" - " FROM ctr_centers," - "deg_degrees," - "crs_courses," - "crs_users" - " WHERE ctr_centers.InsCod=%ld" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role=%u" - " GROUP BY crs_users.CrsCod) AS NumUsrsTable", - Cod, - (unsigned) Role); - case HieLvl_CTR: - if (Role == Rol_UNK) // Any user - return DB_QuerySELECTDouble ("can not get number of users per course", - "SELECT AVG(NumUsrs)" - " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" - " FROM deg_degrees," - "crs_courses," - "crs_users" - " WHERE deg_degrees.CtrCod=%ld" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " GROUP BY crs_users.CrsCod) AS NumUsrsTable", - Cod); - else - return DB_QuerySELECTDouble ("can not get number of users per course", - "SELECT AVG(NumUsrs)" - " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" - " FROM deg_degrees," - "crs_courses," - "crs_users" - " WHERE deg_degrees.CtrCod=%ld" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role=%u" - " GROUP BY crs_users.CrsCod) AS NumUsrsTable", - Cod, - (unsigned) Role); - case HieLvl_DEG: - if (Role == Rol_UNK) // Any user - return DB_QuerySELECTDouble ("can not get number of users per course", - "SELECT AVG(NumUsrs)" - " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" - " FROM crs_courses," - "crs_users" - " WHERE crs_courses.DegCod=%ld" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " GROUP BY crs_users.CrsCod) AS NumUsrsTable", - Cod); - else - return DB_QuerySELECTDouble ("can not get number of users per course", - "SELECT AVG(NumUsrs)" - " FROM (SELECT COUNT(crs_users.UsrCod) AS NumUsrs" - " FROM crs_courses," - "crs_users" - " WHERE crs_courses.DegCod=%ld" - " AND crs_courses.CrsCod=crs_users.CrsCod" - " AND crs_users.Role=%u" - " GROUP BY crs_users.CrsCod) AS NumUsrsTable", - Cod, - (unsigned) Role); - case HieLvl_CRS: - return (double) Usr_GetNumUsrsInCrss (HieLvl_CRS,Cod, - Role == Rol_UNK ? 1 << Rol_STD | - 1 << Rol_NET | - 1 << Rol_TCH : // Any user - 1 << Role); - - default: - Err_WrongScopeExit (); - return 0.0; // Not reached - } - } - double Usr_GetCachedNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) { static const FigCch_FigureCached_t FigureNumUsrsPerCrs[Rol_NUM_ROLES] = @@ -9816,7 +8109,7 @@ double Usr_GetCachedNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role FigCch_DOUBLE,&NumUsrsPerCrs)) { /***** Get current number of users per course from database and update cache *****/ - NumUsrsPerCrs = Usr_GetNumUsrsPerCrs (Scope,Cod,Role); + NumUsrsPerCrs = Enr_DB_GetAverageNumUsrsPerCrs (Scope,Cod,Role); FigCch_UpdateFigureIntoCache (FigureNumUsrsPerCrs[Role],Scope,Cod, FigCch_DOUBLE,&NumUsrsPerCrs); } @@ -9825,28 +8118,31 @@ double Usr_GetCachedNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role } /*****************************************************************************/ -/****************** Check if a user is banned in ranking *********************/ +/************ Get average number of courses with users of a role *************/ /*****************************************************************************/ -bool Usr_DB_CheckIfUsrBanned (long UsrCod) +double Usr_GetCachedNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role) { - return (DB_QueryCOUNT ("can not check if user is banned", - "SELECT COUNT(*)" - " FROM usr_banned" - " WHERE UsrCod=%ld", - UsrCod) != 0); - } + static const FigCch_FigureCached_t FigureNumCrssPerUsr[Rol_NUM_ROLES] = + { + [Rol_UNK] = FigCch_NUM_CRSS_PER_USR, // Number of courses per user + [Rol_STD] = FigCch_NUM_CRSS_PER_STD, // Number of courses per student + [Rol_NET] = FigCch_NUM_CRSS_PER_NET, // Number of courses per non-editing teacher + [Rol_TCH] = FigCch_NUM_CRSS_PER_TCH, // Number of courses per teacher + }; + double NumCrssPerUsr; -/*****************************************************************************/ -/**************** Remove user from banned users in ranking *******************/ -/*****************************************************************************/ + /***** Get number of courses per user from cache *****/ + if (!FigCch_GetFigureFromCache (FigureNumCrssPerUsr[Role],Scope,Cod, + FigCch_DOUBLE,&NumCrssPerUsr)) + { + /***** Get current number of courses per user from database and update cache *****/ + NumCrssPerUsr = Enr_DB_GetAverageNumCrssPerUsr (Scope,Cod,Role); + FigCch_UpdateFigureIntoCache (FigureNumCrssPerUsr[Role],Scope,Cod, + FigCch_DOUBLE,&NumCrssPerUsr); + } -void Usr_DB_RemoveUsrFromBanned (long UsrCod) - { - DB_QueryDELETE ("can not remove user from users banned", - "DELETE FROM usr_banned" - " WHERE UsrCod=%ld", - UsrCod); + return NumCrssPerUsr; } /*****************************************************************************/ diff --git a/swad_user.h b/swad_user.h index 38f19d4e..1f5db56f 100644 --- a/swad_user.h +++ b/swad_user.h @@ -120,16 +120,6 @@ typedef enum Usr_CLASS_PHOTO_PRN, // Only print users } Usr_ClassPhotoType_t; -// Related with type of list of users -#define Usr_NUM_USR_LIST_TYPES 3 -typedef enum - { - Usr_LIST_UNKNOWN = 0, - Usr_LIST_AS_CLASS_PHOTO = 1, - Usr_LIST_AS_LISTING = 2, - } Usr_ShowUsrsType_t; -#define Usr_SHOW_USRS_TYPE_DEFAULT Usr_LIST_AS_CLASS_PHOTO - #define Usr_LIST_USRS_NUM_OPTIONS 8 typedef enum { @@ -305,26 +295,12 @@ void Usr_WriteFirstNameBRSurnames (const struct UsrData *UsrDat); void Usr_FlushCachesUsr (void); -bool Usr_DB_CheckIfUsrIsAdm (long UsrCod,HieLvl_Level_t Scope,long Cod); void Usr_FlushCacheUsrIsSuperuser (void); bool Usr_CheckIfUsrIsSuperuser (long UsrCod); bool Usr_ICanChangeOtherUsrData (const struct UsrData *UsrDat); bool Usr_ICanEditOtherUsr (const struct UsrData *UsrDat); -unsigned Usr_DB_GetNumCrssOfUsr (long UsrCod); -unsigned Usr_DB_GetNumCrssOfUsrNotAccepted (long UsrCod); -unsigned Usr_DB_GetNumCrssOfUsrWithARole (long UsrCod,Rol_Role_t Role); -unsigned Usr_DB_GetNumCrssOfUsrWithARoleNotAccepted (long UsrCod,Rol_Role_t Role); - -unsigned Usr_GetNumUsrsInCrssOfAUsr (long UsrCod,Rol_Role_t UsrRole, - unsigned OthersRoles); - -void Usr_FlushCacheUsrBelongsToCurrentCrs (void); -bool Usr_CheckIfUsrBelongsToCurrentCrs (const struct UsrData *UsrDat); -void Usr_FlushCacheUsrHasAcceptedInCurrentCrs (void); -bool Usr_CheckIfUsrHasAcceptedInCurrentCrs (const struct UsrData *UsrDat); - bool Usr_CheckIfICanViewRecordStd (const struct UsrData *UsrDat); bool Usr_CheckIfICanViewRecordTch (struct UsrData *UsrDat); bool Usr_CheckIfICanViewTstExaMchResult (const struct UsrData *UsrDat); @@ -332,41 +308,6 @@ bool Usr_CheckIfICanViewAsgWrk (const struct UsrData *UsrDat); bool Usr_CheckIfICanViewAtt (const struct UsrData *UsrDat); bool Usr_CheckIfICanViewUsrAgenda (struct UsrData *UsrDat); -void Usr_FlushCacheUsrSharesAnyOfMyCrs (void); -bool Usr_CheckIfUsrSharesAnyOfMyCrs (struct UsrData *UsrDat); -bool Usr_CheckIfUsrSharesAnyOfMyCrsWithDifferentRole (long UsrCod); - -void Cty_GetMyCountrs (void); -void Ins_GetMyInstits (void); -void Ctr_GetMyCenters (void); -void Deg_GetMyDegrees (void); -void Deg_GetUsrMainDeg (long UsrCod, - char ShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1], - Rol_Role_t *MaxRole); -void Crs_GetMyCourses (void); - -void Cty_FreeMyCountrs (void); -void Ins_FreeMyInstits (void); -void Ctr_FreeMyCenters (void); -void Deg_FreeMyDegrees (void); -void Crs_FreeMyCourses (void); - -void Ins_FlushCacheUsrBelongsToIns (void); -bool Ins_CheckIfUsrBelongsToIns (long UsrCod,long InsCod); -void Ctr_FlushCacheUsrBelongsToCtr (void); -bool Ctr_CheckIfUsrBelongsToCtr (long UsrCod,long CtrCod); -void Deg_FlushCacheUsrBelongsToDeg (void); -bool Deg_CheckIfUsrBelongsToDeg (long UsrCod,long DegCod); -void Crs_FlushCacheUsrBelongsToCrs (void); -bool Crs_CheckIfUsrBelongsToCrs (long UsrCod,long CrsCod, - bool CountOnlyAcceptedCourses); - -bool Cty_CheckIfIBelongToCty (long CtyCod); -bool Ins_CheckIfIBelongToIns (long InsCod); -bool Ctr_CheckIfIBelongToCtr (long CtrCod); -bool Deg_CheckIfIBelongToDeg (long DegCod); -bool Crs_CheckIfIBelongToCrs (long CrsCod); - void Usr_WriteLandingPage (void); void Usr_WriteFormLogout (void); void Usr_Logout (void); @@ -489,14 +430,6 @@ unsigned Usr_ListUsrsFound (Rol_Role_t Role, const char SearchQuery[Sch_MAX_BYTES_SEARCH_QUERY]); void Usr_ListDataAdms (void); -void Usr_PutParamsPrefsAboutUsrList (void); -void Usr_GetAndUpdatePrefsAboutUsrList (void); -void Usr_PutParamUsrListType (Usr_ShowUsrsType_t ListType); -void Usr_GetAndUpdateColsClassPhoto (void); -void Usr_PutParamColsClassPhoto (void); -void Usr_PutParamListWithPhotos (void); -void Usr_GetMyPrefAboutListWithPhotosFromDB (void); - void Usr_SeeGuests (void); void Usr_SeeStudents (void); void Usr_SeeTeachers (void); @@ -519,11 +452,8 @@ unsigned Usr_GetCachedNumUsrsInCrss (HieLvl_Level_t Scope,long Cod,unsigned Role unsigned Usr_GetCachedNumUsrsNotBelongingToAnyCrs (void); -double Usr_GetCachedNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); double Usr_GetCachedNumUsrsPerCrs (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); - -bool Usr_DB_CheckIfUsrBanned (long UsrCod); -void Usr_DB_RemoveUsrFromBanned (long UsrCod); +double Usr_GetCachedNumCrssPerUsr (HieLvl_Level_t Scope,long Cod,Rol_Role_t Role); void Usr_PrintUsrQRCode (void); diff --git a/swad_zip.c b/swad_zip.c index e4b85918..c3625ad0 100644 --- a/swad_zip.c +++ b/swad_zip.c @@ -162,7 +162,7 @@ void ZIP_CreateZIPAsgWrk (void) if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat, // Get user's data from database Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) - if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) + if (Enr_CheckIfUsrBelongsToCurrentCrs (&UsrDat)) ZIP_CreateDirCompressionUsr (&UsrDat); }