From babcd3df60de291f9b7379e512c3c3e5b6b739dc Mon Sep 17 00:00:00 2001 From: acanas Date: Wed, 22 Sep 2021 00:18:08 +0200 Subject: [PATCH] Version 21.11: Sep 22, 2021 New module swad_info_database for database queries related to course information. --- Makefile | 5 +- swad_changelog.h | 7 +- swad_enrolment.c | 2 +- swad_indicator_database.c | 13 - swad_info.c | 662 +++++++++++++------------------------- swad_info.h | 9 +- swad_info_database.c | 303 +++++++++++++++++ swad_info_database.h | 71 ++++ swad_syllabus.c | 11 +- swad_user.c | 2 +- 10 files changed, 617 insertions(+), 468 deletions(-) create mode 100644 swad_info_database.c create mode 100644 swad_info_database.h diff --git a/Makefile b/Makefile index 47aa5990..c8188255 100644 --- a/Makefile +++ b/Makefile @@ -56,8 +56,9 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_admin.o \ swad_hierarchy_config.o swad_hierarchy_database.o swad_holiday.o \ swad_holiday_database.o swad_HTML.o \ swad_icon.o swad_ID.o swad_ID_database.o swad_indicator.o \ - swad_indicator_database.o swad_info.o swad_institution.o \ - swad_institution_config.o swad_institution_database.o \ + swad_indicator_database.o swad_info.o swad_info_database.o \ + swad_institution.o swad_institution_config.o \ + swad_institution_database.o \ swad_language.o swad_layout.o swad_link.o swad_log.o swad_logo.o \ swad_MAC.o swad_mail.o swad_main.o swad_maintenance.o swad_map.o \ swad_mark.o swad_match.o swad_match_print.o swad_match_result.o \ diff --git a/swad_changelog.h b/swad_changelog.h index 6fb9ddf8..4e7b0b80 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,16 +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.10 (2021-09-20)" +#define Log_PLATFORM_VERSION "SWAD 21.11 (2021-09-22)" #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 -TODO: Un profesor no puede confirmar DNIs -TODO: Al cambiar un estudiante en una asignatura, dice que el rol ha cambiado de desconocido a estudiante - + Version 21.11: Sep 22, 2021 New module swad_info_database for database queries related to course information. (316228 lines) + Version 21.10.1: Sep 21, 2021 Fixed bugs in roles. Reported by Javier Fernández Baldomero and Mª Carmen García Miranda. (316111 lines) Version 21.10: Sep 20, 2021 New module swad_indicator_database for database queries related to course indicators. (316112 lines) Version 21.9.1: Sep 20, 2021 Queries moved to module swad_browser_database. (316023 lines) Version 21.9: Sep 20, 2021 New module swad_ID_database for database queries related to user's IDs. (316021 lines) diff --git a/swad_enrolment.c b/swad_enrolment.c index 5b2e8c0f..6c4efa14 100644 --- a/swad_enrolment.c +++ b/swad_enrolment.c @@ -3204,7 +3204,7 @@ static void Enr_EffectivelyRemUsrFromCrs (struct UsrData *UsrDat, Grp_RemUsrFromAllGrpsInCrs (UsrDat->UsrCod,Crs->CrsCod); /***** Remove user's status about reading of course information *****/ - Inf_RemoveUsrFromCrsInfoRead (UsrDat->UsrCod,Crs->CrsCod); + Inf_DB_RemoveUsrFromCrsInfoRead (UsrDat->UsrCod,Crs->CrsCod); /***** Remove important production of this user in course *****/ if (RemoveUsrWorks == Enr_REMOVE_USR_PRODUCTION) diff --git a/swad_indicator_database.c b/swad_indicator_database.c index d5ea8f26..340169d8 100644 --- a/swad_indicator_database.c +++ b/swad_indicator_database.c @@ -25,25 +25,12 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ -// #include // For NULL #include // To access MySQL databases -// #include "swad_action.h" -// #include "swad_assignment_database.h" -// #include "swad_box.h" -// #include "swad_browser_database.h" #include "swad_database.h" -// #include "swad_department.h" #include "swad_error.h" -// #include "swad_form.h" -// #include "swad_forum_database.h" #include "swad_global.h" -// #include "swad_hierarchy_level.h" -// #include "swad_HTML.h" #include "swad_indicator.h" -// #include "swad_message.h" -// #include "swad_parameter.h" -// #include "swad_theme.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ diff --git a/swad_info.c b/swad_info.c index 0565f5ee..4511499c 100644 --- a/swad_info.c +++ b/swad_info.c @@ -41,6 +41,7 @@ #include "swad_global.h" #include "swad_HTML.h" #include "swad_info.h" +#include "swad_info_database.h" #include "swad_parameter.h" #include "swad_string.h" @@ -97,16 +98,6 @@ static void (*Inf_FormsForEditionTypes[Inf_NUM_SOURCES])(Inf_Src_t InfoSrc) = [Inf_URL ] = Inf_FormToSendURL, }; -static const char *Inf_NamesInDBForInfoSrc[Inf_NUM_SOURCES] = - { - [Inf_NONE ] = "none", - [Inf_EDITOR ] = "editor", - [Inf_PLAIN_TEXT] = "plain_text", - [Inf_RICH_TEXT ] = "rich_text", - [Inf_PAGE ] = "page", - [Inf_URL ] = "URL", - }; - static const Act_Action_t Inf_ActionsEditInfo[Inf_NUM_TYPES] = { [Inf_INTRODUCTION ] = ActEdiCrsInf, @@ -236,18 +227,6 @@ static const Act_Action_t Inf_ActionsRcvRchTxtInfo[Inf_NUM_TYPES] = [Inf_ASSESSMENT ] = ActRcvRchTxtAss, }; -static const char *Inf_NamesInDBForInfoType[Inf_NUM_TYPES] = - { - [Inf_INTRODUCTION ] = "intro", // TODO: Change this to "introduction"! - [Inf_TEACHING_GUIDE] = "description", // TODO: Change this to "guide"! - [Inf_LECTURES ] = "theory", // TODO: Change this to "lectures"! - [Inf_PRACTICALS ] = "practices", // TODO: Change this to "practicals"! - [Inf_BIBLIOGRAPHY ] = "bibliography", - [Inf_FAQ ] = "FAQ", - [Inf_LINKS ] = "links", - [Inf_ASSESSMENT ] = "assessment", - }; - /***** Help *****/ extern const char *Hlp_COURSE_Information_textual_information; extern const char *Hlp_COURSE_Guide; @@ -273,11 +252,8 @@ static void Inf_PutButtonToEditInfo (void); static void Inf_PutIconToViewInfo (void *Type); static void Inf_PutCheckboxForceStdsToReadInfo (bool MustBeRead,bool Disabled); static void Inf_PutCheckboxConfirmIHaveReadInfo (void); -static bool Inf_CheckIfIHaveReadInfo (void); static bool Inf_GetMustBeReadFromForm (void); static bool Inf_GetIfIHaveReadFromForm (void); -static void Inf_SetForceReadIntoDB (bool MustBeRead); -static void Inf_SetIHaveReadIntoDB (bool IHaveRead); static bool Inf_CheckPage (long CrsCod,Inf_Type_t InfoType); static bool Inf_CheckAndShowPage (void); @@ -293,7 +269,6 @@ static bool Inf_CheckIfInfoAvailable (struct Syl_Syllabus *Syllabus, Inf_Src_t InfoSrc); static void Inf_AsignInfoType (struct Inf_Info *Info, struct Syl_Syllabus *Syllabus); -static void Inf_SetInfoTxtIntoDB (const char *InfoTxtHTML,const char *InfoTxtMD); static bool Inf_CheckPlainTxt (long CrsCod,Inf_Type_t InfoType); static bool Inf_CheckAndShowPlainTxt (void); @@ -443,7 +418,7 @@ static void Inf_PutButtonToEditInfo (void) extern const char *Txt_Edit; Frm_BeginForm (Inf_ActionsEditInfo[Gbl.Crs.Info.Type]); - Btn_PutConfirmButton (Txt_Edit); + Btn_PutConfirmButton (Txt_Edit); Frm_EndForm (); } @@ -488,7 +463,7 @@ static void Inf_PutCheckboxForceStdsToReadInfo (bool MustBeRead,bool Disabled) static void Inf_PutCheckboxConfirmIHaveReadInfo (void) { extern const char *Txt_I_have_read_this_information; - bool IHaveRead = Inf_CheckIfIHaveReadInfo (); + bool IHaveRead = Inf_DB_CheckIfIHaveReadInfo (); Lay_PutContextualCheckbox (Inf_ActionsIHaveReadInfo[Gbl.Crs.Info.Type], NULL, @@ -498,24 +473,6 @@ static void Inf_PutCheckboxConfirmIHaveReadInfo (void) Txt_I_have_read_this_information); } -/*****************************************************************************/ -/******************** Check I have read a course info ************************/ -/*****************************************************************************/ - -static bool Inf_CheckIfIHaveReadInfo (void) - { - /***** Get if info source is already stored in database *****/ - return (DB_QueryCOUNT ("can not get if I have read course info", - "SELECT COUNT(*)" - " FROM crs_info_read" - " WHERE UsrCod=%ld" - " AND CrsCod=%ld" - " AND InfoType='%s'", - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Hierarchy.Crs.CrsCod, - Inf_NamesInDBForInfoType[Gbl.Crs.Info.Type]) != 0); - } - /*****************************************************************************/ /********* Get if students must read any info about current course ***********/ /*****************************************************************************/ @@ -558,7 +515,7 @@ bool Inf_GetIfIMustReadAnyCrsInfoInThisCrs (void) row = mysql_fetch_row (mysql_res); /* Get info type (row[0]) */ - InfoType = Inf_ConvertFromStrDBToInfoType (row[0]); + InfoType = Inf_DB_ConvertFromStrDBToInfoType (row[0]); Gbl.Crs.Info.MustBeRead[InfoType] = true; } @@ -585,28 +542,28 @@ void Inf_WriteMsgYouMustReadInfo (void) NULL,NULL, NULL,Box_CLOSABLE); - /***** Write message *****/ - Ale_ShowAlert (Ale_WARNING,Txt_You_should_read_the_following_information); + /***** Write message *****/ + Ale_ShowAlert (Ale_WARNING,Txt_You_should_read_the_following_information); - /***** Write every information I must read *****/ - HTM_DIV_Begin ("class=\"CM\""); - HTM_UL_Begin ("class=\"LIST_I_MUST_READ\""); - for (InfoType = (Inf_Type_t) 0; - InfoType <= (Inf_Type_t) (Inf_NUM_TYPES - 1); - InfoType++) - if (Gbl.Crs.Info.MustBeRead[InfoType]) - { - HTM_LI_Begin (NULL); - Frm_BeginForm (Inf_ActionsSeeInfo[InfoType]); - HTM_BUTTON_SUBMIT_Begin (Act_GetTitleAction (Inf_ActionsSeeInfo[InfoType]), - The_ClassFormLinkInBox[Gbl.Prefs.Theme],NULL); - HTM_Txt (Act_GetTitleAction (Inf_ActionsSeeInfo[InfoType])); - HTM_BUTTON_End (); - Frm_EndForm (); - HTM_LI_End (); - } - HTM_UL_End (); - HTM_DIV_End (); + /***** Write every information I must read *****/ + HTM_DIV_Begin ("class=\"CM\""); + HTM_UL_Begin ("class=\"LIST_I_MUST_READ\""); + for (InfoType = (Inf_Type_t) 0; + InfoType <= (Inf_Type_t) (Inf_NUM_TYPES - 1); + InfoType++) + if (Gbl.Crs.Info.MustBeRead[InfoType]) + { + HTM_LI_Begin (NULL); + Frm_BeginForm (Inf_ActionsSeeInfo[InfoType]); + HTM_BUTTON_SUBMIT_Begin (Act_GetTitleAction (Inf_ActionsSeeInfo[InfoType]), + The_ClassFormLinkInBox[Gbl.Prefs.Theme],NULL); + HTM_Txt (Act_GetTitleAction (Inf_ActionsSeeInfo[InfoType])); + HTM_BUTTON_End (); + Frm_EndForm (); + HTM_LI_End (); + } + HTM_UL_End (); + HTM_DIV_End (); /***** End box *****/ Box_BoxEnd (); @@ -630,7 +587,7 @@ void Inf_ChangeForceReadInfo (void) Inf_AsignInfoType (&Gbl.Crs.Info,&Syllabus); /***** Set status (if info must be read or not) into database *****/ - Inf_SetForceReadIntoDB (MustBeRead); + Inf_DB_SetForceRead (MustBeRead); /***** Write message of success *****/ Ale_ShowAlert (Ale_SUCCESS, @@ -659,7 +616,7 @@ void Inf_ChangeIHaveReadInfo (void) Inf_AsignInfoType (&Gbl.Crs.Info,&Syllabus); /***** Set status (if I have read or not a information) into database *****/ - Inf_SetIHaveReadIntoDB (IHaveRead); + Inf_DB_SetIHaveRead (IHaveRead); /***** Write message of success *****/ Ale_ShowAlert (Ale_SUCCESS, @@ -688,57 +645,11 @@ static bool Inf_GetIfIHaveReadFromForm (void) return Par_GetParToBool ("IHaveRead"); } -/*****************************************************************************/ -/***************** Set if students must read course info *********************/ -/*****************************************************************************/ - -static void Inf_SetForceReadIntoDB (bool MustBeRead) - { - /***** Insert or replace info source for a specific type of course information *****/ - DB_QueryUPDATE ("can not update if info must be read", - "UPDATE crs_info_src" - " SET MustBeRead='%c'" - " WHERE CrsCod=%ld" - " AND InfoType='%s'", - MustBeRead ? 'Y' : - 'N', - Gbl.Hierarchy.Crs.CrsCod, - Inf_NamesInDBForInfoType[Gbl.Crs.Info.Type]); - } - -/*****************************************************************************/ -/********************* Set if I have read course info ************************/ -/*****************************************************************************/ - -static void Inf_SetIHaveReadIntoDB (bool IHaveRead) - { - if (IHaveRead) - /***** Insert I have read course information *****/ - DB_QueryREPLACE ("can not set that I have read course info", - "REPLACE INTO crs_info_read" - " (UsrCod,CrsCod,InfoType)" - " VALUES" - " (%ld,%ld,'%s')", - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Hierarchy.Crs.CrsCod, - Inf_NamesInDBForInfoType[Gbl.Crs.Info.Type]); - else - /***** Remove I have read course information *****/ - DB_QueryDELETE ("can not set that I have not read course info", - "DELETE FROM crs_info_read" - " WHERE UsrCod=%ld" - " AND CrsCod=%ld" - " AND InfoType='%s'", - Gbl.Usrs.Me.UsrDat.UsrCod, - Gbl.Hierarchy.Crs.CrsCod, - Inf_NamesInDBForInfoType[Gbl.Crs.Info.Type]); - } - /*****************************************************************************/ /********* Remove user's status about reading of course information **********/ /*****************************************************************************/ -void Inf_RemoveUsrFromCrsInfoRead (long UsrCod,long CrsCod) +void Inf_DB_RemoveUsrFromCrsInfoRead (long UsrCod,long CrsCod) { /***** Remove user's status about reading of course information *****/ DB_QueryDELETE ("can not set that I have not read course info", @@ -969,8 +880,8 @@ static void Inf_ShowPage (const char *URL) /***** Link to view in a new window *****/ HTM_A_Begin ("href=\"%s\" target=\"_blank\" class=\"%s\"", URL,The_ClassFormOutBoxBold[Gbl.Prefs.Theme]); - Ico_PutIconTextLink ("expand-arrows-alt.svg", - Txt_View_in_a_new_window); + Ico_PutIconTextLink ("expand-arrows-alt.svg", + Txt_View_in_a_new_window); HTM_A_End (); /***** End box *****/ @@ -993,7 +904,7 @@ void Inf_SetInfoSrc (void) Inf_AsignInfoType (&Gbl.Crs.Info,&Syllabus); /***** Set info source into database *****/ - Inf_SetInfoSrcIntoDB (InfoSrcSelected); + Inf_DB_SetInfoSrc (InfoSrcSelected); /***** Show the selected info *****/ Inf_ShowInfo (); @@ -1049,7 +960,7 @@ void Inf_FormsToSelSendInfo (void) !InfoAvailable[FromDB.Src]) { FromDB.Src = Inf_NONE; - Inf_SetInfoSrcIntoDB (Inf_NONE); + Inf_DB_SetInfoSrc (Inf_NONE); } /***** Form to choice between alternatives *****/ @@ -1058,54 +969,53 @@ void Inf_FormsToSelSendInfo (void) Inf_PutIconToViewInfo,&Gbl.Crs.Info.Type, HelpEdit[Gbl.Crs.Info.Type],Box_NOT_CLOSABLE,4); - /* Options */ - for (InfoSrc = (Inf_Src_t) 0; - InfoSrc <= (Inf_Src_t) (Inf_NUM_SOURCES - 1); - InfoSrc++) - { - HTM_TR_Begin (NULL); - - /* Select info source */ - if (InfoSrc == FromDB.Src) - HTM_TD_Begin ("class=\"DAT LT LIGHT_BLUE\""); - else - HTM_TD_Begin ("class=\"DAT LT\""); - Frm_BeginForm (Inf_ActionsSelecInfoSrc[Gbl.Crs.Info.Type]); - - HTM_INPUT_RADIO ("InfoSrc",InfoSrc != FromDB.Src && - (InfoSrc == Inf_NONE || - InfoAvailable[InfoSrc]), // Info available for this source - "id=\"InfoSrc%u\" value=\"%u\"%s", - (unsigned) InfoSrc,(unsigned) InfoSrc, - InfoSrc == FromDB.Src ? " checked=\"checked\"" : - (InfoSrc == Inf_NONE || - InfoAvailable[InfoSrc]) ? "" : // Info available for this source - " disabled=\"disabled\""); - Frm_EndForm (); - HTM_TD_End (); - - /* Form for this info source */ - if (InfoSrc == FromDB.Src) - HTM_TD_Begin ("class=\"LT LIGHT_BLUE\""); - else - HTM_TD_Begin ("class=\"LT\""); - HTM_LABEL_Begin ("for=\"InfoSrc%u\" class=\"%s\"", - (unsigned) InfoSrc,The_ClassFormInBox[Gbl.Prefs.Theme]); - HTM_Txt (Txt_INFO_SRC_FULL_TEXT[InfoSrc]); - HTM_LABEL_End (); - if (Txt_INFO_SRC_HELP[InfoSrc]) + /* Options */ + for (InfoSrc = (Inf_Src_t) 0; + InfoSrc <= (Inf_Src_t) (Inf_NUM_SOURCES - 1); + InfoSrc++) { - HTM_SPAN_Begin ("class=\"DAT\""); - HTM_BR (); - HTM_TxtF ("(%s)",Txt_INFO_SRC_HELP[InfoSrc]); - HTM_SPAN_End (); - } - if (Inf_FormsForEditionTypes[InfoSrc]) - Inf_FormsForEditionTypes[InfoSrc] (InfoSrc); - HTM_TD_End (); + HTM_TR_Begin (NULL); - HTM_TR_End (); - } + /* Select info source */ + if (InfoSrc == FromDB.Src) + HTM_TD_Begin ("class=\"DAT LT LIGHT_BLUE\""); + else + HTM_TD_Begin ("class=\"DAT LT\""); + Frm_BeginForm (Inf_ActionsSelecInfoSrc[Gbl.Crs.Info.Type]); + HTM_INPUT_RADIO ("InfoSrc",InfoSrc != FromDB.Src && + (InfoSrc == Inf_NONE || + InfoAvailable[InfoSrc]), // Info available for this source + "id=\"InfoSrc%u\" value=\"%u\"%s", + (unsigned) InfoSrc,(unsigned) InfoSrc, + InfoSrc == FromDB.Src ? " checked=\"checked\"" : + (InfoSrc == Inf_NONE || + InfoAvailable[InfoSrc]) ? "" : // Info available for this source + " disabled=\"disabled\""); + Frm_EndForm (); + HTM_TD_End (); + + /* Form for this info source */ + if (InfoSrc == FromDB.Src) + HTM_TD_Begin ("class=\"LT LIGHT_BLUE\""); + else + HTM_TD_Begin ("class=\"LT\""); + HTM_LABEL_Begin ("for=\"InfoSrc%u\" class=\"%s\"", + (unsigned) InfoSrc,The_ClassFormInBox[Gbl.Prefs.Theme]); + HTM_Txt (Txt_INFO_SRC_FULL_TEXT[InfoSrc]); + HTM_LABEL_End (); + if (Txt_INFO_SRC_HELP[InfoSrc]) + { + HTM_SPAN_Begin ("class=\"DAT\""); + HTM_BR (); + HTM_TxtF ("(%s)",Txt_INFO_SRC_HELP[InfoSrc]); + HTM_SPAN_End (); + } + if (Inf_FormsForEditionTypes[InfoSrc]) + Inf_FormsForEditionTypes[InfoSrc] (InfoSrc); + HTM_TD_End (); + + HTM_TR_End (); + } /***** End table and box *****/ Box_BoxTableEnd (); @@ -1161,7 +1071,7 @@ void Inf_FormToEnterIntegratedEditor (Inf_Src_t InfoSrc) extern const char *Txt_Edit; Frm_BeginForm (Inf_ActionsInfo[InfoSrc][Gbl.Crs.Info.Type]); - Btn_PutConfirmButton (Txt_Edit); + Btn_PutConfirmButton (Txt_Edit); Frm_EndForm (); } @@ -1174,7 +1084,7 @@ void Inf_FormToEnterPlainTextEditor (Inf_Src_t InfoSrc) extern const char *Txt_Edit_plain_text; Frm_BeginForm (Inf_ActionsInfo[InfoSrc][Gbl.Crs.Info.Type]); - Btn_PutConfirmButton (Txt_Edit_plain_text); + Btn_PutConfirmButton (Txt_Edit_plain_text); Frm_EndForm (); } @@ -1187,7 +1097,7 @@ void Inf_FormToEnterRichTextEditor (Inf_Src_t InfoSrc) extern const char *Txt_Edit_rich_text; Frm_BeginForm (Inf_ActionsInfo[InfoSrc][Gbl.Crs.Info.Type]); - Btn_PutConfirmButton (Txt_Edit_rich_text); + Btn_PutConfirmButton (Txt_Edit_rich_text); Frm_EndForm (); } @@ -1204,18 +1114,18 @@ void Inf_FormToSendPage (Inf_Src_t InfoSrc) /***** Begin form *****/ Frm_BeginForm (Inf_ActionsInfo[InfoSrc][Gbl.Crs.Info.Type]); - /***** File *****/ - HTM_DIV_Begin ("class=\"CM\""); - HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); - HTM_TxtColonNBSP (Txt_File); - HTM_INPUT_FILE (Fil_NAME_OF_PARAM_FILENAME_ORG,".htm,.html,.pdf,.zip", - HTM_DONT_SUBMIT_ON_CHANGE, - NULL); - HTM_LABEL_End (); - HTM_DIV_End (); + /***** File *****/ + HTM_DIV_Begin ("class=\"CM\""); + HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); + HTM_TxtColonNBSP (Txt_File); + HTM_INPUT_FILE (Fil_NAME_OF_PARAM_FILENAME_ORG,".htm,.html,.pdf,.zip", + HTM_DONT_SUBMIT_ON_CHANGE, + NULL); + HTM_LABEL_End (); + HTM_DIV_End (); - /***** Send button *****/ - Btn_PutCreateButton (Txt_Upload_file); + /***** Send button *****/ + Btn_PutCreateButton (Txt_Upload_file); /***** End form *****/ Frm_EndForm (); @@ -1239,27 +1149,27 @@ void Inf_FormToSendURL (Inf_Src_t InfoSrc) /***** Begin form *****/ Frm_BeginForm (Inf_ActionsInfo[InfoSrc][Gbl.Crs.Info.Type]); - /***** Link *****/ - if ((FileURL = fopen (PathFile,"rb")) != NULL) - { - if (fgets (Gbl.Crs.Info.URL,Cns_MAX_BYTES_WWW,FileURL) == NULL) - Gbl.Crs.Info.URL[0] = '\0'; - /* File is not longer needed. Close it */ - fclose (FileURL); - } - else - Gbl.Crs.Info.URL[0] = '\0'; + /***** Link *****/ + if ((FileURL = fopen (PathFile,"rb")) != NULL) + { + if (fgets (Gbl.Crs.Info.URL,Cns_MAX_BYTES_WWW,FileURL) == NULL) + Gbl.Crs.Info.URL[0] = '\0'; + /* File is not longer needed. Close it */ + fclose (FileURL); + } + else + Gbl.Crs.Info.URL[0] = '\0'; - HTM_DIV_Begin ("class=\"CM\""); - HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); - HTM_TxtColonNBSP (Txt_URL); - HTM_INPUT_URL ("InfoSrcURL",Gbl.Crs.Info.URL,HTM_DONT_SUBMIT_ON_CHANGE, - "size=\"50\""); - HTM_LABEL_End (); - HTM_DIV_End (); + HTM_DIV_Begin ("class=\"CM\""); + HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); + HTM_TxtColonNBSP (Txt_URL); + HTM_INPUT_URL ("InfoSrcURL",Gbl.Crs.Info.URL,HTM_DONT_SUBMIT_ON_CHANGE, + "size=\"50\""); + HTM_LABEL_End (); + HTM_DIV_End (); - /***** Send button *****/ - Btn_PutCreateButton (Txt_Send_URL); + /***** Send button *****/ + Btn_PutCreateButton (Txt_Send_URL); /***** End form *****/ Frm_EndForm (); @@ -1411,54 +1321,6 @@ Inf_Src_t Inf_GetInfoSrcFromForm (void) (unsigned long) Inf_NONE); } -/*****************************************************************************/ -/********* Set info source for a type of course info from database ***********/ -/*****************************************************************************/ - -void Inf_SetInfoSrcIntoDB (Inf_Src_t InfoSrc) - { - /***** Get if info source is already stored in database *****/ - if (DB_QueryCOUNT ("can not get if info source is already stored in database", - "SELECT COUNT(*)" - " FROM crs_info_src" - " WHERE CrsCod=%ld" - " AND InfoType='%s'", - Gbl.Hierarchy.Crs.CrsCod, - Inf_NamesInDBForInfoType[Gbl.Crs.Info.Type])) - // Info is already stored in database, so update it - { // Update info source - if (InfoSrc == Inf_NONE) - DB_QueryUPDATE ("can not update info source", - "UPDATE crs_info_src" - " SET InfoSrc='%s'," - "MustBeRead='N'" - " WHERE CrsCod=%ld" - " AND InfoType='%s'", - Inf_NamesInDBForInfoSrc[Inf_NONE], - Gbl.Hierarchy.Crs.CrsCod, - Inf_NamesInDBForInfoType[Gbl.Crs.Info.Type]); - else // MustBeRead remains unchanged - DB_QueryUPDATE ("can not update info source", - "UPDATE crs_info_src" - " SET InfoSrc='%s'" - " WHERE CrsCod=%ld" - " AND InfoType='%s'", - Inf_NamesInDBForInfoSrc[InfoSrc], - Gbl.Hierarchy.Crs.CrsCod, - Inf_NamesInDBForInfoType[Gbl.Crs.Info.Type]); - } - else // Info is not stored in database, so insert it - DB_QueryINSERT ("can not insert info source", - "INSERT INTO crs_info_src" - " (CrsCod,InfoType,InfoSrc,MustBeRead)" - " VALUES" - " (%ld,'%s','%s','N')", - Gbl.Hierarchy.Crs.CrsCod, - Inf_NamesInDBForInfoType[Gbl.Crs.Info.Type], - Inf_NamesInDBForInfoSrc[InfoSrc]); - } - - /*****************************************************************************/ /***** Get and check info source for a type of course info from database *****/ /*****************************************************************************/ @@ -1470,19 +1332,13 @@ Inf_Src_t Inf_GetInfoSrcFromDB (long CrsCod,Inf_Type_t InfoType) Inf_Src_t InfoSrc; /***** Get info source for a specific type of info from database *****/ - if (DB_QuerySELECT (&mysql_res,"can not get info source", - "SELECT InfoSrc" // row[0] - " FROM crs_info_src" - " WHERE CrsCod=%ld" - " AND InfoType='%s'", - CrsCod, - Inf_NamesInDBForInfoType[InfoType])) + if (Inf_DB_GetInfoSrc (&mysql_res,CrsCod,InfoType)) { /* Get row */ row = mysql_fetch_row (mysql_res); /* Get info source (row[0]) */ - InfoSrc = Inf_ConvertFromStrDBToInfoSrc (row[0]); + InfoSrc = Inf_DB_ConvertFromStrDBToInfoSrc (row[0]); } else InfoSrc = Inf_NONE; @@ -1499,7 +1355,7 @@ Inf_Src_t Inf_GetInfoSrcFromDB (long CrsCod,Inf_Type_t InfoType) void Inf_GetAndCheckInfoSrcFromDB (struct Syl_Syllabus *Syllabus, long CrsCod, - Inf_Type_t Type, + Inf_Type_t InfoType, struct Inf_FromDB *FromDB) { MYSQL_RES *mysql_res; @@ -1510,20 +1366,13 @@ void Inf_GetAndCheckInfoSrcFromDB (struct Syl_Syllabus *Syllabus, FromDB->MustBeRead = false; /***** Get info source for a specific type of info from database *****/ - if (DB_QuerySELECT (&mysql_res,"can not get info source", - "SELECT InfoSrc," // row[0] - "MustBeRead" // row[1] - " FROM crs_info_src" - " WHERE CrsCod=%ld" - " AND InfoType='%s'", - CrsCod, - Inf_NamesInDBForInfoType[Type]) == 1) + if (Inf_DB_GetInfoSrcAndMustBeRead (&mysql_res,CrsCod,InfoType) == 1) { /* Get row */ row = mysql_fetch_row (mysql_res); /* Get info source (row[0]) and if students must read info (row[1]) */ - FromDB->Src = Inf_ConvertFromStrDBToInfoSrc (row[0]); + FromDB->Src = Inf_DB_ConvertFromStrDBToInfoSrc (row[0]); FromDB->MustBeRead = (row[1][0] == 'Y'); } @@ -1536,7 +1385,7 @@ void Inf_GetAndCheckInfoSrcFromDB (struct Syl_Syllabus *Syllabus, case Inf_NONE: break; case Inf_EDITOR: - switch (Type) + switch (InfoType) { case Inf_LECTURES: Syllabus->WhichSyllabus = Syl_LECTURES; @@ -1559,19 +1408,19 @@ void Inf_GetAndCheckInfoSrcFromDB (struct Syl_Syllabus *Syllabus, } break; case Inf_PLAIN_TEXT: - if (!Inf_CheckPlainTxt (CrsCod,Type)) + if (!Inf_CheckPlainTxt (CrsCod,InfoType)) FromDB->Src = Inf_NONE; break; case Inf_RICH_TEXT: - if (!Inf_CheckRichTxt (CrsCod,Type)) + if (!Inf_CheckRichTxt (CrsCod,InfoType)) FromDB->Src = Inf_NONE; break; case Inf_PAGE: - if (!Inf_CheckPage (CrsCod,Type)) + if (!Inf_CheckPage (CrsCod,InfoType)) FromDB->Src = Inf_NONE; break; case Inf_URL: - if (!Inf_CheckURL (CrsCod,Type)) + if (!Inf_CheckURL (CrsCod,InfoType)) FromDB->Src = Inf_NONE; break; } @@ -1580,58 +1429,6 @@ void Inf_GetAndCheckInfoSrcFromDB (struct Syl_Syllabus *Syllabus, FromDB->MustBeRead = false; } -/*****************************************************************************/ -/*** Convert a string with info type in database to a Inf_InfoType_t value ***/ -/*****************************************************************************/ - -Inf_Type_t Inf_ConvertFromStrDBToInfoType (const char *StrInfoTypeDB) - { - Inf_Type_t InfoType; - - for (InfoType = (Inf_Type_t) 0; - InfoType <= (Inf_Type_t) (Inf_NUM_TYPES - 1); - InfoType++) - if (!strcmp (StrInfoTypeDB,Inf_NamesInDBForInfoType[InfoType])) - return InfoType; - - return (Inf_Type_t) 0; - } - -/*****************************************************************************/ -/** Convert a string with info source in database to a Inf_InfoSrc_t value ***/ -/*****************************************************************************/ - -Inf_Src_t Inf_ConvertFromStrDBToInfoSrc (const char *StrInfoSrcDB) - { - Inf_Src_t InfoSrc; - - for (InfoSrc = (Inf_Src_t) 0; - InfoSrc <= (Inf_Src_t) (Inf_NUM_SOURCES - 1); - InfoSrc++) - if (!strcmp (StrInfoSrcDB,Inf_NamesInDBForInfoSrc[InfoSrc])) - return InfoSrc; - - return Inf_NONE; - } - -/*****************************************************************************/ -/********** Set info text for a type of course info from database ************/ -/*****************************************************************************/ - -static void Inf_SetInfoTxtIntoDB (const char *InfoTxtHTML,const char *InfoTxtMD) - { - /***** Insert or replace info source for a specific type of course information *****/ - DB_QueryREPLACE ("can not update info text", - "REPLACE INTO crs_info_txt" - " (CrsCod,InfoType,InfoTxtHTML,InfoTxtMD)" - " VALUES" - " (%ld,'%s','%s','%s')", - Gbl.Hierarchy.Crs.CrsCod, - Inf_NamesInDBForInfoType[Gbl.Crs.Info.Type], - InfoTxtHTML, - InfoTxtMD); - } - /*****************************************************************************/ /********** Get info text for a type of course info from database ************/ /*****************************************************************************/ @@ -1645,14 +1442,7 @@ void Inf_GetInfoTxtFromDB (long CrsCod,Inf_Type_t InfoType, /***** Get info source for a specific type of course information (bibliography, FAQ, links or evaluation) from database *****/ - if (DB_QuerySELECT (&mysql_res,"can not get info text", - "SELECT InfoTxtHTML," // row[0] - "InfoTxtMD" // row[1] - " FROM crs_info_txt" - " WHERE CrsCod=%ld" - " AND InfoType='%s'", - CrsCod, - Inf_NamesInDBForInfoType[InfoType]) == 1) + if (Inf_DB_GetInfoTxt (&mysql_res,CrsCod,InfoType) == 1) { /* Get info text */ row = mysql_fetch_row (mysql_res); @@ -1737,13 +1527,13 @@ static bool Inf_CheckAndShowPlainTxt (void) HTM_DIV_Begin ("class=\"DAT LM\""); - /***** Convert to respectful HTML and insert links *****/ - Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, - TxtHTML,Cns_MAX_BYTES_LONG_TEXT,false); // Convert from HTML to recpectful HTML - Str_InsertLinks (TxtHTML,Cns_MAX_BYTES_LONG_TEXT,60); // Insert links + /***** Convert to respectful HTML and insert links *****/ + Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML, + TxtHTML,Cns_MAX_BYTES_LONG_TEXT,false); // Convert from HTML to recpectful HTML + Str_InsertLinks (TxtHTML,Cns_MAX_BYTES_LONG_TEXT,60); // Insert links - /***** Write text *****/ - HTM_Txt (TxtHTML); + /***** Write text *****/ + HTM_Txt (TxtHTML); /***** End box *****/ HTM_DIV_End (); @@ -1825,75 +1615,75 @@ static bool Inf_CheckAndShowRichTxt (void) HTM_DIV_Begin ("id=\"crs_info\" class=\"LM\""); - /***** Store text into a temporary .md file in HTML output directory *****/ - // TODO: change to another directory? - /* Create a unique name for the .md file */ - snprintf (PathFileMD,sizeof (PathFileMD),"%s/%s.md", - Cfg_PATH_OUT_PRIVATE,Gbl.UniqueNameEncrypted); - snprintf (PathFileHTML,sizeof (PathFileHTML),"%s/%s.md.html", // Do not use only .html because that is the output temporary file - Cfg_PATH_OUT_PRIVATE,Gbl.UniqueNameEncrypted); + /***** Store text into a temporary .md file in HTML output directory *****/ + // TODO: change to another directory? + /* Create a unique name for the .md file */ + snprintf (PathFileMD,sizeof (PathFileMD),"%s/%s.md", + Cfg_PATH_OUT_PRIVATE,Gbl.UniqueNameEncrypted); + snprintf (PathFileHTML,sizeof (PathFileHTML),"%s/%s.md.html", // Do not use only .html because that is the output temporary file + Cfg_PATH_OUT_PRIVATE,Gbl.UniqueNameEncrypted); - /* Open Markdown file for writing */ - if ((FileMD = fopen (PathFileMD,"wb")) == NULL) - Err_ShowErrorAndExit ("Can not create temporary Markdown file."); + /* Open Markdown file for writing */ + if ((FileMD = fopen (PathFileMD,"wb")) == NULL) + Err_ShowErrorAndExit ("Can not create temporary Markdown file."); - /* Write text into Markdown file */ - fprintf (FileMD,"%s",TxtMD); + /* Write text into Markdown file */ + fprintf (FileMD,"%s",TxtMD); - /* Close Markdown file */ - fclose (FileMD); + /* Close Markdown file */ + fclose (FileMD); - /***** Convert from Markdown to HTML *****/ - /* MathJax 2.5.1 + /***** Convert from Markdown to HTML *****/ + /* MathJax 2.5.1 #ifdef Cfg_MATHJAX_LOCAL - // Use the local copy of MathJax - snprintf (MathJaxURL,sizeof (MathJaxURL), - "=%s/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML", - Cfg_URL_SWAD_PUBLIC); + // Use the local copy of MathJax + snprintf (MathJaxURL,sizeof (MathJaxURL), + "=%s/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML", + Cfg_URL_SWAD_PUBLIC); #else - // Use the MathJax Content Delivery Network (CDN) - MathJaxURL[0] = '\0'; + // Use the MathJax Content Delivery Network (CDN) + MathJaxURL[0] = '\0'; #endif - */ - /* MathJax 3.0.1 */ + */ + /* MathJax 3.0.1 */ #ifdef Cfg_MATHJAX_LOCAL - // Use the local copy of MathJax - snprintf (MathJaxURL,sizeof (MathJaxURL),"=%s/mathjax/tex-chtml.js", - Cfg_URL_SWAD_PUBLIC); + // Use the local copy of MathJax + snprintf (MathJaxURL,sizeof (MathJaxURL),"=%s/mathjax/tex-chtml.js", + Cfg_URL_SWAD_PUBLIC); #else - // Use the MathJax Content Delivery Network (CDN) - MathJaxURL[0] = '\0'; + // Use the MathJax Content Delivery Network (CDN) + MathJaxURL[0] = '\0'; #endif - // --ascii uses only ascii characters in output - // (uses numerical entities instead of UTF-8) - // is mandatory in order to convert (with iconv) the UTF-8 output of pandoc to WINDOWS-1252 - snprintf (Command,sizeof (Command), - "iconv -f WINDOWS-1252 -t UTF-8 %s" - " | " - "pandoc --ascii --mathjax%s -f markdown_github+tex_math_dollars -t html5" - " | " - "iconv -f UTF-8 -t WINDOWS-1252 -o %s", - PathFileMD, - MathJaxURL, - PathFileHTML); - ReturnCode = system (Command); - if (ReturnCode == -1) - Err_ShowErrorAndExit ("Error when running command to convert from Markdown to HTML."); + // --ascii uses only ascii characters in output + // (uses numerical entities instead of UTF-8) + // is mandatory in order to convert (with iconv) the UTF-8 output of pandoc to WINDOWS-1252 + snprintf (Command,sizeof (Command), + "iconv -f WINDOWS-1252 -t UTF-8 %s" + " | " + "pandoc --ascii --mathjax%s -f markdown_github+tex_math_dollars -t html5" + " | " + "iconv -f UTF-8 -t WINDOWS-1252 -o %s", + PathFileMD, + MathJaxURL, + PathFileHTML); + ReturnCode = system (Command); + if (ReturnCode == -1) + Err_ShowErrorAndExit ("Error when running command to convert from Markdown to HTML."); - /***** Remove Markdown file *****/ - unlink (PathFileMD); + /***** Remove Markdown file *****/ + unlink (PathFileMD); - /***** Copy HTML file just created to HTML output *****/ - /* Open temporary HTML file for reading */ - if ((FileHTML = fopen (PathFileHTML,"rb")) == NULL) - Err_ShowErrorAndExit ("Can not open temporary HTML file."); + /***** Copy HTML file just created to HTML output *****/ + /* Open temporary HTML file for reading */ + if ((FileHTML = fopen (PathFileHTML,"rb")) == NULL) + Err_ShowErrorAndExit ("Can not open temporary HTML file."); - /* Copy from temporary HTML file to output file */ - Fil_FastCopyOfOpenFiles (FileHTML,Gbl.F.Out); + /* Copy from temporary HTML file to output file */ + Fil_FastCopyOfOpenFiles (FileHTML,Gbl.F.Out); - /* Close and remove temporary HTML file */ - fclose (FileHTML); - unlink (PathFileHTML); + /* Close and remove temporary HTML file */ + fclose (FileHTML); + unlink (PathFileHTML); /***** End box *****/ HTM_DIV_End (); @@ -1935,28 +1725,28 @@ void Inf_EditPlainTxtInfo (void) /***** Begin form and box *****/ Frm_BeginForm (Inf_ActionsRcvPlaTxtInfo[Gbl.Crs.Info.Type]); - Box_BoxBegin (NULL,Txt_INFO_TITLE[Gbl.Crs.Info.Type], - NULL,NULL, - HelpEdit[Gbl.Crs.Info.Type],Box_NOT_CLOSABLE); + Box_BoxBegin (NULL,Txt_INFO_TITLE[Gbl.Crs.Info.Type], + NULL,NULL, + HelpEdit[Gbl.Crs.Info.Type],Box_NOT_CLOSABLE); - if (Gbl.Crs.Info.Type == Inf_INTRODUCTION || - Gbl.Crs.Info.Type == Inf_TEACHING_GUIDE) - Lay_WriteHeaderClassPhoto (false,false,Gbl.Hierarchy.Ins.InsCod,Gbl.Hierarchy.Deg.DegCod,Gbl.Hierarchy.Crs.CrsCod); + if (Gbl.Crs.Info.Type == Inf_INTRODUCTION || + Gbl.Crs.Info.Type == Inf_TEACHING_GUIDE) + Lay_WriteHeaderClassPhoto (false,false,Gbl.Hierarchy.Ins.InsCod,Gbl.Hierarchy.Deg.DegCod,Gbl.Hierarchy.Crs.CrsCod); - /***** Get info text from database *****/ - Inf_GetInfoTxtFromDB (Gbl.Hierarchy.Crs.CrsCod,Gbl.Crs.Info.Type, - TxtHTML,NULL); + /***** Get info text from database *****/ + Inf_GetInfoTxtFromDB (Gbl.Hierarchy.Crs.CrsCod,Gbl.Crs.Info.Type, + TxtHTML,NULL); - /***** Edition area *****/ - HTM_DIV_Begin ("class=\"CM\""); - Lay_HelpPlainEditor (); - HTM_TEXTAREA_Begin ("name=\"Txt\" cols=\"80\" rows=\"20\""); - HTM_Txt (TxtHTML); - HTM_TEXTAREA_End (); - HTM_DIV_End (); + /***** Edition area *****/ + HTM_DIV_Begin ("class=\"CM\""); + Lay_HelpPlainEditor (); + HTM_TEXTAREA_Begin ("name=\"Txt\" cols=\"80\" rows=\"20\""); + HTM_Txt (TxtHTML); + HTM_TEXTAREA_End (); + HTM_DIV_End (); - /***** Send button and end box *****/ - Box_BoxWithButtonEnd (Btn_CONFIRM_BUTTON,Txt_Save_changes); + /***** Send button and end box *****/ + Box_BoxWithButtonEnd (Btn_CONFIRM_BUTTON,Txt_Save_changes); Frm_EndForm (); } @@ -1990,28 +1780,28 @@ void Inf_EditRichTxtInfo (void) /***** Begin form and box *****/ Frm_BeginForm (Inf_ActionsRcvRchTxtInfo[Gbl.Crs.Info.Type]); - Box_BoxBegin (NULL,Txt_INFO_TITLE[Gbl.Crs.Info.Type], - NULL,NULL, - HelpEdit[Gbl.Crs.Info.Type],Box_NOT_CLOSABLE); + Box_BoxBegin (NULL,Txt_INFO_TITLE[Gbl.Crs.Info.Type], + NULL,NULL, + HelpEdit[Gbl.Crs.Info.Type],Box_NOT_CLOSABLE); - if (Gbl.Crs.Info.Type == Inf_INTRODUCTION || - Gbl.Crs.Info.Type == Inf_TEACHING_GUIDE) - Lay_WriteHeaderClassPhoto (false,false,Gbl.Hierarchy.Ins.InsCod,Gbl.Hierarchy.Deg.DegCod,Gbl.Hierarchy.Crs.CrsCod); + if (Gbl.Crs.Info.Type == Inf_INTRODUCTION || + Gbl.Crs.Info.Type == Inf_TEACHING_GUIDE) + Lay_WriteHeaderClassPhoto (false,false,Gbl.Hierarchy.Ins.InsCod,Gbl.Hierarchy.Deg.DegCod,Gbl.Hierarchy.Crs.CrsCod); - /***** Get info text from database *****/ - Inf_GetInfoTxtFromDB (Gbl.Hierarchy.Crs.CrsCod,Gbl.Crs.Info.Type, - TxtHTML,NULL); + /***** Get info text from database *****/ + Inf_GetInfoTxtFromDB (Gbl.Hierarchy.Crs.CrsCod,Gbl.Crs.Info.Type, + TxtHTML,NULL); - /***** Edition area *****/ - HTM_DIV_Begin ("class=\"CM\""); - Lay_HelpRichEditor (); - HTM_TEXTAREA_Begin ("name=\"Txt\" cols=\"80\" rows=\"20\""); - HTM_Txt (TxtHTML); - HTM_TEXTAREA_End (); - HTM_DIV_End (); + /***** Edition area *****/ + HTM_DIV_Begin ("class=\"CM\""); + Lay_HelpRichEditor (); + HTM_TEXTAREA_Begin ("name=\"Txt\" cols=\"80\" rows=\"20\""); + HTM_Txt (TxtHTML); + HTM_TEXTAREA_End (); + HTM_DIV_End (); - /***** Send button and end box *****/ - Box_BoxWithButtonEnd (Btn_CONFIRM_BUTTON,Txt_Save_changes); + /***** Send button and end box *****/ + Box_BoxWithButtonEnd (Btn_CONFIRM_BUTTON,Txt_Save_changes); Frm_EndForm (); } @@ -2041,10 +1831,10 @@ void Inf_RecAndChangePlainTxtInfo (void) Txt_MarkdownFormat,Cns_MAX_BYTES_LONG_TEXT,true); // Store a copy in Markdown format /***** Update text of course info in database *****/ - Inf_SetInfoTxtIntoDB (Txt_HTMLFormat,Txt_MarkdownFormat); + Inf_DB_SetInfoTxt (Txt_HTMLFormat,Txt_MarkdownFormat); /***** Change info source to "plain text" in database *****/ - Inf_SetInfoSrcIntoDB (Txt_HTMLFormat[0] ? Inf_PLAIN_TEXT : + Inf_DB_SetInfoSrc (Txt_HTMLFormat[0] ? Inf_PLAIN_TEXT : Inf_NONE); if (Txt_HTMLFormat[0]) /***** Show the updated info *****/ @@ -2080,10 +1870,10 @@ void Inf_RecAndChangeRichTxtInfo (void) Txt_MarkdownFormat,Cns_MAX_BYTES_LONG_TEXT,true); // Store a copy in Markdown format /***** Update text of course info in database *****/ - Inf_SetInfoTxtIntoDB (Txt_HTMLFormat,Txt_MarkdownFormat); + Inf_DB_SetInfoTxt (Txt_HTMLFormat,Txt_MarkdownFormat); /***** Change info source to "rich text" in database *****/ - Inf_SetInfoSrcIntoDB (Txt_HTMLFormat[0] ? Inf_RICH_TEXT : + Inf_DB_SetInfoSrc (Txt_HTMLFormat[0] ? Inf_RICH_TEXT : Inf_NONE); if (Txt_HTMLFormat[0]) /***** Show the updated info *****/ @@ -2137,7 +1927,7 @@ void Inf_ReceiveURLInfo (void) if (URLIsOK) { /***** Change info source to URL in database *****/ - Inf_SetInfoSrcIntoDB (Inf_URL); + Inf_DB_SetInfoSrc (Inf_URL); /***** Show the updated info *****/ Inf_ShowInfo (); @@ -2145,7 +1935,7 @@ void Inf_ReceiveURLInfo (void) else { /***** Change info source to none in database *****/ - Inf_SetInfoSrcIntoDB (Inf_NONE); + Inf_DB_SetInfoSrc (Inf_NONE); /***** Show again the form to select and send course info *****/ Inf_FormsToSelSendInfo (); @@ -2274,7 +2064,7 @@ void Inf_ReceivePagInfo (void) if (FileIsOK) { /***** Change info source to page in database *****/ - Inf_SetInfoSrcIntoDB (Inf_PAGE); + Inf_DB_SetInfoSrc (Inf_PAGE); /***** Show the updated info *****/ Inf_ShowInfo (); @@ -2282,7 +2072,7 @@ void Inf_ReceivePagInfo (void) else { /***** Change info source to none in database *****/ - Inf_SetInfoSrcIntoDB (Inf_NONE); + Inf_DB_SetInfoSrc (Inf_NONE); /***** Show again the form to select and send course info *****/ Inf_FormsToSelSendInfo (); diff --git a/swad_info.h b/swad_info.h index 798d117a..823ded90 100644 --- a/swad_info.h +++ b/swad_info.h @@ -1,4 +1,4 @@ -// swad_info.c: info about course +// swad_info.h: info about course #ifndef _SWAD_INF #define _SWAD_INF @@ -88,7 +88,7 @@ void Inf_WriteMsgYouMustReadInfo (void); void Inf_ChangeForceReadInfo (void); void Inf_ChangeIHaveReadInfo (void); bool Inf_GetIfIMustReadAnyCrsInfoInThisCrs (void); -void Inf_RemoveUsrFromCrsInfoRead (long UsrCod,long CrsCod); +void Inf_DB_RemoveUsrFromCrsInfoRead (long UsrCod,long CrsCod); void Inf_BuildPathPage (long CrsCod,Inf_Type_t InfoType,char PathDir[PATH_MAX + 1]); void Inf_WriteURLIntoTxtBuffer (char TxtBuffer[Cns_MAX_BYTES_WWW + 1]); void Inf_SetInfoSrc (void); @@ -99,14 +99,11 @@ void Inf_FormToEnterRichTextEditor (Inf_Src_t InfoSrc); void Inf_FormToSendPage (Inf_Src_t InfoSrc); void Inf_FormToSendURL (Inf_Src_t InfoSrc); Inf_Src_t Inf_GetInfoSrcFromForm (void); -void Inf_SetInfoSrcIntoDB (Inf_Src_t InfoSrc); Inf_Src_t Inf_GetInfoSrcFromDB (long CrsCod,Inf_Type_t InfoType); void Inf_GetAndCheckInfoSrcFromDB (struct Syl_Syllabus *Syllabus, long CrsCod, - Inf_Type_t Type, + Inf_Type_t InfoType, struct Inf_FromDB *FromDB); -Inf_Type_t Inf_ConvertFromStrDBToInfoType (const char *StrInfoTypeDB); -Inf_Src_t Inf_ConvertFromStrDBToInfoSrc (const char *StrInfoSrcDB); void Inf_GetInfoTxtFromDB (long CrsCod,Inf_Type_t InfoType, char InfoTxtHTML[Cns_MAX_BYTES_LONG_TEXT + 1], diff --git a/swad_info_database.c b/swad_info_database.c new file mode 100644 index 00000000..9493e456 --- /dev/null +++ b/swad_info_database.c @@ -0,0 +1,303 @@ +// swad_info_database.c: info about course, 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 // For maximum values +// #include // For PATH_MAX, NAME_MAX +// #include // For NULL +// #include // For getenv, etc +// #include // For SOAP_OK and soap functions +#include // For string functions +// #include // For unlink + +// #include "swad_action.h" +// #include "swad_box.h" +#include "swad_database.h" +// #include "swad_error.h" +// #include "swad_form.h" +#include "swad_global.h" +// #include "swad_HTML.h" +// #include "swad_info.h" +// #include "swad_parameter.h" +// #include "swad_string.h" + +/*****************************************************************************/ +/************** External global variables from others modules ****************/ +/*****************************************************************************/ + +extern struct Globals Gbl; + +/*****************************************************************************/ +/****************************** Public constants *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/****************************** Private types ********************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private constants *****************************/ +/*****************************************************************************/ + +static const char *Inf_DB_NamesForInfoType[Inf_NUM_TYPES] = + { + [Inf_INTRODUCTION ] = "intro", // TODO: Change this to "introduction"! + [Inf_TEACHING_GUIDE] = "description", // TODO: Change this to "guide"! + [Inf_LECTURES ] = "theory", // TODO: Change this to "lectures"! + [Inf_PRACTICALS ] = "practices", // TODO: Change this to "practicals"! + [Inf_BIBLIOGRAPHY ] = "bibliography", + [Inf_FAQ ] = "FAQ", + [Inf_LINKS ] = "links", + [Inf_ASSESSMENT ] = "assessment", + }; + +static const char *Inf_DB_NamesForInfoSrc[Inf_NUM_SOURCES] = + { + [Inf_NONE ] = "none", + [Inf_EDITOR ] = "editor", + [Inf_PLAIN_TEXT] = "plain_text", + [Inf_RICH_TEXT ] = "rich_text", + [Inf_PAGE ] = "page", + [Inf_URL ] = "URL", + }; + +/*****************************************************************************/ +/**************************** Private prototypes *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/*** Convert a string with info type in database to a Inf_InfoType_t value ***/ +/*****************************************************************************/ + +Inf_Type_t Inf_DB_ConvertFromStrDBToInfoType (const char *StrInfoTypeDB) + { + Inf_Type_t InfoType; + + for (InfoType = (Inf_Type_t) 0; + InfoType <= (Inf_Type_t) (Inf_NUM_TYPES - 1); + InfoType++) + if (!strcmp (StrInfoTypeDB,Inf_DB_NamesForInfoType[InfoType])) + return InfoType; + + return (Inf_Type_t) 0; + } + +/*****************************************************************************/ +/********* Set info source for a type of course info from database ***********/ +/*****************************************************************************/ + +void Inf_DB_SetInfoSrc (Inf_Src_t InfoSrc) + { + /***** Get if info source is already stored in database *****/ + if (DB_QueryCOUNT ("can not get if info source is already stored in database", + "SELECT COUNT(*)" + " FROM crs_info_src" + " WHERE CrsCod=%ld" + " AND InfoType='%s'", + Gbl.Hierarchy.Crs.CrsCod, + Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type])) + // Info is already stored in database, so update it + { // Update info source + if (InfoSrc == Inf_NONE) + DB_QueryUPDATE ("can not update info source", + "UPDATE crs_info_src" + " SET InfoSrc='%s'," + "MustBeRead='N'" + " WHERE CrsCod=%ld" + " AND InfoType='%s'", + Inf_DB_NamesForInfoSrc[Inf_NONE], + Gbl.Hierarchy.Crs.CrsCod, + Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); + else // MustBeRead remains unchanged + DB_QueryUPDATE ("can not update info source", + "UPDATE crs_info_src" + " SET InfoSrc='%s'" + " WHERE CrsCod=%ld" + " AND InfoType='%s'", + Inf_DB_NamesForInfoSrc[InfoSrc], + Gbl.Hierarchy.Crs.CrsCod, + Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); + } + else // Info is not stored in database, so insert it + DB_QueryINSERT ("can not insert info source", + "INSERT INTO crs_info_src" + " (CrsCod,InfoType,InfoSrc,MustBeRead)" + " VALUES" + " (%ld,'%s','%s','N')", + Gbl.Hierarchy.Crs.CrsCod, + Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type], + Inf_DB_NamesForInfoSrc[InfoSrc]); + } + +/*****************************************************************************/ +/***************** Get info source for a type of course info *****************/ +/*****************************************************************************/ + +unsigned Inf_DB_GetInfoSrc (MYSQL_RES **mysql_res, + long CrsCod,Inf_Type_t InfoType) + { + /***** Get info source for a specific type of info from database *****/ + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get info source", + "SELECT InfoSrc" // row[0] + " FROM crs_info_src" + " WHERE CrsCod=%ld" + " AND InfoType='%s'", + CrsCod, + Inf_DB_NamesForInfoType[InfoType]); + } + +/*****************************************************************************/ +/*** Get info source and wether info must be read for a type of course info **/ +/*****************************************************************************/ + +unsigned Inf_DB_GetInfoSrcAndMustBeRead (MYSQL_RES **mysql_res, + long CrsCod,Inf_Type_t InfoType) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get info source", + "SELECT InfoSrc," // row[0] + "MustBeRead" // row[1] + " FROM crs_info_src" + " WHERE CrsCod=%ld" + " AND InfoType='%s'", + CrsCod, + Inf_DB_NamesForInfoType[InfoType]); + } + +/*****************************************************************************/ +/** Convert a string with info source in database to a Inf_InfoSrc_t value ***/ +/*****************************************************************************/ + +Inf_Src_t Inf_DB_ConvertFromStrDBToInfoSrc (const char *StrInfoSrcDB) + { + Inf_Src_t InfoSrc; + + for (InfoSrc = (Inf_Src_t) 0; + InfoSrc <= (Inf_Src_t) (Inf_NUM_SOURCES - 1); + InfoSrc++) + if (!strcmp (StrInfoSrcDB,Inf_DB_NamesForInfoSrc[InfoSrc])) + return InfoSrc; + + return Inf_NONE; + } + +/*****************************************************************************/ +/********** Set info text for a type of course info from database ************/ +/*****************************************************************************/ + +void Inf_DB_SetInfoTxt (const char *InfoTxtHTML,const char *InfoTxtMD) + { + /***** Insert or replace info source for a specific type of course information *****/ + DB_QueryREPLACE ("can not update info text", + "REPLACE INTO crs_info_txt" + " (CrsCod,InfoType,InfoTxtHTML,InfoTxtMD)" + " VALUES" + " (%ld,'%s','%s','%s')", + Gbl.Hierarchy.Crs.CrsCod, + Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type], + InfoTxtHTML, + InfoTxtMD); + } +/*****************************************************************************/ +/********** Get info text for a type of course info from database ************/ +/*****************************************************************************/ + +unsigned Inf_DB_GetInfoTxt (MYSQL_RES **mysql_res, + long CrsCod,Inf_Type_t InfoType) + { + return (unsigned) + DB_QuerySELECT (mysql_res,"can not get info text", + "SELECT InfoTxtHTML," // row[0] + "InfoTxtMD" // row[1] + " FROM crs_info_txt" + " WHERE CrsCod=%ld" + " AND InfoType='%s'", + CrsCod, + Inf_DB_NamesForInfoType[InfoType]); + } + +/*****************************************************************************/ +/***************** Set if students must read course info *********************/ +/*****************************************************************************/ + +void Inf_DB_SetForceRead (bool MustBeRead) + { + DB_QueryUPDATE ("can not update if info must be read", + "UPDATE crs_info_src" + " SET MustBeRead='%c'" + " WHERE CrsCod=%ld" + " AND InfoType='%s'", + MustBeRead ? 'Y' : + 'N', + Gbl.Hierarchy.Crs.CrsCod, + Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); + } + +/*****************************************************************************/ +/********************* Set if I have read course info ************************/ +/*****************************************************************************/ + +void Inf_DB_SetIHaveRead (bool IHaveRead) + { + if (IHaveRead) + /***** Insert I have read course information *****/ + DB_QueryREPLACE ("can not set that I have read course info", + "REPLACE INTO crs_info_read" + " (UsrCod,CrsCod,InfoType)" + " VALUES" + " (%ld,%ld,'%s')", + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Hierarchy.Crs.CrsCod, + Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); + else + /***** Remove I have read course information *****/ + DB_QueryDELETE ("can not set that I have not read course info", + "DELETE FROM crs_info_read" + " WHERE UsrCod=%ld" + " AND CrsCod=%ld" + " AND InfoType='%s'", + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Hierarchy.Crs.CrsCod, + Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]); + } + +/*****************************************************************************/ +/******************** Check I have read a course info ************************/ +/*****************************************************************************/ + +bool Inf_DB_CheckIfIHaveReadInfo (void) + { + return (DB_QueryCOUNT ("can not get if I have read course info", + "SELECT COUNT(*)" + " FROM crs_info_read" + " WHERE UsrCod=%ld" + " AND CrsCod=%ld" + " AND InfoType='%s'", + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Hierarchy.Crs.CrsCod, + Inf_DB_NamesForInfoType[Gbl.Crs.Info.Type]) != 0); + } diff --git a/swad_info_database.h b/swad_info_database.h new file mode 100644 index 00000000..8497dfc1 --- /dev/null +++ b/swad_info_database.h @@ -0,0 +1,71 @@ +// swad_info_database.h: info about course, operations with database + +#ifndef _SWAD_INF_DB +#define _SWAD_INF_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 // For boolean type + +// #include "swad_constant.h" +#include "swad_info.h" +// #include "swad_syllabus.h" + +/*****************************************************************************/ +/***************************** Public constants ******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************* Public types ********************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Public prototypes *****************************/ +/*****************************************************************************/ + +//------------------------------- Info type ----------------------------------- +Inf_Type_t Inf_DB_ConvertFromStrDBToInfoType (const char *StrInfoTypeDB); + +//------------------------------ Info source ---------------------------------- +void Inf_DB_SetInfoSrc (Inf_Src_t InfoSrc); +unsigned Inf_DB_GetInfoSrc (MYSQL_RES **mysql_res, + long CrsCod,Inf_Type_t InfoType); +unsigned Inf_DB_GetInfoSrcAndMustBeRead (MYSQL_RES **mysql_res, + long CrsCod,Inf_Type_t InfoType); +Inf_Src_t Inf_DB_ConvertFromStrDBToInfoSrc (const char *StrInfoSrcDB); + +//------------------------------- Info text ----------------------------------- +void Inf_DB_SetInfoTxt (const char *InfoTxtHTML,const char *InfoTxtMD); + +unsigned Inf_DB_GetInfoTxt (MYSQL_RES **mysql_res, + long CrsCod,Inf_Type_t InfoType); + +//------------------------- Info read by students? ---------------------------- +void Inf_DB_SetForceRead (bool MustBeRead); +void Inf_DB_SetIHaveRead (bool IHaveRead); + +bool Inf_DB_CheckIfIHaveReadInfo (void); + +#endif diff --git a/swad_syllabus.c b/swad_syllabus.c index 41770840..80dd3ec3 100644 --- a/swad_syllabus.c +++ b/swad_syllabus.c @@ -42,6 +42,7 @@ #include "swad_forum.h" #include "swad_global.h" #include "swad_HTML.h" +#include "swad_info_database.h" #include "swad_parameter.h" #include "swad_string.h" #include "swad_xml.h" @@ -964,7 +965,7 @@ void Syl_RemoveItemSyllabus (void) /***** We are editing a syllabus with the internal editor, so change info source to internal editor in database *****/ - Inf_SetInfoSrcIntoDB (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : + Inf_DB_SetInfoSrc (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : Inf_NONE); /***** Show the updated syllabus to continue editing it *****/ @@ -1070,7 +1071,7 @@ static void Syl_ChangePlaceItemSyllabus (Syl_ChangePosItem_t UpOrDownPos) /***** We are editing a syllabus with the internal editor, so change info source to internal editor in database *****/ - Inf_SetInfoSrcIntoDB (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : + Inf_DB_SetInfoSrc (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : Inf_NONE); /***** Show the updated syllabus to continue editing it *****/ @@ -1239,7 +1240,7 @@ static void Syl_ChangeLevelItemSyllabus (Syl_ChangeLevelItem_t IncreaseOrDecreas /***** We are editing a syllabus with the internal editor, so change info source to internal editor in database *****/ - Inf_SetInfoSrcIntoDB (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : + Inf_DB_SetInfoSrc (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : Inf_NONE); /***** Show the updated syllabus to continue editing it *****/ @@ -1310,7 +1311,7 @@ void Syl_InsertItemSyllabus (void) /***** We are editing a syllabus with the internal editor, so change info source to internal editor in database *****/ - Inf_SetInfoSrcIntoDB (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : + Inf_DB_SetInfoSrc (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : Inf_NONE); /***** Show the updated syllabus to continue editing it *****/ @@ -1362,7 +1363,7 @@ void Syl_ModifyItemSyllabus (void) /***** We are editing a syllabus with the internal editor, so change info source to internal editor in database *****/ - Inf_SetInfoSrcIntoDB (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : + Inf_DB_SetInfoSrc (Syl_LstItemsSyllabus.NumItems ? Inf_EDITOR : Inf_NONE); /***** Show the updated syllabus to continue editing it *****/ diff --git a/swad_user.c b/swad_user.c index 25a29a45..b565e0bf 100644 --- a/swad_user.c +++ b/swad_user.c @@ -3031,7 +3031,7 @@ bool Usr_GetParamOtherUsrCodEncryptedAndGetUsrData (void) /***** Check if user exists and get her/his data *****/ if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat, Usr_DONT_GET_PREFS, - Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) + Usr_GET_ROLE_IN_CURRENT_CRS)) // Existing user return true;