diff --git a/Makefile b/Makefile index 50ee88ad..ec1abebe 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_agenda.o \ swad_agenda_database.o swad_alert.o swad_announcement.o \ swad_announcement_database.o swad_API.o swad_assignment.o \ - swad_attendance.o \ + swad_assignment_database.o swad_attendance.o \ swad_banner.o swad_box.o swad_building.o swad_button.o \ swad_calendar.o swad_call_for_exam.o swad_center.o \ swad_center_config.o swad_chat.o swad_config.o swad_connected.o \ diff --git a/swad_account.c b/swad_account.c index c77f20c9..0c8c9d0d 100644 --- a/swad_account.c +++ b/swad_account.c @@ -30,7 +30,7 @@ #include "swad_account.h" #include "swad_account_database.h" #include "swad_agenda_database.h" -#include "swad_announcement.h" +#include "swad_announcement_database.h" #include "swad_attendance.h" #include "swad_box.h" #include "swad_calendar.h" diff --git a/swad_action.c b/swad_action.c index 6dc2f5ae..0646c002 100644 --- a/swad_action.c +++ b/swad_action.c @@ -582,7 +582,7 @@ const struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = [ActReqRemAsg ] = { 813,-1,TabUnk,ActSeeAsg ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Asg_ReqRemAssignment ,NULL}, [ActRemAsg ] = { 806,-1,TabUnk,ActSeeAsg ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Asg_RemoveAssignment ,NULL}, [ActHidAsg ] = { 964,-1,TabUnk,ActSeeAsg ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Asg_HideAssignment ,NULL}, - [ActShoAsg ] = { 965,-1,TabUnk,ActSeeAsg ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Asg_ShowAssignment ,NULL}, + [ActShoAsg ] = { 965,-1,TabUnk,ActSeeAsg ,0x220,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Asg_UnhideAssignment ,NULL}, [ActReqUsrPrj ] = {1805,-1,TabUnk,ActSeePrj ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_1ST_TAB,NULL ,Prj_ListUsrsToSelect ,NULL}, [ActSeeTblAllPrj ] = {1696,-1,TabUnk,ActSeePrj ,0x238,0x200, 0, 0, 0, 0, 0,Act_CONT_NORM,Act_BRW_NEW_TAB,NULL ,Prj_ShowTableSelectedPrjs ,NULL}, diff --git a/swad_assignment.c b/swad_assignment.c index 5c153ec7..312d6b52 100644 --- a/swad_assignment.c +++ b/swad_assignment.c @@ -33,6 +33,7 @@ #include // For string functions #include "swad_assignment.h" +#include "swad_assignment_database.h" #include "swad_box.h" #include "swad_database.h" #include "swad_error.h" @@ -93,14 +94,10 @@ static void Asg_GetDataOfAssignment (struct Asg_Assignment *Asg, unsigned NumAsgs); static void Asg_ResetAssignment (struct Asg_Assignment *Asg); static void Asg_FreeListAssignments (struct Asg_Assignments *Assignments); -static void Asg_GetAssignmentTxtFromDB (long AsgCod,char Txt[Cns_MAX_BYTES_TEXT + 1]); static void Asg_PutParamAsgCod (long AsgCod); -static bool Asg_CheckIfSimilarAssignmentExists (const char *Field,const char *Value,long AsgCod); static void Asg_ShowLstGrpsToEditAssignment (long AsgCod); -static void Asg_UpdateNumUsrsNotifiedByEMailAboutAssignment (long AsgCod,unsigned NumUsrsToBeNotifiedByEMail); static void Asg_CreateAssignment (struct Asg_Assignment *Asg,const char *Txt); static void Asg_UpdateAssignment (struct Asg_Assignment *Asg,const char *Txt); -static void Asg_RemoveAllTheGrpsAssociatedToAnAssignment (long AsgCod); static void Asg_CreateGrps (long AsgCod); static void Asg_GetAndWriteNamesOfGrpsAssociatedToAsg (struct Asg_Assignment *Asg); static bool Asg_CheckIfIBelongToCrsOrGrpsThisAssignment (long AsgCod); @@ -180,17 +177,19 @@ static void Asg_ShowAllAssignments (struct Asg_Assignments *Assignments) if (Assignments->Num) { - /***** Table head *****/ + /***** Begin table *****/ HTM_TABLE_BeginWideMarginPadding (2); - Asg_PutHeadForSeeing (Assignments,false); // Not print view - /***** Write all the assignments *****/ - for (NumAsg = Pagination.FirstItemVisible; - NumAsg <= Pagination.LastItemVisible; - NumAsg++) - Asg_ShowOneAssignment (Assignments, - Assignments->LstAsgCods[NumAsg - 1], - false); // Not print view + /***** Table head *****/ + Asg_PutHeadForSeeing (Assignments,false); // Not print view + + /***** Write all the assignments *****/ + for (NumAsg = Pagination.FirstItemVisible; + NumAsg <= Pagination.LastItemVisible; + NumAsg++) + Asg_ShowOneAssignment (Assignments, + Assignments->LstAsgCods[NumAsg - 1], + false); // Not print view /***** End table *****/ HTM_TABLE_End (); @@ -229,37 +228,48 @@ static void Asg_PutHeadForSeeing (struct Asg_Assignments *Assignments, HTM_TR_Begin (NULL); - HTM_TH (1,1,"CONTEXT_COL",NULL); // Column for contextual icons - for (Order = Dat_START_TIME; - Order <= Dat_END_TIME; - Order++) - { - HTM_TH_Begin (1,1,"LM"); - - if (!PrintView) + HTM_TH (1,1,"CONTEXT_COL",NULL); // Column for contextual icons + for (Order = Dat_START_TIME; + Order <= Dat_END_TIME; + Order++) { - Frm_BeginForm (ActSeeAsg); - WhichGroups = Grp_GetParamWhichGroups (); - Grp_PutParamWhichGroups (&WhichGroups); - Pag_PutHiddenParamPagNum (Pag_ASSIGNMENTS,Assignments->CurrentPage); - Dat_PutHiddenParamOrder (Order); - HTM_BUTTON_SUBMIT_Begin (Txt_START_END_TIME_HELP[Order],"BT_LINK TIT_TBL",NULL); - if (Order == Assignments->SelectedOrder) - HTM_U_Begin (); - } - HTM_Txt (Txt_START_END_TIME[Order]); - if (!PrintView) - { - if (Order == Assignments->SelectedOrder) - HTM_U_End (); - HTM_BUTTON_End (); - Frm_EndForm (); - } + /* Begin head cell */ + HTM_TH_Begin (1,1,"LM"); - HTM_TH_End (); - } - HTM_TH (1,1,"LM",Txt_Assignment); - HTM_TH (1,1,"LM",Txt_Folder); + if (!PrintView) + { + /* Begin form */ + Frm_BeginForm (ActSeeAsg); + WhichGroups = Grp_GetParamWhichGroups (); + Grp_PutParamWhichGroups (&WhichGroups); + Pag_PutHiddenParamPagNum (Pag_ASSIGNMENTS,Assignments->CurrentPage); + Dat_PutHiddenParamOrder (Order); + + /* Begin link to select order */ + HTM_BUTTON_SUBMIT_Begin (Txt_START_END_TIME_HELP[Order],"BT_LINK TIT_TBL",NULL); + if (Order == Assignments->SelectedOrder) + HTM_U_Begin (); + } + + /* Start / end text */ + HTM_Txt (Txt_START_END_TIME[Order]); + + if (!PrintView) + { + /* End link to select order */ + if (Order == Assignments->SelectedOrder) + HTM_U_End (); + HTM_BUTTON_End (); + + /* End form */ + Frm_EndForm (); + } + + /* End head cell */ + HTM_TH_End (); + } + HTM_TH (1,1,"LM",Txt_Assignment); + HTM_TH (1,1,"LM",Txt_Folder); HTM_TR_End (); } @@ -317,11 +327,15 @@ static void Asg_PutButtonToCreateNewAsg (void *Assignments) if (Assignments) { - ((struct Asg_Assignments *) Assignments)->AsgCodToEdit = -1L; - + /* Begin form */ Frm_BeginForm (ActFrmNewAsg); + ((struct Asg_Assignments *) Assignments)->AsgCodToEdit = -1L; Asg_PutParams (Assignments); - Btn_PutConfirmButton (Txt_New_assignment); + + /* Button to create new assignment */ + Btn_PutConfirmButton (Txt_New_assignment); + + /* End form */ Frm_EndForm (); } } @@ -361,15 +375,17 @@ void Asg_PrintOneAssignment (void) Gbl.Hierarchy.Deg.DegCod, Gbl.Hierarchy.Crs.CrsCod); - /***** Table head *****/ + /***** Begin table *****/ HTM_TABLE_BeginWideMarginPadding (2); - Asg_PutHeadForSeeing (&Assignments, - true); // Print view - /***** Write assignment *****/ - Asg_ShowOneAssignment (&Assignments, - AsgCod, - true); // Print view + /***** Table head *****/ + Asg_PutHeadForSeeing (&Assignments, + true); // Print view + + /***** Write assignment *****/ + Asg_ShowOneAssignment (&Assignments, + AsgCod, + true); // Print view /***** End table *****/ HTM_TABLE_End (); @@ -399,100 +415,102 @@ static void Asg_ShowOneAssignment (struct Asg_Assignments *Assignments, /***** Write first row of data of this assignment *****/ HTM_TR_Begin (NULL); - /* Forms to remove/edit this assignment */ - if (PrintView) - HTM_TD_Begin ("rowspan=\"2\" class=\"CONTEXT_COL\""); - else - { - HTM_TD_Begin ("rowspan=\"2\" class=\"CONTEXT_COL COLOR%u\"",Gbl.RowEvenOdd); - Asg_PutFormsToRemEditOneAsg (Assignments,&Asg,Anchor); - } - HTM_TD_End (); - - /* Start/end date/time */ - UniqueId++; - - for (StartEndTime = (Dat_StartEndTime_t) 0; - StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1); - StartEndTime++) - { - if (asprintf (&Id,"asg_date_%u_%u",(unsigned) StartEndTime,UniqueId) < 0) - Err_NotEnoughMemoryExit (); + /* Forms to remove/edit this assignment */ if (PrintView) - HTM_TD_Begin ("id=\"%s\" class=\"%s LB\"", - Id, - Asg.Hidden ? (Asg.Open ? "DATE_GREEN_LIGHT" : - "DATE_RED_LIGHT") : - (Asg.Open ? "DATE_GREEN" : - "DATE_RED")); + HTM_TD_Begin ("rowspan=\"2\" class=\"CONTEXT_COL\""); else - HTM_TD_Begin ("id=\"%s\" class=\"%s LB COLOR%u\"", - Id, - Asg.Hidden ? (Asg.Open ? "DATE_GREEN_LIGHT" : - "DATE_RED_LIGHT") : - (Asg.Open ? "DATE_GREEN" : - "DATE_RED"), - Gbl.RowEvenOdd); - Dat_WriteLocalDateHMSFromUTC (Id,Asg.TimeUTC[StartEndTime], - Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, - true,true,true,0x7); + { + HTM_TD_Begin ("rowspan=\"2\" class=\"CONTEXT_COL COLOR%u\"",Gbl.RowEvenOdd); + Asg_PutFormsToRemEditOneAsg (Assignments,&Asg,Anchor); + } HTM_TD_End (); - free (Id); - } - /* Assignment title */ - if (PrintView) - HTM_TD_Begin ("class=\"%s LT\"", - Asg.Hidden ? "ASG_TITLE_LIGHT" : - "ASG_TITLE"); - else - HTM_TD_Begin ("class=\"%s LT COLOR%u\"", - Asg.Hidden ? "ASG_TITLE_LIGHT" : - "ASG_TITLE", - Gbl.RowEvenOdd); - HTM_ARTICLE_Begin (Anchor); - HTM_Txt (Asg.Title); - HTM_ARTICLE_End (); - HTM_TD_End (); + /* Start/end date/time */ + UniqueId++; - /* Assignment folder */ - if (PrintView) - HTM_TD_Begin ("class=\"DAT LT\""); - else - HTM_TD_Begin ("class=\"DAT LT COLOR%u\"",Gbl.RowEvenOdd); - if (Asg.SendWork == Asg_SEND_WORK) - Asg_WriteAssignmentFolder (&Asg,PrintView); - HTM_TD_End (); + for (StartEndTime = (Dat_StartEndTime_t) 0; + StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1); + StartEndTime++) + { + if (asprintf (&Id,"asg_date_%u_%u",(unsigned) StartEndTime,UniqueId) < 0) + Err_NotEnoughMemoryExit (); + if (PrintView) + HTM_TD_Begin ("id=\"%s\" class=\"%s LB\"", + Id, + Asg.Hidden ? (Asg.Open ? "DATE_GREEN_LIGHT" : + "DATE_RED_LIGHT") : + (Asg.Open ? "DATE_GREEN" : + "DATE_RED")); + else + HTM_TD_Begin ("id=\"%s\" class=\"%s LB COLOR%u\"", + Id, + Asg.Hidden ? (Asg.Open ? "DATE_GREEN_LIGHT" : + "DATE_RED_LIGHT") : + (Asg.Open ? "DATE_GREEN" : + "DATE_RED"), + Gbl.RowEvenOdd); + Dat_WriteLocalDateHMSFromUTC (Id,Asg.TimeUTC[StartEndTime], + Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK, + true,true,true,0x7); + HTM_TD_End (); + free (Id); + } + + /* Assignment title */ + if (PrintView) + HTM_TD_Begin ("class=\"%s LT\"", + Asg.Hidden ? "ASG_TITLE_LIGHT" : + "ASG_TITLE"); + else + HTM_TD_Begin ("class=\"%s LT COLOR%u\"", + Asg.Hidden ? "ASG_TITLE_LIGHT" : + "ASG_TITLE", + Gbl.RowEvenOdd); + HTM_ARTICLE_Begin (Anchor); + HTM_Txt (Asg.Title); + HTM_ARTICLE_End (); + HTM_TD_End (); + + /* Assignment folder */ + if (PrintView) + HTM_TD_Begin ("class=\"DAT LT\""); + else + HTM_TD_Begin ("class=\"DAT LT COLOR%u\"",Gbl.RowEvenOdd); + if (Asg.SendWork == Asg_SEND_WORK) + Asg_WriteAssignmentFolder (&Asg,PrintView); + HTM_TD_End (); HTM_TR_End (); /***** Write second row of data of this assignment *****/ HTM_TR_Begin (NULL); - /* Author of the assignment */ - if (PrintView) - HTM_TD_Begin ("colspan=\"2\" class=\"LT\""); - else - HTM_TD_Begin ("colspan=\"2\" class=\"LT COLOR%u\"",Gbl.RowEvenOdd); - Asg_WriteAsgAuthor (&Asg); - HTM_TD_End (); + /* Author of the assignment */ + if (PrintView) + HTM_TD_Begin ("colspan=\"2\" class=\"LT\""); + else + HTM_TD_Begin ("colspan=\"2\" class=\"LT COLOR%u\"",Gbl.RowEvenOdd); + Asg_WriteAsgAuthor (&Asg); + HTM_TD_End (); - /* Text of the assignment */ - Asg_GetAssignmentTxtFromDB (Asg.AsgCod,Txt); - Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, - Txt,Cns_MAX_BYTES_TEXT,false); // Convert from HTML to recpectful HTML - Str_InsertLinks (Txt,Cns_MAX_BYTES_TEXT,60); // Insert links - if (PrintView) - HTM_TD_Begin ("colspan=\"2\" class=\"LT\""); - else - HTM_TD_Begin ("colspan=\"2\" class=\"LT COLOR%u\"",Gbl.RowEvenOdd); - if (Gbl.Crs.Grps.NumGrps) - Asg_GetAndWriteNamesOfGrpsAssociatedToAsg (&Asg); - HTM_DIV_Begin ("class=\"PAR %s\"",Asg.Hidden ? "DAT_LIGHT" : - "DAT"); - HTM_Txt (Txt); - HTM_DIV_End (); - HTM_TD_End (); + /* Text of the assignment */ + Asg_DB_GetAssignmentTxtByCod (Asg.AsgCod,Txt); + Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, + Txt,Cns_MAX_BYTES_TEXT,false); // Convert from HTML to recpectful HTML + Str_InsertLinks (Txt,Cns_MAX_BYTES_TEXT,60); // Insert links + if (PrintView) + HTM_TD_Begin ("colspan=\"2\" class=\"LT\""); + else + HTM_TD_Begin ("colspan=\"2\" class=\"LT COLOR%u\"",Gbl.RowEvenOdd); + if (Gbl.Crs.Grps.NumGrps) + Asg_GetAndWriteNamesOfGrpsAssociatedToAsg (&Asg); + + HTM_DIV_Begin ("class=\"PAR %s\"",Asg.Hidden ? "DAT_LIGHT" : + "DAT"); + HTM_Txt (Txt); + HTM_DIV_End (); + + HTM_TD_End (); HTM_TR_End (); @@ -591,10 +609,10 @@ static void Asg_WriteAssignmentFolder (struct Asg_Assignment *Asg,bool PrintView static Dat_StartEndTime_t Asg_GetParamAsgOrder (void) { return (Dat_StartEndTime_t) - Par_GetParToUnsignedLong ("Order", - 0, - Dat_NUM_START_END_TIME - 1, - (unsigned long) Asg_ORDER_DEFAULT); + Par_GetParToUnsignedLong ("Order", + 0, + Dat_NUM_START_END_TIME - 1, + (unsigned long) Asg_ORDER_DEFAULT); } /*****************************************************************************/ @@ -661,29 +679,11 @@ static void Asg_PutParams (void *Assignments) } /*****************************************************************************/ -/************************ List all the assignments ***************************/ +/*************************** List all assignments ****************************/ /*****************************************************************************/ static void Asg_GetListAssignments (struct Asg_Assignments *Assignments) { - static const char *HiddenSubQuery[Rol_NUM_ROLES] = - { - [Rol_UNK ] = " AND Hidden='N'", - [Rol_GST ] = " AND Hidden='N'", - [Rol_USR ] = " AND Hidden='N'", - [Rol_STD ] = " AND Hidden='N'", - [Rol_NET ] = " AND Hidden='N'", - [Rol_TCH ] = "", - [Rol_DEG_ADM] = " AND Hidden='N'", - [Rol_CTR_ADM] = " AND Hidden='N'", - [Rol_INS_ADM] = " AND Hidden='N'", - [Rol_SYS_ADM] = "", - }; - static const char *OrderBySubQuery[Dat_NUM_START_END_TIME] = - { - [Dat_START_TIME] = "StartTime DESC,EndTime DESC,Title DESC", - [Dat_END_TIME ] = "EndTime DESC,StartTime DESC,Title DESC", - }; MYSQL_RES *mysql_res; unsigned NumAsgs; unsigned NumAsg; @@ -693,40 +693,9 @@ static void Asg_GetListAssignments (struct Asg_Assignments *Assignments) /***** Get list of assignments from database *****/ if (Gbl.Crs.Grps.WhichGrps == Grp_MY_GROUPS) - NumAsgs = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get assignments", - "SELECT AsgCod" - " FROM asg_assignments" - " WHERE CrsCod=%ld%s" - " AND (" - // Assignment is for the whole course - "AsgCod NOT IN" - " (SELECT AsgCod" - " FROM asg_groups)" // Not associated to any group - " OR" - // Assignment is for some of my groups - " AsgCod IN" - " (SELECT asg_groups.AsgCod" - " FROM asg_groups," - "grp_users" - " WHERE grp_users.UsrCod=%ld" - " AND asg_groups.GrpCod=grp_users.GrpCod)" - ")" - " ORDER BY %s", - Gbl.Hierarchy.Crs.CrsCod, - HiddenSubQuery[Gbl.Usrs.Me.Role.Logged], - Gbl.Usrs.Me.UsrDat.UsrCod, - OrderBySubQuery[Assignments->SelectedOrder]); + NumAsgs = Asg_DB_GetListAssignmentsMyGrps (&mysql_res,Assignments->SelectedOrder); else // Gbl.Crs.Grps.WhichGrps == Grp_ALL_GROUPS - NumAsgs = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get assignments", - "SELECT AsgCod" - " FROM asg_assignments" - " WHERE CrsCod=%ld%s" - " ORDER BY %s", - Gbl.Hierarchy.Crs.CrsCod, - HiddenSubQuery[Gbl.Usrs.Me.Role.Logged], - OrderBySubQuery[Assignments->SelectedOrder]); + NumAsgs = Asg_DB_GetListAssignmentsAllGrps (&mysql_res,Assignments->SelectedOrder); if (NumAsgs) // Assignments found... { @@ -741,11 +710,9 @@ static void Asg_GetListAssignments (struct Asg_Assignments *Assignments) for (NumAsg = 0; NumAsg < Assignments->Num; NumAsg++) - { /* Get next assignment code */ if ((Assignments->LstAsgCods[NumAsg] = DB_GetNextCode (mysql_res)) <= 0) Err_WrongAssignmentExit (); - } } else Assignments->Num = 0; @@ -768,21 +735,7 @@ void Asg_GetDataOfAssignmentByCod (struct Asg_Assignment *Asg) if (Asg->AsgCod > 0) { /***** Build query *****/ - NumAsgs = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get assignment data", - "SELECT AsgCod," // row[0] - "Hidden," // row[1] - "UsrCod," // row[2] - "UNIX_TIMESTAMP(StartTime)," // row[3] - "UNIX_TIMESTAMP(EndTime)," // row[4] - "NOW() BETWEEN StartTime AND EndTime," // row[5] - "Title," // row[6] - "Folder" // row[7] - " FROM asg_assignments" - " WHERE AsgCod=%ld" - " AND CrsCod=%ld", - Asg->AsgCod, - Gbl.Hierarchy.Crs.CrsCod); + NumAsgs = Asg_DB_GetDataOfAssignmentByCod (&mysql_res,Asg->AsgCod); /***** Get data of assignment *****/ Asg_GetDataOfAssignment (Asg,&mysql_res,NumAsgs); @@ -807,21 +760,7 @@ void Asg_GetDataOfAssignmentByFolder (struct Asg_Assignment *Asg) if (Asg->Folder[0]) { /***** Query database *****/ - NumAsgs = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get assignment data", - "SELECT AsgCod," // row[0] - "Hidden," // row[1] - "UsrCod," // row[2] - "UNIX_TIMESTAMP(StartTime)," // row[3] - "UNIX_TIMESTAMP(EndTime)," // row[4] - "NOW() BETWEEN StartTime AND EndTime," // row[5] - "Title," // row[6] - "Folder" // row[7] - " FROM asg_assignments" - " WHERE CrsCod=%ld" - " AND Folder='%s'", - Gbl.Hierarchy.Crs.CrsCod, - Asg->Folder); + NumAsgs = Asg_DB_GetDataOfAssignmentByFolder (&mysql_res,Asg->Folder); /***** Get data of assignment *****/ Asg_GetDataOfAssignment (Asg,&mysql_res,NumAsgs); @@ -872,10 +811,8 @@ static void Asg_GetDataOfAssignment (struct Asg_Assignment *Asg, /* Get author of the assignment (row[2]) */ Asg->UsrCod = Str_ConvertStrCodToLongCod (row[2]); - /* Get start date (row[3] holds the start UTC time) */ + /* Get start and end dates (row[3] and row[4] hold the start UTC time) */ Asg->TimeUTC[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[3]); - - /* Get end date (row[4] holds the end UTC time) */ Asg->TimeUTC[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[4]); /* Get whether the assignment is open or closed (row(5)) */ @@ -931,22 +868,6 @@ static void Asg_FreeListAssignments (struct Asg_Assignments *Assignments) } } -/*****************************************************************************/ -/******************** Get assignment text from database **********************/ -/*****************************************************************************/ - -static void Asg_GetAssignmentTxtFromDB (long AsgCod,char Txt[Cns_MAX_BYTES_TEXT + 1]) - { - /***** Get text of assignment from database *****/ - DB_QuerySELECTString (Txt,Cns_MAX_BYTES_TEXT,"can not get assignment text", - "SELECT Txt" // row[0] - " FROM asg_assignments" - " WHERE AsgCod=%ld" - " AND CrsCod=%ld", - AsgCod, - Gbl.Hierarchy.Crs.CrsCod); - } - /*****************************************************************************/ /***************** Get summary and content of an assignment *****************/ /*****************************************************************************/ @@ -958,22 +879,12 @@ void Asg_GetNotifAssignment (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], { MYSQL_RES *mysql_res; MYSQL_ROW row; - unsigned NumAsgs; size_t Length; SummaryStr[0] = '\0'; // Return nothing on error - /***** Build query *****/ - NumAsgs = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get assignment title and text", - "SELECT Title," // row[0] - "Txt" // row[1] - " FROM asg_assignments" - " WHERE AsgCod=%ld", - AsgCod); - - /***** Result should have a unique row *****/ - if (NumAsgs == 1) + /***** Query database. Result should have a unique row *****/ + if (Asg_DB_GetAssignmentTitleAndTxtByCod (&mysql_res,AsgCod) == 1) { /***** Get row *****/ row = mysql_fetch_row (mysql_res); @@ -1082,15 +993,10 @@ void Asg_RemoveAssignment (void) Brw_RemoveFoldersAssignmentsIfExistForAllUsrs (Asg.Folder); /***** Remove all the groups of this assignment *****/ - Asg_RemoveAllTheGrpsAssociatedToAnAssignment (Asg.AsgCod); + Asg_DB_RemoveAllGrpsAssociatedToAnAssignment (Asg.AsgCod); /***** Remove assignment *****/ - DB_QueryDELETE ("can not remove assignment", - "DELETE FROM asg_assignments" - " WHERE AsgCod=%ld" - " AND CrsCod=%ld", - Asg.AsgCod, - Gbl.Hierarchy.Crs.CrsCod); + Asg_DB_RemoveAssignment (Asg.AsgCod); /***** Mark possible notifications as removed *****/ Ntf_MarkNotifAsRemoved (Ntf_EVENT_ASSIGNMENT,Asg.AsgCod); @@ -1128,23 +1034,17 @@ void Asg_HideAssignment (void) Asg_GetDataOfAssignmentByCod (&Asg); /***** Hide assignment *****/ - DB_QueryUPDATE ("can not hide assignment", - "UPDATE asg_assignments" - " SET Hidden='Y'" - " WHERE AsgCod=%ld" - " AND CrsCod=%ld", - Asg.AsgCod, - Gbl.Hierarchy.Crs.CrsCod); + Asg_DB_HideAssignment (Asg.AsgCod); /***** Show all assignments again *****/ Asg_ShowAllAssignments (&Assignments); } /*****************************************************************************/ -/**************************** Show an assignment *****************************/ +/**************************** Unhide an assignment ***************************/ /*****************************************************************************/ -void Asg_ShowAssignment (void) +void Asg_UnhideAssignment (void) { struct Asg_Assignments Assignments; struct Asg_Assignment Asg; @@ -1164,36 +1064,13 @@ void Asg_ShowAssignment (void) /***** Get data of the assignment from database *****/ Asg_GetDataOfAssignmentByCod (&Asg); - /***** Hide assignment *****/ - DB_QueryUPDATE ("can not show assignment", - "UPDATE asg_assignments" - " SET Hidden='N'" - " WHERE AsgCod=%ld" - " AND CrsCod=%ld", - Asg.AsgCod, - Gbl.Hierarchy.Crs.CrsCod); + /***** Unhide assignment *****/ + Asg_DB_UnhideAssignment (Asg.AsgCod); /***** Show all assignments again *****/ Asg_ShowAllAssignments (&Assignments); } -/*****************************************************************************/ -/******** Check if the title or the folder of an assignment exists ***********/ -/*****************************************************************************/ - -static bool Asg_CheckIfSimilarAssignmentExists (const char *Field,const char *Value,long AsgCod) - { - /***** Get number of assignments with a field value from database *****/ - return (DB_QueryCOUNT ("can not get similar assignments", - "SELECT COUNT(*)" - " FROM asg_assignments" - " WHERE CrsCod=%ld" - " AND %s='%s'" - " AND AsgCod<>%ld", - Gbl.Hierarchy.Crs.CrsCod, - Field,Value,AsgCod) != 0); - } - /*****************************************************************************/ /****************** Put a form to create a new assignment ********************/ /*****************************************************************************/ @@ -1255,7 +1132,7 @@ void Asg_RequestCreatOrEditAsg (void) Asg_GetDataOfAssignmentByCod (&Asg); /* Get text of the assignment from database */ - Asg_GetAssignmentTxtFromDB (Asg.AsgCod,Txt); + Asg_DB_GetAssignmentTxtByCod (Asg.AsgCod,Txt); } /***** Begin form *****/ @@ -1377,42 +1254,42 @@ static void Asg_ShowLstGrpsToEditAssignment (long AsgCod) /***** Begin box and table *****/ HTM_TR_Begin (NULL); - HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]); - HTM_TxtColon (Txt_Groups); - HTM_TD_End (); + HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]); + HTM_TxtColon (Txt_Groups); + HTM_TD_End (); - HTM_TD_Begin ("class=\"LT\""); - Box_BoxTableBegin ("100%",NULL, - NULL,NULL, - Hlp_USERS_Groups,Box_NOT_CLOSABLE,0); + HTM_TD_Begin ("class=\"LT\""); - /***** First row: checkbox to select the whole course *****/ - HTM_TR_Begin (NULL); + Box_BoxTableBegin ("100%",NULL, + NULL,NULL, + Hlp_USERS_Groups,Box_NOT_CLOSABLE,0); - HTM_TD_Begin ("colspan=\"7\" class=\"DAT LM\""); - HTM_LABEL_Begin (NULL); - HTM_INPUT_CHECKBOX ("WholeCrs",HTM_DONT_SUBMIT_ON_CHANGE, - "id=\"WholeCrs\" value=\"Y\"%s" - " onclick=\"uncheckChildren(this,'GrpCods')\"", - Grp_CheckIfAssociatedToGrps ("asg_groups","AsgCod",AsgCod) ? "" : - " checked=\"checked\""); - HTM_TxtF ("%s %s",Txt_The_whole_course,Gbl.Hierarchy.Crs.ShrtName); - HTM_LABEL_End (); - HTM_TD_End (); + /***** First row: checkbox to select the whole course *****/ + HTM_TR_Begin (NULL); + HTM_TD_Begin ("colspan=\"7\" class=\"DAT LM\""); + HTM_LABEL_Begin (NULL); + HTM_INPUT_CHECKBOX ("WholeCrs",HTM_DONT_SUBMIT_ON_CHANGE, + "id=\"WholeCrs\" value=\"Y\"%s" + " onclick=\"uncheckChildren(this,'GrpCods')\"", + Grp_CheckIfAssociatedToGrps ("asg_groups","AsgCod",AsgCod) ? "" : + " checked=\"checked\""); + HTM_TxtF ("%s %s",Txt_The_whole_course,Gbl.Hierarchy.Crs.ShrtName); + HTM_LABEL_End (); + HTM_TD_End (); + HTM_TR_End (); - HTM_TR_End (); + /***** List the groups for each group type *****/ + for (NumGrpTyp = 0; + NumGrpTyp < Gbl.Crs.Grps.GrpTypes.Num; + NumGrpTyp++) + if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) + Grp_ListGrpsToEditAsgAttSvyEvtMch (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp], + Grp_ASSIGNMENT,AsgCod); - /***** List the groups for each group type *****/ - for (NumGrpTyp = 0; - NumGrpTyp < Gbl.Crs.Grps.GrpTypes.Num; - NumGrpTyp++) - if (Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) - Grp_ListGrpsToEditAsgAttSvyEvtMch (&Gbl.Crs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp], - Grp_ASSIGNMENT,AsgCod); + /***** End table and box *****/ + Box_BoxTableEnd (); - /***** End table and box *****/ - Box_BoxTableEnd (); - HTM_TD_End (); + HTM_TD_End (); HTM_TR_End (); } @@ -1491,7 +1368,7 @@ void Asg_ReceiveFormAssignment (void) if (NewAsg.Title[0]) // If there's an assignment title { /* If title of assignment was in database... */ - if (Asg_CheckIfSimilarAssignmentExists ("Title",NewAsg.Title,NewAsg.AsgCod)) + if (Asg_DB_CheckIfSimilarAssignmentExists ("Title",NewAsg.Title,NewAsg.AsgCod)) { NewAssignmentIsCorrect = false; @@ -1504,7 +1381,7 @@ void Asg_ReceiveFormAssignment (void) { if (Str_ConvertFilFolLnkNameToValid (NewAsg.Folder)) // If folder name is valid... { - if (Asg_CheckIfSimilarAssignmentExists ("Folder",NewAsg.Folder,NewAsg.AsgCod)) // If folder of assignment was in database... + if (Asg_DB_CheckIfSimilarAssignmentExists ("Folder",NewAsg.Folder,NewAsg.AsgCod)) // If folder of assignment was in database... { NewAssignmentIsCorrect = false; @@ -1570,7 +1447,8 @@ void Asg_ReceiveFormAssignment (void) /***** Notify by email about the new assignment *****/ if ((NumUsrsToBeNotifiedByEMail = Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_ASSIGNMENT,NewAsg.AsgCod))) - Asg_UpdateNumUsrsNotifiedByEMailAboutAssignment (NewAsg.AsgCod,NumUsrsToBeNotifiedByEMail); + Asg_DB_UpdateNumUsrsNotifiedByEMailAboutAssignment (NewAsg.AsgCod, + NumUsrsToBeNotifiedByEMail); /***** Show all assignments again *****/ Asg_ShowAllAssignments (&Assignments); @@ -1580,21 +1458,6 @@ void Asg_ReceiveFormAssignment (void) Asg_RequestCreatOrEditAsg (); } -/*****************************************************************************/ -/******** Update number of users notified in table of assignments ************/ -/*****************************************************************************/ - -static void Asg_UpdateNumUsrsNotifiedByEMailAboutAssignment (long AsgCod,unsigned NumUsrsToBeNotifiedByEMail) - { - /***** Update number of users notified *****/ - DB_QueryUPDATE ("can not update the number of notifs. of an assignment", - "UPDATE asg_assignments" - " SET NumNotif=NumNotif+%u" - " WHERE AsgCod=%ld", - NumUsrsToBeNotifiedByEMail, - AsgCod); - } - /*****************************************************************************/ /************************ Create a new assignment ****************************/ /*****************************************************************************/ @@ -1602,23 +1465,7 @@ static void Asg_UpdateNumUsrsNotifiedByEMailAboutAssignment (long AsgCod,unsigne static void Asg_CreateAssignment (struct Asg_Assignment *Asg,const char *Txt) { /***** Create a new assignment *****/ - Asg->AsgCod = - DB_QueryINSERTandReturnCode ("can not create new assignment", - "INSERT INTO asg_assignments" - " (CrsCod,UsrCod," - "StartTime,EndTime," - "Title,Folder,Txt)" - " VALUES" - " (%ld,%ld," - "FROM_UNIXTIME(%ld),FROM_UNIXTIME(%ld)," - "'%s','%s','%s')", - Gbl.Hierarchy.Crs.CrsCod, - Gbl.Usrs.Me.UsrDat.UsrCod, - Asg->TimeUTC[Dat_START_TIME], - Asg->TimeUTC[Dat_END_TIME ], - Asg->Title, - Asg->Folder, - Txt); + Asg->AsgCod = Asg_DB_CreateAssignment (Asg,Txt); /***** Create groups *****/ if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) @@ -1632,76 +1479,17 @@ static void Asg_CreateAssignment (struct Asg_Assignment *Asg,const char *Txt) static void Asg_UpdateAssignment (struct Asg_Assignment *Asg,const char *Txt) { /***** Update the data of the assignment *****/ - DB_QueryUPDATE ("can not update assignment", - "UPDATE asg_assignments" - " SET StartTime=FROM_UNIXTIME(%ld)," - "EndTime=FROM_UNIXTIME(%ld)," - "Title='%s'," - "Folder='%s'," - "Txt='%s'" - " WHERE AsgCod=%ld" - " AND CrsCod=%ld", - Asg->TimeUTC[Dat_START_TIME], - Asg->TimeUTC[Dat_END_TIME ], - Asg->Title, - Asg->Folder, - Txt, - Asg->AsgCod, - Gbl.Hierarchy.Crs.CrsCod); + Asg_DB_UpdateAssignment (Asg,Txt); /***** Update groups *****/ /* Remove old groups */ - Asg_RemoveAllTheGrpsAssociatedToAnAssignment (Asg->AsgCod); + Asg_DB_RemoveAllGrpsAssociatedToAnAssignment (Asg->AsgCod); /* Create new groups */ if (Gbl.Crs.Grps.LstGrpsSel.NumGrps) Asg_CreateGrps (Asg->AsgCod); } -/*****************************************************************************/ -/********************* Remove groups of an assignment ************************/ -/*****************************************************************************/ - -static void Asg_RemoveAllTheGrpsAssociatedToAnAssignment (long AsgCod) - { - /***** Remove groups of the assignment *****/ - DB_QueryDELETE ("can not remove the groups associated to an assignment", - "DELETE FROM asg_groups" - " WHERE AsgCod=%ld", - AsgCod); - } - -/*****************************************************************************/ -/**************** Remove one group from all the assignments ******************/ -/*****************************************************************************/ - -void Asg_RemoveGroup (long GrpCod) - { - /***** Remove group from all the assignments *****/ - DB_QueryDELETE ("can not remove group from the associations" - " between assignments and groups", - "DELETE FROM asg_groups" - " WHERE GrpCod=%ld", - GrpCod); - } - -/*****************************************************************************/ -/*********** Remove groups of one type from all the assignments **************/ -/*****************************************************************************/ - -void Asg_RemoveGroupsOfType (long GrpTypCod) - { - /***** Remove group from all the assignments *****/ - DB_QueryDELETE ("can not remove groups of a type from the associations" - " between assignments and groups", - "DELETE FROM asg_groups" - " USING grp_groups," - "asg_groups" - " WHERE grp_groups.GrpTypCod=%ld" - " AND grp_groups.GrpCod=asg_groups.GrpCod", - GrpTypCod); - } - /*****************************************************************************/ /********************* Create groups of an assignment ************************/ /*****************************************************************************/ @@ -1714,14 +1502,7 @@ static void Asg_CreateGrps (long AsgCod) for (NumGrpSel = 0; NumGrpSel < Gbl.Crs.Grps.LstGrpsSel.NumGrps; NumGrpSel++) - /* Create group */ - DB_QueryINSERT ("can not associate a group to an assignment", - "INSERT INTO asg_groups" - " (AsgCod,GrpCod)" - " VALUES" - " (%ld,%ld)", - AsgCod, - Gbl.Crs.Grps.LstGrpsSel.GrpCods[NumGrpSel]); + Asg_DB_CreateGrp (AsgCod,Gbl.Crs.Grps.LstGrpsSel.GrpCods[NumGrpSel]); } /*****************************************************************************/ @@ -1740,52 +1521,39 @@ static void Asg_GetAndWriteNamesOfGrpsAssociatedToAsg (struct Asg_Assignment *As unsigned NumGrp; /***** Get groups associated to an assignment from database *****/ - NumGrps = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get groups of an assignment", - "SELECT grp_types.GrpTypName," // row[0] - "grp_groups.GrpName" // row[1] - " FROM asg_groups," - "grp_groups," - "grp_types" - " WHERE asg_groups.AsgCod=%ld" - " AND asg_groups.GrpCod=grp_groups.GrpCod" - " AND grp_groups.GrpTypCod=grp_types.GrpTypCod" - " ORDER BY grp_types.GrpTypName," - "grp_groups.GrpName", - Asg->AsgCod); + NumGrps = Asg_DB_GetGrps (&mysql_res,Asg->AsgCod); /***** Write heading *****/ HTM_DIV_Begin ("class=\"%s\"",Asg->Hidden ? "ASG_GRP_LIGHT" : "ASG_GRP"); - HTM_TxtColonNBSP (NumGrps == 1 ? Txt_Group : - Txt_Groups); - /***** Write groups *****/ - if (NumGrps) // Groups found... - { - /* Get and write the group types and names */ - for (NumGrp = 0; - NumGrp < NumGrps; - NumGrp++) - { - /* Get next group */ - row = mysql_fetch_row (mysql_res); + HTM_TxtColonNBSP (NumGrps == 1 ? Txt_Group : + Txt_Groups); - /* Write group type name and group name */ - HTM_TxtF ("%s %s",row[0],row[1]); + /***** Write groups *****/ + if (NumGrps) // Groups found... + /* Get and write the group types and names */ + for (NumGrp = 0; + NumGrp < NumGrps; + NumGrp++) + { + /* Get next group */ + row = mysql_fetch_row (mysql_res); - if (NumGrps >= 2) - { - if (NumGrp == NumGrps - 2) - HTM_TxtF (" %s ",Txt_and); - if (NumGrps >= 3) - if (NumGrp < NumGrps - 2) - HTM_Txt (", "); - } - } - } - else - HTM_TxtF ("%s %s",Txt_The_whole_course,Gbl.Hierarchy.Crs.ShrtName); + /* Write group type name and group name */ + HTM_TxtF ("%s %s",row[0],row[1]); + + if (NumGrps >= 2) + { + if (NumGrp == NumGrps - 2) + HTM_TxtF (" %s ",Txt_and); + if (NumGrps >= 3) + if (NumGrp < NumGrps - 2) + HTM_Txt (", "); + } + } + else + HTM_TxtF ("%s %s",Txt_The_whole_course,Gbl.Hierarchy.Crs.ShrtName); HTM_DIV_End (); @@ -1799,20 +1567,11 @@ static void Asg_GetAndWriteNamesOfGrpsAssociatedToAsg (struct Asg_Assignment *As void Asg_RemoveCrsAssignments (long CrsCod) { - /***** Remove groups *****/ - DB_QueryDELETE ("can not remove groups associated to assignments in a course", - "DELETE FROM asg_groups" - " USING asg_assignments," - "asg_groups" - " WHERE asg_assignments.CrsCod=%ld" - " AND asg_assignments.AsgCod=asg_groups.AsgCod", - CrsCod); + /***** Remove groups associated to assignments in course *****/ + Asg_DB_RemoveGrpsAssociatedToAsgsInCrs (CrsCod); /***** Remove assignments *****/ - DB_QueryDELETE ("can not remove all assignments in a course", - "DELETE FROM asg_assignments" - " WHERE CrsCod=%ld", - CrsCod); + Asg_DB_RemoveCrsAssignments (CrsCod); } /*****************************************************************************/ @@ -1828,25 +1587,7 @@ static bool Asg_CheckIfIBelongToCrsOrGrpsThisAssignment (long AsgCod) case Rol_TCH: // Students and teachers can do assignments depending on groups /***** Get if I can do an assignment from database *****/ - return (DB_QueryCOUNT ("can not check if I can do an assignment", - "SELECT COUNT(*)" - " FROM asg_assignments" - " WHERE AsgCod=%ld" - " AND (" - // Assignment is for the whole course - "AsgCod NOT IN" - " (SELECT AsgCod" - " FROM asg_groups)" - " OR " - // Assignment is for some of my groups - "AsgCod IN" - " (SELECT asg_groups.AsgCod" - " FROM grp_users," - "asg_groups" - " WHERE grp_users.UsrCod=%ld" - " AND asg_groups.GrpCod=grp_users.GrpCod)" - ")", - AsgCod,Gbl.Usrs.Me.UsrDat.UsrCod) != 0); + return Asg_DB_CheckIfICanDoAssignment (AsgCod); case Rol_SYS_ADM: return true; default: @@ -1854,84 +1595,6 @@ static bool Asg_CheckIfIBelongToCrsOrGrpsThisAssignment (long AsgCod) } } -/*****************************************************************************/ -/****************** Get number of courses with assignments *******************/ -/*****************************************************************************/ -// Returns the number of courses with assignments -// in this location (all the platform, current degree or current course) - -unsigned Asg_GetNumCoursesWithAssignments (Hie_Lvl_Level_t Scope) - { - /***** Get number of courses with assignments from database *****/ - switch (Scope) - { - case Hie_Lvl_SYS: - return (unsigned) - DB_QueryCOUNT ("can not get number of courses with assignments", - "SELECT COUNT(DISTINCT CrsCod)" - " FROM asg_assignments" - " WHERE CrsCod>0"); - case Hie_Lvl_CTY: - return (unsigned) - DB_QueryCOUNT ("can not get number of courses with assignments", - "SELECT COUNT(DISTINCT asg_assignments.CrsCod)" - " FROM ins_instits," - "ctr_centers," - "deg_degrees," - "courses," - "asg_assignments" - " 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=asg_assignments.CrsCod", - Gbl.Hierarchy.Cty.CtyCod); - case Hie_Lvl_INS: - return (unsigned) - DB_QueryCOUNT ("can not get number of courses with assignments", - "SELECT COUNT(DISTINCT asg_assignments.CrsCod)" - " FROM ctr_centers," - "deg_degrees," - "crs_courses," - "asg_assignments" - " WHERE ctr_centers.InsCod=%ld" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=asg_assignments.CrsCod", - Gbl.Hierarchy.Ins.InsCod); - case Hie_Lvl_CTR: - return (unsigned) - DB_QueryCOUNT ("can not get number of courses with assignments", - "SELECT COUNT(DISTINCT asg_assignments.CrsCod)" - " FROM deg_degrees," - "crs_courses," - "asg_assignments" - " WHERE deg_degrees.CtrCod=%ld" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=asg_assignments.CrsCod", - Gbl.Hierarchy.Ctr.CtrCod); - case Hie_Lvl_DEG: - return (unsigned) - DB_QueryCOUNT ("can not get number of courses with assignments", - "SELECT COUNT(DISTINCT asg_assignments.CrsCod)" - " FROM crs_courses," - "asg_assignments" - " WHERE crs_courses.DegCod=%ld" - " AND crs_courses.CrsCod=asg_assignments.CrsCod", - Gbl.Hierarchy.Deg.DegCod); - case Hie_Lvl_CRS: - return (unsigned) - DB_QueryCOUNT ("can not get number of courses with assignments", - "SELECT COUNT(DISTINCT CrsCod)" - " FROM asg_assignments" - " WHERE CrsCod=%ld", - Gbl.Hierarchy.Crs.CrsCod); - default: - Err_WrongScopeExit (); - return 0; - } - } - /*****************************************************************************/ /************************ Get number of assignments **************************/ /*****************************************************************************/ @@ -1944,112 +1607,26 @@ unsigned Asg_GetNumAssignments (Hie_Lvl_Level_t Scope,unsigned *NumNotif) MYSQL_ROW row; unsigned NumAssignments; + /***** Default values *****/ + NumAssignments = 0; + *NumNotif = 0; + /***** Get number of assignments from database *****/ - switch (Scope) + if (Asg_DB_GetNumAssignments (&mysql_res,Scope)) { - case Hie_Lvl_SYS: - DB_QuerySELECT (&mysql_res,"can not get number of assignments", - "SELECT COUNT(*)," // row[0] - "SUM(NumNotif)" // row[1] - " FROM asg_assignments" - " WHERE CrsCod>0"); - break; - case Hie_Lvl_CTY: - DB_QuerySELECT (&mysql_res,"can not get number of assignments", - "SELECT COUNT(*)," // row[0] - "SUM(asg_assignments.NumNotif)" // row[1] - " FROM ins_instits," - "ctr_centers," - "deg_degrees," - "crs_courses," - "asg_assignments" - " 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=asg_assignments.CrsCod", - Gbl.Hierarchy.Cty.CtyCod); - break; - case Hie_Lvl_INS: - DB_QuerySELECT (&mysql_res,"can not get number of assignments", - "SELECT COUNT(*)," // row[0] - "SUM(asg_assignments.NumNotif)" // row[1] - " FROM ctr_centers," - "deg_degrees," - "crs_courses," - "asg_assignments" - " WHERE ctr_centers.InsCod=%ld" - " AND ctr_centers.CtrCod=deg_degrees.CtrCod" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=asg_assignments.CrsCod", - Gbl.Hierarchy.Ins.InsCod); - break; - case Hie_Lvl_CTR: - DB_QuerySELECT (&mysql_res,"can not get number of assignments", - "SELECT COUNT(*)," // row[0] - "SUM(asg_assignments.NumNotif)" // row[1] - " FROM deg_degrees," - "crs_courses," - "asg_assignments" - " WHERE deg_degrees.CtrCod=%ld" - " AND deg_degrees.DegCod=crs_courses.DegCod" - " AND crs_courses.CrsCod=asg_assignments.CrsCod", - Gbl.Hierarchy.Ctr.CtrCod); - break; - case Hie_Lvl_DEG: - DB_QuerySELECT (&mysql_res,"can not get number of assignments", - "SELECT COUNT(*)," // row[0] - "SUM(asg_assignments.NumNotif)" // row[1] - " FROM crs_courses," - "asg_assignments" - " WHERE crs_courses.DegCod=%ld" - " AND crs_courses.CrsCod=asg_assignments.CrsCod", - Gbl.Hierarchy.Deg.DegCod); - break; - case Hie_Lvl_CRS: - DB_QuerySELECT (&mysql_res,"can not get number of assignments", - "SELECT COUNT(*)," // row[0] - "SUM(NumNotif)" // row[1] - " FROM asg_assignments" - " WHERE CrsCod=%ld", - Gbl.Hierarchy.Crs.CrsCod); - break; - default: - Err_WrongScopeExit (); - break; - } + /***** Get number of assignments *****/ + row = mysql_fetch_row (mysql_res); + if (sscanf (row[0],"%u",&NumAssignments) != 1) + Err_ShowErrorAndExit ("Error when getting number of assignments."); - /***** Get number of assignments *****/ - row = mysql_fetch_row (mysql_res); - if (sscanf (row[0],"%u",&NumAssignments) != 1) - Err_ShowErrorAndExit ("Error when getting number of assignments."); - - /***** Get number of notifications by email *****/ - if (row[1]) - { - if (sscanf (row[1],"%u",NumNotif) != 1) - Err_ShowErrorAndExit ("Error when getting number of notifications of assignments."); + /***** Get number of notifications by email *****/ + if (row[1]) + if (sscanf (row[1],"%u",NumNotif) != 1) + Err_ShowErrorAndExit ("Error when getting number of notifications of assignments."); } - else - *NumNotif = 0; /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); return NumAssignments; } - -/*****************************************************************************/ -/****************** Get number of assignments in a course ********************/ -/*****************************************************************************/ - -unsigned Asg_GetNumAssignmentsInCrs (long CrsCod) - { - /***** Get number of assignments in a course from database *****/ - return (unsigned) - DB_QueryCOUNT ("can not get number of assignments in course", - "SELECT COUNT(*)" - " FROM asg_assignments" - " WHERE CrsCod=%ld", - CrsCod); - } diff --git a/swad_assignment.h b/swad_assignment.h index 3a347abf..8acd9162 100644 --- a/swad_assignment.h +++ b/swad_assignment.h @@ -94,14 +94,10 @@ long Asg_GetParamAsgCod (void); void Asg_ReqRemAssignment (void); void Asg_RemoveAssignment (void); void Asg_HideAssignment (void); -void Asg_ShowAssignment (void); +void Asg_UnhideAssignment (void); void Asg_ReceiveFormAssignment (void); -void Asg_RemoveGroup (long GrpCod); -void Asg_RemoveGroupsOfType (long GrpTypCod); void Asg_RemoveCrsAssignments (long CrsCod); -unsigned Asg_GetNumCoursesWithAssignments (Hie_Lvl_Level_t Scope); unsigned Asg_GetNumAssignments (Hie_Lvl_Level_t Scope,unsigned *NumNotif); -unsigned Asg_GetNumAssignmentsInCrs (long CrsCod); #endif diff --git a/swad_assignment_database.c b/swad_assignment_database.c new file mode 100644 index 00000000..27a40884 --- /dev/null +++ b/swad_assignment_database.c @@ -0,0 +1,640 @@ +// swad_assignment_database.c: assignments operations with database + +/* + SWAD (Shared Workspace At a Distance), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2021 Antonio Cañas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +#include "swad_assignment.h" +#include "swad_assignment_database.h" +#include "swad_database.h" +#include "swad_date.h" +#include "swad_error.h" +#include "swad_global.h" + +/*****************************************************************************/ +/************** External global variables from others modules ****************/ +/*****************************************************************************/ + +extern struct Globals Gbl; + +/*****************************************************************************/ +/***************************** Private constants *****************************/ +/*****************************************************************************/ + +static const char *Asg_DB_HiddenSubQuery[Rol_NUM_ROLES] = + { + [Rol_UNK ] = " AND Hidden='N'", + [Rol_GST ] = " AND Hidden='N'", + [Rol_USR ] = " AND Hidden='N'", + [Rol_STD ] = " AND Hidden='N'", + [Rol_NET ] = " AND Hidden='N'", + [Rol_TCH ] = "", + [Rol_DEG_ADM] = " AND Hidden='N'", + [Rol_CTR_ADM] = " AND Hidden='N'", + [Rol_INS_ADM] = " AND Hidden='N'", + [Rol_SYS_ADM] = "", + }; +static const char *Asg_DB_OrderSubQuery[Dat_NUM_START_END_TIME] = + { + [Dat_START_TIME] = "StartTime DESC," + "EndTime DESC," + "Title DESC", + [Dat_END_TIME ] = "EndTime DESC," + "StartTime DESC," + "Title DESC", + }; + +/*****************************************************************************/ +/***************************** Private variables *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private prototypes ****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************* Get list of assignments for my groups *******************/ +/*****************************************************************************/ + +unsigned Asg_DB_GetListAssignmentsMyGrps (MYSQL_RES **mysql_res, + Dat_StartEndTime_t SelectedOrder) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get assignments", + "SELECT AsgCod" + " FROM asg_assignments" + " WHERE CrsCod=%ld%s" + " AND (" + // Assignment is for the whole course + "AsgCod NOT IN" + " (SELECT AsgCod" + " FROM asg_groups)" // Not associated to any group + " OR" + // Assignment is for some of my groups + " AsgCod IN" + " (SELECT asg_groups.AsgCod" + " FROM asg_groups," + "grp_users" + " WHERE grp_users.UsrCod=%ld" + " AND asg_groups.GrpCod=grp_users.GrpCod)" + ")" + " ORDER BY %s", + Gbl.Hierarchy.Crs.CrsCod, + Asg_DB_HiddenSubQuery[Gbl.Usrs.Me.Role.Logged], + Gbl.Usrs.Me.UsrDat.UsrCod, + Asg_DB_OrderSubQuery[SelectedOrder]); + } + +/*****************************************************************************/ +/****************** Get list of assignments for all groups *******************/ +/*****************************************************************************/ + +unsigned Asg_DB_GetListAssignmentsAllGrps (MYSQL_RES **mysql_res, + Dat_StartEndTime_t SelectedOrder) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get assignments", + "SELECT AsgCod" + " FROM asg_assignments" + " WHERE CrsCod=%ld%s" + " ORDER BY %s", + Gbl.Hierarchy.Crs.CrsCod, + Asg_DB_HiddenSubQuery[Gbl.Usrs.Me.Role.Logged], + Asg_DB_OrderSubQuery[SelectedOrder]); + } + +/*****************************************************************************/ +/******************* Get assignment data using its code **********************/ +/*****************************************************************************/ + +unsigned Asg_DB_GetDataOfAssignmentByCod (MYSQL_RES **mysql_res,long AsgCod) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get assignment data", + "SELECT AsgCod," // row[0] + "Hidden," // row[1] + "UsrCod," // row[2] + "UNIX_TIMESTAMP(StartTime)," // row[3] + "UNIX_TIMESTAMP(EndTime)," // row[4] + "NOW() BETWEEN StartTime AND EndTime," // row[5] + "Title," // row[6] + "Folder" // row[7] + " FROM asg_assignments" + " WHERE AsgCod=%ld" + " AND CrsCod=%ld", // Extra check + AsgCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/**************** Get assignment data using its folder name ******************/ +/*****************************************************************************/ + +unsigned Asg_DB_GetDataOfAssignmentByFolder (MYSQL_RES **mysql_res, + const char Folder[Brw_MAX_BYTES_FOLDER + 1]) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get assignment data", + "SELECT AsgCod," // row[0] + "Hidden," // row[1] + "UsrCod," // row[2] + "UNIX_TIMESTAMP(StartTime)," // row[3] + "UNIX_TIMESTAMP(EndTime)," // row[4] + "NOW() BETWEEN StartTime AND EndTime," // row[5] + "Title," // row[6] + "Folder" // row[7] + " FROM asg_assignments" + " WHERE CrsCod=%ld" // Extra check + " AND Folder='%s'", + Gbl.Hierarchy.Crs.CrsCod, + Folder); + } + +/*****************************************************************************/ +/************* Get title and text of assignment using its code ***************/ +/*****************************************************************************/ + +unsigned Asg_DB_GetAssignmentTitleAndTxtByCod (MYSQL_RES **mysql_res,long AsgCod) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get assignment title and text", + "SELECT Title," // row[0] + "Txt" // row[1] + " FROM asg_assignments" + " WHERE AsgCod=%ld", + AsgCod); + } + +/*****************************************************************************/ +/******************** Get assignment text from database **********************/ +/*****************************************************************************/ + +void Asg_DB_GetAssignmentTxtByCod (long AsgCod,char Txt[Cns_MAX_BYTES_TEXT + 1]) + { + DB_QuerySELECTString (Txt,Cns_MAX_BYTES_TEXT,"can not get assignment text", + "SELECT Txt" + " FROM asg_assignments" + " WHERE AsgCod=%ld" + " AND CrsCod=%ld", // Extra check + AsgCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/******** Check if the title or the folder of an assignment exists ***********/ +/*****************************************************************************/ + +bool Asg_DB_CheckIfSimilarAssignmentExists (const char *Field,const char *Value, + long AsgCod) + { + /***** Get number of assignments with a field value from database *****/ + return (DB_QueryCOUNT ("can not get similar assignments", + "SELECT COUNT(*)" + " FROM asg_assignments" + " WHERE CrsCod=%ld" + " AND %s='%s'" + " AND AsgCod<>%ld", + Gbl.Hierarchy.Crs.CrsCod, + Field,Value,AsgCod) != 0); + } + +/*****************************************************************************/ +/************************ Create a new assignment ****************************/ +/*****************************************************************************/ + +long Asg_DB_CreateAssignment (const struct Asg_Assignment *Asg,const char *Txt) + { + return + DB_QueryINSERTandReturnCode ("can not create new assignment", + "INSERT INTO asg_assignments" + " (CrsCod,UsrCod," + "StartTime,EndTime," + "Title,Folder,Txt)" + " VALUES" + " (%ld,%ld," + "FROM_UNIXTIME(%ld),FROM_UNIXTIME(%ld)," + "'%s','%s','%s')", + Gbl.Hierarchy.Crs.CrsCod, + Gbl.Usrs.Me.UsrDat.UsrCod, + Asg->TimeUTC[Dat_START_TIME], + Asg->TimeUTC[Dat_END_TIME ], + Asg->Title, + Asg->Folder, + Txt); + } + +/*****************************************************************************/ +/********************* Update an existing assignment *************************/ +/*****************************************************************************/ + +void Asg_DB_UpdateAssignment (const struct Asg_Assignment *Asg,const char *Txt) + { + /***** Update the data of the assignment *****/ + DB_QueryUPDATE ("can not update assignment", + "UPDATE asg_assignments" + " SET StartTime=FROM_UNIXTIME(%ld)," + "EndTime=FROM_UNIXTIME(%ld)," + "Title='%s'," + "Folder='%s'," + "Txt='%s'" + " WHERE AsgCod=%ld" + " AND CrsCod=%ld", // Extra check + Asg->TimeUTC[Dat_START_TIME], + Asg->TimeUTC[Dat_END_TIME ], + Asg->Title, + Asg->Folder, + Txt, + Asg->AsgCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/************************** Hide/unhide an assignment ************************/ +/*****************************************************************************/ + +void Asg_DB_HideAssignment (long AsgCod) + { + DB_QueryUPDATE ("can not hide assignment", + "UPDATE asg_assignments" + " SET Hidden='Y'" + " WHERE AsgCod=%ld" + " AND CrsCod=%ld", // Extra check + AsgCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +void Asg_DB_UnhideAssignment (long AsgCod) + { + DB_QueryUPDATE ("can not unhide assignment", + "UPDATE asg_assignments" + " SET Hidden='N'" + " WHERE AsgCod=%ld" + " AND CrsCod=%ld", + AsgCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/**************************** Remove an assignment ***************************/ +/*****************************************************************************/ + +void Asg_DB_RemoveAssignment (long AsgCod) + { + DB_QueryDELETE ("can not remove assignment", + "DELETE FROM asg_assignments" + " WHERE AsgCod=%ld" + " AND CrsCod=%ld", // Extra check + AsgCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/******************* Get groups associated to an assignment ******************/ +/*****************************************************************************/ + +bool Asg_DB_CheckIfICanDoAssignment (long AsgCod) + { + // Students and teachers can do assignments depending on groups + /***** Get if I can do an assignment from database *****/ + return (DB_QueryCOUNT ("can not check if I can do an assignment", + "SELECT COUNT(*)" + " FROM asg_assignments" + " WHERE AsgCod=%ld" + " AND (" + // Assignment is for the whole course + "AsgCod NOT IN" + " (SELECT AsgCod" + " FROM asg_groups)" + " OR " + // Assignment is for some of my groups + "AsgCod IN" + " (SELECT asg_groups.AsgCod" + " FROM grp_users," + "asg_groups" + " WHERE grp_users.UsrCod=%ld" + " AND asg_groups.GrpCod=grp_users.GrpCod)" + ")", + AsgCod, + Gbl.Usrs.Me.UsrDat.UsrCod) != 0); + } + +/*****************************************************************************/ +/******************* Get groups associated to an assignment ******************/ +/*****************************************************************************/ + +unsigned Asg_DB_GetGrps (MYSQL_RES **mysql_res,long AsgCod) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get groups of an assignment", + "SELECT grp_types.GrpTypName," // row[0] + "grp_groups.GrpName" // row[1] + " FROM asg_groups," + "grp_groups," + "grp_types" + " WHERE asg_groups.AsgCod=%ld" + " AND asg_groups.GrpCod=grp_groups.GrpCod" + " AND grp_groups.GrpTypCod=grp_types.GrpTypCod" + " ORDER BY grp_types.GrpTypName," + "grp_groups.GrpName", + AsgCod); + } + +/*****************************************************************************/ +/********************* Create a group of an assignment ************************/ +/*****************************************************************************/ + +void Asg_DB_CreateGrp (long AsgCod,long GrpCod) + { + DB_QueryINSERT ("can not associate a group to an assignment", + "INSERT INTO asg_groups" + " (AsgCod,GrpCod)" + " VALUES" + " (%ld,%ld)", + AsgCod, + GrpCod); + } + +/*****************************************************************************/ +/**************** Remove one group from all the assignments ******************/ +/*****************************************************************************/ + +void Asg_DB_RemoveGroup (long GrpCod) + { + /***** Remove group from all the assignments *****/ + DB_QueryDELETE ("can not remove group from the associations" + " between assignments and groups", + "DELETE FROM asg_groups" + " WHERE GrpCod=%ld", + GrpCod); + } + +/*****************************************************************************/ +/*********** Remove groups of one type from all the assignments **************/ +/*****************************************************************************/ + +void Asg_DB_RemoveGroupsOfType (long GrpTypCod) + { + /***** Remove group from all the assignments *****/ + DB_QueryDELETE ("can not remove groups of a type from the associations" + " between assignments and groups", + "DELETE FROM asg_groups" + " USING grp_groups," + "asg_groups" + " WHERE grp_groups.GrpTypCod=%ld" + " AND grp_groups.GrpCod=asg_groups.GrpCod", + GrpTypCod); + } + +/*****************************************************************************/ +/********************* Remove groups of an assignment ************************/ +/*****************************************************************************/ + +void Asg_DB_RemoveAllGrpsAssociatedToAnAssignment (long AsgCod) + { + /***** Remove groups of the assignment *****/ + DB_QueryDELETE ("can not remove the groups associated to an assignment", + "DELETE FROM asg_groups" + " WHERE AsgCod=%ld", + AsgCod); + } + +/*****************************************************************************/ +/*********** Remove groups associated to assignments in a course *************/ +/*****************************************************************************/ + +void Asg_DB_RemoveGrpsAssociatedToAsgsInCrs (long CrsCod) + { + DB_QueryDELETE ("can not remove groups associated to assignments in a course", + "DELETE FROM asg_groups" + " USING asg_assignments," + "asg_groups" + " WHERE asg_assignments.CrsCod=%ld" + " AND asg_assignments.AsgCod=asg_groups.AsgCod", + CrsCod); + } + +/*****************************************************************************/ +/****************** Remove all the assignments in a course *******************/ +/*****************************************************************************/ + +void Asg_DB_RemoveCrsAssignments (long CrsCod) + { + DB_QueryDELETE ("can not remove all assignments in a course", + "DELETE FROM asg_assignments" + " WHERE CrsCod=%ld", + CrsCod); + } + +/*****************************************************************************/ +/******** Update number of users notified in table of assignments ************/ +/*****************************************************************************/ + +void Asg_DB_UpdateNumUsrsNotifiedByEMailAboutAssignment (long AsgCod, + unsigned NumUsrsToBeNotifiedByEMail) + { + /***** Update number of users notified *****/ + DB_QueryUPDATE ("can not update the number of notifs. of an assignment", + "UPDATE asg_assignments" + " SET NumNotif=NumNotif+%u" + " WHERE AsgCod=%ld", + NumUsrsToBeNotifiedByEMail, + AsgCod); + } + +/*****************************************************************************/ +/****************** Get number of courses with assignments *******************/ +/*****************************************************************************/ +// Returns the number of courses with assignments +// in this location (all the platform, current degree or current course) + +unsigned Asg_DB_GetNumCoursesWithAssignments (Hie_Lvl_Level_t Scope) + { + /***** Get number of courses with assignments from database *****/ + switch (Scope) + { + case Hie_Lvl_SYS: + return (unsigned) + DB_QueryCOUNT ("can not get number of courses with assignments", + "SELECT COUNT(DISTINCT CrsCod)" + " FROM asg_assignments" + " WHERE CrsCod>0"); + case Hie_Lvl_CTY: + return (unsigned) + DB_QueryCOUNT ("can not get number of courses with assignments", + "SELECT COUNT(DISTINCT asg_assignments.CrsCod)" + " FROM ins_instits," + "ctr_centers," + "deg_degrees," + "courses," + "asg_assignments" + " 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=asg_assignments.CrsCod", + Gbl.Hierarchy.Cty.CtyCod); + case Hie_Lvl_INS: + return (unsigned) + DB_QueryCOUNT ("can not get number of courses with assignments", + "SELECT COUNT(DISTINCT asg_assignments.CrsCod)" + " FROM ctr_centers," + "deg_degrees," + "crs_courses," + "asg_assignments" + " WHERE ctr_centers.InsCod=%ld" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=asg_assignments.CrsCod", + Gbl.Hierarchy.Ins.InsCod); + case Hie_Lvl_CTR: + return (unsigned) + DB_QueryCOUNT ("can not get number of courses with assignments", + "SELECT COUNT(DISTINCT asg_assignments.CrsCod)" + " FROM deg_degrees," + "crs_courses," + "asg_assignments" + " WHERE deg_degrees.CtrCod=%ld" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=asg_assignments.CrsCod", + Gbl.Hierarchy.Ctr.CtrCod); + case Hie_Lvl_DEG: + return (unsigned) + DB_QueryCOUNT ("can not get number of courses with assignments", + "SELECT COUNT(DISTINCT asg_assignments.CrsCod)" + " FROM crs_courses," + "asg_assignments" + " WHERE crs_courses.DegCod=%ld" + " AND crs_courses.CrsCod=asg_assignments.CrsCod", + Gbl.Hierarchy.Deg.DegCod); + case Hie_Lvl_CRS: + return (unsigned) + DB_QueryCOUNT ("can not get number of courses with assignments", + "SELECT COUNT(DISTINCT CrsCod)" + " FROM asg_assignments" + " WHERE CrsCod=%ld", + Gbl.Hierarchy.Crs.CrsCod); + default: + Err_WrongScopeExit (); + return 0; + } + } + +/*****************************************************************************/ +/************************ Get number of assignments **************************/ +/*****************************************************************************/ +// Returns the number of assignments +// in this location (all the platform, current degree or current course) + +unsigned Asg_DB_GetNumAssignments (MYSQL_RES **mysql_res,Hie_Lvl_Level_t Scope) + { + /***** Get number of assignments from database *****/ + switch (Scope) + { + case Hie_Lvl_SYS: + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get number of assignments", + "SELECT COUNT(*)," // row[0] + "SUM(NumNotif)" // row[1] + " FROM asg_assignments" + " WHERE CrsCod>0"); + case Hie_Lvl_CTY: + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get number of assignments", + "SELECT COUNT(*)," // row[0] + "SUM(asg_assignments.NumNotif)" // row[1] + " FROM ins_instits," + "ctr_centers," + "deg_degrees," + "crs_courses," + "asg_assignments" + " 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=asg_assignments.CrsCod", + Gbl.Hierarchy.Cty.CtyCod); + case Hie_Lvl_INS: + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get number of assignments", + "SELECT COUNT(*)," // row[0] + "SUM(asg_assignments.NumNotif)" // row[1] + " FROM ctr_centers," + "deg_degrees," + "crs_courses," + "asg_assignments" + " WHERE ctr_centers.InsCod=%ld" + " AND ctr_centers.CtrCod=deg_degrees.CtrCod" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=asg_assignments.CrsCod", + Gbl.Hierarchy.Ins.InsCod); + case Hie_Lvl_CTR: + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get number of assignments", + "SELECT COUNT(*)," // row[0] + "SUM(asg_assignments.NumNotif)" // row[1] + " FROM deg_degrees," + "crs_courses," + "asg_assignments" + " WHERE deg_degrees.CtrCod=%ld" + " AND deg_degrees.DegCod=crs_courses.DegCod" + " AND crs_courses.CrsCod=asg_assignments.CrsCod", + Gbl.Hierarchy.Ctr.CtrCod); + case Hie_Lvl_DEG: + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get number of assignments", + "SELECT COUNT(*)," // row[0] + "SUM(asg_assignments.NumNotif)" // row[1] + " FROM crs_courses," + "asg_assignments" + " WHERE crs_courses.DegCod=%ld" + " AND crs_courses.CrsCod=asg_assignments.CrsCod", + Gbl.Hierarchy.Deg.DegCod); + case Hie_Lvl_CRS: + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get number of assignments", + "SELECT COUNT(*)," // row[0] + "SUM(NumNotif)" // row[1] + " FROM asg_assignments" + " WHERE CrsCod=%ld", + Gbl.Hierarchy.Crs.CrsCod); + default: + Err_WrongScopeExit (); + return 0; // Not reached + } + } + +/*****************************************************************************/ +/****************** Get number of assignments in a course ********************/ +/*****************************************************************************/ + +unsigned Asg_DB_GetNumAssignmentsInCrs (long CrsCod) + { + /***** Get number of assignments in a course from database *****/ + return (unsigned) + DB_QueryCOUNT ("can not get number of assignments in course", + "SELECT COUNT(*)" + " FROM asg_assignments" + " WHERE CrsCod=%ld", + CrsCod); + } diff --git a/swad_assignment_database.h b/swad_assignment_database.h new file mode 100644 index 00000000..05eadafe --- /dev/null +++ b/swad_assignment_database.h @@ -0,0 +1,83 @@ +// swad_assignment_database.h: assignments operations with database + +#ifndef _SWAD_ASG_DB +#define _SWAD_ASG_DB +/* + SWAD (Shared Workspace At a Distance), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2021 Antonio Cañas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/********************************* Headers ***********************************/ +/*****************************************************************************/ + +#include "swad_assignment.h" +#include "swad_database.h" +#include "swad_file_browser.h" + +/*****************************************************************************/ +/************************** Public types and constants ***********************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Public prototypes *****************************/ +/*****************************************************************************/ + +unsigned Asg_DB_GetListAssignmentsMyGrps (MYSQL_RES **mysql_res, + Dat_StartEndTime_t SelectedOrder); +unsigned Asg_DB_GetListAssignmentsAllGrps (MYSQL_RES **mysql_res, + Dat_StartEndTime_t SelectedOrder); + +unsigned Asg_DB_GetDataOfAssignmentByCod (MYSQL_RES **mysql_res,long AsgCod); +unsigned Asg_DB_GetDataOfAssignmentByFolder (MYSQL_RES **mysql_res, + const char Folder[Brw_MAX_BYTES_FOLDER + 1]); +unsigned Asg_DB_GetAssignmentTitleAndTxtByCod (MYSQL_RES **mysql_res,long AsgCod); +void Asg_DB_GetAssignmentTxtByCod (long AsgCod,char Txt[Cns_MAX_BYTES_TEXT + 1]); + +bool Asg_DB_CheckIfSimilarAssignmentExists (const char *Field,const char *Value, + long AsgCod); + +long Asg_DB_CreateAssignment (const struct Asg_Assignment *Asg,const char *Txt); +void Asg_DB_UpdateAssignment (const struct Asg_Assignment *Asg,const char *Txt); +void Asg_DB_HideAssignment (long AsgCod); +void Asg_DB_UnhideAssignment (long AsgCod); + +void Asg_DB_RemoveAssignment (long AsgCod); + +bool Asg_DB_CheckIfICanDoAssignment (long AsgCod); + +unsigned Asg_DB_GetGrps (MYSQL_RES **mysql_res,long AsgCod); +void Asg_DB_CreateGrp (long AsgCod,long GrpCod); +void Asg_DB_RemoveGroup (long GrpCod); +void Asg_DB_RemoveGroupsOfType (long GrpTypCod); +void Asg_DB_RemoveAllGrpsAssociatedToAnAssignment (long AsgCod); + +void Asg_DB_RemoveGrpsAssociatedToAsgsInCrs (long CrsCod); +void Asg_DB_RemoveCrsAssignments (long CrsCod); + +void Asg_DB_UpdateNumUsrsNotifiedByEMailAboutAssignment (long AsgCod, + unsigned NumUsrsToBeNotifiedByEMail); + +unsigned Asg_DB_GetNumCoursesWithAssignments (Hie_Lvl_Level_t Scope); + +unsigned Asg_DB_GetNumAssignments (MYSQL_RES **mysql_res,Hie_Lvl_Level_t Scope); + +unsigned Asg_DB_GetNumAssignmentsInCrs (long CrsCod); + +#endif diff --git a/swad_changelog.h b/swad_changelog.h index f67ee69b..c7f7036e 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -599,15 +599,18 @@ TODO: BUG: Cuando un tipo de grupo s TODO: Salvador Romero Cortés: @acanas opción para editar posts TODO: FIX BUG, URGENT! En las fechas como parámetro Dat_WriteParamsIniEndDates(), por ejemplo al cambiar el color de la gráfica de accesos por día y hora, no se respeta la zona horaria. + +TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo. */ -#define Log_PLATFORM_VERSION "SWAD 20.74 (2021-05-11)" +#define Log_PLATFORM_VERSION "SWAD 20.75 (2021-05-11)" #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 20.74: May 11, 2021 New module swad_announcement_database for database queries related to announcements. (? lines) + Version 20.75: May 11, 2021 New module swad_assignment_database for database queries related to assignments. (310858 lines) + Version 20.74: May 11, 2021 New module swad_announcement_database for database queries related to announcements. (310629 lines) Version 20.73: May 10, 2021 New module swad_agenda_database for database queries related to agenda. (310474 lines) Version 20.72: May 10, 2021 New module swad_account_database for database queries related to user's account. (310328 lines) Version 20.71: May 10, 2021 New module swad_media_database for database queries related to media. (310080 lines) diff --git a/swad_figure.c b/swad_figure.c index 45c0fb38..e709adec 100644 --- a/swad_figure.c +++ b/swad_figure.c @@ -32,6 +32,7 @@ #include "swad_action.h" #include "swad_agenda_database.h" +#include "swad_assignment_database.h" #include "swad_box.h" #include "swad_database.h" #include "swad_error.h" @@ -3182,7 +3183,7 @@ static void Fig_GetAndShowAssignmentsStats (void) /***** Get the number of assignments from this location *****/ if ((NumAssignments = Asg_GetNumAssignments (Gbl.Scope.Current,&NumNotif))) - if ((NumCoursesWithAssignments = Asg_GetNumCoursesWithAssignments (Gbl.Scope.Current)) != 0) + if ((NumCoursesWithAssignments = Asg_DB_GetNumCoursesWithAssignments (Gbl.Scope.Current)) != 0) NumAssignmentsPerCourse = (double) NumAssignments / (double) NumCoursesWithAssignments; diff --git a/swad_group.c b/swad_group.c index 290d9380..4f3f744d 100644 --- a/swad_group.c +++ b/swad_group.c @@ -32,6 +32,7 @@ #include // For string functions #include "swad_action.h" +#include "swad_assignment_database.h" #include "swad_attendance.h" #include "swad_box.h" #include "swad_database.h" @@ -4143,7 +4144,7 @@ static void Grp_RemoveGroupTypeCompletely (void) Brw_RemoveZonesOfGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod); /***** Remove the associations of assignments to groups of this type *****/ - Asg_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod); + Asg_DB_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod); /***** Remove the associations of attendance events to groups of this type *****/ Att_RemoveGroupsOfType (Gbl.Crs.Grps.GrpTyp.GrpTypCod); @@ -4212,7 +4213,7 @@ static void Grp_RemoveGroupCompletely (void) Brw_RemoveGrpZones (Gbl.Hierarchy.Crs.CrsCod,GrpDat.GrpCod); /***** Remove this group from all assignments *****/ - Asg_RemoveGroup (GrpDat.GrpCod); + Asg_DB_RemoveGroup (GrpDat.GrpCod); /***** Remove this group from all attendance events *****/ Att_RemoveGroup (GrpDat.GrpCod); diff --git a/swad_indicator.c b/swad_indicator.c index ae5cb3d2..ad734aca 100644 --- a/swad_indicator.c +++ b/swad_indicator.c @@ -29,6 +29,7 @@ #include // To access MySQL databases #include "swad_action.h" +#include "swad_assignment_database.h" #include "swad_box.h" #include "swad_database.h" #include "swad_department.h" @@ -1439,7 +1440,7 @@ void Ind_ComputeAndStoreIndicatorsCrs (long CrsCod,int NumIndicatorsFromDB, IndicatorsCrs->NumIndicators++; /***** Indicator #2: information about assignments *****/ - IndicatorsCrs->NumAssignments = Asg_GetNumAssignmentsInCrs (CrsCod); + IndicatorsCrs->NumAssignments = Asg_DB_GetNumAssignmentsInCrs (CrsCod); IndicatorsCrs->NumFilesAssignments = Ind_GetNumFilesInAssigZonesOfCrsFromDB (CrsCod); IndicatorsCrs->NumFilesWorks = Ind_GetNumFilesInWorksZonesOfCrsFromDB (CrsCod); IndicatorsCrs->ThereAreAssignments = (IndicatorsCrs->NumAssignments != 0) ||