swad-core/swad_info.c

2108 lines
75 KiB
C
Raw Normal View History

2014-12-01 23:55:08 +01:00
// swad_info.c: info about course
/*
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-2023 Antonio Ca<EFBFBD>as Vargas
2014-12-01 23:55:08 +01:00
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 <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
#include <limits.h> // For maximum values
#include <linux/limits.h> // For PATH_MAX, NAME_MAX
2019-12-29 12:39:00 +01:00
#include <stddef.h> // For NULL
2014-12-01 23:55:08 +01:00
#include <stdlib.h> // For getenv, etc
#include <stdsoap2.h> // For SOAP_OK and soap functions
#include <string.h> // For string functions
#include <unistd.h> // For unlink
#include "swad_action.h"
#include "swad_action_list.h"
#include "swad_alert.h"
#include "swad_autolink.h"
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
2014-12-01 23:55:08 +01:00
#include "swad_database.h"
#include "swad_error.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2014-12-01 23:55:08 +01:00
#include "swad_global.h"
2019-10-23 19:05:05 +02:00
#include "swad_HTML.h"
2014-12-01 23:55:08 +01:00
#include "swad_info.h"
#include "swad_info_database.h"
2014-12-01 23:55:08 +01:00
#include "swad_parameter.h"
#include "swad_string.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
2019-11-21 16:47:07 +01:00
/****************************** Public constants *****************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
const Act_Action_t Inf_ActionsSeeInfo[Inf_NUM_TYPES] =
2014-12-01 23:55:08 +01:00
{
2019-11-21 16:47:07 +01:00
[Inf_INTRODUCTION ] = ActSeeCrsInf,
[Inf_TEACHING_GUIDE] = ActSeeTchGui,
[Inf_LECTURES ] = ActSeeSylLec,
[Inf_PRACTICALS ] = ActSeeSylPra,
[Inf_BIBLIOGRAPHY ] = ActSeeBib,
[Inf_FAQ ] = ActSeeFAQ,
[Inf_LINKS ] = ActSeeCrsLnk,
[Inf_ASSESSMENT ] = ActSeeAss,
2014-12-01 23:55:08 +01:00
};
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
static const char *Inf_FileNamesForInfoType[Inf_NUM_TYPES] =
2014-12-01 23:55:08 +01:00
{
2019-11-21 16:47:07 +01:00
[Inf_INTRODUCTION ] = Cfg_CRS_INFO_INTRODUCTION,
[Inf_TEACHING_GUIDE] = Cfg_CRS_INFO_TEACHING_GUIDE,
[Inf_LECTURES ] = Cfg_CRS_INFO_LECTURES,
[Inf_PRACTICALS ] = Cfg_CRS_INFO_PRACTICALS,
[Inf_BIBLIOGRAPHY ] = Cfg_CRS_INFO_BIBLIOGRAPHY,
[Inf_FAQ ] = Cfg_CRS_INFO_FAQ,
[Inf_LINKS ] = Cfg_CRS_INFO_LINKS,
[Inf_ASSESSMENT ] = Cfg_CRS_INFO_ASSESSMENT,
2014-12-01 23:55:08 +01:00
};
static const Act_Action_t Inf_ActionsInfo[Inf_NUM_SOURCES][Inf_NUM_TYPES] =
2014-12-01 23:55:08 +01:00
{
[Inf_NONE ][Inf_INTRODUCTION ] = ActUnk,
[Inf_NONE ][Inf_TEACHING_GUIDE] = ActUnk,
[Inf_NONE ][Inf_LECTURES ] = ActUnk,
[Inf_NONE ][Inf_PRACTICALS ] = ActUnk,
[Inf_NONE ][Inf_BIBLIOGRAPHY ] = ActUnk,
[Inf_NONE ][Inf_FAQ ] = ActUnk,
[Inf_NONE ][Inf_LINKS ] = ActUnk,
[Inf_NONE ][Inf_ASSESSMENT ] = ActUnk,
[Inf_EDITOR ][Inf_INTRODUCTION ] = ActEditorCrsInf,
[Inf_EDITOR ][Inf_TEACHING_GUIDE] = ActEditorTchGui,
[Inf_EDITOR ][Inf_LECTURES ] = ActEditorSylLec,
[Inf_EDITOR ][Inf_PRACTICALS ] = ActEditorSylPra,
[Inf_EDITOR ][Inf_BIBLIOGRAPHY ] = ActEditorBib,
[Inf_EDITOR ][Inf_FAQ ] = ActEditorFAQ,
[Inf_EDITOR ][Inf_LINKS ] = ActEditorCrsLnk,
[Inf_EDITOR ][Inf_ASSESSMENT ] = ActEditorAss,
[Inf_PLAIN_TEXT][Inf_INTRODUCTION ] = ActPlaTxtEdiCrsInf,
[Inf_PLAIN_TEXT][Inf_TEACHING_GUIDE] = ActPlaTxtEdiTchGui,
[Inf_PLAIN_TEXT][Inf_LECTURES ] = ActPlaTxtEdiSylLec,
[Inf_PLAIN_TEXT][Inf_PRACTICALS ] = ActPlaTxtEdiSylPra,
[Inf_PLAIN_TEXT][Inf_BIBLIOGRAPHY ] = ActPlaTxtEdiBib,
[Inf_PLAIN_TEXT][Inf_FAQ ] = ActPlaTxtEdiFAQ,
[Inf_PLAIN_TEXT][Inf_LINKS ] = ActPlaTxtEdiCrsLnk,
[Inf_PLAIN_TEXT][Inf_ASSESSMENT ] = ActPlaTxtEdiAss,
[Inf_RICH_TEXT ][Inf_INTRODUCTION ] = ActRchTxtEdiCrsInf,
[Inf_RICH_TEXT ][Inf_TEACHING_GUIDE] = ActRchTxtEdiTchGui,
[Inf_RICH_TEXT ][Inf_LECTURES ] = ActRchTxtEdiSylLec,
[Inf_RICH_TEXT ][Inf_PRACTICALS ] = ActRchTxtEdiSylPra,
[Inf_RICH_TEXT ][Inf_BIBLIOGRAPHY ] = ActRchTxtEdiBib,
[Inf_RICH_TEXT ][Inf_FAQ ] = ActRchTxtEdiFAQ,
[Inf_RICH_TEXT ][Inf_LINKS ] = ActRchTxtEdiCrsLnk,
[Inf_RICH_TEXT ][Inf_ASSESSMENT ] = ActRchTxtEdiAss,
[Inf_PAGE ][Inf_INTRODUCTION ] = ActRcvPagCrsInf,
[Inf_PAGE ][Inf_TEACHING_GUIDE] = ActRcvPagTchGui,
[Inf_PAGE ][Inf_LECTURES ] = ActRcvPagSylLec,
[Inf_PAGE ][Inf_PRACTICALS ] = ActRcvPagSylPra,
[Inf_PAGE ][Inf_BIBLIOGRAPHY ] = ActRcvPagBib,
[Inf_PAGE ][Inf_FAQ ] = ActRcvPagFAQ,
[Inf_PAGE ][Inf_LINKS ] = ActRcvPagCrsLnk,
[Inf_PAGE ][Inf_ASSESSMENT ] = ActRcvPagAss,
[Inf_URL ][Inf_INTRODUCTION ] = ActRcvURLCrsInf,
[Inf_URL ][Inf_TEACHING_GUIDE] = ActRcvURLTchGui,
[Inf_URL ][Inf_LECTURES ] = ActRcvURLSylLec,
[Inf_URL ][Inf_PRACTICALS ] = ActRcvURLSylPra,
[Inf_URL ][Inf_BIBLIOGRAPHY ] = ActRcvURLBib,
[Inf_URL ][Inf_FAQ ] = ActRcvURLFAQ,
[Inf_URL ][Inf_LINKS ] = ActRcvURLCrsLnk,
[Inf_URL ][Inf_ASSESSMENT ] = ActRcvURLAss,
2014-12-01 23:55:08 +01:00
};
2019-11-21 16:47:07 +01:00
2016-12-16 00:52:27 +01:00
/***** Help *****/
extern const char *Hlp_COURSE_Information_textual_information;
extern const char *Hlp_COURSE_Guide;
extern const char *Hlp_COURSE_Syllabus;
extern const char *Hlp_COURSE_Bibliography;
extern const char *Hlp_COURSE_FAQ;
extern const char *Hlp_COURSE_Links;
extern const char *Hlp_COURSE_Assessment;
2016-12-16 00:52:27 +01:00
extern const char *Hlp_COURSE_Information_edit;
extern const char *Hlp_COURSE_Guide_edit;
extern const char *Hlp_COURSE_Syllabus_edit;
extern const char *Hlp_COURSE_Bibliography_edit;
extern const char *Hlp_COURSE_FAQ_edit;
extern const char *Hlp_COURSE_Links_edit;
extern const char *Hlp_COURSE_Assessment_edit;
2016-12-16 00:52:27 +01:00
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/**************************** Private prototypes *****************************/
/*****************************************************************************/
2020-04-08 18:18:46 +02:00
static void Inf_PutIconToViewInfo (void *Type);
2017-05-22 12:23:08 +02:00
static void Inf_PutCheckboxForceStdsToReadInfo (bool MustBeRead,bool Disabled);
2016-12-19 00:55:24 +01:00
static void Inf_PutCheckboxConfirmIHaveReadInfo (void);
2014-12-01 23:55:08 +01:00
static bool Inf_GetMustBeReadFromForm (void);
static bool Inf_GetIfIHaveReadFromForm (void);
static bool Inf_CheckPage (long CrsCod,Inf_Type_t InfoType);
2016-05-30 14:27:10 +02:00
static bool Inf_CheckAndShowPage (void);
static bool Inf_CheckURL (long CrsCod,Inf_Type_t InfoType);
2016-05-30 14:27:10 +02:00
static bool Inf_CheckAndShowURL (void);
static void Inf_BuildPathURL (long CrsCod,Inf_Type_t InfoType,
2018-10-18 02:02:32 +02:00
char PathFile[PATH_MAX + 1]);
2016-05-30 14:27:10 +02:00
2016-03-17 10:39:23 +01:00
static void Inf_ShowPage (const char *URL);
2016-05-30 14:27:10 +02:00
2020-04-12 02:47:32 +02:00
static bool Inf_CheckIfInfoAvailable (struct Syl_Syllabus *Syllabus,
Inf_Src_t InfoSrc);
2020-04-12 02:47:32 +02:00
static void Inf_AsignInfoType (struct Inf_Info *Info,
struct Syl_Syllabus *Syllabus);
2016-05-30 14:27:10 +02:00
static bool Inf_CheckPlainTxt (long CrsCod,Inf_Type_t InfoType);
2016-05-30 14:27:10 +02:00
static bool Inf_CheckAndShowPlainTxt (void);
static bool Inf_CheckRichTxt (long CrsCod,Inf_Type_t InfoType);
2016-05-30 14:27:10 +02:00
static bool Inf_CheckAndShowRichTxt (void);
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/******** Show course info (theory, practices, bibliography, etc.) ***********/
/*****************************************************************************/
void Inf_ShowInfo (void)
{
extern const char *Txt_INFO_TITLE[Inf_NUM_TYPES];
2016-03-18 19:45:36 +01:00
extern const char *Txt_No_information;
2020-04-12 02:47:32 +02:00
struct Syl_Syllabus Syllabus;
struct Inf_FromDB FromDB;
2017-05-22 12:23:08 +02:00
bool Disabled;
2017-06-04 18:18:54 +02:00
bool ICanEdit = (Gbl.Usrs.Me.Role.Logged == Rol_TCH ||
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM);
2016-03-18 19:45:36 +01:00
bool ShowWarningNoInfo = false;
const char *Help[Inf_NUM_TYPES] =
2016-12-16 00:52:27 +01:00
{
2019-11-21 01:27:17 +01:00
[Inf_INTRODUCTION ] = Hlp_COURSE_Information_textual_information,
[Inf_TEACHING_GUIDE] = Hlp_COURSE_Guide,
[Inf_LECTURES ] = Hlp_COURSE_Syllabus,
[Inf_PRACTICALS ] = Hlp_COURSE_Syllabus,
[Inf_BIBLIOGRAPHY ] = Hlp_COURSE_Bibliography,
[Inf_FAQ ] = Hlp_COURSE_FAQ,
[Inf_LINKS ] = Hlp_COURSE_Links,
[Inf_ASSESSMENT ] = Hlp_COURSE_Assessment,
2016-12-16 00:52:27 +01:00
};
2016-03-17 10:39:23 +01:00
2020-04-12 02:47:32 +02:00
/***** Reset syllabus context *****/
Syl_ResetSyllabus (&Syllabus);
2016-03-17 10:39:23 +01:00
/***** Set info type *****/
2020-04-12 02:47:32 +02:00
Inf_AsignInfoType (&Gbl.Crs.Info,&Syllabus);
2014-12-01 23:55:08 +01:00
/***** Get info source from database *****/
2020-04-12 02:47:32 +02:00
Inf_GetAndCheckInfoSrcFromDB (&Syllabus,
Gbl.Hierarchy.Crs.CrsCod,
2019-04-04 10:45:15 +02:00
Gbl.Crs.Info.Type,
&FromDB);
2014-12-01 23:55:08 +01:00
2017-06-04 18:18:54 +02:00
switch (Gbl.Usrs.Me.Role.Logged)
2014-12-01 23:55:08 +01:00
{
2017-05-18 19:13:41 +02:00
case Rol_STD:
if (FromDB.MustBeRead)
2016-12-19 00:55:24 +01:00
{
2019-10-24 09:46:20 +02:00
/***** Contextual menu *****/
Mnu_ContextMenuBegin ();
Inf_PutCheckboxConfirmIHaveReadInfo (); // Checkbox to confirm that...
// ...I have read this couse info
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuEnd ();
2016-12-19 00:55:24 +01:00
}
2014-12-01 23:55:08 +01:00
break;
2017-05-22 12:23:08 +02:00
case Rol_NET:
2017-05-18 19:13:41 +02:00
case Rol_TCH:
2015-04-07 21:44:24 +02:00
case Rol_SYS_ADM:
2019-10-24 09:46:20 +02:00
/* Put */
if (FromDB.Src != Inf_NONE)
2016-12-18 20:10:37 +01:00
{
2019-10-24 09:46:20 +02:00
/***** Contextual menu *****/
Mnu_ContextMenuBegin ();
Disabled = (Gbl.Usrs.Me.Role.Logged == Rol_NET); // Non-editing teachers can not change the status of checkbox
Inf_PutCheckboxForceStdsToReadInfo (FromDB.MustBeRead,Disabled); // Checkbox to force students...
// ...to read this couse info
2019-10-24 09:46:20 +02:00
Mnu_ContextMenuEnd ();
2016-12-18 20:10:37 +01:00
}
2014-12-01 23:55:08 +01:00
break;
default:
break;
}
switch (FromDB.Src)
2014-12-01 23:55:08 +01:00
{
case Inf_NONE:
2016-03-18 19:45:36 +01:00
ShowWarningNoInfo = true;
2014-12-01 23:55:08 +01:00
break;
case Inf_EDITOR:
2019-04-04 10:45:15 +02:00
switch (Gbl.Crs.Info.Type)
2014-12-01 23:55:08 +01:00
{
case Inf_LECTURES:
case Inf_PRACTICALS:
2020-04-12 02:47:32 +02:00
ShowWarningNoInfo = !Syl_CheckAndEditSyllabus (&Syllabus);
2014-12-01 23:55:08 +01:00
break;
2016-03-17 10:39:23 +01:00
case Inf_INTRODUCTION:
2014-12-01 23:55:08 +01:00
case Inf_TEACHING_GUIDE:
case Inf_BIBLIOGRAPHY:
case Inf_FAQ:
case Inf_LINKS:
case Inf_ASSESSMENT:
2016-03-18 19:45:36 +01:00
ShowWarningNoInfo = true;
2014-12-01 23:55:08 +01:00
break;
}
break;
case Inf_PLAIN_TEXT:
2016-05-30 14:27:10 +02:00
ShowWarningNoInfo = !Inf_CheckAndShowPlainTxt ();
2015-04-07 21:44:24 +02:00
break;
case Inf_RICH_TEXT:
2016-05-30 14:27:10 +02:00
ShowWarningNoInfo = !Inf_CheckAndShowRichTxt ();
2014-12-01 23:55:08 +01:00
break;
case Inf_PAGE:
2014-12-01 23:55:08 +01:00
/***** Open file with web page *****/
2016-05-30 14:27:10 +02:00
ShowWarningNoInfo = !Inf_CheckAndShowPage ();
2014-12-01 23:55:08 +01:00
break;
case Inf_URL:
2014-12-01 23:55:08 +01:00
/***** Check if file with URL exists *****/
2016-05-30 14:27:10 +02:00
ShowWarningNoInfo = !Inf_CheckAndShowURL ();
2014-12-01 23:55:08 +01:00
break;
}
2016-03-18 19:45:36 +01:00
if (ShowWarningNoInfo)
{
2020-03-26 02:54:30 +01:00
if (ICanEdit)
Box_BoxBegin ("100%",Txt_INFO_TITLE[Gbl.Crs.Info.Type],
2020-04-08 18:18:46 +02:00
Inf_PutIconToEditInfo,&Gbl.Crs.Info.Type,
2020-03-26 02:54:30 +01:00
Help[Gbl.Crs.Info.Type],Box_NOT_CLOSABLE);
else
Box_BoxBegin ("100%",Txt_INFO_TITLE[Gbl.Crs.Info.Type],
NULL,NULL,
Help[Gbl.Crs.Info.Type],Box_NOT_CLOSABLE);
2019-02-16 16:18:54 +01:00
Ale_ShowAlert (Ale_INFO,Txt_No_information);
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2016-03-18 19:45:36 +01:00
}
2014-12-01 23:55:08 +01:00
}
2016-03-17 10:39:23 +01:00
/*****************************************************************************/
/************************ Put icon to edit course info ***********************/
/*****************************************************************************/
2020-04-08 18:18:46 +02:00
static void Inf_PutIconToViewInfo (void *Type)
2017-05-02 12:39:23 +02:00
{
2020-04-08 18:18:46 +02:00
if (Type)
Ico_PutContextualIconToView (Inf_ActionsSeeInfo[*((Inf_Type_t *) Type)],NULL,
2020-03-26 02:54:30 +01:00
NULL,NULL);
2017-05-02 12:39:23 +02:00
}
2020-04-08 18:18:46 +02:00
void Inf_PutIconToEditInfo (void *Type)
2016-03-17 10:39:23 +01:00
{
static const Act_Action_t Inf_ActionsEditInfo[Inf_NUM_TYPES] =
{
[Inf_INTRODUCTION ] = ActEdiCrsInf,
[Inf_TEACHING_GUIDE] = ActEdiTchGui,
[Inf_LECTURES ] = ActEdiSylLec,
[Inf_PRACTICALS ] = ActEdiSylPra,
[Inf_BIBLIOGRAPHY ] = ActEdiBib,
[Inf_FAQ ] = ActEdiFAQ,
[Inf_LINKS ] = ActEdiCrsLnk,
[Inf_ASSESSMENT ] = ActEdiAss,
};
2020-04-08 18:18:46 +02:00
if (Type)
Ico_PutContextualIconToEdit (Inf_ActionsEditInfo[*((Inf_Type_t *) Type)],NULL,
2020-03-26 02:54:30 +01:00
NULL,NULL);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********** Put a form (checkbox) to force students to read info *************/
/*****************************************************************************/
2017-05-22 12:23:08 +02:00
static void Inf_PutCheckboxForceStdsToReadInfo (bool MustBeRead,bool Disabled)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_Force_students_to_read_this_information;
static const Act_Action_t Inf_ActionsChangeForceReadInfo[Inf_NUM_TYPES] =
{
[Inf_INTRODUCTION ] = ActChgFrcReaCrsInf,
[Inf_TEACHING_GUIDE] = ActChgFrcReaTchGui,
[Inf_LECTURES ] = ActChgFrcReaSylLec,
[Inf_PRACTICALS ] = ActChgFrcReaSylPra,
[Inf_BIBLIOGRAPHY ] = ActChgFrcReaBib,
[Inf_FAQ ] = ActChgFrcReaFAQ,
[Inf_LINKS ] = ActChgFrcReaCrsLnk,
[Inf_ASSESSMENT ] = ActChgFrcReaAss,
};
2014-12-01 23:55:08 +01:00
2019-04-04 10:45:15 +02:00
Lay_PutContextualCheckbox (Inf_ActionsChangeForceReadInfo[Gbl.Crs.Info.Type],
2016-12-18 20:10:37 +01:00
NULL,
2017-05-22 12:23:08 +02:00
"MustBeRead",
MustBeRead,Disabled,
2016-12-18 20:10:37 +01:00
Txt_Force_students_to_read_this_information,
Txt_Force_students_to_read_this_information);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2016-12-19 00:55:24 +01:00
/********** Put a form (checkbox) to force students to read info *************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-12-19 00:55:24 +01:00
static void Inf_PutCheckboxConfirmIHaveReadInfo (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_I_have_read_this_information;
static const Act_Action_t Inf_ActionsIHaveReadInfo[Inf_NUM_TYPES] =
{
[Inf_INTRODUCTION ] = ActChgHavReaCrsInf,
[Inf_TEACHING_GUIDE] = ActChgHavReaTchGui,
[Inf_LECTURES ] = ActChgHavReaSylLec,
[Inf_PRACTICALS ] = ActChgHavReaSylPra,
[Inf_BIBLIOGRAPHY ] = ActChgHavReaBib,
[Inf_FAQ ] = ActChgHavReaFAQ,
[Inf_LINKS ] = ActChgHavReaCrsLnk,
[Inf_ASSESSMENT ] = ActChgHavReaAss,
};
bool IHaveRead = Inf_DB_CheckIfIHaveReadInfo ();
2014-12-01 23:55:08 +01:00
2019-04-04 10:45:15 +02:00
Lay_PutContextualCheckbox (Inf_ActionsIHaveReadInfo[Gbl.Crs.Info.Type],
2016-12-19 00:55:24 +01:00
NULL,
2017-05-22 12:23:08 +02:00
"IHaveRead",
IHaveRead,false,
2016-12-19 00:55:24 +01:00
Txt_I_have_read_this_information,
Txt_I_have_read_this_information);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********* Get if students must read any info about current course ***********/
/*****************************************************************************/
bool Inf_GetIfIMustReadAnyCrsInfoInThisCrs (void)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumInfos;
unsigned NumInfo;
Inf_Type_t InfoType;
2014-12-01 23:55:08 +01:00
/***** Reset must-be-read to false for all info types *****/
for (InfoType = (Inf_Type_t) 0;
InfoType <= (Inf_Type_t) (Inf_NUM_TYPES - 1);
2014-12-01 23:55:08 +01:00
InfoType++)
2019-04-04 10:45:15 +02:00
Gbl.Crs.Info.MustBeRead[InfoType] = false;
2014-12-01 23:55:08 +01:00
/***** Get info types where students must read info *****/
NumInfos = Inf_DB_GetInfoTypesfIMustReadInfo (&mysql_res);
2014-12-01 23:55:08 +01:00
/***** Set must-be-read to true for each rown in result *****/
for (NumInfo = 0;
NumInfo < NumInfos;
NumInfo++)
2014-12-01 23:55:08 +01:00
{
row = mysql_fetch_row (mysql_res);
/* Get info type (row[0]) */
InfoType = Inf_DB_ConvertFromStrDBToInfoType (row[0]);
2014-12-01 23:55:08 +01:00
2019-04-04 10:45:15 +02:00
Gbl.Crs.Info.MustBeRead[InfoType] = true;
2014-12-01 23:55:08 +01:00
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return (NumInfos != 0);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***** Write message if students must read any info about current course *****/
/*****************************************************************************/
void Inf_WriteMsgYouMustReadInfo (void)
{
2016-12-19 00:55:24 +01:00
extern const char *Txt_Required_reading;
extern const char *Txt_You_should_read_the_following_information;
Inf_Type_t InfoType;
2014-12-01 23:55:08 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_Required_reading,
NULL,NULL,
2019-11-29 17:42:05 +01:00
NULL,Box_CLOSABLE);
2016-12-19 00:55:24 +01:00
/***** 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]),
"class=\"BT_LINK FORM_IN_%s\"",
The_GetSuffix ());
HTM_Txt (Act_GetTitleAction (Inf_ActionsSeeInfo[InfoType]));
HTM_BUTTON_End ();
Frm_EndForm ();
HTM_LI_End ();
}
HTM_UL_End ();
HTM_DIV_End ();
2016-12-19 00:55:24 +01:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****** Change teacher's preference about force students to read info ********/
/*****************************************************************************/
void Inf_ChangeForceReadInfo (void)
{
extern const char *Txt_Students_now_are_required_to_read_this_information;
extern const char *Txt_Students_are_no_longer_obliged_to_read_this_information;
2020-04-12 02:47:32 +02:00
struct Syl_Syllabus Syllabus;
2014-12-01 23:55:08 +01:00
bool MustBeRead = Inf_GetMustBeReadFromForm ();
2020-04-12 02:47:32 +02:00
/***** Reset syllabus context *****/
Syl_ResetSyllabus (&Syllabus);
2016-03-17 10:39:23 +01:00
/***** Set info type *****/
2020-04-12 02:47:32 +02:00
Inf_AsignInfoType (&Gbl.Crs.Info,&Syllabus);
2016-03-17 10:39:23 +01:00
2014-12-01 23:55:08 +01:00
/***** Set status (if info must be read or not) into database *****/
Inf_DB_SetForceRead (MustBeRead);
2014-12-01 23:55:08 +01:00
/***** Write message of success *****/
2019-02-16 16:18:54 +01:00
Ale_ShowAlert (Ale_SUCCESS,
2014-12-01 23:55:08 +01:00
MustBeRead ? Txt_Students_now_are_required_to_read_this_information :
Txt_Students_are_no_longer_obliged_to_read_this_information);
/***** Show the selected info *****/
Inf_ShowInfo ();
}
/*****************************************************************************/
/************** Change confirmation of I have read course info ***************/
/*****************************************************************************/
void Inf_ChangeIHaveReadInfo (void)
{
extern const char *Txt_You_have_confirmed_that_you_have_read_this_information;
extern const char *Txt_You_have_eliminated_the_confirmation_that_you_have_read_this_information;
2020-04-12 02:47:32 +02:00
struct Syl_Syllabus Syllabus;
2014-12-01 23:55:08 +01:00
bool IHaveRead = Inf_GetIfIHaveReadFromForm ();
2020-04-12 02:47:32 +02:00
/***** Reset syllabus context *****/
Syl_ResetSyllabus (&Syllabus);
2016-03-17 10:39:23 +01:00
/***** Set info type *****/
2020-04-12 02:47:32 +02:00
Inf_AsignInfoType (&Gbl.Crs.Info,&Syllabus);
2016-03-17 10:39:23 +01:00
2014-12-01 23:55:08 +01:00
/***** Set status (if I have read or not a information) into database *****/
Inf_DB_SetIHaveRead (IHaveRead);
2014-12-01 23:55:08 +01:00
/***** Write message of success *****/
2019-02-16 16:18:54 +01:00
Ale_ShowAlert (Ale_SUCCESS,
2014-12-01 23:55:08 +01:00
IHaveRead ? Txt_You_have_confirmed_that_you_have_read_this_information :
Txt_You_have_eliminated_the_confirmation_that_you_have_read_this_information);
/***** Show the selected info *****/
Inf_ShowInfo ();
}
/*****************************************************************************/
/************* Get if info must be read by students from form ****************/
/*****************************************************************************/
static bool Inf_GetMustBeReadFromForm (void)
{
return Par_GetParBool ("MustBeRead");
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************* Get if info must be read by students from form ****************/
/*****************************************************************************/
static bool Inf_GetIfIHaveReadFromForm (void)
{
return Par_GetParBool ("IHaveRead");
2014-12-01 23:55:08 +01:00
}
2016-05-30 14:27:10 +02:00
/*****************************************************************************/
/************************** Check if exists a page ***************************/
/*****************************************************************************/
// Return true if info available
static bool Inf_CheckPage (long CrsCod,Inf_Type_t InfoType)
2016-05-30 14:27:10 +02:00
{
2017-01-28 15:58:46 +01:00
char PathRelDirHTML[PATH_MAX + 1];
2019-12-19 01:42:24 +01:00
char PathRelFileHTML[PATH_MAX + 1 + 10 + 1];
2016-05-30 14:27:10 +02:00
// TODO !!!!!!!!!!!! If the page is hosted in server ==> it should be created a temporary public directory
// and host the page in a private directory !!!!!!!!!!!!!!!!!
/***** Build path of directory containing web page *****/
Inf_BuildPathPage (CrsCod,InfoType,PathRelDirHTML);
/***** Open file with web page *****/
/* 1. Check if index.html exists */
snprintf (PathRelFileHTML,sizeof (PathRelFileHTML),"%s/index.html",
2018-10-18 02:02:32 +02:00
PathRelDirHTML);
2016-05-30 14:27:10 +02:00
if (Fil_CheckIfPathExists (PathRelFileHTML)) // TODO: Check if not empty?
return true;
/* 2. If index.html does not exist, try index.htm */
snprintf (PathRelFileHTML,sizeof (PathRelFileHTML),"%s/index.htm",
2018-10-18 02:02:32 +02:00
PathRelDirHTML);
2016-05-30 14:27:10 +02:00
if (Fil_CheckIfPathExists (PathRelFileHTML)) // TODO: Check if not empty?
return true;
return false;
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2014-12-20 13:24:12 +01:00
/**************** Check if exists and show link to a page ********************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-05-30 14:27:10 +02:00
// Return true if info available
2014-12-01 23:55:08 +01:00
2016-05-30 14:27:10 +02:00
static bool Inf_CheckAndShowPage (void)
2014-12-01 23:55:08 +01:00
{
2017-01-28 15:58:46 +01:00
char PathRelDirHTML[PATH_MAX + 1];
2019-12-19 01:42:24 +01:00
char PathRelFileHTML[PATH_MAX + 1 + 10 + 1];
2017-01-28 15:58:46 +01:00
char URL[PATH_MAX + 1];
2014-12-01 23:55:08 +01:00
// TODO !!!!!!!!!!!! If the page is hosted in server ==> it should be created a temporary public directory
// and host the page in a private directory !!!!!!!!!!!!!!!!!
2016-05-30 14:27:10 +02:00
/***** Build path of directory containing web page *****/
2019-04-04 10:45:15 +02:00
Inf_BuildPathPage (Gbl.Hierarchy.Crs.CrsCod,Gbl.Crs.Info.Type,PathRelDirHTML);
2016-05-30 14:27:10 +02:00
2014-12-01 23:55:08 +01:00
/***** Open file with web page *****/
/* 1. Check if index.html exists */
snprintf (PathRelFileHTML,sizeof (PathRelFileHTML),"%s/index.html",
2018-10-18 02:02:32 +02:00
PathRelDirHTML);
2016-05-30 14:27:10 +02:00
if (Fil_CheckIfPathExists (PathRelFileHTML)) // TODO: Check if not empty?
2014-12-01 23:55:08 +01:00
{
snprintf (URL,sizeof (URL),"%s/%ld/%s/index.html",
2019-04-04 10:45:15 +02:00
Cfg_URL_CRS_PUBLIC,Gbl.Hierarchy.Crs.CrsCod,
Inf_FileNamesForInfoType[Gbl.Crs.Info.Type]);
2016-03-17 10:39:23 +01:00
Inf_ShowPage (URL);
2016-05-30 14:27:10 +02:00
return true;
2014-12-01 23:55:08 +01:00
}
2016-05-30 14:27:10 +02:00
/* 2. If index.html does not exist, try index.htm */
snprintf (PathRelFileHTML,sizeof (PathRelFileHTML),"%s/index.htm",
2018-10-18 02:02:32 +02:00
PathRelDirHTML);
2016-05-30 14:27:10 +02:00
if (Fil_CheckIfPathExists (PathRelFileHTML)) // TODO: Check if not empty?
2014-12-01 23:55:08 +01:00
{
snprintf (URL,sizeof (URL),"%s/%ld/%s/index.htm",
2019-04-04 10:45:15 +02:00
Cfg_URL_CRS_PUBLIC,Gbl.Hierarchy.Crs.CrsCod,
Inf_FileNamesForInfoType[Gbl.Crs.Info.Type]);
2016-05-30 14:27:10 +02:00
Inf_ShowPage (URL);
return true;
2014-12-01 23:55:08 +01:00
}
2016-05-30 14:27:10 +02:00
return false;
}
/*****************************************************************************/
/* Build path inside a course for a given a info type to store web page file */
/*****************************************************************************/
void Inf_BuildPathPage (long CrsCod,Inf_Type_t InfoType,char PathDir[PATH_MAX + 1])
2016-05-30 14:27:10 +02:00
{
snprintf (PathDir,PATH_MAX + 1,"%s/%ld/%s",
Cfg_PATH_CRS_PUBLIC,CrsCod,Inf_FileNamesForInfoType[InfoType]);
2014-12-01 23:55:08 +01:00
}
2016-05-30 14:27:10 +02:00
/*****************************************************************************/
/********************* Check if exists link to a page ************************/
/*****************************************************************************/
// Return true if info available
static bool Inf_CheckURL (long CrsCod,Inf_Type_t InfoType)
2016-05-30 14:27:10 +02:00
{
2017-01-28 15:58:46 +01:00
char PathFile[PATH_MAX + 1];
2016-05-30 14:27:10 +02:00
FILE *FileURL;
/***** Build path to file containing URL *****/
Inf_BuildPathURL (CrsCod,InfoType,PathFile);
/***** Check if file with URL exists *****/
if ((FileURL = fopen (PathFile,"rb")))
{
2019-04-04 10:45:15 +02:00
if (fgets (Gbl.Crs.Info.URL,Cns_MAX_BYTES_WWW,FileURL) == NULL)
Gbl.Crs.Info.URL[0] = '\0';
2016-05-30 14:27:10 +02:00
/* File is not longer needed ==> close it */
fclose (FileURL);
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Info.URL[0])
2016-05-30 14:27:10 +02:00
return true;
}
return false;
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2014-12-20 13:24:12 +01:00
/**************** Check if exists and show link to a page ********************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2016-05-30 14:27:10 +02:00
// Return true if info available
2014-12-01 23:55:08 +01:00
2016-05-30 14:27:10 +02:00
static bool Inf_CheckAndShowURL (void)
2014-12-01 23:55:08 +01:00
{
2017-01-28 15:58:46 +01:00
char PathFile[PATH_MAX + 1];
2014-12-01 23:55:08 +01:00
FILE *FileURL;
2016-05-30 14:27:10 +02:00
/***** Build path to file containing URL *****/
2019-04-04 10:45:15 +02:00
Inf_BuildPathURL (Gbl.Hierarchy.Crs.CrsCod,Gbl.Crs.Info.Type,PathFile);
2016-05-30 14:27:10 +02:00
2014-12-01 23:55:08 +01:00
/***** Check if file with URL exists *****/
2016-05-30 14:27:10 +02:00
if ((FileURL = fopen (PathFile,"rb")))
2014-12-01 23:55:08 +01:00
{
2019-04-04 10:45:15 +02:00
if (fgets (Gbl.Crs.Info.URL,Cns_MAX_BYTES_WWW,FileURL) == NULL)
Gbl.Crs.Info.URL[0] = '\0';
2014-12-01 23:55:08 +01:00
/* File is not longer needed ==> close it */
fclose (FileURL);
2016-05-30 14:27:10 +02:00
2019-04-04 10:45:15 +02:00
if (Gbl.Crs.Info.URL[0])
2016-05-30 14:27:10 +02:00
{
2019-04-04 10:45:15 +02:00
Inf_ShowPage (Gbl.Crs.Info.URL);
2016-05-30 14:27:10 +02:00
return true;
}
2014-12-01 23:55:08 +01:00
}
2016-05-30 14:27:10 +02:00
return false;
}
/*****************************************************************************/
/*** Build path inside a course for a given a info type to store URL file ****/
/*****************************************************************************/
static void Inf_BuildPathURL (long CrsCod,Inf_Type_t InfoType,
2018-10-18 02:02:32 +02:00
char PathFile[PATH_MAX + 1])
2016-05-30 14:27:10 +02:00
{
snprintf (PathFile,PATH_MAX + 1,"%s/%ld/%s.url",
Cfg_PATH_CRS_PRIVATE,CrsCod,Inf_FileNamesForInfoType[InfoType]);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************* Check if exists and write URL into text buffer ****************/
/*****************************************************************************/
// This function is called only from web service