mirror of https://github.com/acanas/swad-core.git
Version 20.74: May 11, 2021 New module swad_announcement_database for database queries related to announcements.
This commit is contained in:
parent
701a479e04
commit
101c24381c
5
Makefile
5
Makefile
|
@ -27,8 +27,9 @@
|
|||
###############################################################################
|
||||
|
||||
OBJS = swad_account.o swad_account_database.o swad_action.o swad_agenda.o \
|
||||
swad_agenda_database.o swad_alert.o swad_announcement.o swad_API.o \
|
||||
swad_assignment.o swad_attendance.o \
|
||||
swad_agenda_database.o swad_alert.o swad_announcement.o \
|
||||
swad_announcement_database.o swad_API.o swad_assignment.o \
|
||||
swad_attendance.o \
|
||||
swad_banner.o swad_box.o swad_building.o swad_button.o \
|
||||
swad_calendar.o swad_call_for_exam.o swad_center.o \
|
||||
swad_center_config.o swad_chat.o swad_config.o swad_connected.o \
|
||||
|
|
|
@ -27,12 +27,8 @@
|
|||
/********************************** Headers **********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
// #include <stdbool.h> // For boolean type
|
||||
|
||||
// #include "swad_constant.h"
|
||||
#include "swad_database.h"
|
||||
#include "swad_ID.h"
|
||||
// #include "swad_user.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Public constants *****************************/
|
||||
|
|
|
@ -1506,8 +1506,8 @@ void Agd_RequestCreatOrEditEvent (void)
|
|||
HTM_TD_Begin ("class=\"LT\"");
|
||||
HTM_TEXTAREA_Begin ("id=\"Txt\" name=\"Txt\" rows=\"5\""
|
||||
" class=\"TITLE_DESCRIPTION_WIDTH\"");
|
||||
if (!ItsANewEvent)
|
||||
HTM_Txt (Txt);
|
||||
if (!ItsANewEvent)
|
||||
HTM_Txt (Txt);
|
||||
HTM_TEXTAREA_End ();
|
||||
HTM_TD_End ();
|
||||
|
||||
|
|
78
swad_alert.c
78
swad_alert.c
|
@ -61,7 +61,7 @@ extern struct Globals Gbl;
|
|||
/*****************************************************************************/
|
||||
|
||||
static void Ale_ResetLastAlert (void);
|
||||
static void Ale_ResetAlert (size_t i);
|
||||
static void Ale_ResetAlert (size_t NumAlert);
|
||||
|
||||
static void Ale_ShowFixAlert (Ale_AlertType_t AlertType,const char *Txt);
|
||||
|
||||
|
@ -135,12 +135,12 @@ const char *Ale_GetTextOfLastAlert (void)
|
|||
|
||||
void Ale_ResetAllAlerts (void)
|
||||
{
|
||||
size_t i;
|
||||
size_t NumAlert;
|
||||
|
||||
for (i = 0;
|
||||
i < Gbl.Alerts.Num;
|
||||
i++)
|
||||
Ale_ResetAlert (i);
|
||||
for (NumAlert = 0;
|
||||
NumAlert < Gbl.Alerts.Num;
|
||||
NumAlert++)
|
||||
Ale_ResetAlert (NumAlert);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -157,29 +157,29 @@ static void Ale_ResetLastAlert (void)
|
|||
/********************* Reset one alert given its index ***********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Ale_ResetAlert (size_t i)
|
||||
static void Ale_ResetAlert (size_t NumAlert)
|
||||
{
|
||||
bool NoMoreAlertsPending;
|
||||
size_t j;
|
||||
size_t i;
|
||||
|
||||
if (i < Gbl.Alerts.Num)
|
||||
if (Gbl.Alerts.List[i].Type != Ale_NONE)
|
||||
if (NumAlert < Gbl.Alerts.Num)
|
||||
if (Gbl.Alerts.List[NumAlert].Type != Ale_NONE)
|
||||
{
|
||||
/***** Reset i-esim alert *****/
|
||||
Gbl.Alerts.List[i].Type = Ale_NONE; // Reset alert
|
||||
/***** Reset alert *****/
|
||||
Gbl.Alerts.List[NumAlert].Type = Ale_NONE; // Reset alert
|
||||
|
||||
/***** Free memory allocated for text *****/
|
||||
if (Gbl.Alerts.List[i].Text)
|
||||
if (Gbl.Alerts.List[NumAlert].Text)
|
||||
{
|
||||
free (Gbl.Alerts.List[i].Text);
|
||||
Gbl.Alerts.List[i].Text = NULL;
|
||||
free (Gbl.Alerts.List[NumAlert].Text);
|
||||
Gbl.Alerts.List[NumAlert].Text = NULL;
|
||||
}
|
||||
|
||||
/***** Free memory allocated for section *****/
|
||||
if (Gbl.Alerts.List[i].Section)
|
||||
if (Gbl.Alerts.List[NumAlert].Section)
|
||||
{
|
||||
free (Gbl.Alerts.List[i].Section);
|
||||
Gbl.Alerts.List[i].Section = NULL;
|
||||
free (Gbl.Alerts.List[NumAlert].Section);
|
||||
Gbl.Alerts.List[NumAlert].Section = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,10 +187,10 @@ static void Ale_ResetAlert (size_t i)
|
|||
if there are no more alerts
|
||||
pending to be shown *****/
|
||||
NoMoreAlertsPending = true;
|
||||
for (j = 0;
|
||||
NoMoreAlertsPending && j < Gbl.Alerts.Num;
|
||||
j++)
|
||||
if (Gbl.Alerts.List[j].Type != Ale_NONE)
|
||||
for (i = 0;
|
||||
NoMoreAlertsPending && i < Gbl.Alerts.Num;
|
||||
i++)
|
||||
if (Gbl.Alerts.List[i].Type != Ale_NONE)
|
||||
NoMoreAlertsPending = false;
|
||||
|
||||
if (NoMoreAlertsPending)
|
||||
|
@ -215,25 +215,25 @@ void Ale_ShowAlertsAndExit ()
|
|||
|
||||
void Ale_ShowAlerts (const char *Section)
|
||||
{
|
||||
size_t i;
|
||||
bool ShowAlert;
|
||||
size_t NumAlerts = Ale_GetNumAlerts ();
|
||||
size_t NumAlert;
|
||||
bool ShowAlert;
|
||||
|
||||
for (i = 0;
|
||||
i < NumAlerts;
|
||||
i++)
|
||||
if (Gbl.Alerts.List[i].Type != Ale_NONE)
|
||||
for (NumAlert = 0;
|
||||
NumAlert < NumAlerts;
|
||||
NumAlert++)
|
||||
if (Gbl.Alerts.List[NumAlert].Type != Ale_NONE)
|
||||
{
|
||||
if (Section)
|
||||
ShowAlert = (bool) !strcmp (Gbl.Alerts.List[i].Section,Section);
|
||||
ShowAlert = (bool) !strcmp (Gbl.Alerts.List[NumAlert].Section,Section);
|
||||
else
|
||||
ShowAlert = true;
|
||||
|
||||
if (ShowAlert)
|
||||
{
|
||||
Ale_ShowFixAlert (Gbl.Alerts.List[i].Type,
|
||||
Gbl.Alerts.List[i].Text);
|
||||
Ale_ResetAlert (i);
|
||||
Ale_ShowFixAlert (Gbl.Alerts.List[NumAlert].Type,
|
||||
Gbl.Alerts.List[NumAlert].Text);
|
||||
Ale_ResetAlert (NumAlert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -413,10 +413,10 @@ static void Ale_ShowFixAlertAndButton1 (Ale_AlertType_t AlertType,const char *Tx
|
|||
if (AlertClosable[AlertType])
|
||||
{
|
||||
HTM_DIV_Begin ("class=\"ALERT_CLOSE\"");
|
||||
HTM_A_Begin ("href=\"\" onclick=\"toggleDisplay('%s');return false;\" /",
|
||||
IdAlert);
|
||||
Ico_PutIcon ("times.svg",Txt_Close,"ICO16x16");
|
||||
HTM_A_End ();
|
||||
HTM_A_Begin ("href=\"\" onclick=\"toggleDisplay('%s');return false;\" /",
|
||||
IdAlert);
|
||||
Ico_PutIcon ("times.svg",Txt_Close,"ICO16x16");
|
||||
HTM_A_End ();
|
||||
HTM_DIV_End ();
|
||||
}
|
||||
|
||||
|
@ -447,10 +447,12 @@ void Ale_ShowAlertAndButton2 (Act_Action_t NextAction,const char *Anchor,const c
|
|||
/* Begin form */
|
||||
Frm_BeginFormAnchorOnSubmit (NextAction,Anchor,OnSubmit);
|
||||
if (FuncParams)
|
||||
{
|
||||
FuncParams (Args);
|
||||
}
|
||||
|
||||
/* Put button *****/
|
||||
Btn_PutButton (Button,TxtButton);
|
||||
/* Put button */
|
||||
Btn_PutButton (Button,TxtButton);
|
||||
|
||||
/* End form */
|
||||
Frm_EndForm ();
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#include "swad_announcement.h"
|
||||
#include "swad_announcement_database.h"
|
||||
#include "swad_box.h"
|
||||
#include "swad_database.h"
|
||||
#include "swad_error.h"
|
||||
|
@ -72,7 +73,6 @@ static void Ann_PutParams (void *AnnCod);
|
|||
static long Ann_GetParamAnnCod (void);
|
||||
static void Ann_PutSubjectMessage (const char *Field,const char *Label,
|
||||
unsigned Rows);
|
||||
static void Ann_CreateAnnouncement (unsigned Roles,const char *Subject,const char *Content);
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************** Show global announcements ************************/
|
||||
|
@ -98,89 +98,57 @@ void Ann_ShowAllAnnouncements (void)
|
|||
/***** Get announcements from database *****/
|
||||
if (ICanEdit)
|
||||
/* Select all announcements */
|
||||
NumAnnouncements = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get announcements",
|
||||
"SELECT AnnCod," // row[0]
|
||||
"Status," // row[1]
|
||||
"Roles," // row[2]
|
||||
"Subject," // row[3]
|
||||
"Content" // row[4]
|
||||
" FROM ann_announcements"
|
||||
" ORDER BY AnnCod DESC");
|
||||
NumAnnouncements = Ann_DB_GetAllAnnouncements (&mysql_res);
|
||||
else if (Gbl.Usrs.Me.Logged)
|
||||
{
|
||||
/* Select only announcements I can see */
|
||||
Rol_GetRolesInAllCrss (&Gbl.Usrs.Me.UsrDat);
|
||||
NumAnnouncements = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get announcements",
|
||||
"SELECT AnnCod," // row[0]
|
||||
"Status," // row[1]
|
||||
"Roles," // row[2]
|
||||
"Subject," // row[3]
|
||||
"Content" // row[4]
|
||||
" FROM ann_announcements"
|
||||
" WHERE (Roles&%u)<>0 " // All my roles in different courses
|
||||
" ORDER BY AnnCod DESC",
|
||||
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss);
|
||||
}
|
||||
NumAnnouncements = Ann_DB_GetAnnouncementsICanSee (&mysql_res);
|
||||
else // No user logged
|
||||
/* Select only active announcements for unknown users */
|
||||
NumAnnouncements = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get announcements",
|
||||
"SELECT AnnCod," // row[0]
|
||||
"Status," // row[1]
|
||||
"Roles," // row[2]
|
||||
"Subject," // row[3]
|
||||
"Content" // row[4]
|
||||
" FROM ann_announcements"
|
||||
" WHERE Status=%u"
|
||||
" AND (Roles&%u)<>0 "
|
||||
" ORDER BY AnnCod DESC",
|
||||
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
|
||||
(unsigned) (1 << Rol_UNK));
|
||||
NumAnnouncements = Ann_DB_GetAnnouncementsForUnknownUsers (&mysql_res);
|
||||
|
||||
/***** Begin box *****/
|
||||
Box_BoxBegin ("550px",Txt_Announcements,
|
||||
ICanEdit ? Ann_PutIconToAddNewAnnouncement :
|
||||
NULL,NULL,
|
||||
Hlp_COMMUNICATION_Announcements,Box_NOT_CLOSABLE);
|
||||
if (!NumAnnouncements)
|
||||
Ale_ShowAlert (Ale_INFO,Txt_No_announcements);
|
||||
|
||||
/***** Show the announcements *****/
|
||||
for (NumAnn = 0;
|
||||
NumAnn < NumAnnouncements;
|
||||
NumAnn++)
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
if (!NumAnnouncements)
|
||||
Ale_ShowAlert (Ale_INFO,Txt_No_announcements);
|
||||
|
||||
/* Get announcement code (row[0]) */
|
||||
if (sscanf (row[0],"%ld",&AnnCod) != 1)
|
||||
Err_WrongAnnouncementExit ();
|
||||
/***** Show the announcements *****/
|
||||
for (NumAnn = 0;
|
||||
NumAnn < NumAnnouncements;
|
||||
NumAnn++)
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Get status of the announcement (row[1]) */
|
||||
Status = Ann_OBSOLETE_ANNOUNCEMENT;
|
||||
if (sscanf (row[1],"%u",&UnsignedNum) == 1)
|
||||
if (UnsignedNum < Ann_NUM_STATUS)
|
||||
Status = (Ann_Status_t) UnsignedNum;
|
||||
/* Get announcement code (row[0]) */
|
||||
if (sscanf (row[0],"%ld",&AnnCod) != 1)
|
||||
Err_WrongAnnouncementExit ();
|
||||
|
||||
/* Get roles (row[2]) */
|
||||
if (sscanf (row[2],"%u",&Roles) != 1)
|
||||
Err_ShowErrorAndExit ("Error when reading roles of announcement.");
|
||||
/* Get status of the announcement (row[1]) */
|
||||
Status = Ann_OBSOLETE_ANNOUNCEMENT;
|
||||
if (sscanf (row[1],"%u",&UnsignedNum) == 1)
|
||||
if (UnsignedNum < Ann_NUM_STATUS)
|
||||
Status = (Ann_Status_t) UnsignedNum;
|
||||
|
||||
/* Get the subject (row[3]), the content (row[4]), and insert links */
|
||||
Str_Copy (Subject,row[3],sizeof (Subject) - 1);
|
||||
Str_Copy (Content,row[4],sizeof (Content) - 1);
|
||||
Str_InsertLinks (Content,Cns_MAX_BYTES_TEXT,50);
|
||||
/* Get roles (row[2]) */
|
||||
if (sscanf (row[2],"%u",&Roles) != 1)
|
||||
Err_ShowErrorAndExit ("Error when reading roles of announcement.");
|
||||
|
||||
/* Show the announcement */
|
||||
Ann_DrawAnAnnouncement (AnnCod,Status,Subject,Content,
|
||||
Roles,true,ICanEdit);
|
||||
}
|
||||
/* Get the subject (row[3]), the content (row[4]), and insert links */
|
||||
Str_Copy (Subject,row[3],sizeof (Subject) - 1);
|
||||
Str_Copy (Content,row[4],sizeof (Content) - 1);
|
||||
Str_InsertLinks (Content,Cns_MAX_BYTES_TEXT,50);
|
||||
|
||||
/***** Button to add new announcement *****/
|
||||
if (ICanEdit)
|
||||
Ann_PutButtonToAddNewAnnouncement ();
|
||||
/* Show the announcement */
|
||||
Ann_DrawAnAnnouncement (AnnCod,Status,Subject,Content,
|
||||
Roles,true,ICanEdit);
|
||||
}
|
||||
|
||||
/***** Button to add new announcement *****/
|
||||
if (ICanEdit)
|
||||
Ann_PutButtonToAddNewAnnouncement ();
|
||||
|
||||
/***** End box *****/
|
||||
Box_BoxEnd ();
|
||||
|
@ -231,47 +199,32 @@ void Ann_ShowMyAnnouncementsNotMarkedAsSeen (void)
|
|||
|
||||
/***** Select announcements not seen *****/
|
||||
Rol_GetRolesInAllCrss (&Gbl.Usrs.Me.UsrDat);
|
||||
NumAnnouncements = (unsigned)
|
||||
DB_QuerySELECT (&mysql_res,"can not get announcements",
|
||||
"SELECT AnnCod," // row[0]
|
||||
"Subject," // row[1]
|
||||
"Content" // row[2]
|
||||
" FROM ann_announcements"
|
||||
" WHERE Status=%u"
|
||||
" AND (Roles&%u)<>0 " // All my roles in different courses
|
||||
" AND AnnCod NOT IN"
|
||||
" (SELECT AnnCod"
|
||||
" FROM ann_seen"
|
||||
" WHERE UsrCod=%ld)"
|
||||
" ORDER BY AnnCod DESC", // Newest first
|
||||
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
|
||||
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss,
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
NumAnnouncements = Ann_DB_GetAnnouncementsNotSeen (&mysql_res);
|
||||
|
||||
/***** Show the announcements *****/
|
||||
if (NumAnnouncements)
|
||||
{
|
||||
HTM_DIV_Begin ("class=\"CM\"");
|
||||
|
||||
for (NumAnn = 0;
|
||||
NumAnn < NumAnnouncements;
|
||||
NumAnn++)
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
for (NumAnn = 0;
|
||||
NumAnn < NumAnnouncements;
|
||||
NumAnn++)
|
||||
{
|
||||
row = mysql_fetch_row (mysql_res);
|
||||
|
||||
/* Get announcement code (row[0]) */
|
||||
if (sscanf (row[0],"%ld",&AnnCod) != 1)
|
||||
Err_WrongAnnouncementExit ();
|
||||
/* Get announcement code (row[0]) */
|
||||
if (sscanf (row[0],"%ld",&AnnCod) != 1)
|
||||
Err_WrongAnnouncementExit ();
|
||||
|
||||
/* Get the subject (row[1]), the content (row[2]), and insert links */
|
||||
Str_Copy (Subject,row[1],sizeof (Subject) - 1);
|
||||
Str_Copy (Content,row[2],sizeof (Content) - 1);
|
||||
Str_InsertLinks (Content,Cns_MAX_BYTES_TEXT,50);
|
||||
/* Get the subject (row[1]), the content (row[2]), and insert links */
|
||||
Str_Copy (Subject,row[1],sizeof (Subject) - 1);
|
||||
Str_Copy (Content,row[2],sizeof (Content) - 1);
|
||||
Str_InsertLinks (Content,Cns_MAX_BYTES_TEXT,50);
|
||||
|
||||
/* Show the announcement */
|
||||
Ann_DrawAnAnnouncement (AnnCod,Ann_ACTIVE_ANNOUNCEMENT,Subject,Content,
|
||||
0,false,false);
|
||||
}
|
||||
/* Show the announcement */
|
||||
Ann_DrawAnAnnouncement (AnnCod,Ann_ACTIVE_ANNOUNCEMENT,Subject,Content,
|
||||
0,false,false);
|
||||
}
|
||||
|
||||
HTM_DIV_End ();
|
||||
}
|
||||
|
@ -316,62 +269,64 @@ static void Ann_DrawAnAnnouncement (long AnnCod,Ann_Status_t Status,
|
|||
/***** Start yellow note *****/
|
||||
HTM_DIV_Begin ("class=\"%s\"",ContainerClass[Status]);
|
||||
|
||||
if (ICanEdit)
|
||||
{
|
||||
/***** Put form to remove announcement *****/
|
||||
Ico_PutContextualIconToRemove (ActRemAnn,NULL,
|
||||
Ann_PutParams,&AnnCod);
|
||||
|
||||
/***** Put form to change the status of the announcement *****/
|
||||
switch (Status)
|
||||
if (ICanEdit)
|
||||
{
|
||||
case Ann_ACTIVE_ANNOUNCEMENT:
|
||||
Ico_PutContextualIconToHide (ActHidAnn,NULL,
|
||||
Ann_PutParams,&AnnCod);
|
||||
break;
|
||||
case Ann_OBSOLETE_ANNOUNCEMENT:
|
||||
Ico_PutContextualIconToUnhide (ActRevAnn,NULL,
|
||||
Ann_PutParams,&AnnCod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/***** Put form to remove announcement *****/
|
||||
Ico_PutContextualIconToRemove (ActRemAnn,NULL,
|
||||
Ann_PutParams,&AnnCod);
|
||||
|
||||
/***** Write the subject of the announcement *****/
|
||||
HTM_DIV_Begin ("class=\"%s\"",SubjectClass[Status]);
|
||||
HTM_Txt (Subject);
|
||||
HTM_DIV_End ();
|
||||
|
||||
/***** Write the content of the announcement *****/
|
||||
HTM_DIV_Begin ("class=\"%s\"",ContentClass[Status]);
|
||||
HTM_Txt (Content);
|
||||
HTM_DIV_End ();
|
||||
|
||||
/***** Write form *****/
|
||||
HTM_DIV_Begin ("class=\"NOTICE_USERS %s\"",UsersClass[Status]);
|
||||
|
||||
if (ShowAllAnnouncements)
|
||||
{
|
||||
/* Users' roles who can view this announcement */
|
||||
HTM_TxtColon (Txt_Users);
|
||||
for (Role = Rol_UNK, SomeRolesAreSelected = false;
|
||||
Role <= Rol_TCH;
|
||||
Role++)
|
||||
if (Roles & (1 << Role))
|
||||
/***** Put form to change the status of the announcement *****/
|
||||
switch (Status)
|
||||
{
|
||||
if (SomeRolesAreSelected)
|
||||
HTM_Comma ();
|
||||
SomeRolesAreSelected = true;
|
||||
HTM_TxtF (" %s",Txt_ROLES_PLURAL_abc[Role][Usr_SEX_UNKNOWN]);
|
||||
case Ann_ACTIVE_ANNOUNCEMENT:
|
||||
Ico_PutContextualIconToHide (ActHidAnn,NULL,
|
||||
Ann_PutParams,&AnnCod);
|
||||
break;
|
||||
case Ann_OBSOLETE_ANNOUNCEMENT:
|
||||
Ico_PutContextualIconToUnhide (ActRevAnn,NULL,
|
||||
Ann_PutParams,&AnnCod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
/***** Put form to mark announcement as seen *****/
|
||||
Lay_PutContextualLinkIconText (ActAnnSee,NULL,
|
||||
Ann_PutParams,&AnnCod,
|
||||
"times.svg",
|
||||
Txt_Do_not_show_again);
|
||||
}
|
||||
|
||||
HTM_DIV_End ();
|
||||
/***** Write the subject of the announcement *****/
|
||||
HTM_DIV_Begin ("class=\"%s\"",SubjectClass[Status]);
|
||||
HTM_Txt (Subject);
|
||||
HTM_DIV_End ();
|
||||
|
||||
/***** Write the content of the announcement *****/
|
||||
HTM_DIV_Begin ("class=\"%s\"",ContentClass[Status]);
|
||||
HTM_Txt (Content);
|
||||
HTM_DIV_End ();
|
||||
|
||||
/***** Write announcement foot *****/
|
||||
/* Begin container for foot */
|
||||
HTM_DIV_Begin ("class=\"NOTICE_USERS %s\"",UsersClass[Status]);
|
||||
|
||||
if (ShowAllAnnouncements)
|
||||
{
|
||||
/* Users' roles who can view this announcement */
|
||||
HTM_TxtColon (Txt_Users);
|
||||
for (Role = Rol_UNK, SomeRolesAreSelected = false;
|
||||
Role <= Rol_TCH;
|
||||
Role++)
|
||||
if (Roles & (1 << Role))
|
||||
{
|
||||
if (SomeRolesAreSelected)
|
||||
HTM_Comma ();
|
||||
SomeRolesAreSelected = true;
|
||||
HTM_TxtF (" %s",Txt_ROLES_PLURAL_abc[Role][Usr_SEX_UNKNOWN]);
|
||||
}
|
||||
}
|
||||
else
|
||||
/***** Put form to mark announcement as seen *****/
|
||||
Lay_PutContextualLinkIconText (ActAnnSee,NULL,
|
||||
Ann_PutParams,&AnnCod,
|
||||
"times.svg",
|
||||
Txt_Do_not_show_again);
|
||||
|
||||
/* End container for foot */
|
||||
HTM_DIV_End ();
|
||||
|
||||
/***** End yellow note *****/
|
||||
HTM_DIV_End ();
|
||||
|
@ -418,40 +373,40 @@ void Ann_ShowFormAnnouncement (void)
|
|||
/***** Begin form *****/
|
||||
Frm_BeginForm (ActRcvAnn);
|
||||
|
||||
/***** Begin box and table *****/
|
||||
Box_BoxTableBegin (NULL,Txt_New_announcement,
|
||||
NULL,NULL,
|
||||
Hlp_COMMUNICATION_Announcements,Box_NOT_CLOSABLE,2);
|
||||
/***** Begin box and table *****/
|
||||
Box_BoxTableBegin (NULL,Txt_New_announcement,
|
||||
NULL,NULL,
|
||||
Hlp_COMMUNICATION_Announcements,Box_NOT_CLOSABLE,2);
|
||||
|
||||
/***** Announcement subject and body *****/
|
||||
Ann_PutSubjectMessage ("Subject",Txt_MSG_Subject, 2);
|
||||
Ann_PutSubjectMessage ("Content",Txt_MSG_Content,20);
|
||||
/***** Announcement subject and body *****/
|
||||
Ann_PutSubjectMessage ("Subject",Txt_MSG_Subject, 2);
|
||||
Ann_PutSubjectMessage ("Content",Txt_MSG_Content,20);
|
||||
|
||||
/***** Users' roles who can view the announcement *****/
|
||||
HTM_TR_Begin (NULL);
|
||||
/***** Users' roles who can view the announcement *****/
|
||||
HTM_TR_Begin (NULL);
|
||||
|
||||
HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
||||
HTM_TxtColonNBSP (Txt_Users);
|
||||
HTM_TD_End ();
|
||||
HTM_TD_Begin ("class=\"%s RT\"",The_ClassFormInBox[Gbl.Prefs.Theme]);
|
||||
HTM_TxtColonNBSP (Txt_Users);
|
||||
HTM_TD_End ();
|
||||
|
||||
HTM_TD_Begin ("class=\"DAT LT\"");
|
||||
Rol_WriteSelectorRoles (1 << Rol_UNK |
|
||||
1 << Rol_GST |
|
||||
1 << Rol_STD |
|
||||
1 << Rol_NET |
|
||||
1 << Rol_TCH,
|
||||
1 << Rol_UNK |
|
||||
1 << Rol_GST |
|
||||
1 << Rol_STD |
|
||||
1 << Rol_NET |
|
||||
1 << Rol_TCH,
|
||||
false,false);
|
||||
HTM_TD_End ();
|
||||
HTM_TD_Begin ("class=\"DAT LT\"");
|
||||
Rol_WriteSelectorRoles (1 << Rol_UNK |
|
||||
1 << Rol_GST |
|
||||
1 << Rol_STD |
|
||||
1 << Rol_NET |
|
||||
1 << Rol_TCH,
|
||||
1 << Rol_UNK |
|
||||
1 << Rol_GST |
|
||||
1 << Rol_STD |
|
||||
1 << Rol_NET |
|
||||
1 << Rol_TCH,
|
||||
false,false);
|
||||
HTM_TD_End ();
|
||||
|
||||
HTM_TR_End ();
|
||||
HTM_TR_End ();
|
||||
|
||||
/***** End table, send button and end box *****/
|
||||
Box_BoxTableWithButtonEnd (Btn_CREATE_BUTTON,Txt_Create_announcement);
|
||||
/***** End table, send button and end box *****/
|
||||
Box_BoxTableWithButtonEnd (Btn_CREATE_BUTTON,Txt_Create_announcement);
|
||||
|
||||
/***** End form *****/
|
||||
Frm_EndForm ();
|
||||
|
@ -469,15 +424,15 @@ static void Ann_PutSubjectMessage (const char *Field,const char *Label,
|
|||
/***** Subject or content *****/
|
||||
HTM_TR_Begin (NULL);
|
||||
|
||||
/* Label */
|
||||
Frm_LabelColumn ("RT",Field,Label);
|
||||
/* Label */
|
||||
Frm_LabelColumn ("RT",Field,Label);
|
||||
|
||||
/* Data */
|
||||
HTM_TD_Begin ("class=\"LT\"");
|
||||
HTM_TEXTAREA_Begin ("id=\"%s\" name=\"%s\" cols=\"75\" rows=\"%u\"",
|
||||
Field,Field,Rows);
|
||||
HTM_TEXTAREA_End ();
|
||||
HTM_TD_End ();
|
||||
/* Data */
|
||||
HTM_TD_Begin ("class=\"LT\"");
|
||||
HTM_TEXTAREA_Begin ("id=\"%s\" name=\"%s\" cols=\"75\" rows=\"%u\"",
|
||||
Field,Field,Rows);
|
||||
HTM_TEXTAREA_End ();
|
||||
HTM_TD_End ();
|
||||
|
||||
HTM_TR_End ();
|
||||
}
|
||||
|
@ -505,7 +460,7 @@ void Ann_ReceiveAnnouncement (void)
|
|||
Roles = Rol_GetSelectedRoles ();
|
||||
|
||||
/***** Create a new announcement in database *****/
|
||||
Ann_CreateAnnouncement (Roles,Subject,Content);
|
||||
Ann_DB_CreateAnnouncement (Roles,Subject,Content);
|
||||
|
||||
/***** Write message of success *****/
|
||||
Ale_ShowAlert (Ale_SUCCESS,Txt_Announcement_created);
|
||||
|
@ -514,23 +469,6 @@ void Ann_ReceiveAnnouncement (void)
|
|||
Ann_ShowAllAnnouncements ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************ Create a new announcement **************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Ann_CreateAnnouncement (unsigned Roles,const char *Subject,const char *Content)
|
||||
{
|
||||
/***** Select announcements not seen *****/
|
||||
DB_QueryINSERT ("can not create announcement",
|
||||
"INSERT INTO ann_announcements"
|
||||
" (Roles,Subject,Content)"
|
||||
" VALUES"
|
||||
" (%u,'%s','%s')",
|
||||
Roles,
|
||||
Subject,
|
||||
Content);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********** Mark as hidden a global announcement that was active ************/
|
||||
/*****************************************************************************/
|
||||
|
@ -543,12 +481,7 @@ void Ann_HideActiveAnnouncement (void)
|
|||
AnnCod = Ann_GetParamAnnCod ();
|
||||
|
||||
/***** Set global announcement as hidden *****/
|
||||
DB_QueryUPDATE ("can not hide announcement",
|
||||
"UPDATE ann_announcements"
|
||||
" SET Status=%u"
|
||||
" WHERE AnnCod=%ld",
|
||||
(unsigned) Ann_OBSOLETE_ANNOUNCEMENT,
|
||||
AnnCod);
|
||||
Ann_DB_HideAnnouncement (AnnCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -562,13 +495,8 @@ void Ann_RevealHiddenAnnouncement (void)
|
|||
/***** Get the code of the global announcement to show *****/
|
||||
AnnCod = Ann_GetParamAnnCod ();
|
||||
|
||||
/***** Set global announcement as shown *****/
|
||||
DB_QueryUPDATE ("can not reveal announcement",
|
||||
"UPDATE ann_announcements"
|
||||
" SET Status=%u"
|
||||
" WHERE AnnCod=%ld",
|
||||
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
|
||||
AnnCod);
|
||||
/***** Set global announcement as not hidden *****/
|
||||
Ann_DB_UnhideAnnouncement (AnnCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -583,17 +511,11 @@ void Ann_RemoveAnnouncement (void)
|
|||
/***** Get the code of the global announcement *****/
|
||||
AnnCod = Ann_GetParamAnnCod ();
|
||||
|
||||
/***** Remove announcement *****/
|
||||
DB_QueryDELETE ("can not remove announcement",
|
||||
"DELETE FROM ann_announcements"
|
||||
" WHERE AnnCod=%ld",
|
||||
AnnCod);
|
||||
|
||||
/***** Remove users who have seen the announcement *****/
|
||||
DB_QueryDELETE ("can not remove announcement",
|
||||
"DELETE FROM ann_seen"
|
||||
" WHERE AnnCod=%ld",
|
||||
AnnCod);
|
||||
Ann_DB_RemoveUsrsWhoSawAnnouncement (AnnCod);
|
||||
|
||||
/***** Remove the announcement *****/
|
||||
Ann_DB_RemoveAnnouncement (AnnCod);
|
||||
|
||||
/***** Write message of success *****/
|
||||
Ale_ShowAlert (Ale_SUCCESS,Txt_Announcement_removed);
|
||||
|
@ -614,26 +536,8 @@ void Ann_MarkAnnouncementAsSeen (void)
|
|||
AnnCod = Ann_GetParamAnnCod ();
|
||||
|
||||
/***** Mark announcement as seen *****/
|
||||
DB_QueryREPLACE ("can not mark announcement as seen",
|
||||
"REPLACE INTO ann_seen"
|
||||
" (AnnCod,UsrCod)"
|
||||
" VALUES"
|
||||
" (%ld,%ld)",
|
||||
AnnCod,
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
Ann_DB_MarkAnnouncementAsSeenByMe (AnnCod);
|
||||
|
||||
/***** Show other announcements again *****/
|
||||
Ann_ShowMyAnnouncementsNotMarkedAsSeen ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Remove user from seen announcements ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Ann_DB_RemoveUsrFromSeenAnnouncements (long UsrCod)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove user from seen announcements",
|
||||
"DELETE FROM ann_seen"
|
||||
" WHERE UsrCod=%ld",
|
||||
UsrCod);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,5 @@ void Ann_HideActiveAnnouncement (void);
|
|||
void Ann_RevealHiddenAnnouncement (void);
|
||||
void Ann_RemoveAnnouncement (void);
|
||||
void Ann_MarkAnnouncementAsSeen (void);
|
||||
void Ann_DB_RemoveUsrFromSeenAnnouncements (long UsrCod);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
// swad_announcement_database.c: Global announcements 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 3 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 "swad_announcement.h"
|
||||
#include "swad_announcement_database.h"
|
||||
#include "swad_global.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Public constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************* Private types *******************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/************** External global variables from others modules ****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
extern struct Globals Gbl;
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* Private global variables **************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Private prototypes ****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************** Select all announcements *************************/
|
||||
/*****************************************************************************/
|
||||
// Returns the number of announcements got
|
||||
|
||||
unsigned Ann_DB_GetAllAnnouncements (MYSQL_RES **mysql_res)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get announcements",
|
||||
"SELECT AnnCod," // row[0]
|
||||
"Status," // row[1]
|
||||
"Roles," // row[2]
|
||||
"Subject," // row[3]
|
||||
"Content" // row[4]
|
||||
" FROM ann_announcements"
|
||||
" ORDER BY AnnCod DESC");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Select only announcements I can see ********************/
|
||||
/*****************************************************************************/
|
||||
// Returns the number of announcements got
|
||||
|
||||
unsigned Ann_DB_GetAnnouncementsICanSee (MYSQL_RES **mysql_res)
|
||||
{
|
||||
Rol_GetRolesInAllCrss (&Gbl.Usrs.Me.UsrDat);
|
||||
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get announcements",
|
||||
"SELECT AnnCod," // row[0]
|
||||
"Status," // row[1]
|
||||
"Roles," // row[2]
|
||||
"Subject," // row[3]
|
||||
"Content" // row[4]
|
||||
" FROM ann_announcements"
|
||||
" WHERE (Roles&%u)<>0 " // All my roles in different courses
|
||||
" ORDER BY AnnCod DESC",
|
||||
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************ Select only active announcements for unknown users *************/
|
||||
/*****************************************************************************/
|
||||
// Returns the number of announcements got
|
||||
|
||||
unsigned Ann_DB_GetAnnouncementsForUnknownUsers (MYSQL_RES **mysql_res)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get announcements",
|
||||
"SELECT AnnCod," // row[0]
|
||||
"Status," // row[1]
|
||||
"Roles," // row[2]
|
||||
"Subject," // row[3]
|
||||
"Content" // row[4]
|
||||
" FROM ann_announcements"
|
||||
" WHERE Status=%u"
|
||||
" AND (Roles&%u)<>0 "
|
||||
" ORDER BY AnnCod DESC",
|
||||
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
|
||||
(unsigned) (1 << Rol_UNK));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************ Select announcements not seen **********************/
|
||||
/*****************************************************************************/
|
||||
// Returns the number of announcements got
|
||||
|
||||
unsigned Ann_DB_GetAnnouncementsNotSeen (MYSQL_RES **mysql_res)
|
||||
{
|
||||
return (unsigned)
|
||||
DB_QuerySELECT (mysql_res,"can not get announcements",
|
||||
"SELECT AnnCod," // row[0]
|
||||
"Subject," // row[1]
|
||||
"Content" // row[2]
|
||||
" FROM ann_announcements"
|
||||
" WHERE Status=%u"
|
||||
" AND (Roles&%u)<>0 " // All my roles in different courses
|
||||
" AND AnnCod NOT IN"
|
||||
" (SELECT AnnCod"
|
||||
" FROM ann_seen"
|
||||
" WHERE UsrCod=%ld)"
|
||||
" ORDER BY AnnCod DESC", // Newest first
|
||||
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
|
||||
(unsigned) Gbl.Usrs.Me.UsrDat.Roles.InCrss,
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************ Create a new announcement **************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Ann_DB_CreateAnnouncement (unsigned Roles,
|
||||
const char *Subject,const char *Content)
|
||||
{
|
||||
DB_QueryINSERT ("can not create announcement",
|
||||
"INSERT INTO ann_announcements"
|
||||
" (Roles,Subject,Content)"
|
||||
" VALUES"
|
||||
" (%u,'%s','%s')",
|
||||
Roles,
|
||||
Subject,
|
||||
Content);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************* Set global announcement as hidden *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Ann_DB_HideAnnouncement (long AnnCod)
|
||||
{
|
||||
DB_QueryUPDATE ("can not hide announcement",
|
||||
"UPDATE ann_announcements"
|
||||
" SET Status=%u"
|
||||
" WHERE AnnCod=%ld",
|
||||
(unsigned) Ann_OBSOLETE_ANNOUNCEMENT,
|
||||
AnnCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Set global announcement as unhidden ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Ann_DB_UnhideAnnouncement (long AnnCod)
|
||||
{
|
||||
DB_QueryUPDATE ("can not unhide announcement",
|
||||
"UPDATE ann_announcements"
|
||||
" SET Status=%u"
|
||||
" WHERE AnnCod=%ld",
|
||||
(unsigned) Ann_ACTIVE_ANNOUNCEMENT,
|
||||
AnnCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**************** Remove users who have seen an announcement *****************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Ann_DB_RemoveUsrsWhoSawAnnouncement (long AnnCod)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove users who saw announcement",
|
||||
"DELETE FROM ann_seen"
|
||||
" WHERE AnnCod=%ld",
|
||||
AnnCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************** Remove an announcement ***************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Ann_DB_RemoveAnnouncement (long AnnCod)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove announcement",
|
||||
"DELETE FROM ann_announcements"
|
||||
" WHERE AnnCod=%ld",
|
||||
AnnCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Mark an announcement as seen by me *********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Ann_DB_MarkAnnouncementAsSeenByMe (long AnnCod)
|
||||
{
|
||||
DB_QueryREPLACE ("can not mark announcement as seen",
|
||||
"REPLACE INTO ann_seen"
|
||||
" (AnnCod,UsrCod)"
|
||||
" VALUES"
|
||||
" (%ld,%ld)",
|
||||
AnnCod,
|
||||
Gbl.Usrs.Me.UsrDat.UsrCod);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************** Remove user from seen announcements ********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
void Ann_DB_RemoveUsrFromSeenAnnouncements (long UsrCod)
|
||||
{
|
||||
DB_QueryDELETE ("can not remove user from seen announcements",
|
||||
"DELETE FROM ann_seen"
|
||||
" WHERE UsrCod=%ld",
|
||||
UsrCod);
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
// swad_announcement_database.h: Global announcements operations with database
|
||||
|
||||
#ifndef _SWAD_ANN_DB
|
||||
#define _SWAD_ANN_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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
/********************************* Headers ***********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#include "swad_database.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Public constants ******************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************* Public types ********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/***************************** Public prototypes *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
unsigned Ann_DB_GetAllAnnouncements (MYSQL_RES **mysql_res);
|
||||
unsigned Ann_DB_GetAnnouncementsICanSee (MYSQL_RES **mysql_res);
|
||||
unsigned Ann_DB_GetAnnouncementsForUnknownUsers (MYSQL_RES **mysql_res);
|
||||
unsigned Ann_DB_GetAnnouncementsNotSeen (MYSQL_RES **mysql_res);
|
||||
|
||||
void Ann_DB_CreateAnnouncement (unsigned Roles,
|
||||
const char *Subject,const char *Content);
|
||||
|
||||
void Ann_DB_HideAnnouncement (long AnnCod);
|
||||
void Ann_DB_UnhideAnnouncement (long AnnCod);
|
||||
|
||||
void Ann_DB_RemoveUsrsWhoSawAnnouncement (long AnnCod);
|
||||
void Ann_DB_RemoveAnnouncement (long AnnCod);
|
||||
|
||||
void Ann_DB_MarkAnnouncementAsSeenByMe (long AnnCod);
|
||||
|
||||
void Ann_DB_RemoveUsrFromSeenAnnouncements (long UsrCod);
|
||||
|
||||
#endif
|
|
@ -600,13 +600,14 @@ TODO: Salvador Romero Cort
|
|||
|
||||
TODO: FIX BUG, URGENT! En las fechas como parámetro Dat_WriteParamsIniEndDates(), por ejemplo al cambiar el color de la gráfica de accesos por día y hora, no se respeta la zona horaria.
|
||||
*/
|
||||
#define Log_PLATFORM_VERSION "SWAD 20.73 (2021-05-10)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 20.74 (2021-05-11)"
|
||||
#define CSS_FILE "swad20.45.css"
|
||||
#define JS_FILE "swad20.69.1.js"
|
||||
/*
|
||||
TODO: Rename CENTRE to CENTER in help wiki.
|
||||
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
|
||||
|
||||
Version 20.74: May 11, 2021 New module swad_announcement_database for database queries related to announcements. (? lines)
|
||||
Version 20.73: May 10, 2021 New module swad_agenda_database for database queries related to agenda. (310474 lines)
|
||||
Version 20.72: May 10, 2021 New module swad_account_database for database queries related to user's account. (310328 lines)
|
||||
Version 20.71: May 10, 2021 New module swad_media_database for database queries related to media. (310080 lines)
|
||||
|
|
Loading…
Reference in New Issue