swad-core/swad_announcement.c

479 lines
17 KiB
C
Raw Normal View History

2014-12-01 23:55:08 +01:00
// swad_announcement.c: Global announcement
/*
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.
2015-01-01 14:34:06 +01:00
Copyright (C) 1999-2015 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 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 <string.h> // For strncpy...
#include "swad_database.h"
#include "swad_global.h"
#include "swad_parameter.h"
/*****************************************************************************/
/****************************** Public constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Internal constants ****************************/
/*****************************************************************************/
/*****************************************************************************/
/****************************** Internal types *******************************/
/*****************************************************************************/
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/************************* Internal global variables *************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Internal prototypes ***************************/
/*****************************************************************************/
static void Ann_ListAnnouncements (void);
static void Ann_ShowAnnouncement (long AnnCod,const char *Subject,const char *Content,
unsigned Roles,bool ShowAllAnnouncements);
static void Ann_PutHiddenParamAnnCod (long AnnCod);
static long Ann_GetParamAnnCod (void);
static void Ann_CreateAnnouncement (unsigned Roles,const char *Subject,const char *Content);
/*****************************************************************************/
/************************** Show global announcements ************************/
/*****************************************************************************/
void Ann_ShowAllAnnouncements (void)
{
extern const char *Txt_New_announcement;
/***** Put link (form) to create a new announcement *****/
2015-04-07 21:44:24 +02:00
if (Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM)
2014-12-01 23:55:08 +01:00
{
2015-04-02 14:22:21 +02:00
fprintf (Gbl.F.Out,"<div class=\"CONTEXT_MENU\">");
2015-04-02 18:39:49 +02:00
Act_PutContextualLink (ActWriAnn,NULL,"new",Txt_New_announcement);
2015-04-02 14:22:21 +02:00
fprintf (Gbl.F.Out,"</div>");
2014-12-01 23:55:08 +01:00
}
/***** List announcements *****/
Ann_ListAnnouncements ();
}
/*****************************************************************************/
/************************** Show global announcements ************************/
/*****************************************************************************/
static void Ann_ListAnnouncements (void)
{
char Query[256];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumAnnouncements;
unsigned NumAnn;
long AnnCod;
unsigned Roles;
char Subject[Cns_MAX_BYTES_SUBJECT+1];
char Content[Cns_MAX_BYTES_TEXT+1];
/***** Select announcements *****/
sprintf (Query,"SELECT AnnCod,Roles,Subject,Content FROM announcements"
" ORDER BY AnnCod DESC");
NumAnnouncements = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get announcements");
/***** Show the announcements *****/
for (NumAnn = 0;
NumAnn < NumAnnouncements;
NumAnn++)
{
row = mysql_fetch_row (mysql_res);
/* Get announcement code (row[0]) */
if (sscanf (row[0],"%ld",&AnnCod) != 1)
Lay_ShowErrorAndExit ("Wrong code of announcement.");
/* Get roles (row[1]) */
if (sscanf (row[1],"%u",&Roles) != 1)
Lay_ShowErrorAndExit ("Error when reading roles of announcement.");
/* Get the content (row[2]) */
strncpy (Subject,row[2],Cns_MAX_BYTES_SUBJECT);
Content[Cns_MAX_BYTES_SUBJECT] = '\0';
/* Get the content (row[3]) and insert links */
strncpy (Content,row[3],Cns_MAX_BYTES_TEXT);
Content[Cns_MAX_BYTES_TEXT] = '\0';
Str_InsertLinkInURLs (Content,Cns_MAX_BYTES_TEXT,50);
/* Show the announcement */
Ann_ShowAnnouncement (AnnCod,Subject,Content,Roles,true);
}
}
/*****************************************************************************/
/************************** Show global announcements ************************/
/*****************************************************************************/
void Ann_ShowMyAnnouncementsNotMarkedAsSeen (void)
{
char Query[256];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumAnnouncements;
unsigned NumAnn;
long AnnCod;
char Subject[Cns_MAX_BYTES_SUBJECT+1];
char Content[Cns_MAX_BYTES_TEXT+1];
/***** Select announcements not seen *****/
// Roles == 24 ==> Teachers and students
sprintf (Query,"SELECT AnnCod,Subject,Content FROM announcements"
" WHERE (Roles&%u)<>0 AND AnnCod NOT IN"
" (SELECT AnnCod FROM ann_seen WHERE UsrCod='%ld')"
" ORDER BY AnnCod DESC", // Newest first
Gbl.Usrs.Me.UsrDat.Roles, // All my roles in different courses
Gbl.Usrs.Me.UsrDat.UsrCod);
NumAnnouncements = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get announcements");
/***** Show the announcements *****/
if (NumAnnouncements)
{
2015-09-03 00:59:03 +02:00
fprintf (Gbl.F.Out,"<div class=\"CENTER_MIDDLE\">");
2014-12-01 23:55:08 +01:00
for (NumAnn = 0;
NumAnn < NumAnnouncements;
NumAnn++)
{
row = mysql_fetch_row (mysql_res);
/* Get announcement code (row[0]) */
if (sscanf (row[0],"%ld",&AnnCod) != 1)
Lay_ShowErrorAndExit ("Wrong code of announcement.");
/* Get the content (row[1]) */
strncpy (Subject,row[1],Cns_MAX_BYTES_SUBJECT);
Content[Cns_MAX_BYTES_SUBJECT] = '\0';
/* Get the content (row[2]) and insert links */
strncpy (Content,row[2],Cns_MAX_BYTES_TEXT);
Content[Cns_MAX_BYTES_TEXT] = '\0';
Str_InsertLinkInURLs (Content,Cns_MAX_BYTES_TEXT,50);
/* Show the announcement */
Ann_ShowAnnouncement (AnnCod,Subject,Content,0,false);
}
fprintf (Gbl.F.Out,"</div>");
}
}
/*****************************************************************************/
/****************** Draw an announcement as a yellow note ********************/
/*****************************************************************************/
static void Ann_ShowAnnouncement (long AnnCod,const char *Subject,const char *Content,
unsigned Roles,bool ShowAllAnnouncements)
{
2015-07-27 21:25:45 +02:00
extern const char *The_ClassForm[The_NUM_THEMES];
2014-12-01 23:55:08 +01:00
extern const char *Txt_Users;
extern const char *Txt_ROLES_PLURAL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
extern const char *Txt_Remove;
extern const char *Txt_Do_not_show_again;
Rol_Role_t Role;
bool RolesSelected;
/***** Start yellow note *****/
2015-11-01 14:11:46 +01:00
fprintf (Gbl.F.Out,"<div class=\"NOTICE_CONTAINER_ACTIVE\""
2015-09-28 18:28:29 +02:00
" style=\"width:500px;\">");
2014-12-01 23:55:08 +01:00
/***** Write the content of the announcement *****/
2015-11-01 14:11:46 +01:00
fprintf (Gbl.F.Out,"<div class=\"NOTICE_SUBJECT_ACTIVE\">%s</div>",
2014-12-01 23:55:08 +01:00
Subject);
/***** Write the content of the announcement *****/
2015-11-01 14:11:46 +01:00
fprintf (Gbl.F.Out,"<div class=\"NOTICE_TEXT_ACTIVE\">%s</div>",
2014-12-01 23:55:08 +01:00
Content);
/***** Write form *****/
2015-09-28 18:28:29 +02:00
fprintf (Gbl.F.Out,"<div class=\"CENTER_MIDDLE\" style=\"margin:12px;\">");
2014-12-01 23:55:08 +01:00
if (ShowAllAnnouncements)
{
/* Users' roles who can view this announcement */
fprintf (Gbl.F.Out,"<p class=\"DAT\">%s:",
Txt_Users);
2015-04-07 21:44:24 +02:00
for (Role = Rol_STUDENT, RolesSelected = false;
Role <= Rol_TEACHER;
2014-12-01 23:55:08 +01:00
Role++)
if (Roles & (1 << Role))
{
if (RolesSelected)
fprintf (Gbl.F.Out,",");
else
RolesSelected = true;
fprintf (Gbl.F.Out," %s",Txt_ROLES_PLURAL_abc[Role][Usr_SEX_UNKNOWN]);
}
fprintf (Gbl.F.Out,"</p>");
/* Form to remove announcement */
Act_FormStart (ActRemAnn);
Ann_PutHiddenParamAnnCod (AnnCod);
2015-07-27 21:25:45 +02:00
Act_LinkFormSubmit (Txt_Remove,The_ClassForm[Gbl.Prefs.Theme]);
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"<img src=\"%s/delon16x16.gif\""
2015-07-21 17:24:52 +02:00
" alt=\"%s\" title=\"%s\""
" class=\"ICON16x16\" />"
2015-03-13 00:16:02 +01:00
" %s</a>",
2014-12-01 23:55:08 +01:00
Gbl.Prefs.IconsURL,
2015-07-22 19:59:28 +02:00
Txt_Remove,
Txt_Remove,
2014-12-01 23:55:08 +01:00
Txt_Remove);
2015-03-13 00:16:02 +01:00
Act_FormEnd ();
2014-12-01 23:55:08 +01:00
}
else
{
/* Form to mark announcement as seen */
Act_FormStart (ActAnnSee);
Ann_PutHiddenParamAnnCod (AnnCod);
2015-07-27 21:25:45 +02:00
Act_LinkFormSubmit (Txt_Do_not_show_again,The_ClassForm[Gbl.Prefs.Theme]);
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"<img src=\"%s/delon16x16.gif\""
2015-07-21 17:24:52 +02:00
" alt=\"%s\" title=\"%s\""
" class=\"ICON16x16\" />"
2015-03-13 00:16:02 +01:00
" %s</a>",
2014-12-01 23:55:08 +01:00
Gbl.Prefs.IconsURL,
2015-07-22 19:59:28 +02:00
Txt_Do_not_show_again,
Txt_Do_not_show_again,
2014-12-01 23:55:08 +01:00
Txt_Do_not_show_again);
2015-03-13 00:16:02 +01:00
Act_FormEnd ();
2014-12-01 23:55:08 +01:00
}
fprintf (Gbl.F.Out,"</div>");
/***** End yellow note *****/
fprintf (Gbl.F.Out,"</div>");
}
/*****************************************************************************/
/************** Put parameter with the code of an announcement ***************/
/*****************************************************************************/
static void Ann_PutHiddenParamAnnCod (long AnnCod)
{
Par_PutHiddenParamLong ("AnnCod",AnnCod);
}
/*****************************************************************************/
/************** Get parameter with the code of an announcement ***************/
/*****************************************************************************/
static long Ann_GetParamAnnCod (void)
{
char LongStr[1+10+1]; // String that holds the announcement code
long AnnCod;
/* Get notice code */
Par_GetParToText ("AnnCod",LongStr,1+10);
if (sscanf (LongStr,"%ld",&AnnCod) != 1)
Lay_ShowErrorAndExit ("Wrong code of announcement.");
return AnnCod;
}
/*****************************************************************************/
/***************** Show form to create a new announcement ********************/
/*****************************************************************************/
void Ann_ShowFormAnnouncement (void)
{
2015-07-27 21:25:45 +02:00
extern const char *The_ClassForm[The_NUM_THEMES];
2014-12-01 23:55:08 +01:00
extern const char *Txt_New_announcement;
extern const char *Txt_MSG_Subject;
extern const char *Txt_MSG_Message;
extern const char *Txt_Users;
extern const char *Txt_Create_announcement;
2015-04-11 17:33:14 +02:00
/***** Start form *****/
2014-12-01 23:55:08 +01:00
Act_FormStart (ActRcvAnn);
2015-03-24 17:47:26 +01:00
/***** Start frame *****/
2015-04-12 18:01:06 +02:00
Lay_StartRoundFrameTable (NULL,2,Txt_New_announcement);
2015-03-24 17:47:26 +01:00
2014-12-01 23:55:08 +01:00
/***** Message subject and body *****/
2015-03-24 17:47:26 +01:00
fprintf (Gbl.F.Out,"<tr>"
2015-07-27 21:25:45 +02:00
"<td class=\"%s RIGHT_TOP\">"
2014-12-22 14:08:19 +01:00
"%s: "
"</td>"
2015-07-28 00:51:32 +02:00
"<td class=\"LEFT_TOP\">"
2014-12-22 14:08:19 +01:00
"<textarea name=\"Subject\" cols=\"75\" rows=\"2\">"
"</textarea>"
2014-12-01 23:55:08 +01:00
"</td>"
"</tr>"
"<tr>"
2015-07-27 21:25:45 +02:00
"<td class=\"%s RIGHT_TOP\">"
2014-12-22 14:08:19 +01:00
"%s: "
"</td>"
2015-07-28 00:51:32 +02:00
"<td class=\"LEFT_TOP\">"
2014-12-22 14:08:19 +01:00
"<textarea name=\"Content\" cols=\"75\" rows=\"20\">"
"</textarea>"
2014-12-01 23:55:08 +01:00
"</td>"
"</tr>",
2015-07-27 21:25:45 +02:00
The_ClassForm[Gbl.Prefs.Theme],
2014-12-01 23:55:08 +01:00
Txt_MSG_Subject,
2015-07-27 21:25:45 +02:00
The_ClassForm[Gbl.Prefs.Theme],
2014-12-01 23:55:08 +01:00
Txt_MSG_Message);
/***** Users' roles who can view the announcement *****/
fprintf (Gbl.F.Out,"<tr>"
2015-07-27 21:25:45 +02:00
"<td class=\"%s RIGHT_TOP\">"
2014-12-22 14:08:19 +01:00
"%s: "
"</td>"
2015-07-28 00:51:32 +02:00
"<td class=\"DAT LEFT_TOP\">",
2015-07-27 21:25:45 +02:00
The_ClassForm[Gbl.Prefs.Theme],
2014-12-01 23:55:08 +01:00
Txt_Users);
2015-04-07 21:44:24 +02:00
Rol_WriteSelectorRoles (1 << Rol_STUDENT |
1 << Rol_TEACHER);
2014-12-01 23:55:08 +01:00
fprintf (Gbl.F.Out,"</td>"
2015-03-24 17:47:26 +01:00
"</tr>");
2015-04-11 23:46:21 +02:00
/***** Button to create announcement and end frame *****/
2015-04-12 18:01:06 +02:00
Lay_EndRoundFrameTableWithButton (Lay_CREATE_BUTTON,Txt_Create_announcement);
2014-12-01 23:55:08 +01:00
2015-04-11 17:33:14 +02:00
/***** End form *****/
2015-03-13 00:16:02 +01:00
Act_FormEnd ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****** Receive a new announcement from a form and store it in database ******/
/*****************************************************************************/
void Ann_ReceiveAnnouncement (void)
{
extern const char *Txt_Announcement_created;
unsigned Roles;
char Subject[Cns_MAX_BYTES_SUBJECT+1];
char Content[Cns_MAX_BYTES_TEXT+1];
/***** Get data from form *****/
/* Get the subject of the announcement */
Par_GetParToHTML ("Subject",Subject,Cns_MAX_BYTES_SUBJECT);
/* Get the content of the announcement */
Par_GetParAndChangeFormat ("Content",Content,Cns_MAX_BYTES_TEXT,
Str_TO_RIGOROUS_HTML,true);
/* Get users who can view this announcement */
2014-12-12 20:25:00 +01:00
Rol_GetSelectedRoles (&Roles);
2014-12-01 23:55:08 +01:00
/***** Create a new announcement in database *****/
Ann_CreateAnnouncement (Roles,Subject,Content);
/***** Write message of success *****/
Lay_ShowAlert (Lay_SUCCESS,Txt_Announcement_created);
/***** Refresh list of announcements *****/
Ann_ShowAllAnnouncements ();
}
/*****************************************************************************/
/************************ Create a new announcement **************************/
/*****************************************************************************/
static void Ann_CreateAnnouncement (unsigned Roles,const char *Subject,const char *Content)
{
char Query[128+Cns_MAX_BYTES_SUBJECT+Cns_MAX_BYTES_TEXT];
/***** Select announcements not seen *****/
sprintf (Query,"INSERT INTO announcements (Roles,Subject,Content)"
" VALUES ('%u','%s','%s')",
Roles,Subject,Content);
DB_QueryINSERT (Query,"can not create announcement");
}
/*****************************************************************************/
/********************** Remove a global announcement *************************/
/*****************************************************************************/
void Ann_RemoveAnnouncement (void)
{
extern const char *Txt_Announcement_removed;
char Query[128];
long AnnCod;
/***** Get the code of the global announcement *****/
AnnCod = Ann_GetParamAnnCod ();
/***** Remove announcement *****/
sprintf (Query,"DELETE FROM announcements WHERE AnnCod='%ld'",
AnnCod);
2015-03-18 01:06:43 +01:00
DB_QueryDELETE (Query,"can not remove announcement");
2014-12-01 23:55:08 +01:00
/***** Remove users who have seen the announcement *****/
sprintf (Query,"DELETE FROM ann_seen WHERE AnnCod='%ld'",
AnnCod);
2015-03-18 01:06:43 +01:00
DB_QueryDELETE (Query,"can not remove announcement");
2014-12-01 23:55:08 +01:00
/***** Write message of success *****/
Lay_ShowAlert (Lay_SUCCESS,Txt_Announcement_removed);
/***** Refresh list of announcements *****/
Ann_ShowAllAnnouncements ();
}
/*****************************************************************************/
/************************ Create a new announcement **************************/
/*****************************************************************************/
void Ann_MarkAnnouncementAsSeen (void)
{
char Query[128];
long AnnCod;
/***** Get the code of the global announcement *****/
AnnCod = Ann_GetParamAnnCod ();
/***** Mark announcement as seen *****/
sprintf (Query,"REPLACE INTO ann_seen (AnnCod,UsrCod) VALUES ('%ld','%ld')",
AnnCod,Gbl.Usrs.Me.UsrDat.UsrCod);
DB_QueryREPLACE (Query,"can not mark announcement as seen");
/***** Show other announcements again *****/
Ann_ShowMyAnnouncementsNotMarkedAsSeen ();
}
/*****************************************************************************/
/******************** Remove user from seen announcements ********************/
/*****************************************************************************/
void Ann_RemoveUsrFromSeenAnnouncements (long UsrCod)
{
char Query[128];
/***** Remove user from seen announcements *****/
sprintf (Query,"DELETE FROM ann_seen WHERE UsrCod='%ld'",
UsrCod);
DB_QueryDELETE (Query,"can not remove user from seen announcements");
}