mirror of https://github.com/acanas/swad-core.git
Version 20.94.5: Jun 25, 2021 Queries moved to module swad_group_database.
This commit is contained in:
parent
0be1d7ba16
commit
6a8c7b9efe
|
@ -59,6 +59,7 @@
|
||||||
#include "swad_forum.h"
|
#include "swad_forum.h"
|
||||||
#include "swad_game.h"
|
#include "swad_game.h"
|
||||||
#include "swad_global.h"
|
#include "swad_global.h"
|
||||||
|
#include "swad_group_database.h"
|
||||||
#include "swad_hierarchy.h"
|
#include "swad_hierarchy.h"
|
||||||
#include "swad_holiday.h"
|
#include "swad_holiday.h"
|
||||||
#include "swad_ID.h"
|
#include "swad_ID.h"
|
||||||
|
@ -4113,7 +4114,7 @@ void Act_AdjustCurrentAction (void)
|
||||||
the only action possible
|
the only action possible
|
||||||
is show a form to register in groups *****/
|
is show a form to register in groups *****/
|
||||||
if (JustAfterLogin) // Only after login because the following query may be slow
|
if (JustAfterLogin) // Only after login because the following query may be slow
|
||||||
if (Grp_GetIfAvailableGrpTyp (-1L)) // This query may be slow
|
if (Grp_DB_CheckIfAvailableGrpTyp (-1L)) // This query may be slow
|
||||||
{
|
{
|
||||||
Gbl.Action.Act = ActReqSelGrp;
|
Gbl.Action.Act = ActReqSelGrp;
|
||||||
Tab_SetCurrentTab ();
|
Tab_SetCurrentTab ();
|
||||||
|
|
|
@ -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.
|
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
|
||||||
*/
|
*/
|
||||||
#define Log_PLATFORM_VERSION "SWAD 20.94.4 (2021-06-24)"
|
#define Log_PLATFORM_VERSION "SWAD 20.94.5 (2021-06-25)"
|
||||||
#define CSS_FILE "swad20.45.css"
|
#define CSS_FILE "swad20.45.css"
|
||||||
#define JS_FILE "swad20.69.1.js"
|
#define JS_FILE "swad20.69.1.js"
|
||||||
/*
|
/*
|
||||||
TODO: Rename CENTRE to CENTER in help wiki.
|
TODO: Rename CENTRE to CENTER in help wiki.
|
||||||
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
|
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
|
||||||
|
|
||||||
|
Version 20.94.5: Jun 25, 2021 Queries moved to module swad_group_database. (313686 lines)
|
||||||
Version 20.94.4: Jun 24, 2021 Queries moved to module swad_group_database. (313637 lines)
|
Version 20.94.4: Jun 24, 2021 Queries moved to module swad_group_database. (313637 lines)
|
||||||
Version 20.94.3: Jun 18, 2021 Queries moved to module swad_group_database. (313602 lines)
|
Version 20.94.3: Jun 18, 2021 Queries moved to module swad_group_database. (313602 lines)
|
||||||
Version 20.94.2: Jun 18, 2021 Queries moved to module swad_group_database. (313557 lines)
|
Version 20.94.2: Jun 18, 2021 Queries moved to module swad_group_database. (313557 lines)
|
||||||
|
|
252
swad_group.c
252
swad_group.c
|
@ -51,6 +51,7 @@
|
||||||
#include "swad_project.h"
|
#include "swad_project.h"
|
||||||
#include "swad_setting.h"
|
#include "swad_setting.h"
|
||||||
#include "swad_survey.h"
|
#include "swad_survey.h"
|
||||||
|
#include "swad_timetable.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*************************** Private constants *******************************/
|
/*************************** Private constants *******************************/
|
||||||
|
@ -135,7 +136,7 @@ static void Grp_PutFormToCreateGroupType (void);
|
||||||
static void Grp_PutFormToCreateGroup (const struct Roo_Rooms *Rooms);
|
static void Grp_PutFormToCreateGroup (const struct Roo_Rooms *Rooms);
|
||||||
static void Grp_GetDataOfGroupTypeByCod (struct GroupType *GrpTyp);
|
static void Grp_GetDataOfGroupTypeByCod (struct GroupType *GrpTyp);
|
||||||
static bool Grp_GetMultipleEnrolmentOfAGroupType (long GrpTypCod);
|
static bool Grp_GetMultipleEnrolmentOfAGroupType (long GrpTypCod);
|
||||||
static void Grp_GetLstCodGrpsUsrBelongs (long CrsCod,long GrpTypCod,long UsrCod,
|
static void Grp_GetLstCodGrpsUsrBelongs (long UsrCod,long GrpTypCod,
|
||||||
struct ListCodGrps *LstGrps);
|
struct ListCodGrps *LstGrps);
|
||||||
static bool Grp_CheckIfGrpIsInList (long GrpCod,struct ListCodGrps *LstGrps);
|
static bool Grp_CheckIfGrpIsInList (long GrpCod,struct ListCodGrps *LstGrps);
|
||||||
static bool Grp_CheckIfOpenTimeInTheFuture (time_t OpenTimeUTC);
|
static bool Grp_CheckIfOpenTimeInTheFuture (time_t OpenTimeUTC);
|
||||||
|
@ -536,8 +537,8 @@ void Grp_GetParCodsSeveralGrpsToShowUsrs (void)
|
||||||
{
|
{
|
||||||
/***** I I haven't selected any group, show by default the groups I belong to *****/
|
/***** I I haven't selected any group, show by default the groups I belong to *****/
|
||||||
/* Get list of groups of all types in current course I belong to */
|
/* Get list of groups of all types in current course I belong to */
|
||||||
Grp_GetLstCodGrpsUsrBelongs (Gbl.Hierarchy.Crs.CrsCod,-1L,
|
Grp_GetLstCodGrpsUsrBelongs (Gbl.Usrs.Me.UsrDat.UsrCod,-1L,
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,&LstGrpsIBelong);
|
&LstGrpsIBelong);
|
||||||
|
|
||||||
if (LstGrpsIBelong.NumGrps)
|
if (LstGrpsIBelong.NumGrps)
|
||||||
{
|
{
|
||||||
|
@ -778,8 +779,8 @@ bool Grp_ChangeMyGrpsAtomically (struct ListCodGrps *LstGrpsIWant)
|
||||||
Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS);
|
Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS);
|
||||||
|
|
||||||
/***** Query in the database the group codes which I belong to *****/
|
/***** Query in the database the group codes which I belong to *****/
|
||||||
Grp_GetLstCodGrpsUsrBelongs (Gbl.Hierarchy.Crs.CrsCod,-1L,
|
Grp_GetLstCodGrpsUsrBelongs (Gbl.Usrs.Me.UsrDat.UsrCod,-1L,
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,&LstGrpsIBelong);
|
&LstGrpsIBelong);
|
||||||
|
|
||||||
if (Gbl.Usrs.Me.Role.Logged == Rol_STD)
|
if (Gbl.Usrs.Me.Role.Logged == Rol_STD)
|
||||||
{
|
{
|
||||||
|
@ -919,8 +920,8 @@ void Grp_ChangeGrpsOtherUsrAtomically (struct ListCodGrps *LstGrpsUsrWants)
|
||||||
Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS);
|
Grp_GetListGrpTypesAndGrpsInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS);
|
||||||
|
|
||||||
/***** Query in the database the group codes which user belongs to *****/
|
/***** Query in the database the group codes which user belongs to *****/
|
||||||
Grp_GetLstCodGrpsUsrBelongs (Gbl.Hierarchy.Crs.CrsCod,-1L,
|
Grp_GetLstCodGrpsUsrBelongs (Gbl.Usrs.Other.UsrDat.UsrCod,-1L,
|
||||||
Gbl.Usrs.Other.UsrDat.UsrCod,&LstGrpsUsrBelongs);
|
&LstGrpsUsrBelongs);
|
||||||
|
|
||||||
/***** Go across the list of groups user belongs to, removing those groups that are not present in the list of groups user wants to belong to *****/
|
/***** Go across the list of groups user belongs to, removing those groups that are not present in the list of groups user wants to belong to *****/
|
||||||
for (NumGrpUsrBelongs = 0;
|
for (NumGrpUsrBelongs = 0;
|
||||||
|
@ -1079,8 +1080,8 @@ void Grp_RegisterUsrIntoGroups (struct UsrData *UsrDat,struct ListCodGrps *LstGr
|
||||||
/***** Query in the database the group codes of any group of this type the student belongs to *****/
|
/***** Query in the database the group codes of any group of this type the student belongs to *****/
|
||||||
LstGrpsHeBelongs.NumGrps = 0; // Initialized to avoid bug reported by Coverity
|
LstGrpsHeBelongs.NumGrps = 0; // Initialized to avoid bug reported by Coverity
|
||||||
LstGrpsHeBelongs.GrpCods = NULL; // Initialized to avoid bug reported by Coverity
|
LstGrpsHeBelongs.GrpCods = NULL; // Initialized to avoid bug reported by Coverity
|
||||||
Grp_GetLstCodGrpsUsrBelongs (Gbl.Hierarchy.Crs.CrsCod,Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].GrpTypCod,
|
Grp_GetLstCodGrpsUsrBelongs (UsrDat->UsrCod,Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].GrpTypCod,
|
||||||
UsrDat->UsrCod,&LstGrpsHeBelongs);
|
&LstGrpsHeBelongs);
|
||||||
|
|
||||||
/***** For each group selected by me... *****/
|
/***** For each group selected by me... *****/
|
||||||
for (NumGrpSel = 0;
|
for (NumGrpSel = 0;
|
||||||
|
@ -1144,8 +1145,8 @@ unsigned Grp_RemoveUsrFromGroups (struct UsrData *UsrDat,struct ListCodGrps *Lst
|
||||||
unsigned NumGrpsHeIsRemoved = 0;
|
unsigned NumGrpsHeIsRemoved = 0;
|
||||||
|
|
||||||
/***** Query in the database the group codes of any group the user belongs to *****/
|
/***** Query in the database the group codes of any group the user belongs to *****/
|
||||||
Grp_GetLstCodGrpsUsrBelongs (Gbl.Hierarchy.Crs.CrsCod,-1L,
|
Grp_GetLstCodGrpsUsrBelongs (UsrDat->UsrCod,-1L,
|
||||||
UsrDat->UsrCod,&LstGrpsHeBelongs);
|
&LstGrpsHeBelongs);
|
||||||
|
|
||||||
/***** For each group selected by me... *****/
|
/***** For each group selected by me... *****/
|
||||||
for (NumGrpSel = 0;
|
for (NumGrpSel = 0;
|
||||||
|
@ -1646,8 +1647,8 @@ void Grp_ListGrpsToEditAsgAttSvyEvtMch (struct GroupType *GrpTyp,
|
||||||
Grp_WriteGrpHead (GrpTyp);
|
Grp_WriteGrpHead (GrpTyp);
|
||||||
|
|
||||||
/***** Query from the database the groups of this type which I belong to *****/
|
/***** Query from the database the groups of this type which I belong to *****/
|
||||||
Grp_GetLstCodGrpsUsrBelongs (Gbl.Hierarchy.Crs.CrsCod,GrpTyp->GrpTypCod,
|
Grp_GetLstCodGrpsUsrBelongs (Gbl.Usrs.Me.UsrDat.UsrCod,GrpTyp->GrpTypCod,
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,&LstGrpsIBelong);
|
&LstGrpsIBelong);
|
||||||
|
|
||||||
/***** List the groups *****/
|
/***** List the groups *****/
|
||||||
for (NumGrpThisType = 0;
|
for (NumGrpThisType = 0;
|
||||||
|
@ -1823,9 +1824,9 @@ static void Grp_ShowWarningToStdsToChangeGrps (void)
|
||||||
// If there are groups of this type...
|
// If there are groups of this type...
|
||||||
if (GrpTyp->NumGrps)
|
if (GrpTyp->NumGrps)
|
||||||
// If I don't belong to any group
|
// If I don't belong to any group
|
||||||
if (!Grp_DB_CheckIfIBelongToGrpsOfType (GrpTyp->GrpTypCod)) // Fast check (not necesary, but avoid slow check)
|
if (!Grp_DB_CheckIfIBelongToGrpsOfType (GrpTyp->GrpTypCod)) // Fast check (not necesary, but avoid slow check)
|
||||||
// If there is any group of this type available
|
// If there is any group of this type available
|
||||||
if (Grp_GetIfAvailableGrpTyp (GrpTyp->GrpTypCod)) // Slow check
|
if (Grp_DB_CheckIfAvailableGrpTyp (GrpTyp->GrpTypCod)) // Slow check
|
||||||
{
|
{
|
||||||
if (GrpTyp->MandatoryEnrolment)
|
if (GrpTyp->MandatoryEnrolment)
|
||||||
Ale_ShowAlert (Ale_WARNING,GrpTyp->MultipleEnrolment ? Txt_You_have_to_register_compulsorily_at_least_in_one_group_of_type_X :
|
Ale_ShowAlert (Ale_WARNING,GrpTyp->MultipleEnrolment ? Txt_You_have_to_register_compulsorily_at_least_in_one_group_of_type_X :
|
||||||
|
@ -1860,8 +1861,8 @@ static bool Grp_ListGrpsForChangeMySelection (struct GroupType *GrpTyp,
|
||||||
Grp_WriteGrpHead (GrpTyp);
|
Grp_WriteGrpHead (GrpTyp);
|
||||||
|
|
||||||
/***** Query in the database the group of this type that I belong to *****/
|
/***** Query in the database the group of this type that I belong to *****/
|
||||||
Grp_GetLstCodGrpsUsrBelongs (Gbl.Hierarchy.Crs.CrsCod,GrpTyp->GrpTypCod,
|
Grp_GetLstCodGrpsUsrBelongs (Gbl.Usrs.Me.UsrDat.UsrCod,GrpTyp->GrpTypCod,
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,&LstGrpsIBelong);
|
&LstGrpsIBelong);
|
||||||
*NumGrpsThisTypeIBelong = LstGrpsIBelong.NumGrps;
|
*NumGrpsThisTypeIBelong = LstGrpsIBelong.NumGrps;
|
||||||
|
|
||||||
/***** Check if I can change my selection *****/
|
/***** Check if I can change my selection *****/
|
||||||
|
@ -2065,8 +2066,8 @@ static void Grp_ListGrpsToAddOrRemUsrs (struct GroupType *GrpTyp,long UsrCod)
|
||||||
|
|
||||||
/***** Query the groups of this type which the user belongs to *****/
|
/***** Query the groups of this type which the user belongs to *****/
|
||||||
if (UsrCod > 0)
|
if (UsrCod > 0)
|
||||||
Grp_GetLstCodGrpsUsrBelongs (Gbl.Hierarchy.Crs.CrsCod,GrpTyp->GrpTypCod,
|
Grp_GetLstCodGrpsUsrBelongs (Gbl.Usrs.Other.UsrDat.UsrCod,GrpTyp->GrpTypCod,
|
||||||
Gbl.Usrs.Other.UsrDat.UsrCod,&LstGrpsUsrBelongs);
|
&LstGrpsUsrBelongs);
|
||||||
|
|
||||||
/***** List the groups *****/
|
/***** List the groups *****/
|
||||||
for (NumGrpThisType = 0;
|
for (NumGrpThisType = 0;
|
||||||
|
@ -2131,8 +2132,8 @@ static void Grp_ListGrpsForMultipleSelection (struct GroupType *GrpTyp,
|
||||||
Grp_WriteGrpHead (GrpTyp);
|
Grp_WriteGrpHead (GrpTyp);
|
||||||
|
|
||||||
/***** Query from the database the groups of this type which I belong to *****/
|
/***** Query from the database the groups of this type which I belong to *****/
|
||||||
Grp_GetLstCodGrpsUsrBelongs (Gbl.Hierarchy.Crs.CrsCod,GrpTyp->GrpTypCod,
|
Grp_GetLstCodGrpsUsrBelongs (Gbl.Usrs.Me.UsrDat.UsrCod,GrpTyp->GrpTypCod,
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,&LstGrpsIBelong);
|
&LstGrpsIBelong);
|
||||||
|
|
||||||
/***** List the groups of this type *****/
|
/***** List the groups of this type *****/
|
||||||
for (NumGrpThisType = 0;
|
for (NumGrpThisType = 0;
|
||||||
|
@ -3016,7 +3017,7 @@ bool Grp_GetIfIBelongToGrp (long GrpCod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*************** Check if a user belongs to any of my courses ****************/
|
/***** Check if a user belongs to any of my groups in the current course *****/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (void)
|
void Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (void)
|
||||||
|
@ -3076,175 +3077,26 @@ bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat)
|
||||||
/***** 9. Slow check: Get if user shares any group in this course with me from database *****/
|
/***** 9. Slow check: Get if user shares any group in this course with me from database *****/
|
||||||
/* Check if user shares any group with me */
|
/* Check if user shares any group with me */
|
||||||
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod = UsrDat->UsrCod;
|
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.UsrCod = UsrDat->UsrCod;
|
||||||
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares =
|
Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares = Grp_DB_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (UsrDat->UsrCod);
|
||||||
(DB_QueryCOUNT ("can not check if a user shares any group"
|
|
||||||
" in the current course with you",
|
|
||||||
"SELECT COUNT(*)"
|
|
||||||
" FROM grp_users"
|
|
||||||
" WHERE UsrCod=%ld"
|
|
||||||
" AND GrpCod IN"
|
|
||||||
" (SELECT grp_users.GrpCod"
|
|
||||||
" FROM grp_users,"
|
|
||||||
"grp_groups,"
|
|
||||||
"grp_types"
|
|
||||||
" WHERE grp_users.UsrCod=%ld"
|
|
||||||
" AND grp_users.GrpCod=grp_groups.GrpCod"
|
|
||||||
" AND grp_groups.GrpTypCod=grp_types.GrpTypCod"
|
|
||||||
" AND grp_types.CrsCod=%ld)",
|
|
||||||
UsrDat->UsrCod,
|
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod,
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod) != 0);
|
|
||||||
return Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares;
|
return Gbl.Cache.UsrSharesAnyOfMyGrpsInCurrentCrs.Shares;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/**** Get if any group in group-type/this-course is open and has vacants *****/
|
|
||||||
/*****************************************************************************/
|
|
||||||
// If GrpTypCod > 0 ==> restrict to the given group type, mandatory or not
|
|
||||||
// If GrpTypCod <= 0 ==> all mandatory group types in the current course
|
|
||||||
|
|
||||||
bool Grp_GetIfAvailableGrpTyp (long GrpTypCod)
|
|
||||||
{
|
|
||||||
unsigned NumGrpTypes;
|
|
||||||
char *SubQueryGrpTypes;
|
|
||||||
|
|
||||||
if (GrpTypCod > 0) // restrict to the given group type, mandatory or not
|
|
||||||
{
|
|
||||||
if (asprintf (&SubQueryGrpTypes,"grp_types.GrpTypCod=%ld",
|
|
||||||
GrpTypCod) < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
}
|
|
||||||
else // all mandatory group types in the current course
|
|
||||||
{
|
|
||||||
if (asprintf (&SubQueryGrpTypes,"grp_types.CrsCod=%ld"
|
|
||||||
" AND grp_types.Mandatory='Y'",
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod) < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** Get the number of types of group in this course
|
|
||||||
with one or more open groups with vacants, from database *****/
|
|
||||||
NumGrpTypes = (unsigned)
|
|
||||||
DB_QueryCOUNT ("can not check if there has available mandatory group types",
|
|
||||||
"SELECT COUNT(GrpTypCod)"
|
|
||||||
" FROM ("
|
|
||||||
// Available mandatory groups with students
|
|
||||||
"SELECT GrpTypCod"
|
|
||||||
" FROM (SELECT grp_types.GrpTypCod AS GrpTypCod,"
|
|
||||||
"COUNT(*) AS NumStudents,"
|
|
||||||
"grp_groups.MaxStudents as MaxStudents"
|
|
||||||
" FROM grp_types,"
|
|
||||||
"grp_groups,"
|
|
||||||
"grp_users,"
|
|
||||||
"crs_users"
|
|
||||||
" WHERE %s" // Which group types?
|
|
||||||
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
|
||||||
" AND grp_groups.Open='Y'" // Open
|
|
||||||
" AND grp_groups.MaxStudents>0" // Admits students
|
|
||||||
" AND grp_types.CrsCod=crs_users.CrsCod"
|
|
||||||
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
|
||||||
" AND grp_users.UsrCod=crs_users.UsrCod"
|
|
||||||
" AND crs_users.Role=%u" // Student
|
|
||||||
" GROUP BY grp_groups.GrpCod"
|
|
||||||
" HAVING NumStudents<MaxStudents" // Not full
|
|
||||||
") AS available_grp_types_with_stds"
|
|
||||||
|
|
||||||
" UNION "
|
|
||||||
|
|
||||||
// Available mandatory groups...
|
|
||||||
"SELECT grp_types.GrpTypCod AS GrpTypCod"
|
|
||||||
" FROM grp_types,"
|
|
||||||
"grp_groups"
|
|
||||||
" WHERE %s" // Which group types?
|
|
||||||
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
|
||||||
" AND grp_groups.Open='Y'" // Open
|
|
||||||
" AND grp_groups.MaxStudents>0" // Admits students
|
|
||||||
// ...without students
|
|
||||||
" AND grp_groups.GrpCod NOT IN"
|
|
||||||
" (SELECT grp_users.GrpCod"
|
|
||||||
" FROM crs_users,"
|
|
||||||
"grp_users"
|
|
||||||
" WHERE crs_users.CrsCod=%ld"
|
|
||||||
" AND crs_users.Role=%u" // Student
|
|
||||||
" AND crs_users.UsrCod=grp_users.UsrCod)"
|
|
||||||
|
|
||||||
") AS available_grp_types"
|
|
||||||
|
|
||||||
// ...to which I don't belong
|
|
||||||
" WHERE GrpTypCod NOT IN"
|
|
||||||
" (SELECT grp_types.GrpTypCod"
|
|
||||||
" FROM grp_types,"
|
|
||||||
"grp_groups,"
|
|
||||||
"grp_users"
|
|
||||||
" WHERE %s" // Which group types?
|
|
||||||
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
|
||||||
" AND grp_groups.Open='Y'" // Open
|
|
||||||
" AND grp_groups.MaxStudents>0" // Admits students
|
|
||||||
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
|
||||||
" AND grp_users.UsrCod=%ld)", // I belong
|
|
||||||
|
|
||||||
SubQueryGrpTypes,(unsigned) Rol_STD,
|
|
||||||
SubQueryGrpTypes,
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod,(unsigned) Rol_STD,
|
|
||||||
SubQueryGrpTypes,Gbl.Usrs.Me.UsrDat.UsrCod);
|
|
||||||
|
|
||||||
/***** Free allocated memory for subquery *****/
|
|
||||||
free (SubQueryGrpTypes);
|
|
||||||
|
|
||||||
return (NumGrpTypes != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/****** Query list of group codes of a type to which a user belongs to *******/
|
/****** Query list of group codes of a type to which a user belongs to *******/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
// If CrsCod < 0 ==> get the groups from all the user's courses
|
|
||||||
// If GrpTypCod < 0 ==> get the groups of any type
|
// If GrpTypCod < 0 ==> get the groups of any type
|
||||||
|
|
||||||
static void Grp_GetLstCodGrpsUsrBelongs (long CrsCod,long GrpTypCod,
|
static void Grp_GetLstCodGrpsUsrBelongs (long UsrCod,long GrpTypCod,
|
||||||
long UsrCod,struct ListCodGrps *LstGrps)
|
struct ListCodGrps *LstGrps)
|
||||||
{
|
{
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
unsigned NumGrp;
|
unsigned NumGrp;
|
||||||
|
|
||||||
/***** Get groups which a user belong to from database *****/
|
/***** Get groups which a user belong to from database *****/
|
||||||
if (CrsCod < 0) // Query the groups from all the user's courses
|
if (GrpTypCod < 0) // Query the groups of any type in the current course
|
||||||
LstGrps->NumGrps = (unsigned)
|
LstGrps->NumGrps = Grp_DB_GetLstCodGrpsOfAnyTypeInCurrentCrsUsrBelongs (&mysql_res,UsrCod);
|
||||||
DB_QuerySELECT (&mysql_res,"can not get the groups which a user belongs to",
|
else // Query only the groups of specified type in the current course
|
||||||
"SELECT GrpCod" // row[0]
|
LstGrps->NumGrps = Grp_DB_GetLstCodGrpsOfATypeInCurrentCrsUsrBelongs (&mysql_res,UsrCod,GrpTypCod);
|
||||||
" FROM grp_users"
|
|
||||||
" WHERE UsrCod=%ld", // Groups will be unordered
|
|
||||||
UsrCod);
|
|
||||||
else if (GrpTypCod < 0) // Query the groups of any type in the course
|
|
||||||
LstGrps->NumGrps = (unsigned)
|
|
||||||
DB_QuerySELECT (&mysql_res,"can not get the groups which a user belongs to",
|
|
||||||
"SELECT grp_groups.GrpCod" // row[0]
|
|
||||||
" FROM grp_types,"
|
|
||||||
"grp_groups,"
|
|
||||||
"grp_users"
|
|
||||||
" WHERE grp_types.CrsCod=%ld"
|
|
||||||
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
|
||||||
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
|
||||||
" AND grp_users.UsrCod=%ld"
|
|
||||||
" ORDER BY grp_types.GrpTypName,"
|
|
||||||
"grp_groups.GrpName",
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod,
|
|
||||||
UsrCod);
|
|
||||||
else // Query only the groups of specified type in the course
|
|
||||||
LstGrps->NumGrps = (unsigned)
|
|
||||||
DB_QuerySELECT (&mysql_res,"can not get the groups which a user belongs to",
|
|
||||||
"SELECT grp_groups.GrpCod" // row[0]
|
|
||||||
" FROM grp_types,"
|
|
||||||
"grp_groups,"
|
|
||||||
"grp_users"
|
|
||||||
" WHERE grp_types.CrsCod=%ld"
|
|
||||||
" AND grp_types.GrpTypCod=%ld"
|
|
||||||
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
|
||||||
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
|
||||||
" AND grp_users.UsrCod=%ld"
|
|
||||||
" ORDER BY grp_groups.GrpName",
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod,
|
|
||||||
GrpTypCod,
|
|
||||||
UsrCod);
|
|
||||||
|
|
||||||
/***** Get the groups *****/
|
/***** Get the groups *****/
|
||||||
if (LstGrps->NumGrps)
|
if (LstGrps->NumGrps)
|
||||||
|
@ -3274,22 +3126,8 @@ void Grp_GetLstCodGrpsWithFileZonesIBelong (struct ListCodGrps *LstGrps)
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
unsigned NumGrp;
|
unsigned NumGrp;
|
||||||
|
|
||||||
/***** Get groups which I belong to from database *****/
|
/***** Get groups with file zones which I belong to from database *****/
|
||||||
LstGrps->NumGrps = (unsigned)
|
LstGrps->NumGrps = Grp_DB_GetLstCodGrpsWithFileZonesInCurrentCrsIBelong (&mysql_res);
|
||||||
DB_QuerySELECT (&mysql_res,"can not get the groups which you belong to",
|
|
||||||
"SELECT grp_groups.GrpCod" // row[0]
|
|
||||||
" FROM grp_types,"
|
|
||||||
"grp_groups,"
|
|
||||||
"grp_users"
|
|
||||||
" WHERE grp_types.CrsCod=%ld"
|
|
||||||
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
|
||||||
" AND grp_groups.FileZones='Y'"
|
|
||||||
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
|
||||||
" AND grp_users.UsrCod=%ld"
|
|
||||||
" ORDER BY grp_types.GrpTypName,"
|
|
||||||
"grp_groups.GrpName",
|
|
||||||
Gbl.Hierarchy.Crs.CrsCod,
|
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod);
|
|
||||||
|
|
||||||
/***** Get the groups *****/
|
/***** Get the groups *****/
|
||||||
if (LstGrps->NumGrps)
|
if (LstGrps->NumGrps)
|
||||||
|
@ -3323,6 +3161,7 @@ static bool Grp_CheckIfGrpIsInList (long GrpCod,struct ListCodGrps *LstGrps)
|
||||||
NumGrp++)
|
NumGrp++)
|
||||||
if (GrpCod == LstGrps->GrpCods[NumGrp])
|
if (GrpCod == LstGrps->GrpCods[NumGrp])
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3330,7 +3169,7 @@ static bool Grp_CheckIfGrpIsInList (long GrpCod,struct ListCodGrps *LstGrps)
|
||||||
/********** Query names of groups of a type which user belongs to ************/
|
/********** Query names of groups of a type which user belongs to ************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Grp_GetNamesGrpsStdBelongsTo (long GrpTypCod,long UsrCod,char *GroupNames)
|
void Grp_GetNamesGrpsUsrBelongsTo (long UsrCod,long GrpTypCod,char *GroupNames)
|
||||||
{
|
{
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
|
@ -3340,17 +3179,7 @@ void Grp_GetNamesGrpsStdBelongsTo (long GrpTypCod,long UsrCod,char *GroupNames)
|
||||||
Gbl.Crs.Grps.GrpTypes.NumGrpsTotal;
|
Gbl.Crs.Grps.GrpTypes.NumGrpsTotal;
|
||||||
|
|
||||||
/***** Get the names of groups which a user belongs to, from database *****/
|
/***** Get the names of groups which a user belongs to, from database *****/
|
||||||
NumGrps = (unsigned)
|
NumGrps = Grp_DB_GetNamesGrpsUsrBelongsTo (&mysql_res,UsrCod,GrpTypCod);
|
||||||
DB_QuerySELECT (&mysql_res,"can not get names of groups a user belongs to",
|
|
||||||
"SELECT grp_groups.GrpName" // row[0]
|
|
||||||
" FROM grp_groups,"
|
|
||||||
"grp_users"
|
|
||||||
" WHERE grp_groups.GrpTypCod=%ld"
|
|
||||||
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
|
||||||
" AND grp_users.UsrCod=%ld"
|
|
||||||
" ORDER BY grp_groups.GrpName",
|
|
||||||
GrpTypCod,
|
|
||||||
UsrCod);
|
|
||||||
|
|
||||||
/***** Get the groups *****/
|
/***** Get the groups *****/
|
||||||
GroupNames[0] = '\0';
|
GroupNames[0] = '\0';
|
||||||
|
@ -3684,15 +3513,8 @@ static void Grp_RemoveGroupTypeCompletely (void)
|
||||||
/***** Remove the associations of surveys to groups of this type *****/
|
/***** Remove the associations of surveys to groups of this type *****/
|
||||||
Svy_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod);
|
Svy_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod);
|
||||||
|
|
||||||
/***** Change all groups of this type in course timetable *****/
|
/***** Orphan all groups of this type in course timetable *****/
|
||||||
DB_QueryUPDATE ("can not update all groups of a type in course timetable",
|
Tmt_DB_OrphanAllGrpsOfATypeInCrsTimeTable (Gbl.Crs.Grps.GrpTyp.GrpTypCod);
|
||||||
"UPDATE tmt_courses"
|
|
||||||
" SET GrpCod=-1"
|
|
||||||
" WHERE GrpCod IN"
|
|
||||||
" (SELECT GrpCod"
|
|
||||||
" FROM grp_groups"
|
|
||||||
" WHERE GrpTypCod=%ld)",
|
|
||||||
Gbl.Crs.Grps.GrpTyp.GrpTypCod);
|
|
||||||
|
|
||||||
/***** Remove all the students in groups of this type *****/
|
/***** Remove all the students in groups of this type *****/
|
||||||
DB_QueryDELETE ("can not remove users from all groups of a type",
|
DB_QueryDELETE ("can not remove users from all groups of a type",
|
||||||
|
|
|
@ -200,10 +200,8 @@ bool Grp_GetIfIBelongToGrp (long GrpCod);
|
||||||
void Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (void);
|
void Grp_FlushCacheUsrSharesAnyOfMyGrpsInCurrentCrs (void);
|
||||||
bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat);
|
bool Grp_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (const struct UsrData *UsrDat);
|
||||||
|
|
||||||
bool Grp_GetIfAvailableGrpTyp (long GrpTypCod);
|
|
||||||
|
|
||||||
void Grp_GetLstCodGrpsWithFileZonesIBelong (struct ListCodGrps *LstGrps);
|
void Grp_GetLstCodGrpsWithFileZonesIBelong (struct ListCodGrps *LstGrps);
|
||||||
void Grp_GetNamesGrpsStdBelongsTo (long GrpTypCod,long UsrCod,char *GrpNames);
|
void Grp_GetNamesGrpsUsrBelongsTo (long UsrCod,long GrpTypCod,char *GroupNames);
|
||||||
void Grp_ReceiveFormNewGrpTyp (void);
|
void Grp_ReceiveFormNewGrpTyp (void);
|
||||||
void Grp_ReceiveFormNewGrp (void);
|
void Grp_ReceiveFormNewGrp (void);
|
||||||
void Grp_ReqRemGroupType (void);
|
void Grp_ReqRemGroupType (void);
|
||||||
|
|
|
@ -25,9 +25,9 @@
|
||||||
/*********************************** Headers *********************************/
|
/*********************************** Headers *********************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
// #define _GNU_SOURCE // For asprintf
|
#define _GNU_SOURCE // For asprintf
|
||||||
// #include <stddef.h> // For NULL
|
// #include <stddef.h> // For NULL
|
||||||
// #include <stdio.h> // For asprintf
|
#include <stdio.h> // For asprintf
|
||||||
// #include <stdlib.h> // For exit, system, malloc, free, rand, etc.
|
// #include <stdlib.h> // For exit, system, malloc, free, rand, etc.
|
||||||
// #include <string.h> // For string functions
|
// #include <string.h> // For string functions
|
||||||
|
|
||||||
|
@ -355,6 +355,32 @@ bool Grp_DB_CheckIfIBelongToGrp (long GrpCod)
|
||||||
Gbl.Usrs.Me.UsrDat.UsrCod) != 0);
|
Gbl.Usrs.Me.UsrDat.UsrCod) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***** Check if a user belongs to any of my groups in the current course *****/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned Grp_DB_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (long UsrCod)
|
||||||
|
{
|
||||||
|
return (unsigned)
|
||||||
|
(DB_QueryCOUNT ("can not check if a user shares any group"
|
||||||
|
" in the current course with you",
|
||||||
|
"SELECT COUNT(*)"
|
||||||
|
" FROM grp_users"
|
||||||
|
" WHERE UsrCod=%ld"
|
||||||
|
" AND GrpCod IN"
|
||||||
|
" (SELECT grp_users.GrpCod"
|
||||||
|
" FROM grp_users,"
|
||||||
|
"grp_groups,"
|
||||||
|
"grp_types"
|
||||||
|
" WHERE grp_users.UsrCod=%ld"
|
||||||
|
" AND grp_users.GrpCod=grp_groups.GrpCod"
|
||||||
|
" AND grp_groups.GrpTypCod=grp_types.GrpTypCod"
|
||||||
|
" AND grp_types.CrsCod=%ld)",
|
||||||
|
UsrCod,
|
||||||
|
Gbl.Usrs.Me.UsrDat.UsrCod,
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************** Get group types with groups in current course ****************/
|
/************** Get group types with groups in current course ****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -491,6 +517,96 @@ unsigned Grp_DB_GetGrpsOfType (MYSQL_RES **mysql_res,long GrpTypCod)
|
||||||
GrpTypCod);
|
GrpTypCod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/*********** Get the list of group codes of any type **************/
|
||||||
|
/*********** to which a user belongs to (in the current course) **************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned Grp_DB_GetLstCodGrpsOfAnyTypeInCurrentCrsUsrBelongs (MYSQL_RES **mysql_res,long UsrCod)
|
||||||
|
{
|
||||||
|
return (unsigned)
|
||||||
|
DB_QuerySELECT (mysql_res,"can not get the groups which a user belongs to",
|
||||||
|
"SELECT grp_groups.GrpCod" // row[0]
|
||||||
|
" FROM grp_types,"
|
||||||
|
"grp_groups,"
|
||||||
|
"grp_users"
|
||||||
|
" WHERE grp_types.CrsCod=%ld"
|
||||||
|
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
||||||
|
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
||||||
|
" AND grp_users.UsrCod=%ld"
|
||||||
|
" ORDER BY grp_types.GrpTypName,"
|
||||||
|
"grp_groups.GrpName",
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod,
|
||||||
|
UsrCod);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************ Get the list of group codes of a type *************/
|
||||||
|
/************ to which a user belongs to (in the current course) *************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned Grp_DB_GetLstCodGrpsOfATypeInCurrentCrsUsrBelongs (MYSQL_RES **mysql_res,long UsrCod,long GrpTypCod)
|
||||||
|
{
|
||||||
|
return (unsigned)
|
||||||
|
DB_QuerySELECT (mysql_res,"can not get the groups which a user belongs to",
|
||||||
|
"SELECT grp_groups.GrpCod" // row[0]
|
||||||
|
" FROM grp_types,"
|
||||||
|
"grp_groups,"
|
||||||
|
"grp_users"
|
||||||
|
" WHERE grp_types.CrsCod=%ld"
|
||||||
|
" AND grp_types.GrpTypCod=%ld"
|
||||||
|
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
||||||
|
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
||||||
|
" AND grp_users.UsrCod=%ld"
|
||||||
|
" ORDER BY grp_groups.GrpName",
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod,
|
||||||
|
GrpTypCod,
|
||||||
|
UsrCod);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**************** Get groups with file zones which I belong ******************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned Grp_DB_GetLstCodGrpsWithFileZonesInCurrentCrsIBelong (MYSQL_RES **mysql_res)
|
||||||
|
{
|
||||||
|
return (unsigned)
|
||||||
|
DB_QuerySELECT (mysql_res,"can not get the groups which you belong to",
|
||||||
|
"SELECT grp_groups.GrpCod" // row[0]
|
||||||
|
" FROM grp_types,"
|
||||||
|
"grp_groups,"
|
||||||
|
"grp_users"
|
||||||
|
" WHERE grp_types.CrsCod=%ld"
|
||||||
|
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
||||||
|
" AND grp_groups.FileZones='Y'"
|
||||||
|
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
||||||
|
" AND grp_users.UsrCod=%ld"
|
||||||
|
" ORDER BY grp_types.GrpTypName,"
|
||||||
|
"grp_groups.GrpName",
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod,
|
||||||
|
Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/********** Query names of groups of a type which user belongs to ************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
unsigned Grp_DB_GetNamesGrpsUsrBelongsTo (MYSQL_RES **mysql_res,
|
||||||
|
long UsrCod,long GrpTypCod)
|
||||||
|
{
|
||||||
|
return (unsigned)
|
||||||
|
DB_QuerySELECT (mysql_res,"can not get names of groups a user belongs to",
|
||||||
|
"SELECT grp_groups.GrpName" // row[0]
|
||||||
|
" FROM grp_groups,"
|
||||||
|
"grp_users"
|
||||||
|
" WHERE grp_groups.GrpTypCod=%ld"
|
||||||
|
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
||||||
|
" AND grp_users.UsrCod=%ld"
|
||||||
|
" ORDER BY grp_groups.GrpName",
|
||||||
|
GrpTypCod,
|
||||||
|
UsrCod);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********************** Get the type of group of a group *********************/
|
/********************** Get the type of group of a group *********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -577,6 +693,103 @@ void Grp_DB_ClearMustBeOpened (long GrpTypCod)
|
||||||
GrpTypCod);
|
GrpTypCod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**** Get if any group in group-type/this-course is open and has vacants *****/
|
||||||
|
/*****************************************************************************/
|
||||||
|
// If GrpTypCod > 0 ==> restrict to the given group type, mandatory or not
|
||||||
|
// If GrpTypCod <= 0 ==> all mandatory group types in the current course
|
||||||
|
|
||||||
|
bool Grp_DB_CheckIfAvailableGrpTyp (long GrpTypCod)
|
||||||
|
{
|
||||||
|
unsigned NumGrpTypes;
|
||||||
|
char *SubQueryGrpTypes;
|
||||||
|
|
||||||
|
if (GrpTypCod > 0) // restrict to the given group type, mandatory or not
|
||||||
|
{
|
||||||
|
if (asprintf (&SubQueryGrpTypes,"grp_types.GrpTypCod=%ld",
|
||||||
|
GrpTypCod) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
|
else // all mandatory group types in the current course
|
||||||
|
{
|
||||||
|
if (asprintf (&SubQueryGrpTypes,"grp_types.CrsCod=%ld"
|
||||||
|
" AND grp_types.Mandatory='Y'",
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Get the number of types of group in this course
|
||||||
|
with one or more open groups with vacants, from database *****/
|
||||||
|
NumGrpTypes = (unsigned)
|
||||||
|
DB_QueryCOUNT ("can not check if there has available mandatory group types",
|
||||||
|
"SELECT COUNT(GrpTypCod)"
|
||||||
|
" FROM ("
|
||||||
|
// Available mandatory groups with students
|
||||||
|
"SELECT GrpTypCod"
|
||||||
|
" FROM (SELECT grp_types.GrpTypCod AS GrpTypCod,"
|
||||||
|
"COUNT(*) AS NumStudents,"
|
||||||
|
"grp_groups.MaxStudents as MaxStudents"
|
||||||
|
" FROM grp_types,"
|
||||||
|
"grp_groups,"
|
||||||
|
"grp_users,"
|
||||||
|
"crs_users"
|
||||||
|
" WHERE %s" // Which group types?
|
||||||
|
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
||||||
|
" AND grp_groups.Open='Y'" // Open
|
||||||
|
" AND grp_groups.MaxStudents>0" // Admits students
|
||||||
|
" AND grp_types.CrsCod=crs_users.CrsCod"
|
||||||
|
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
||||||
|
" AND grp_users.UsrCod=crs_users.UsrCod"
|
||||||
|
" AND crs_users.Role=%u" // Student
|
||||||
|
" GROUP BY grp_groups.GrpCod"
|
||||||
|
" HAVING NumStudents<MaxStudents" // Not full
|
||||||
|
") AS available_grp_types_with_stds"
|
||||||
|
|
||||||
|
" UNION "
|
||||||
|
|
||||||
|
// Available mandatory groups...
|
||||||
|
"SELECT grp_types.GrpTypCod AS GrpTypCod"
|
||||||
|
" FROM grp_types,"
|
||||||
|
"grp_groups"
|
||||||
|
" WHERE %s" // Which group types?
|
||||||
|
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
||||||
|
" AND grp_groups.Open='Y'" // Open
|
||||||
|
" AND grp_groups.MaxStudents>0" // Admits students
|
||||||
|
// ...without students
|
||||||
|
" AND grp_groups.GrpCod NOT IN"
|
||||||
|
" (SELECT grp_users.GrpCod"
|
||||||
|
" FROM crs_users,"
|
||||||
|
"grp_users"
|
||||||
|
" WHERE crs_users.CrsCod=%ld"
|
||||||
|
" AND crs_users.Role=%u" // Student
|
||||||
|
" AND crs_users.UsrCod=grp_users.UsrCod)"
|
||||||
|
|
||||||
|
") AS available_grp_types"
|
||||||
|
|
||||||
|
// ...to which I don't belong
|
||||||
|
" WHERE GrpTypCod NOT IN"
|
||||||
|
" (SELECT grp_types.GrpTypCod"
|
||||||
|
" FROM grp_types,"
|
||||||
|
"grp_groups,"
|
||||||
|
"grp_users"
|
||||||
|
" WHERE %s" // Which group types?
|
||||||
|
" AND grp_types.GrpTypCod=grp_groups.GrpTypCod"
|
||||||
|
" AND grp_groups.Open='Y'" // Open
|
||||||
|
" AND grp_groups.MaxStudents>0" // Admits students
|
||||||
|
" AND grp_groups.GrpCod=grp_users.GrpCod"
|
||||||
|
" AND grp_users.UsrCod=%ld)", // I belong
|
||||||
|
|
||||||
|
SubQueryGrpTypes,(unsigned) Rol_STD,
|
||||||
|
SubQueryGrpTypes,
|
||||||
|
Gbl.Hierarchy.Crs.CrsCod,(unsigned) Rol_STD,
|
||||||
|
SubQueryGrpTypes,Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||||
|
|
||||||
|
/***** Free allocated memory for subquery *****/
|
||||||
|
free (SubQueryGrpTypes);
|
||||||
|
|
||||||
|
return (NumGrpTypes != 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*************************** Rename a group type *****************************/
|
/*************************** Rename a group type *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -65,6 +65,7 @@ unsigned Grp_DB_CountNumUsrsInNoGrpsOfType (Rol_Role_t Role,long GrpTypCod);
|
||||||
|
|
||||||
bool Grp_DB_CheckIfIBelongToGrpsOfType (long GrpTypCod);
|
bool Grp_DB_CheckIfIBelongToGrpsOfType (long GrpTypCod);
|
||||||
bool Grp_DB_CheckIfIBelongToGrp (long GrpCod);
|
bool Grp_DB_CheckIfIBelongToGrp (long GrpCod);
|
||||||
|
unsigned Grp_DB_CheckIfUsrSharesAnyOfMyGrpsInCurrentCrs (long UsrCod);
|
||||||
|
|
||||||
unsigned Grp_DB_GetGrpTypesWithGrpsInCurrentCrs (MYSQL_RES **mysql_res);
|
unsigned Grp_DB_GetGrpTypesWithGrpsInCurrentCrs (MYSQL_RES **mysql_res);
|
||||||
unsigned Grp_DB_GetAllGrpTypesInCurrentCrs (MYSQL_RES **mysql_res);
|
unsigned Grp_DB_GetAllGrpTypesInCurrentCrs (MYSQL_RES **mysql_res);
|
||||||
|
@ -75,6 +76,13 @@ unsigned Grp_DB_CountNumGrpsInCurrentCrs (void);
|
||||||
unsigned Grp_DB_CountNumGrpsInThisCrsOfType (long GrpTypCod);
|
unsigned Grp_DB_CountNumGrpsInThisCrsOfType (long GrpTypCod);
|
||||||
unsigned Grp_DB_GetGrpsOfType (MYSQL_RES **mysql_res,long GrpTypCod);
|
unsigned Grp_DB_GetGrpsOfType (MYSQL_RES **mysql_res,long GrpTypCod);
|
||||||
|
|
||||||
|
unsigned Grp_DB_GetLstCodGrpsInAllCrssUsrBelongs (MYSQL_RES **mysql_res,long UsrCod);
|
||||||
|
unsigned Grp_DB_GetLstCodGrpsOfAnyTypeInCurrentCrsUsrBelongs (MYSQL_RES **mysql_res,long UsrCod);
|
||||||
|
unsigned Grp_DB_GetLstCodGrpsOfATypeInCurrentCrsUsrBelongs (MYSQL_RES **mysql_res,long UsrCod,long GrpTypCod);
|
||||||
|
unsigned Grp_DB_GetLstCodGrpsWithFileZonesInCurrentCrsIBelong (MYSQL_RES **mysql_res);
|
||||||
|
unsigned Grp_DB_GetNamesGrpsUsrBelongsTo (MYSQL_RES **mysql_res,
|
||||||
|
long UsrCod,long GrpTypCod);
|
||||||
|
|
||||||
long Grp_DB_GetGrpTypeFromGrp (long GrpCod);
|
long Grp_DB_GetGrpTypeFromGrp (long GrpCod);
|
||||||
|
|
||||||
bool Grp_DB_CheckIfAssociatedToGrp (const char *Table,const char *Field,
|
bool Grp_DB_CheckIfAssociatedToGrp (const char *Table,const char *Field,
|
||||||
|
@ -84,6 +92,8 @@ bool Grp_DB_CheckIfAssociatedToGrps (const char *Table,const char *Field,long Co
|
||||||
void Grp_DB_OpenGrpsOfType (long GrpTypCod);
|
void Grp_DB_OpenGrpsOfType (long GrpTypCod);
|
||||||
void Grp_DB_ClearMustBeOpened (long GrpTypCod);
|
void Grp_DB_ClearMustBeOpened (long GrpTypCod);
|
||||||
|
|
||||||
|
bool Grp_DB_CheckIfAvailableGrpTyp (long GrpTypCod);
|
||||||
|
|
||||||
void Grp_DB_RenameGrpTyp (long GrpTypCod,
|
void Grp_DB_RenameGrpTyp (long GrpTypCod,
|
||||||
const char NewNameGrpTyp[Grp_MAX_BYTES_GROUP_TYPE_NAME + 1]);
|
const char NewNameGrpTyp[Grp_MAX_BYTES_GROUP_TYPE_NAME + 1]);
|
||||||
void Grp_DB_RenameGrp (long GrpCod,
|
void Grp_DB_RenameGrp (long GrpCod,
|
||||||
|
|
|
@ -1823,3 +1823,19 @@ static void Tmt_TimeTableDrawCell (const struct Tmt_Timetable *Timetable,
|
||||||
/***** End cell *****/
|
/***** End cell *****/
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************ Orphan all groups of this type in course timetable *************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Tmt_DB_OrphanAllGrpsOfATypeInCrsTimeTable (long GrpTypCod)
|
||||||
|
{
|
||||||
|
DB_QueryUPDATE ("can not update all groups of a type in course timetable",
|
||||||
|
"UPDATE tmt_courses"
|
||||||
|
" SET GrpCod=-1"
|
||||||
|
" WHERE GrpCod IN"
|
||||||
|
" (SELECT GrpCod"
|
||||||
|
" FROM grp_groups"
|
||||||
|
" WHERE GrpTypCod=%ld)",
|
||||||
|
Gbl.Crs.Grps.GrpTyp.GrpTypCod);
|
||||||
|
}
|
||||||
|
|
|
@ -115,4 +115,6 @@ void Tmt_EditCrsTimeTable (void);
|
||||||
void Tmt_EditMyTutTimeTable (void);
|
void Tmt_EditMyTutTimeTable (void);
|
||||||
void Tmt_ShowTimeTable (struct Tmt_Timetable *Timetable,long UsrCod);
|
void Tmt_ShowTimeTable (struct Tmt_Timetable *Timetable,long UsrCod);
|
||||||
|
|
||||||
|
void Tmt_DB_OrphanAllGrpsOfATypeInCrsTimeTable (long GrpTypCod);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
145
swad_user.c
145
swad_user.c
|
@ -3849,84 +3849,85 @@ static void Usr_WriteRowStdAllData (struct UsrData *UsrDat,char *GroupNames)
|
||||||
/***** Start row *****/
|
/***** Start row *****/
|
||||||
HTM_TR_Begin (NULL);
|
HTM_TR_Begin (NULL);
|
||||||
|
|
||||||
if (Gbl.Usrs.Listing.WithPhotos)
|
if (Gbl.Usrs.Listing.WithPhotos)
|
||||||
{
|
{
|
||||||
/***** Show student's photo *****/
|
/***** Show student's photo *****/
|
||||||
HTM_TD_Begin ("class=\"LM COLOR%u\"",Gbl.RowEvenOdd);
|
HTM_TD_Begin ("class=\"LM COLOR%u\"",Gbl.RowEvenOdd);
|
||||||
Pho_ShowUsrPhotoIfAllowed (UsrDat,"PHOTO21x28",Pho_NO_ZOOM,false);
|
Pho_ShowUsrPhotoIfAllowed (UsrDat,"PHOTO21x28",Pho_NO_ZOOM,false);
|
||||||
|
HTM_TD_End ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/****** Write user's ID ******/
|
||||||
|
HTM_TD_Begin ("class=\"%s LM COLOR%u\"",
|
||||||
|
UsrDat->Accepted ? "DAT_SMALL_N" :
|
||||||
|
"DAT_SMALL",
|
||||||
|
Gbl.RowEvenOdd);
|
||||||
|
ID_WriteUsrIDs (UsrDat,NULL);
|
||||||
|
HTM_NBSP ();
|
||||||
HTM_TD_End ();
|
HTM_TD_End ();
|
||||||
}
|
|
||||||
|
|
||||||
/****** Write user's ID ******/
|
/***** Write rest of main student's data *****/
|
||||||
HTM_TD_Begin ("class=\"%s LM COLOR%u\"",
|
Ins.InsCod = UsrDat->InsCod;
|
||||||
UsrDat->Accepted ? "DAT_SMALL_N" :
|
Ins_GetDataOfInstitutionByCod (&Ins);
|
||||||
"DAT_SMALL",
|
Usr_WriteMainUsrDataExceptUsrID (UsrDat,Gbl.ColorRows[Gbl.RowEvenOdd]);
|
||||||
Gbl.RowEvenOdd);
|
Usr_WriteEmail (UsrDat,Gbl.ColorRows[Gbl.RowEvenOdd]);
|
||||||
ID_WriteUsrIDs (UsrDat,NULL);
|
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],
|
||||||
HTM_NBSP ();
|
Ins.FullName,
|
||||||
HTM_TD_End ();
|
NULL,true,UsrDat->Accepted);
|
||||||
|
|
||||||
/***** Write rest of main student's data *****/
|
/***** Write the rest of the data of the student *****/
|
||||||
Ins.InsCod = UsrDat->InsCod;
|
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],
|
||||||
Ins_GetDataOfInstitutionByCod (&Ins);
|
UsrDat->Phone[0][0] ? (ShowData ? UsrDat->Phone[0] :
|
||||||
Usr_WriteMainUsrDataExceptUsrID (UsrDat,Gbl.ColorRows[Gbl.RowEvenOdd]);
|
"********") :
|
||||||
Usr_WriteEmail (UsrDat,Gbl.ColorRows[Gbl.RowEvenOdd]);
|
" ",
|
||||||
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],
|
NULL,true,UsrDat->Accepted);
|
||||||
Ins.FullName,
|
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],
|
||||||
NULL,true,UsrDat->Accepted);
|
UsrDat->Phone[1][0] ? (ShowData ? UsrDat->Phone[1] :
|
||||||
|
"********") :
|
||||||
|
" ",
|
||||||
|
NULL,true,UsrDat->Accepted);
|
||||||
|
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],
|
||||||
|
UsrDat->StrBirthday[0] ? (ShowData ? UsrDat->StrBirthday :
|
||||||
|
"********") :
|
||||||
|
" ",
|
||||||
|
NULL,true,UsrDat->Accepted);
|
||||||
|
|
||||||
/***** Write the rest of the data of the student *****/
|
if (Gbl.Scope.Current == HieLvl_CRS)
|
||||||
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],
|
{
|
||||||
UsrDat->Phone[0][0] ? (ShowData ? UsrDat->Phone[0] :
|
/***** Write the groups a the que pertenece the student *****/
|
||||||
"********") :
|
for (NumGrpTyp = 0;
|
||||||
" ",
|
NumGrpTyp < Gbl.Crs.Grps.GrpTypes.Num;
|
||||||
NULL,true,UsrDat->Accepted);
|
NumGrpTyp++)
|
||||||
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],
|
if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) // If current course tiene groups of este type
|
||||||
UsrDat->Phone[1][0] ? (ShowData ? UsrDat->Phone[1] :
|
{
|
||||||
"********") :
|
Grp_GetNamesGrpsUsrBelongsTo (UsrDat->UsrCod,
|
||||||
" ",
|
Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].GrpTypCod,
|
||||||
NULL,true,UsrDat->Accepted);
|
GroupNames);
|
||||||
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],
|
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],GroupNames,NULL,true,UsrDat->Accepted);
|
||||||
UsrDat->StrBirthday[0] ? (ShowData ? UsrDat->StrBirthday :
|
}
|
||||||
"********") :
|
|
||||||
" ",
|
|
||||||
NULL,true,UsrDat->Accepted);
|
|
||||||
|
|
||||||
if (Gbl.Scope.Current == HieLvl_CRS)
|
/***** Fields of the record dependientes of the course *****/
|
||||||
{
|
for (NumField = 0;
|
||||||
/***** Write the groups a the que pertenece the student *****/
|
NumField < Gbl.Crs.Records.LstFields.Num;
|
||||||
for (NumGrpTyp = 0;
|
NumField++)
|
||||||
NumGrpTyp < Gbl.Crs.Grps.GrpTypes.Num;
|
{
|
||||||
NumGrpTyp++)
|
/* Get the text of the field */
|
||||||
if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) // If current course tiene groups of este type
|
if (Rec_DB_GetFieldFromCrsRecord (&mysql_res,UsrDat->UsrCod,
|
||||||
{
|
Gbl.Crs.Records.LstFields.Lst[NumField].FieldCod))
|
||||||
Grp_GetNamesGrpsStdBelongsTo (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].GrpTypCod,
|
{
|
||||||
UsrDat->UsrCod,GroupNames);
|
row = mysql_fetch_row (mysql_res);
|
||||||
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],GroupNames,NULL,true,UsrDat->Accepted);
|
Str_Copy (Text,row[0],sizeof (Text) - 1);
|
||||||
}
|
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
||||||
|
Text,Cns_MAX_BYTES_TEXT,false); // Se convierte of HTML a HTML respetuoso
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Text[0] = '\0';
|
||||||
|
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],Text,NULL,false,UsrDat->Accepted);
|
||||||
|
|
||||||
/***** Fields of the record dependientes of the course *****/
|
/* Free structure that stores the query result */
|
||||||
for (NumField = 0;
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
NumField < Gbl.Crs.Records.LstFields.Num;
|
}
|
||||||
NumField++)
|
}
|
||||||
{
|
|
||||||
/* Get the text of the field */
|
|
||||||
if (Rec_DB_GetFieldFromCrsRecord (&mysql_res,UsrDat->UsrCod,
|
|
||||||
Gbl.Crs.Records.LstFields.Lst[NumField].FieldCod))
|
|
||||||
{
|
|
||||||
row = mysql_fetch_row (mysql_res);
|
|
||||||
Str_Copy (Text,row[0],sizeof (Text) - 1);
|
|
||||||
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
|
|
||||||
Text,Cns_MAX_BYTES_TEXT,false); // Se convierte of HTML a HTML respetuoso
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Text[0] = '\0';
|
|
||||||
Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],Text,NULL,false,UsrDat->Accepted);
|
|
||||||
|
|
||||||
/* Free structure that stores the query result */
|
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** End row *****/
|
/***** End row *****/
|
||||||
HTM_TR_End ();
|
HTM_TR_End ();
|
||||||
|
|
Loading…
Reference in New Issue