From 00302bea7daf0c3228c70010ea467564b289ee60 Mon Sep 17 00:00:00 2001 From: acanas Date: Sun, 24 Oct 2021 18:16:12 +0200 Subject: [PATCH] Version 21.41: Oct 24, 2021 New module swad_tag_database for database queries related to question tags. --- Makefile | 8 +- swad_center_database.c | 115 ++++++++++ swad_center_database.h | 7 + swad_changelog.h | 4 +- swad_institution.c | 3 +- swad_institution_config.c | 5 +- swad_institution_database.c | 75 ------- swad_institution_database.h | 4 - swad_photo_database.c | 30 --- swad_photo_database.h | 1 - swad_report_database.c | 14 -- swad_statistic_database.h | 3 - swad_survey_database.c | 15 -- swad_syllabus.c | 101 +++++---- swad_system_config.c | 214 ++++++++----------- swad_tag.c | 408 ++++++++++++------------------------ swad_tag.h | 7 - swad_tag_database.c | 218 +++++++++++++++++++ swad_tag_database.h | 59 ++++++ swad_test.c | 23 +- 20 files changed, 695 insertions(+), 619 deletions(-) create mode 100644 swad_tag_database.c create mode 100644 swad_tag_database.h diff --git a/Makefile b/Makefile index 156b4b37..27920dec 100644 --- a/Makefile +++ b/Makefile @@ -82,10 +82,10 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \ swad_setting.o swad_setting_database.o swad_statistic.o \ swad_statistic_database.o swad_string.o swad_survey.o \ swad_survey_database.o swad_syllabus.o swad_system_config.o \ - swad_tab.o swad_tag.o swad_test.o swad_test_config.o \ - swad_test_import.o swad_test_print.o swad_test_visibility.o \ - swad_theme.o \ - swad_timeline.o swad_timeline_comment.o swad_timeline_database.o \ + swad_tab.o swad_tag.o swad_tag_database.o swad_test.o \ + swad_test_config.o swad_test_import.o swad_test_print.o \ + swad_test_visibility.o swad_theme.o swad_timeline.o \ + swad_timeline_comment.o swad_timeline_database.o \ swad_timeline_favourite.o swad_timeline_form.o swad_timeline_note.o \ swad_timeline_notification.o swad_timeline_post.o \ swad_timeline_publication.o swad_timeline_share.o \ diff --git a/swad_center_database.c b/swad_center_database.c index f2b5e36c..d30a7386 100644 --- a/swad_center_database.c +++ b/swad_center_database.c @@ -25,6 +25,9 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ +#define _GNU_SOURCE // For asprintf +#include // For asprintf + #include "swad_center.h" #include "swad_center_config.h" #include "swad_database.h" @@ -615,6 +618,118 @@ void Ctr_DB_UpdateCtrStatus (long CtrCod,Ctr_Status_t NewStatus) CtrCod); } +/*****************************************************************************/ +/********** Check if any of the centers in an institution has map ************/ +/*****************************************************************************/ + +bool Ctr_DB_GetIfMapIsAvailableInIns (long InsCod) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + bool MapIsAvailable = false; + + /***** Get if any center in current institution has a coordinate set + (coordinates 0, 0 means not set ==> don't show map) *****/ + if (DB_QuerySELECT (&mysql_res,"can not get if map is available", + "SELECT EXISTS" // row[0] + "(SELECT *" + " FROM ctr_centers" + " WHERE InsCod=%ld" + " AND (Latitude<>0" + " OR" + " Longitude<>0))", + InsCod)) + { + /* Get if map is available */ + row = mysql_fetch_row (mysql_res); + MapIsAvailable = (row[0][0] == '1'); + } + + /* Free structure that stores the query result */ + DB_FreeMySQLResult (&mysql_res); + + return MapIsAvailable; + } + +/*****************************************************************************/ +/********* Get average coordinates of centers in current institution *********/ +/*****************************************************************************/ + +void Ctr_DB_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom) + { + char *Query; + + /***** Get average coordinates of centers with both coordinates set + (coordinates 0, 0 means not set ==> don't show map) *****/ + if (asprintf (&Query, + "SELECT AVG(Latitude)," // row[0] + "AVG(Longitude)," // row[1] + "GREATEST(MAX(Latitude)-MIN(Latitude)," + "MAX(Longitude)-MIN(Longitude))" // row[2] + " FROM ctr_centers" + " WHERE Latitude<>0" + " AND Longitude<>0") < 0) + Err_NotEnoughMemoryExit (); + Map_GetCoordAndZoom (Coord,Zoom,Query); + free (Query); + } + +/*****************************************************************************/ +/********* Get average coordinates of centers in current institution *********/ +/*****************************************************************************/ + +void Ctr_DB_GetCoordAndZoomInCurrentIns (struct Map_Coordinates *Coord,unsigned *Zoom) + { + char *Query; + + /***** Get average coordinates of centers of current institution + with both coordinates set + (coordinates 0, 0 means not set ==> don't show map) *****/ + if (asprintf (&Query, + "SELECT AVG(Latitude)," // row[0] + "AVG(Longitude)," // row[1] + "GREATEST(MAX(Latitude)-MIN(Latitude)," + "MAX(Longitude)-MIN(Longitude))" // row[2] + " FROM ctr_centers" + " WHERE InsCod=%ld" + " AND Latitude<>0" + " AND Longitude<>0", + Gbl.Hierarchy.Ins.InsCod) < 0) + Err_NotEnoughMemoryExit (); + Map_GetCoordAndZoom (Coord,Zoom,Query); + free (Query); + } + +/*****************************************************************************/ +/******************* Get centres which have coordinates **********************/ +/*****************************************************************************/ + +unsigned Ctr_DB_GetCtrsWithCoords (MYSQL_RES **mysql_res) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get centers with coordinates", + "SELECT CtrCod" + " FROM ctr_centers" + " WHERE ctr_centers.Latitude<>0" + " AND ctr_centers.Longitude<>0"); + } + +/*****************************************************************************/ +/******** Get centres which have coordinates in current institution **********/ +/*****************************************************************************/ + +unsigned Ctr_DB_GetCtrsWithCoordsInCurrentIns (MYSQL_RES **mysql_res) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get centers with coordinates", + "SELECT CtrCod" // row[0] + " FROM ctr_centers" + " WHERE InsCod=%ld" + " AND Latitude<>0" + " AND Longitude<>0", + Gbl.Hierarchy.Ins.InsCod); + } + /*****************************************************************************/ /****************************** Remove a center ******************************/ /*****************************************************************************/ diff --git a/swad_center_database.h b/swad_center_database.h index 2227948c..89933a6c 100644 --- a/swad_center_database.h +++ b/swad_center_database.h @@ -80,6 +80,13 @@ void Ctr_DB_UpdateCtrCoordinate (long CtrCod, const char *CoordField,double NewCoord); void Ctr_DB_UpdateCtrStatus (long CtrCod,Ctr_Status_t NewStatus); + +bool Ctr_DB_GetIfMapIsAvailableInIns (long InsCod); +void Ctr_DB_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom); +void Ctr_DB_GetCoordAndZoomInCurrentIns (struct Map_Coordinates *Coord,unsigned *Zoom); +unsigned Ctr_DB_GetCtrsWithCoords (MYSQL_RES **mysql_res); +unsigned Ctr_DB_GetCtrsWithCoordsInCurrentIns (MYSQL_RES **mysql_res); + void Ctr_DB_RemoveCenter (long CtrCod); #endif diff --git a/swad_changelog.h b/swad_changelog.h index 5ee08bfa..c34e41b4 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,13 +602,15 @@ TODO: FIX BUG, URGENT! En las fechas como par TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo. */ -#define Log_PLATFORM_VERSION "SWAD 21.40 (2021-10-24)" +#define Log_PLATFORM_VERSION "SWAD 21.41 (2021-10-24)" #define CSS_FILE "swad20.45.css" #define JS_FILE "swad20.69.1.js" /* TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams + Version 21.41: Oct 24, 2021 New module swad_tag_database for database queries related to question tags. (320721 lines) + Version 21.40.1: Oct 24, 2021 Queries moved to module swad_center_database. (320621 lines) Version 21.40: Oct 24, 2021 Queries moved to module swad_survey_database. (320673 lines) Version 21.39.2: Oct 22, 2021 Fixed bug in settings. (320544 lines) Version 21.39.1: Oct 21, 2021 Queries moved to module swad_survey_database. (320540 lines) diff --git a/swad_institution.c b/swad_institution.c index bc061a39..d83a83d6 100644 --- a/swad_institution.c +++ b/swad_institution.c @@ -32,6 +32,7 @@ #include "swad_admin_database.h" #include "swad_browser_database.h" +#include "swad_center_database.h" #include "swad_database.h" #include "swad_department.h" #include "swad_enrolment_database.h" @@ -1972,7 +1973,7 @@ static void Ins_FormToGoToMap (struct Ins_Instit *Ins) { extern const char *Txt_Map; - if (Ins_DB_GetIfMapIsAvailable (Ins->InsCod)) + if (Ctr_DB_GetIfMapIsAvailableInIns (Ins->InsCod)) { Ins_EditingIns = Ins; // Used to pass parameter with the code of the institution Lay_PutContextualLinkOnlyIcon (ActSeeInsInf,NULL, diff --git a/swad_institution_config.c b/swad_institution_config.c index ba4565ec..3e3c9322 100644 --- a/swad_institution_config.c +++ b/swad_institution_config.c @@ -31,6 +31,7 @@ #include // For asprintf #include // For free +#include "swad_center_database.h" #include "swad_database.h" #include "swad_department_database.h" #include "swad_error.h" @@ -273,14 +274,14 @@ static void InsCfg_Map (void) HTM_SCRIPT_Begin (NULL,NULL); /* Let's create a map with pretty Mapbox Streets tiles */ - Ins_DB_GetCoordAndZoom (&InsAvgCoord,&Zoom); + Ctr_DB_GetCoordAndZoomInCurrentIns (&InsAvgCoord,&Zoom); Map_CreateMap (InsCfg_MAP_CONTAINER_ID,&InsAvgCoord,Zoom); /* Add Mapbox Streets tile layer to our map */ Map_AddTileLayer (); /* Get centers with coordinates */ - NumCtrs = Ins_DB_GetCtrsWithCoordsInCurrentIns (&mysql_res); + NumCtrs = Ctr_DB_GetCtrsWithCoordsInCurrentIns (&mysql_res); /* Add a marker and a popup for each center */ for (NumCtr = 0; diff --git a/swad_institution_database.c b/swad_institution_database.c index 4322e605..e54980dc 100644 --- a/swad_institution_database.c +++ b/swad_institution_database.c @@ -753,81 +753,6 @@ unsigned Ins_DB_GetNumInnsWithUsrs (Rol_Role_t Role, SubQuery,(unsigned) Role); } -/*****************************************************************************/ -/********** Check if any of the centers in an institution has map ************/ -/*****************************************************************************/ - -bool Ins_DB_GetIfMapIsAvailable (long InsCod) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - bool MapIsAvailable = false; - - /***** Get if any center in current institution has a coordinate set - (coordinates 0, 0 means not set ==> don't show map) *****/ - if (DB_QuerySELECT (&mysql_res,"can not get if map is available", - "SELECT EXISTS" // row[0] - "(SELECT *" - " FROM ctr_centers" - " WHERE InsCod=%ld" - " AND (Latitude<>0" - " OR" - " Longitude<>0))", - InsCod)) - { - /* Get if map is available */ - row = mysql_fetch_row (mysql_res); - MapIsAvailable = (row[0][0] == '1'); - } - - /* Free structure that stores the query result */ - DB_FreeMySQLResult (&mysql_res); - - return MapIsAvailable; - } - -/*****************************************************************************/ -/********* Get average coordinates of centers in current institution *********/ -/*****************************************************************************/ - -void Ins_DB_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom) - { - char *Query; - - /***** Get average coordinates of centers of current institution - with both coordinates set - (coordinates 0, 0 means not set ==> don't show map) *****/ - if (asprintf (&Query, - "SELECT AVG(Latitude)," // row[0] - "AVG(Longitude)," // row[1] - "GREATEST(MAX(Latitude)-MIN(Latitude)," - "MAX(Longitude)-MIN(Longitude))" // row[2] - " FROM ctr_centers" - " WHERE InsCod=%ld" - " AND Latitude<>0" - " AND Longitude<>0", - Gbl.Hierarchy.Ins.InsCod) < 0) - Err_NotEnoughMemoryExit (); - Map_GetCoordAndZoom (Coord,Zoom,Query); - free (Query); - } - -/*****************************************************************************/ -/******** Get centres which have coordinates in current institution **********/ -/*****************************************************************************/ - -unsigned Ins_DB_GetCtrsWithCoordsInCurrentIns (MYSQL_RES **mysql_res) - { - return (unsigned) - DB_QuerySELECT (mysql_res,"can not get centers with coordinates", - "SELECT CtrCod" // row[0] - " FROM ctr_centers" - " WHERE InsCod=%ld" - " AND Latitude<>0" - " AND Longitude<>0", - Gbl.Hierarchy.Ins.InsCod); - } - /*****************************************************************************/ /***************************** Remove institution ****************************/ /*****************************************************************************/ diff --git a/swad_institution_database.h b/swad_institution_database.h index 9b63a59f..4e3f5181 100644 --- a/swad_institution_database.h +++ b/swad_institution_database.h @@ -80,10 +80,6 @@ unsigned Ins_DB_GetNumInssWithCrss (HieLvl_Level_t Scope,long Cod); unsigned Ins_DB_GetNumInnsWithUsrs (Rol_Role_t Role, HieLvl_Level_t Scope,long Cod); -bool Ins_DB_GetIfMapIsAvailable (long InsCod); -void Ins_DB_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom); -unsigned Ins_DB_GetCtrsWithCoordsInCurrentIns (MYSQL_RES **mysql_res); - void Ins_DB_RemoveInstitution (long InsCod); #endif diff --git a/swad_photo_database.c b/swad_photo_database.c index 302c04d6..03910ca0 100644 --- a/swad_photo_database.c +++ b/swad_photo_database.c @@ -25,39 +25,9 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ -// #define _GNU_SOURCE // For asprintf -// #include // For PATH_MAX -// #include // For log10, floor, ceil, modf, sqrt... -// #include // For NULL -// #include // For asprintf -// #include // For system, getenv, etc. -// #include // For string functions -// #include // For the macro WEXITSTATUS -// #include // For unlink - -// #include "swad_action.h" -// #include "swad_box.h" -// #include "swad_browser.h" -// #include "swad_config.h" #include "swad_database.h" -// #include "swad_enrolment.h" -// #include "swad_error.h" -// #include "swad_file.h" -// #include "swad_follow.h" -// #include "swad_form.h" #include "swad_global.h" -// #include "swad_hierarchy.h" -// #include "swad_hierarchy_level.h" -// #include "swad_HTML.h" -// #include "swad_logo.h" -// #include "swad_parameter.h" -// #include "swad_photo.h" #include "swad_photo_database.h" -// #include "swad_privacy.h" -// #include "swad_setting.h" -// #include "swad_statistic.h" -// #include "swad_theme.h" -// #include "swad_user.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ diff --git a/swad_photo_database.h b/swad_photo_database.h index 57e87954..8ee3a46c 100644 --- a/swad_photo_database.h +++ b/swad_photo_database.h @@ -31,7 +31,6 @@ #include "swad_cryptography.h" #include "swad_photo.h" -// #include "swad_user.h" /*****************************************************************************/ /************************* Public types and constants ************************/ diff --git a/swad_report_database.c b/swad_report_database.c index 5baddb63..244e91d1 100644 --- a/swad_report_database.c +++ b/swad_report_database.c @@ -25,23 +25,9 @@ /*********************************** Headers *********************************/ /*****************************************************************************/ -// #include // For free -// #include // For mkdir -// #include // For mkdir - -// #include "swad_box.h" -// #include "swad_browser_database.h" #include "swad_database.h" -// #include "swad_error.h" -// #include "swad_form.h" -// #include "swad_global.h" -// #include "swad_hierarchy_level.h" -// #include "swad_HTML.h" -// #include "swad_ID.h" -// #include "swad_profile.h" #include "swad_report.h" #include "swad_report_database.h" -// #include "swad_tab.h" /*****************************************************************************/ /****************************** Public constants *****************************/ diff --git a/swad_statistic_database.h b/swad_statistic_database.h index 97c8a173..4fc3645b 100644 --- a/swad_statistic_database.h +++ b/swad_statistic_database.h @@ -29,9 +29,6 @@ #include // To access MySQL databases -// #include "swad_indicator.h" -// #include "swad_photo.h" -// #include "swad_user.h" #include "swad_statistic.h" /*****************************************************************************/ diff --git a/swad_survey_database.c b/swad_survey_database.c index e9bd4f32..ad77b6f6 100644 --- a/swad_survey_database.c +++ b/swad_survey_database.c @@ -26,28 +26,13 @@ /*****************************************************************************/ #define _GNU_SOURCE // For asprintf -// #include // For PATH_MAX -// #include // For NULL #include // For asprintf #include // For free #include // For string functions -// #include "swad_attendance.h" -// #include "swad_box.h" #include "swad_database.h" #include "swad_error.h" -// #include "swad_figure.h" -// #include "swad_form.h" #include "swad_global.h" -// #include "swad_group.h" -// #include "swad_group_database.h" -// #include "swad_HTML.h" -// #include "swad_notification.h" -// #include "swad_notification_database.h" -// #include "swad_pagination.h" -// #include "swad_parameter.h" -// #include "swad_role.h" -// #include "swad_setting.h" #include "swad_survey.h" #include "swad_survey_database.h" diff --git a/swad_syllabus.c b/swad_syllabus.c index 00496539..3bf6e6f6 100644 --- a/swad_syllabus.c +++ b/swad_syllabus.c @@ -106,8 +106,7 @@ struct LstItemsSyllabus Syl_LstItemsSyllabus; static unsigned Syl_GetParamItemNumber (void); static void Syl_SetSyllabusTypeFromAction (struct Syl_Syllabus *Syllabus); -static void Syl_ShowSyllabus (struct Syl_Syllabus *Syllabus, - bool PutIconToEdit); +static void Syl_ShowSyllabus (struct Syl_Syllabus *Syllabus); static void Syl_ShowRowSyllabus (struct Syl_Syllabus *Syllabus,unsigned NumItem, int Level,int *CodItem,const char *Text,bool NewItem); static void Syl_PutFormItemSyllabus (struct Syl_Syllabus *Syllabus, @@ -159,26 +158,26 @@ void Syl_PutFormWhichSyllabus (Syl_WhichSyllabus_t SyllabusSelected) /***** Form to select which syllabus I want to see (lectures/practicals) *****/ Frm_BeginForm (ActSeeSyl); - HTM_DIV_Begin ("class=\"CM\""); - HTM_UL_Begin ("class=\"LIST_LEFT\""); + HTM_DIV_Begin ("class=\"CM\""); + HTM_UL_Begin ("class=\"LIST_LEFT\""); - for (WhichSyl = (Syl_WhichSyllabus_t) 0; - WhichSyl <= (Syl_WhichSyllabus_t) (For_NUM_FORUM_SETS - 1); - WhichSyl++) - { - HTM_LI_Begin ("class=\"DAT LM\""); - HTM_LABEL_Begin (NULL); - HTM_INPUT_RADIO ("WhichSyllabus",true, - "value=\"%u\"%s", - (unsigned) WhichSyl, - WhichSyl == SyllabusSelected ? " checked=\"checked\"" : - ""); - HTM_Txt (Txt_SYLLABUS_WHICH_SYLLABUS[WhichSyl]); - HTM_LABEL_End (); - HTM_LI_End (); - } - HTM_UL_End (); - HTM_DIV_End (); + for (WhichSyl = (Syl_WhichSyllabus_t) 0; + WhichSyl <= (Syl_WhichSyllabus_t) (For_NUM_FORUM_SETS - 1); + WhichSyl++) + { + HTM_LI_Begin ("class=\"DAT LM\""); + HTM_LABEL_Begin (NULL); + HTM_INPUT_RADIO ("WhichSyllabus",true, + "value=\"%u\"%s", + (unsigned) WhichSyl, + WhichSyl == SyllabusSelected ? " checked=\"checked\"" : + ""); + HTM_Txt (Txt_SYLLABUS_WHICH_SYLLABUS[WhichSyl]); + HTM_LABEL_End (); + HTM_LI_End (); + } + HTM_UL_End (); + HTM_DIV_End (); Frm_EndForm (); } @@ -222,11 +221,6 @@ bool Syl_CheckSyllabus (struct Syl_Syllabus *Syllabus,long CrsCod) bool Syl_CheckAndEditSyllabus (struct Syl_Syllabus *Syllabus) { - extern const Act_Action_t Inf_ActionsSeeInfo[Inf_NUM_TYPES]; - extern const char *Txt_Done; - bool ICanEdit; - bool PutIconToEdit; - /***** Set syllabus type depending on current action *****/ Syl_SetSyllabusTypeFromAction (Syllabus); @@ -252,24 +246,8 @@ bool Syl_CheckAndEditSyllabus (struct Syl_Syllabus *Syllabus) if (Syllabus->EditionIsActive || Syl_LstItemsSyllabus.NumItems) { - ICanEdit = Gbl.Usrs.Me.Role.Logged == Rol_TCH || - Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM; - PutIconToEdit = ICanEdit && !Syllabus->EditionIsActive; - /***** Write the current syllabus *****/ - Syl_ShowSyllabus (Syllabus,PutIconToEdit); - - if (Syllabus->EditionIsActive) - { - /***** Button to view *****/ - Frm_BeginForm (Inf_ActionsSeeInfo[Gbl.Crs.Info.Type]); - Btn_PutConfirmButton (Txt_Done); - Frm_EndForm (); - } - - /***** End box *****/ - Box_BoxEnd (); - + Syl_ShowSyllabus (Syllabus); return true; } @@ -440,11 +418,11 @@ void Syl_LoadListItemsSyllabusIntoMemory (struct Syl_Syllabus *Syllabus, /* Set the code (number) of the item */ CodItem[Syl_LstItemsSyllabus.Lst[NumItem].Level]++; - for (N = Syl_LstItemsSyllabus.Lst[NumItem].Level + 1; + for (N = Syl_LstItemsSyllabus.Lst[NumItem].Level + 1; N <= Syl_MAX_LEVELS_SYLLABUS; N++) CodItem[N] = 0; - for (N = 1; + for (N = 1; N <= Syl_MAX_LEVELS_SYLLABUS; N++) Syl_LstItemsSyllabus.Lst[NumItem].CodItem[N] = CodItem[N]; @@ -527,12 +505,13 @@ int Syl_ReadLevelItemSyllabus (void) /***************** Show a syllabus of lectures or practicals *****************/ /*****************************************************************************/ -static void Syl_ShowSyllabus (struct Syl_Syllabus *Syllabus, - bool PutIconToEdit) +static void Syl_ShowSyllabus (struct Syl_Syllabus *Syllabus) { + extern const Act_Action_t Inf_ActionsSeeInfo[Inf_NUM_TYPES]; extern const char *Txt_INFO_TITLE[Inf_NUM_TYPES]; extern const char *Hlp_COURSE_Syllabus_edit; extern const char *Hlp_COURSE_Syllabus; + extern const char *Txt_Done; unsigned NumItem; int i; int NumButtons = Syllabus->EditionIsActive ? 5 : @@ -541,6 +520,9 @@ static void Syl_ShowSyllabus (struct Syl_Syllabus *Syllabus, Gbl.Action.Act == ActModIteSylLec || Gbl.Action.Act == ActModIteSylPra || Gbl.Action.Act == ActRgtIteSylLec || Gbl.Action.Act == ActRgtIteSylPra || Gbl.Action.Act == ActLftIteSylLec || Gbl.Action.Act == ActLftIteSylPra); + bool ICanEdit = Gbl.Usrs.Me.Role.Logged == Rol_TCH || + Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM; + bool PutIconToEdit = ICanEdit && !Syllabus->EditionIsActive; /***** Begin box and table *****/ if (PutIconToEdit) @@ -562,7 +544,7 @@ static void Syl_ShowSyllabus (struct Syl_Syllabus *Syllabus, i < NumButtons; i++) HTM_Txt (""); - for (i = 1; + for (i = 1; i <= Syl_LstItemsSyllabus.NumLevels; i++) HTM_TxtF ("",i * Syl_WIDTH_NUM_SYLLABUS); @@ -593,6 +575,17 @@ static void Syl_ShowSyllabus (struct Syl_Syllabus *Syllabus, /***** End table *****/ HTM_TABLE_End (); + + if (Syllabus->EditionIsActive) + { + /***** Button to view *****/ + Frm_BeginForm (Inf_ActionsSeeInfo[Gbl.Crs.Info.Type]); + Btn_PutConfirmButton (Txt_Done); + Frm_EndForm (); + } + + /***** End box *****/ + Box_BoxEnd (); } /*****************************************************************************/ @@ -655,7 +648,7 @@ static void Syl_ShowRowSyllabus (struct Syl_Syllabus *Syllabus,unsigned NumItem, Syl_PutParamNumItem,&Syllabus->ParamNumItem, "arrow-up.svg", Str_BuildStringStr (Syl_LstItemsSyllabus.Lst[NumItem].HasChildren ? Txt_Move_up_X_and_its_subsections : - Txt_Move_up_X, + Txt_Move_up_X, StrItemCod)); Str_FreeString (); } @@ -674,7 +667,7 @@ static void Syl_ShowRowSyllabus (struct Syl_Syllabus *Syllabus,unsigned NumItem, Syl_PutParamNumItem,&Syllabus->ParamNumItem, "arrow-down.svg", Str_BuildStringStr (Syl_LstItemsSyllabus.Lst[NumItem].HasChildren ? Txt_Move_down_X_and_its_subsections : - Txt_Move_down_X, + Txt_Move_down_X, StrItemCod)); Str_FreeString (); } @@ -1048,11 +1041,11 @@ static void Syl_ChangePlaceItemSyllabus (Syl_ChangePosItem_t UpOrDownPos) NumItem < Subtree.ToGetDown.Ini; NumItem++) Syl_WriteItemFileSyllabus (NewFile,Syl_LstItemsSyllabus.Lst[NumItem].Level,Syl_LstItemsSyllabus.Lst[NumItem].Text); - for (NumItem = Subtree.ToGetUp.Ini; + for (NumItem = Subtree.ToGetUp.Ini; NumItem <= Subtree.ToGetUp.End; NumItem++) Syl_WriteItemFileSyllabus (NewFile,Syl_LstItemsSyllabus.Lst[NumItem].Level,Syl_LstItemsSyllabus.Lst[NumItem].Text); - for (NumItem = Subtree.ToGetDown.Ini; + for (NumItem = Subtree.ToGetDown.Ini; NumItem <= Subtree.ToGetDown.End; NumItem++) Syl_WriteItemFileSyllabus (NewFile,Syl_LstItemsSyllabus.Lst[NumItem].Level,Syl_LstItemsSyllabus.Lst[NumItem].Text); @@ -1312,7 +1305,7 @@ void Syl_InsertItemSyllabus (void) /***** We are editing a syllabus with the internal editor, so change info source to internal editor in database *****/ Inf_DB_SetInfoSrc (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : - Inf_NONE); + Inf_NONE); /***** Show the updated syllabus to continue editing it *****/ Syl_FreeListItemsSyllabus (); @@ -1364,7 +1357,7 @@ void Syl_ModifyItemSyllabus (void) /***** We are editing a syllabus with the internal editor, so change info source to internal editor in database *****/ Inf_DB_SetInfoSrc (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : - Inf_NONE); + Inf_NONE); /***** Show the updated syllabus to continue editing it *****/ Syl_FreeListItemsSyllabus (); diff --git a/swad_system_config.c b/swad_system_config.c index 0d8950ff..e992e5e3 100644 --- a/swad_system_config.c +++ b/swad_system_config.c @@ -33,6 +33,7 @@ #include // For string functions #include "swad_box.h" +#include "swad_center_database.h" #include "swad_config.h" #include "swad_course.h" #include "swad_database.h" @@ -68,7 +69,6 @@ static void SysCfg_Configuration (bool PrintView); static void SysCfg_PutIconToPrint (__attribute__((unused)) void *Args); -static void SysCfg_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom); static void SysCfg_Map (void); static void SysCfg_Platform (void); static void SysCfg_Shortcut (bool PrintView); @@ -122,48 +122,48 @@ static void SysCfg_Configuration (bool PrintView) /**************************** Left part ***********************************/ HTM_DIV_Begin ("class=\"HIE_CFG_LEFT HIE_CFG_WIDTH\""); - /***** Begin table *****/ - HTM_TABLE_BeginWidePadding (2); + /***** Begin table *****/ + HTM_TABLE_BeginWidePadding (2); - /***** Platform *****/ - SysCfg_Platform (); + /***** Platform *****/ + SysCfg_Platform (); - /***** Shortcut to the country *****/ - SysCfg_Shortcut (PrintView); + /***** Shortcut to the country *****/ + SysCfg_Shortcut (PrintView); - /***** Get number of centers with map *****/ - NumCtrsWithMap = Ctr_GetCachedNumCtrsWithMapInSys (); + /***** Get number of centers with map *****/ + NumCtrsWithMap = Ctr_GetCachedNumCtrsWithMapInSys (); - if (PrintView) - /***** QR code with link to the country *****/ - SysCfg_QR (); - else - { - /***** Get number of centers *****/ - NumCtrs = Ctr_GetCachedNumCtrsInSys (); + if (PrintView) + /***** QR code with link to the country *****/ + SysCfg_QR (); + else + { + /***** Get number of centers *****/ + NumCtrs = Ctr_GetCachedNumCtrsInSys (); - /***** Number of countries, - number of institutions, - number of centers, - number of degrees, - number of courses *****/ - SysCfg_NumCtys (); - SysCfg_NumInss (); - HieCfg_NumCtrs (NumCtrs, - false); // Don't put form - HieCfg_NumCtrsWithMap (NumCtrs,NumCtrsWithMap); - SysCfg_NumDegs (); - SysCfg_NumCrss (); + /***** Number of countries, + number of institutions, + number of centers, + number of degrees, + number of courses *****/ + SysCfg_NumCtys (); + SysCfg_NumInss (); + HieCfg_NumCtrs (NumCtrs, + false); // Don't put form + HieCfg_NumCtrsWithMap (NumCtrs,NumCtrsWithMap); + SysCfg_NumDegs (); + SysCfg_NumCrss (); - /***** Number of users in courses of this country *****/ - HieCfg_NumUsrsInCrss (HieLvl_SYS,-1L,Rol_TCH); - HieCfg_NumUsrsInCrss (HieLvl_SYS,-1L,Rol_NET); - HieCfg_NumUsrsInCrss (HieLvl_SYS,-1L,Rol_STD); - HieCfg_NumUsrsInCrss (HieLvl_SYS,-1L,Rol_UNK); - } + /***** Number of users in courses of this country *****/ + HieCfg_NumUsrsInCrss (HieLvl_SYS,-1L,Rol_TCH); + HieCfg_NumUsrsInCrss (HieLvl_SYS,-1L,Rol_NET); + HieCfg_NumUsrsInCrss (HieLvl_SYS,-1L,Rol_STD); + HieCfg_NumUsrsInCrss (HieLvl_SYS,-1L,Rol_UNK); + } - /***** End table *****/ - HTM_TABLE_End (); + /***** End table *****/ + HTM_TABLE_End (); /***** End of left part *****/ HTM_DIV_End (); @@ -173,8 +173,8 @@ static void SysCfg_Configuration (bool PrintView) { HTM_DIV_Begin ("class=\"HIE_CFG_RIGHT HIE_CFG_WIDTH\""); - /***** Country map *****/ - SysCfg_Map (); + /***** Country map *****/ + SysCfg_Map (); HTM_DIV_End (); } @@ -193,29 +193,6 @@ static void SysCfg_PutIconToPrint (__attribute__((unused)) void *Args) NULL,NULL); } -/*****************************************************************************/ -/********* Get average coordinates of centers in current institution *********/ -/*****************************************************************************/ - -static void SysCfg_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom) - { - char *Query; - - /***** Get average coordinates of centers with both coordinates set - (coordinates 0, 0 means not set ==> don't show map) *****/ - if (asprintf (&Query, - "SELECT AVG(Latitude)," // row[0] - "AVG(Longitude)," // row[1] - "GREATEST(MAX(Latitude)-MIN(Latitude)," - "MAX(Longitude)-MIN(Longitude))" // row[2] - " FROM ctr_centers" - " WHERE Latitude<>0" - " AND Longitude<>0") < 0) - Err_NotEnoughMemoryExit (); - Map_GetCoordAndZoom (Coord,Zoom,Query); - free (Query); - } - /*****************************************************************************/ /****************************** Draw country map *****************************/ /*****************************************************************************/ @@ -245,46 +222,41 @@ static void SysCfg_Map (void) /***** Script to draw the map *****/ HTM_SCRIPT_Begin (NULL,NULL); - /* Let's create a map with pretty Mapbox Streets tiles */ - SysCfg_GetCoordAndZoom (&CtyAvgCoord,&Zoom); - Map_CreateMap (SysCfg_MAP_CONTAINER_ID,&CtyAvgCoord,Zoom); + /* Let's create a map with pretty Mapbox Streets tiles */ + Ctr_DB_GetCoordAndZoom (&CtyAvgCoord,&Zoom); + Map_CreateMap (SysCfg_MAP_CONTAINER_ID,&CtyAvgCoord,Zoom); - /* Add Mapbox Streets tile layer to our map */ - Map_AddTileLayer (); + /* Add Mapbox Streets tile layer to our map */ + Map_AddTileLayer (); - /* Get centers with coordinates */ - NumCtrs = (unsigned) - DB_QuerySELECT (&mysql_res,"can not get centers with coordinates", - "SELECT CtrCod" - " FROM ctr_centers" - " WHERE ctr_centers.Latitude<>0" - " AND ctr_centers.Longitude<>0"); + /* Get centers with coordinates */ + NumCtrs = Ctr_DB_GetCtrsWithCoords (&mysql_res); - /* Add a marker and a popup for each center */ - for (NumCtr = 0; - NumCtr < NumCtrs; - NumCtr++) - { - /* Get next center */ - Ctr.CtrCod = DB_GetNextCode (mysql_res); + /* Add a marker and a popup for each center */ + for (NumCtr = 0; + NumCtr < NumCtrs; + NumCtr++) + { + /* Get next center */ + Ctr.CtrCod = DB_GetNextCode (mysql_res); - /* Get data of center */ - Ctr_GetDataOfCenterByCod (&Ctr); + /* Get data of center */ + Ctr_GetDataOfCenterByCod (&Ctr); - /* Get data of institution */ - Ins.InsCod = Ctr.InsCod; - Ins_GetDataOfInstitByCod (&Ins); + /* Get data of institution */ + Ins.InsCod = Ctr.InsCod; + Ins_GetDataOfInstitByCod (&Ins); - /* Add marker */ - Map_AddMarker (&Ctr.Coord); + /* Add marker */ + Map_AddMarker (&Ctr.Coord); - /* Add popup */ - Map_AddPopup (Ctr.ShrtName,Ins.ShrtName, - false); // Closed - } + /* Add popup */ + Map_AddPopup (Ctr.ShrtName,Ins.ShrtName, + false); // Closed + } - /* Free structure that stores the query result */ - DB_FreeMySQLResult (&mysql_res); + /* Free structure that stores the query result */ + DB_FreeMySQLResult (&mysql_res); HTM_SCRIPT_End (); } @@ -340,17 +312,17 @@ static void SysCfg_NumCtys (void) /***** Number of countries ******/ HTM_TR_Begin (NULL); - /* Label */ - Frm_LabelColumn ("RT",NULL,Txt_Countries); + /* Label */ + Frm_LabelColumn ("RT",NULL,Txt_Countries); - /* Data */ - HTM_TD_Begin ("class=\"LB\""); - Frm_BeginFormGoTo (ActSeeCty); - HTM_BUTTON_SUBMIT_Begin (Txt_Countries,"BT_LINK DAT",NULL); - HTM_Unsigned (Cty_GetCachedNumCtysInSys ()); - HTM_BUTTON_End (); - Frm_EndForm (); - HTM_TD_End (); + /* Data */ + HTM_TD_Begin ("class=\"LB\""); + Frm_BeginFormGoTo (ActSeeCty); + HTM_BUTTON_SUBMIT_Begin (Txt_Countries,"BT_LINK DAT",NULL); + HTM_Unsigned (Cty_GetCachedNumCtysInSys ()); + HTM_BUTTON_End (); + Frm_EndForm (); + HTM_TD_End (); HTM_TR_End (); } @@ -366,13 +338,13 @@ static void SysCfg_NumInss (void) /***** Number of institutions ******/ HTM_TR_Begin (NULL); - /* Label */ - Frm_LabelColumn ("RT",NULL,Txt_Institutions); + /* Label */ + Frm_LabelColumn ("RT",NULL,Txt_Institutions); - /* Data */ - HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Ins_GetCachedNumInssInSys ()); - HTM_TD_End (); + /* Data */ + HTM_TD_Begin ("class=\"DAT LB\""); + HTM_Unsigned (Ins_GetCachedNumInssInSys ()); + HTM_TD_End (); HTM_TR_End (); } @@ -388,13 +360,13 @@ static void SysCfg_NumDegs (void) /***** Number of degrees *****/ HTM_TR_Begin (NULL); - /* Label */ - Frm_LabelColumn ("RT",NULL,Txt_Degrees); + /* Label */ + Frm_LabelColumn ("RT",NULL,Txt_Degrees); - /* Data */ - HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Deg_GetCachedNumDegsInSys ()); - HTM_TD_End (); + /* Data */ + HTM_TD_Begin ("class=\"DAT LB\""); + HTM_Unsigned (Deg_GetCachedNumDegsInSys ()); + HTM_TD_End (); HTM_TR_End (); } @@ -410,13 +382,13 @@ static void SysCfg_NumCrss (void) /***** Number of courses *****/ HTM_TR_Begin (NULL); - /* Label */ - Frm_LabelColumn ("RT",NULL,Txt_Courses); + /* Label */ + Frm_LabelColumn ("RT",NULL,Txt_Courses); - /* Data */ - HTM_TD_Begin ("class=\"DAT LB\""); - HTM_Unsigned (Crs_GetCachedNumCrssInSys ()); - HTM_TD_End (); + /* Data */ + HTM_TD_Begin ("class=\"DAT LB\""); + HTM_Unsigned (Crs_GetCachedNumCrssInSys ()); + HTM_TD_End (); HTM_TR_End (); } diff --git a/swad_tag.c b/swad_tag.c index 72db80b2..c0c1c344 100644 --- a/swad_tag.c +++ b/swad_tag.c @@ -36,6 +36,7 @@ #include "swad_form.h" #include "swad_global.h" #include "swad_tag.h" +#include "swad_tag_database.h" #include "swad_theme.h" /*****************************************************************************/ @@ -64,13 +65,8 @@ extern struct Globals Gbl; /***************************** Private prototypes ****************************/ /*****************************************************************************/ -static void Tag_EnableOrDisableTag (long TagCod,bool TagHidden); - static long Tag_GetParamTagCode (void); -static long Tag_GetTagCodFromTagTxt (const char *TagTxt); -static long Tag_CreateNewTag (long CrsCod,const char *TagTxt); - static void Tag_PutIconEnable (long TagCod,const char *TagTxt); static void Tag_PutIconDisable (long TagCod,const char *TagTxt); @@ -121,57 +117,6 @@ void Tag_PutIconToEditTags (void) Txt_Edit_tags); } -/*****************************************************************************/ -/******************* Check if current course has test tags *******************/ -/*****************************************************************************/ -// Return the number of rows of the result - -bool Tag_CheckIfCurrentCrsHasTestTags (void) - { - /***** Get available tags from database *****/ - return (DB_QueryCOUNT ("can not check if course has tags", - "SELECT COUNT(*)" - " FROM tst_tags" - " WHERE CrsCod=%ld", - Gbl.Hierarchy.Crs.CrsCod) != 0); - } - -/*****************************************************************************/ -/********* Get all (enabled or disabled) test tags for this course ***********/ -/*****************************************************************************/ -// Return the number of rows of the result - -unsigned Tag_GetAllTagsFromCurrentCrs (MYSQL_RES **mysql_res) - { - /***** Get available tags from database *****/ - return (unsigned) DB_QuerySELECT (mysql_res,"can not get available tags", - "SELECT TagCod," // row[0] - "TagTxt," // row[1] - "TagHidden" // row[2] - " FROM tst_tags" - " WHERE CrsCod=%ld" - " ORDER BY TagTxt", - Gbl.Hierarchy.Crs.CrsCod); - } - -/*****************************************************************************/ -/********************** Get enabled test tags for this course ****************/ -/*****************************************************************************/ -// Return the number of rows of the result - -unsigned Tag_GetEnabledTagsFromThisCrs (MYSQL_RES **mysql_res) - { - /***** Get available not hidden tags from database *****/ - return (unsigned) DB_QuerySELECT (mysql_res,"can not get available enabled tags", - "SELECT TagCod," // row[0] - "TagTxt" // row[1] - " FROM tst_tags" - " WHERE CrsCod=%ld" - " AND TagHidden='N'" - " ORDER BY TagTxt", - Gbl.Hierarchy.Crs.CrsCod); - } - /*****************************************************************************/ /******************************* Enable a test tag ***************************/ /*****************************************************************************/ @@ -181,7 +126,7 @@ void Tag_EnableTag (void) long TagCod = Tag_GetParamTagCode (); /***** Change tag status to enabled *****/ - Tag_EnableOrDisableTag (TagCod,false); + Tag_DB_EnableOrDisableTag (TagCod,false); /***** Show again the form to edit tags *****/ Tag_ShowFormEditTags (); @@ -196,31 +141,12 @@ void Tag_DisableTag (void) long TagCod = Tag_GetParamTagCode (); /***** Change tag status to disabled *****/ - Tag_EnableOrDisableTag (TagCod,true); + Tag_DB_EnableOrDisableTag (TagCod,true); /***** Show again the form to edit tags *****/ Tag_ShowFormEditTags (); } -/*****************************************************************************/ -/********** Change visibility of an existing tag into tst_tags table *********/ -/*****************************************************************************/ - -static void Tag_EnableOrDisableTag (long TagCod,bool TagHidden) - { - /***** Insert new tag into tst_tags table *****/ - DB_QueryUPDATE ("can not update the visibility of a tag", - "UPDATE tst_tags" - " SET TagHidden='%c'," - "ChangeTime=NOW()" - " WHERE TagCod=%ld" - " AND CrsCod=%ld", - TagHidden ? 'Y' : - 'N', - TagCod, - Gbl.Hierarchy.Crs.CrsCod); - } - /*****************************************************************************/ /************************* Get parameter with tag code ***********************/ /*****************************************************************************/ @@ -273,7 +199,7 @@ void Tag_RenameTag (void) // are not the same (case insensitively) /* Check if the new tag text is equal to any of the tags already present in the database */ - if ((ExistingTagCod = Tag_GetTagCodFromTagTxt (NewTagTxt)) > 0) + if ((ExistingTagCod = Tag_DB_GetTagCodFromTagTxt (NewTagTxt)) > 0) // The new tag was already in database ComplexRenaming = true; @@ -286,7 +212,7 @@ void Tag_RenameTag (void) - If the new tag did not exist for a question ==> change old tag to new tag in tst_question_tags *****/ /* Get tag code of the old tag */ - if ((OldTagCod = Tag_GetTagCodFromTagTxt (OldTagTxt)) <= 0) + if ((OldTagCod = Tag_DB_GetTagCodFromTagTxt (OldTagTxt)) <= 0) Err_WrongTagExit (); /* Create a temporary table with all the question codes @@ -361,22 +287,6 @@ void Tag_RenameTag (void) Tag_ShowFormEditTags (); } -/*****************************************************************************/ -/***************** Check if this tag exists for current course ***************/ -/*****************************************************************************/ - -static long Tag_GetTagCodFromTagTxt (const char *TagTxt) - { - /***** Get tag code from database *****/ - return DB_QuerySELECTCode ("can not get tag", - "SELECT TagCod" - " FROM tst_tags" - " WHERE CrsCod=%ld" - " AND TagTxt='%s'", - Gbl.Hierarchy.Crs.CrsCod, - TagTxt); - } - /*****************************************************************************/ /*********************** Insert tags in the tags table ***********************/ /*****************************************************************************/ @@ -384,51 +294,27 @@ static long Tag_GetTagCodFromTagTxt (const char *TagTxt) void Tag_InsertTagsIntoDB (long QstCod,const struct Tag_Tags *Tags) { unsigned NumTag; - unsigned TagIdx; + unsigned TagInd; long TagCod; /***** For each tag... *****/ - for (NumTag = 0, TagIdx = 0; - TagIdx < Tags->Num; + for (NumTag = 0, TagInd = 0; + TagInd < Tags->Num; NumTag++) if (Tags->Txt[NumTag][0]) { /***** Check if this tag exists for current course *****/ - if ((TagCod = Tag_GetTagCodFromTagTxt (Tags->Txt[NumTag])) < 0) + if ((TagCod = Tag_DB_GetTagCodFromTagTxt (Tags->Txt[NumTag])) < 0) /* This tag is new for current course. Add it to tags table */ - TagCod = Tag_CreateNewTag (Gbl.Hierarchy.Crs.CrsCod,Tags->Txt[NumTag]); + TagCod = Tag_DB_CreateNewTag (Gbl.Hierarchy.Crs.CrsCod,Tags->Txt[NumTag]); /***** Insert tag in tst_question_tags *****/ - DB_QueryINSERT ("can not create tag", - "INSERT INTO tst_question_tags" - " (QstCod,TagCod,TagInd)" - " VALUES" - " (%ld,%ld,%u)", - QstCod, - TagCod, - TagIdx); + Tag_DB_AddTagToQst (QstCod,TagCod,TagInd); - TagIdx++; + TagInd++; } } -/*****************************************************************************/ -/********************* Insert new tag into tst_tags table ********************/ -/*****************************************************************************/ - -static long Tag_CreateNewTag (long CrsCod,const char *TagTxt) - { - /***** Insert new tag into tst_tags table *****/ - return - DB_QueryINSERTandReturnCode ("can not create new tag", - "INSERT INTO tst_tags" - " (CrsCod,ChangeTime,TagTxt,TagHidden)" - " VALUES" - " (%ld,NOW(),'%s','Y')", // Hidden by default - CrsCod, - TagTxt); - } - /*****************************************************************************/ /********************* Show a form to select test tags ***********************/ /*****************************************************************************/ @@ -455,81 +341,84 @@ void Tag_ShowFormSelTags (const struct Tag_Tags *Tags, */ HTM_TR_Begin (NULL); - /***** Label *****/ - HTM_TD_Begin ("class=\"RT %s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); - HTM_TxtColon (Txt_Tags); - HTM_TD_End (); - - /***** Select all tags *****/ - HTM_TD_Begin ("class=\"LT\""); - - HTM_TABLE_BeginPadding (2); - HTM_TR_Begin (NULL); - if (!ShowOnlyEnabledTags) - HTM_TD_Empty (1); - - HTM_TD_Begin ("class=\"LM\""); - HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); - HTM_INPUT_CHECKBOX ("AllTags",HTM_DONT_SUBMIT_ON_CHANGE, - "value=\"Y\"%s onclick=\"togglecheckChildren(this,'ChkTag');\"", - Tags->All ? " checked=\"checked\"" : - ""); - HTM_TxtF (" %s",Txt_All_tags); - HTM_LABEL_End (); - HTM_TD_End (); - - HTM_TR_End (); - - /***** Select tags one by one *****/ - for (NumTag = 1; - NumTag <= Tags->Num; - NumTag++) - { - row = mysql_fetch_row (mysql_res); - HTM_TR_Begin (NULL); - - if (!ShowOnlyEnabledTags) - { - TagHidden = (row[2][0] == 'Y'); - HTM_TD_Begin ("class=\"LM\""); - Ico_PutIconOff (TagHidden ? "eye-slash-red.svg" : - "eye-green.svg", - TagHidden ? Txt_Tag_not_allowed : - Txt_Tag_allowed); - HTM_TD_End (); - } - - Checked = false; - if (Tags->List) - { - Ptr = Tags->List; - while (*Ptr) - { - Par_GetNextStrUntilSeparParamMult (&Ptr,TagText,Tag_MAX_BYTES_TAG); - if (!strcmp (row[1],TagText)) - { - Checked = true; - break; - } - } - } - - HTM_TD_Begin ("class=\"LM\""); - HTM_LABEL_Begin ("class=\"DAT\""); - HTM_INPUT_CHECKBOX ("ChkTag",HTM_DONT_SUBMIT_ON_CHANGE, - "value=\"%s\"%s onclick=\"checkParent(this,'AllTags');\"", - row[1], - Checked ? " checked=\"checked\"" : - ""); - HTM_TxtF (" %s",row[1]); - HTM_LABEL_End (); + /***** Label *****/ + HTM_TD_Begin ("class=\"RT %s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); + HTM_TxtColon (Txt_Tags); HTM_TD_End (); - HTM_TR_End (); - } + /***** Select all tags *****/ + HTM_TD_Begin ("class=\"LT\""); + + HTM_TABLE_BeginPadding (2); + + HTM_TR_Begin (NULL); + + if (!ShowOnlyEnabledTags) + HTM_TD_Empty (1); + + HTM_TD_Begin ("class=\"LM\""); + HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); + HTM_INPUT_CHECKBOX ("AllTags",HTM_DONT_SUBMIT_ON_CHANGE, + "value=\"Y\"%s onclick=\"togglecheckChildren(this,'ChkTag');\"", + Tags->All ? " checked=\"checked\"" : + ""); + HTM_TxtF (" %s",Txt_All_tags); + HTM_LABEL_End (); + HTM_TD_End (); + + HTM_TR_End (); + + /***** Select tags one by one *****/ + for (NumTag = 1; + NumTag <= Tags->Num; + NumTag++) + { + row = mysql_fetch_row (mysql_res); + HTM_TR_Begin (NULL); + + if (!ShowOnlyEnabledTags) + { + TagHidden = (row[2][0] == 'Y'); + HTM_TD_Begin ("class=\"LM\""); + Ico_PutIconOff (TagHidden ? "eye-slash-red.svg" : + "eye-green.svg", + TagHidden ? Txt_Tag_not_allowed : + Txt_Tag_allowed); + HTM_TD_End (); + } + + Checked = false; + if (Tags->List) + { + Ptr = Tags->List; + while (*Ptr) + { + Par_GetNextStrUntilSeparParamMult (&Ptr,TagText,Tag_MAX_BYTES_TAG); + if (!strcmp (row[1],TagText)) + { + Checked = true; + break; + } + } + } + + HTM_TD_Begin ("class=\"LM\""); + HTM_LABEL_Begin ("class=\"DAT\""); + HTM_INPUT_CHECKBOX ("ChkTag",HTM_DONT_SUBMIT_ON_CHANGE, + "value=\"%s\"%s onclick=\"checkParent(this,'AllTags');\"", + row[1], + Checked ? " checked=\"checked\"" : + ""); + HTM_TxtF (" %s",row[1]); + HTM_LABEL_End (); + HTM_TD_End (); + + HTM_TR_End (); + } + + HTM_TABLE_End (); + HTM_TD_End (); - HTM_TABLE_End (); - HTM_TD_End (); HTM_TR_End (); } @@ -549,47 +438,47 @@ void Tag_ShowFormEditTags (void) long TagCod; /***** Get current tags in current course *****/ - if ((NumTags = Tag_GetAllTagsFromCurrentCrs (&mysql_res))) + if ((NumTags = Tag_DB_GetAllTagsFromCurrentCrs (&mysql_res))) { /***** Begin box and table *****/ Box_BoxTableBegin (NULL,Txt_Tags, NULL,NULL, Hlp_ASSESSMENT_Questions_editing_tags,Box_NOT_CLOSABLE,2); - /***** Show tags *****/ - for (NumTag = 0; - NumTag < NumTags; - NumTag++) - { - row = mysql_fetch_row (mysql_res); - /* - row[0] TagCod - row[1] TagTxt - row[2] TagHidden - */ - if ((TagCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) - Err_WrongTagExit (); + /***** Show tags *****/ + for (NumTag = 0; + NumTag < NumTags; + NumTag++) + { + row = mysql_fetch_row (mysql_res); + /* + row[0] TagCod + row[1] TagTxt + row[2] TagHidden + */ + if ((TagCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) + Err_WrongTagExit (); - HTM_TR_Begin (NULL); + HTM_TR_Begin (NULL); - /* Form to enable / disable this tag */ - if (row[2][0] == 'Y') // Tag disabled - Tag_PutIconEnable (TagCod,row[1]); - else - Tag_PutIconDisable (TagCod,row[1]); + /* Form to enable / disable this tag */ + if (row[2][0] == 'Y') // Tag disabled + Tag_PutIconEnable (TagCod,row[1]); + else + Tag_PutIconDisable (TagCod,row[1]); - /* Form to rename this tag */ - HTM_TD_Begin ("class=\"LM\""); - Frm_BeginForm (ActRenTag); - Par_PutHiddenParamString (NULL,"OldTagTxt",row[1]); - HTM_INPUT_TEXT ("NewTagTxt",Tag_MAX_CHARS_TAG,row[1], - HTM_SUBMIT_ON_CHANGE, - "size=\"36\" required=\"required\""); - Frm_EndForm (); - HTM_TD_End (); + /* Form to rename this tag */ + HTM_TD_Begin ("class=\"LM\""); + Frm_BeginForm (ActRenTag); + Par_PutHiddenParamString (NULL,"OldTagTxt",row[1]); + HTM_INPUT_TEXT ("NewTagTxt",Tag_MAX_CHARS_TAG,row[1], + HTM_SUBMIT_ON_CHANGE, + "size=\"36\" required=\"required\""); + Frm_EndForm (); + HTM_TD_End (); - HTM_TR_End (); - } + HTM_TR_End (); + } /***** End table and box *****/ Box_BoxTableEnd (); @@ -610,13 +499,13 @@ static void Tag_PutIconEnable (long TagCod,const char *TagTxt) extern const char *Txt_Tag_X_not_allowed_Click_to_allow_it; HTM_TD_Begin ("class=\"BM\""); - Frm_BeginForm (ActEnaTag); - Par_PutHiddenParamLong (NULL,"TagCod",TagCod); - Ico_PutIconLink ("eye-slash-red.svg", - Str_BuildStringStr (Txt_Tag_X_not_allowed_Click_to_allow_it, - TagTxt)); - Str_FreeString (); - Frm_EndForm (); + Frm_BeginForm (ActEnaTag); + Par_PutHiddenParamLong (NULL,"TagCod",TagCod); + Ico_PutIconLink ("eye-slash-red.svg", + Str_BuildStringStr (Txt_Tag_X_not_allowed_Click_to_allow_it, + TagTxt)); + Str_FreeString (); + Frm_EndForm (); HTM_TD_End (); } @@ -629,45 +518,12 @@ static void Tag_PutIconDisable (long TagCod,const char *TagTxt) extern const char *Txt_Tag_X_allowed_Click_to_disable_it; HTM_TD_Begin ("class=\"BM\""); - Frm_BeginForm (ActDisTag); - Par_PutHiddenParamLong (NULL,"TagCod",TagCod); - Ico_PutIconLink ("eye-green.svg", - Str_BuildStringStr (Txt_Tag_X_allowed_Click_to_disable_it, - TagTxt)); - Str_FreeString (); - Frm_EndForm (); + Frm_BeginForm (ActDisTag); + Par_PutHiddenParamLong (NULL,"TagCod",TagCod); + Ico_PutIconLink ("eye-green.svg", + Str_BuildStringStr (Txt_Tag_X_allowed_Click_to_disable_it, + TagTxt)); + Str_FreeString (); + Frm_EndForm (); HTM_TD_End (); } - -/*****************************************************************************/ -/************************** Remove tags from a question **********************/ -/*****************************************************************************/ - -void Tag_RemTagsFromQst (long QstCod) - { - /***** Remove tags *****/ - DB_QueryDELETE ("can not remove the tags of a question", - "DELETE FROM tst_question_tags" - " WHERE QstCod=%ld", - QstCod); - } - -/*****************************************************************************/ -/********************** Remove unused tags in a course ***********************/ -/*****************************************************************************/ - -void Tag_RemoveUnusedTagsFromCrs (long CrsCod) - { - /***** Remove unused tags from tst_tags *****/ - DB_QueryDELETE ("can not remove unused tags", - "DELETE FROM tst_tags" - " WHERE CrsCod=%ld" - " AND TagCod NOT IN" - " (SELECT DISTINCT tst_question_tags.TagCod" - " FROM tst_questions," - "tst_question_tags" - " WHERE tst_questions.CrsCod=%ld" - " AND tst_questions.QstCod=tst_question_tags.QstCod)", - CrsCod, - CrsCod); - } diff --git a/swad_tag.h b/swad_tag.h index f67a6fe4..a5e926d5 100644 --- a/swad_tag.h +++ b/swad_tag.h @@ -61,10 +61,6 @@ void Tag_FreeTagsList (struct Tag_Tags *Tags); void Tag_PutIconToEditTags (void); -bool Tag_CheckIfCurrentCrsHasTestTags (void); -unsigned Tag_GetAllTagsFromCurrentCrs (MYSQL_RES **mysql_res); -unsigned Tag_GetEnabledTagsFromThisCrs (MYSQL_RES **mysql_res); - void Tag_EnableTag (void); void Tag_DisableTag (void); void Tag_RenameTag (void); @@ -76,7 +72,4 @@ void Tag_ShowFormSelTags (const struct Tag_Tags *Tags, bool ShowOnlyEnabledTags); void Tag_ShowFormEditTags (void); -void Tag_RemTagsFromQst (long QstCod); -void Tag_RemoveUnusedTagsFromCrs (long CrsCod); - #endif diff --git a/swad_tag_database.c b/swad_tag_database.c new file mode 100644 index 00000000..5ba39365 --- /dev/null +++ b/swad_tag_database.c @@ -0,0 +1,218 @@ +// swad_tag_database.c: tags for questions, 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 // To access MySQL databases +// #include // For boolean type +// #include // For free +// #include // For string functions + +// #include "swad_action.h" +#include "swad_database.h" +// #include "swad_error.h" +// #include "swad_form.h" +#include "swad_global.h" +// #include "swad_tag.h" +#include "swad_tag_database.h" +// #include "swad_theme.h" + +/*****************************************************************************/ +/***************************** Public constants ******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/**************************** Private constants ******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************* Private types *******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/************** External global variables from others modules ****************/ +/*****************************************************************************/ + +extern struct Globals Gbl; + +/*****************************************************************************/ +/************************* Private global variables **************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private prototypes ****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/********************* Insert new tag into tst_tags table ********************/ +/*****************************************************************************/ + +long Tag_DB_CreateNewTag (long CrsCod,const char *TagTxt) + { + /***** Insert new tag into tst_tags table *****/ + return + DB_QueryINSERTandReturnCode ("can not create new tag", + "INSERT INTO tst_tags" + " (CrsCod,ChangeTime,TagTxt,TagHidden)" + " VALUES" + " (%ld,NOW(),'%s','Y')", // Hidden by default + CrsCod, + TagTxt); + } + +/*****************************************************************************/ +/*************************** Add tag to a question ***************************/ +/*****************************************************************************/ + +void Tag_DB_AddTagToQst (long QstCod,long TagCod,unsigned TagInd) + { + DB_QueryINSERT ("can not create tag", + "INSERT INTO tst_question_tags" + " (QstCod,TagCod,TagInd)" + " VALUES" + " (%ld,%ld,%u)", + QstCod, + TagCod, + TagInd); + } + +/*****************************************************************************/ +/********** Change visibility of an existing tag into tst_tags table *********/ +/*****************************************************************************/ + +void Tag_DB_EnableOrDisableTag (long TagCod,bool TagHidden) + { + /***** Insert new tag into tst_tags table *****/ + DB_QueryUPDATE ("can not update the visibility of a tag", + "UPDATE tst_tags" + " SET TagHidden='%c'," + "ChangeTime=NOW()" + " WHERE TagCod=%ld" + " AND CrsCod=%ld", + TagHidden ? 'Y' : + 'N', + TagCod, + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/********* Get all (enabled or disabled) test tags for this course ***********/ +/*****************************************************************************/ +// Return the number of rows of the result + +unsigned Tag_DB_GetAllTagsFromCurrentCrs (MYSQL_RES **mysql_res) + { + /***** Get available tags from database *****/ + return (unsigned) DB_QuerySELECT (mysql_res,"can not get available tags", + "SELECT TagCod," // row[0] + "TagTxt," // row[1] + "TagHidden" // row[2] + " FROM tst_tags" + " WHERE CrsCod=%ld" + " ORDER BY TagTxt", + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/********************** Get enabled test tags for this course ****************/ +/*****************************************************************************/ +// Return the number of rows of the result + +unsigned Tag_DB_GetEnabledTagsFromThisCrs (MYSQL_RES **mysql_res) + { + /***** Get available not hidden tags from database *****/ + return (unsigned) DB_QuerySELECT (mysql_res,"can not get available enabled tags", + "SELECT TagCod," // row[0] + "TagTxt" // row[1] + " FROM tst_tags" + " WHERE CrsCod=%ld" + " AND TagHidden='N'" + " ORDER BY TagTxt", + Gbl.Hierarchy.Crs.CrsCod); + } + +/*****************************************************************************/ +/******************* Check if current course has test tags *******************/ +/*****************************************************************************/ +// Return the number of rows of the result + +bool Tag_DB_CheckIfCurrentCrsHasTestTags (void) + { + /***** Get available tags from database *****/ + return (DB_QueryCOUNT ("can not check if course has tags", + "SELECT COUNT(*)" + " FROM tst_tags" + " WHERE CrsCod=%ld", + Gbl.Hierarchy.Crs.CrsCod) != 0); + } + +/*****************************************************************************/ +/***************** Check if this tag exists for current course ***************/ +/*****************************************************************************/ + +long Tag_DB_GetTagCodFromTagTxt (const char *TagTxt) + { + /***** Get tag code from database *****/ + return DB_QuerySELECTCode ("can not get tag", + "SELECT TagCod" + " FROM tst_tags" + " WHERE CrsCod=%ld" + " AND TagTxt='%s'", + Gbl.Hierarchy.Crs.CrsCod, + TagTxt); + } + +/*****************************************************************************/ +/************************** Remove tags from a question **********************/ +/*****************************************************************************/ + +void Tag_DB_RemTagsFromQst (long QstCod) + { + /***** Remove tags *****/ + DB_QueryDELETE ("can not remove the tags of a question", + "DELETE FROM tst_question_tags" + " WHERE QstCod=%ld", + QstCod); + } + +/*****************************************************************************/ +/********************** Remove unused tags in a course ***********************/ +/*****************************************************************************/ + +void Tag_DB_RemoveUnusedTagsFromCrs (long CrsCod) + { + /***** Remove unused tags from tst_tags *****/ + DB_QueryDELETE ("can not remove unused tags", + "DELETE FROM tst_tags" + " WHERE CrsCod=%ld" + " AND TagCod NOT IN" + " (SELECT DISTINCT tst_question_tags.TagCod" + " FROM tst_questions," + "tst_question_tags" + " WHERE tst_questions.CrsCod=%ld" + " AND tst_questions.QstCod=tst_question_tags.QstCod)", + CrsCod, + CrsCod); + } diff --git a/swad_tag_database.h b/swad_tag_database.h new file mode 100644 index 00000000..77aa3ead --- /dev/null +++ b/swad_tag_database.h @@ -0,0 +1,59 @@ +// swad_tag_database.h: tags for questions, operations with database + +#ifndef _SWAD_TAG_DB +#define _SWAD_TAG_DB +/* + SWAD (Shared Workspace At a Distance in Spanish), + 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 // To access MySQL databases +#include // For boolean type +// #include "swad_string.h" + +/*****************************************************************************/ +/***************************** Public constants ******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************* Public types ********************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Public prototypes *****************************/ +/*****************************************************************************/ + +long Tag_DB_CreateNewTag (long CrsCod,const char *TagTxt); +void Tag_DB_AddTagToQst (long QstCod,long TagCod,unsigned TagInd); + +void Tag_DB_EnableOrDisableTag (long TagCod,bool TagHidden); + +unsigned Tag_DB_GetAllTagsFromCurrentCrs (MYSQL_RES **mysql_res); +unsigned Tag_DB_GetEnabledTagsFromThisCrs (MYSQL_RES **mysql_res); +bool Tag_DB_CheckIfCurrentCrsHasTestTags (void); +long Tag_DB_GetTagCodFromTagTxt (const char *TagTxt); + +void Tag_DB_RemTagsFromQst (long QstCod); +void Tag_DB_RemoveUnusedTagsFromCrs (long CrsCod); + +#endif diff --git a/swad_test.c b/swad_test.c index 22f56f6a..fd708636 100644 --- a/swad_test.c +++ b/swad_test.c @@ -52,12 +52,13 @@ #include "swad_match.h" #include "swad_media.h" #include "swad_parameter.h" -#include "swad_theme.h" +#include "swad_tag_database.h" #include "swad_test.h" #include "swad_test_config.h" #include "swad_test_import.h" #include "swad_test_print.h" #include "swad_test_visibility.h" +#include "swad_theme.h" #include "swad_user.h" #include "swad_xml.h" @@ -304,7 +305,7 @@ static void Tst_ShowFormRequestTest (struct Tst_Test *Test) Hlp_ASSESSMENT_Tests,Box_NOT_CLOSABLE); /***** Get tags *****/ - if ((Test->Tags.Num = Tag_GetEnabledTagsFromThisCrs (&mysql_res)) != 0) + if ((Test->Tags.Num = Tag_DB_GetEnabledTagsFromThisCrs (&mysql_res)) != 0) { /***** Check if minimum date-time of next access to test is older than now *****/ if (Tst_CheckIfNextTstAllowed ()) @@ -1013,7 +1014,7 @@ static void Tst_ShowFormRequestEditTests (struct Tst_Test *Test) Hlp_ASSESSMENT_Questions_editing_questions,Box_NOT_CLOSABLE); /***** Get tags already present in the table of questions *****/ - if ((Test->Tags.Num = Tag_GetAllTagsFromCurrentCrs (&mysql_res))) + if ((Test->Tags.Num = Tag_DB_GetAllTagsFromCurrentCrs (&mysql_res))) { Frm_BeginForm (ActLstTstQst); Par_PutHiddenParamUnsigned (NULL,"Order",(unsigned) Tst_DEFAULT_ORDER); @@ -1111,7 +1112,7 @@ static void Tst_ShowFormRequestSelectTestsForSet (struct Exa_Exams *Exams, Hlp_ASSESSMENT_Exams_questions,Box_NOT_CLOSABLE); /***** Get tags already present in the table of questions *****/ - if ((Test->Tags.Num = Tag_GetAllTagsFromCurrentCrs (&mysql_res))) + if ((Test->Tags.Num = Tag_DB_GetAllTagsFromCurrentCrs (&mysql_res))) { Frm_BeginForm (ActLstTstQstForSet); ExaSet_PutParamsOneSet (Exams); @@ -1173,7 +1174,7 @@ static void Tst_ShowFormRequestSelectTestsForGame (struct Gam_Games *Games, Hlp_ASSESSMENT_Games_questions,Box_NOT_CLOSABLE); /***** Get tags already present in the table of questions *****/ - if ((Test->Tags.Num = Tag_GetAllTagsFromCurrentCrs (&mysql_res))) + if ((Test->Tags.Num = Tag_DB_GetAllTagsFromCurrentCrs (&mysql_res))) { Frm_BeginForm (ActGamLstTstQst); Gam_PutParams (Games); @@ -1391,7 +1392,7 @@ bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void) /***** Get if current course has tests from database *****/ if (TstCfg_GetConfigPluggable () == TstCfg_PLUGGABLE_UNKNOWN) - return Tag_CheckIfCurrentCrsHasTestTags (); // Return true if course has tests + return Tag_DB_CheckIfCurrentCrsHasTestTags (); // Return true if course has tests return false; // Pluggable is not unknown } @@ -3262,7 +3263,7 @@ static void Tst_PutFormEditOneQst (struct Tst_Question *Question) HTM_TR_End (); /***** Get tags already existing for questions in current course *****/ - NumTags = Tag_GetAllTagsFromCurrentCrs (&mysql_res); + NumTags = Tag_DB_GetAllTagsFromCurrentCrs (&mysql_res); /***** Write the tags *****/ HTM_TR_Begin (NULL); @@ -4852,8 +4853,8 @@ static void Tst_RemoveOneQstFromDB (long CrsCod,long QstCod) /***** Remove the question from all the tables *****/ /* Remove answers and tags from this test question */ Tst_RemAnsFromQst (QstCod); - Tag_RemTagsFromQst (QstCod); - Tag_RemoveUnusedTagsFromCrs (CrsCod); + Tag_DB_RemTagsFromQst (QstCod); + Tag_DB_RemoveUnusedTagsFromCrs (CrsCod); /* Remove the question itself */ DB_QueryDELETE ("can not remove a question", @@ -4953,7 +4954,7 @@ void Tst_InsertOrUpdateQstTagsAnsIntoDB (struct Tst_Question *Question) Tag_InsertTagsIntoDB (Question->QstCod,&Question->Tags); /***** Remove unused tags in current course *****/ - Tag_RemoveUnusedTagsFromCrs (Gbl.Hierarchy.Crs.CrsCod); + Tag_DB_RemoveUnusedTagsFromCrs (Gbl.Hierarchy.Crs.CrsCod); /***** Insert answers in the answers table *****/ Tst_InsertAnswersIntoDB (Question); @@ -5026,7 +5027,7 @@ static void Tst_InsertOrUpdateQstIntoDB (struct Tst_Question *Question) /* Remove answers and tags from this test question */ Tst_RemAnsFromQst (Question->QstCod); - Tag_RemTagsFromQst (Question->QstCod); + Tag_DB_RemTagsFromQst (Question->QstCod); } }