diff --git a/swad_changelog.h b/swad_changelog.h index 039c9f27..d2e306df 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,13 +602,14 @@ 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.17.3 (2021-09-29)" +#define Log_PLATFORM_VERSION "SWAD 21.17.4 (2021-09-29)" #define CSS_FILE "swad20.45.css" #define JS_FILE "swad20.69.1.js" /* TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams + Version 21.17.4: Sep 29, 2021 Queries moved to module swad_message_database. (317408 lines) Version 21.17.3: Sep 29, 2021 Queries moved to module swad_message_database. (317431 lines) Version 21.17.2: Sep 27, 2021 Queries moved to module swad_message_database. (317358 lines) Version 21.17.1: Sep 27, 2021 Queries moved to module swad_message_database. (317325 lines) diff --git a/swad_message.c b/swad_message.c index 040b8a38..f0527cca 100644 --- a/swad_message.c +++ b/swad_message.c @@ -139,9 +139,6 @@ static unsigned long Msg_RemoveSomeRecOrSntMsgsUsr (const struct Msg_Messages *M const char *FilterFromToSubquery); static void Msg_MoveRcvMsgToDeleted (long MsgCod,long UsrCod); static void Msg_MoveSntMsgToDeleted (long MsgCod); -static void Msg_MoveMsgContentToDeleted (long MsgCod); -static unsigned Msg_DB_GetNumUnreadMsgs (const struct Msg_Messages *Messages, - const char *FilterFromToSubquery); static void Msg_GetMsgSntData (long MsgCod,long *CrsCod,long *UsrCod, time_t *CreatTimeUTC, @@ -1015,7 +1012,7 @@ void Msg_ReqDelAllSntMsgs (void) void Msg_DelAllRecMsgs (void) { struct Msg_Messages Messages; - char FilterFromToSubquery[Msg_MAX_BYTES_MESSAGES_QUERY + 1]; + char FilterFromToSubquery[Msg_DB_MAX_BYTES_MESSAGES_QUERY + 1]; unsigned long NumMsgs; /***** Reset messages context *****/ @@ -1031,8 +1028,8 @@ void Msg_DelAllRecMsgs (void) /***** Delete messages *****/ Messages.TypeOfMessages = Msg_RECEIVED; NumMsgs = Msg_RemoveSomeRecOrSntMsgsUsr (&Messages, - Gbl.Usrs.Me.UsrDat.UsrCod, - FilterFromToSubquery); + Gbl.Usrs.Me.UsrDat.UsrCod, + FilterFromToSubquery); Msg_ShowNumMsgsDeleted (NumMsgs); Msg_ShowRecMsgs (); } @@ -1044,7 +1041,7 @@ void Msg_DelAllRecMsgs (void) void Msg_DelAllSntMsgs (void) { struct Msg_Messages Messages; - char FilterFromToSubquery[Msg_MAX_BYTES_MESSAGES_QUERY + 1]; + char FilterFromToSubquery[Msg_DB_MAX_BYTES_MESSAGES_QUERY + 1]; unsigned long NumMsgs; /***** Reset messages context *****/ @@ -1059,8 +1056,8 @@ void Msg_DelAllSntMsgs (void) /***** Delete messages *****/ Messages.TypeOfMessages = Msg_SENT; NumMsgs = Msg_RemoveSomeRecOrSntMsgsUsr (&Messages, - Gbl.Usrs.Me.UsrDat.UsrCod, - FilterFromToSubquery); + Gbl.Usrs.Me.UsrDat.UsrCod, + FilterFromToSubquery); Msg_ShowNumMsgsDeleted (NumMsgs); Msg_ShowSntMsgs (); } @@ -1342,7 +1339,7 @@ static void Msg_MoveRcvMsgToDeleted (long MsgCod,long UsrCod) /***** If message content is not longer necessary, move it to msg_content_deleted *****/ if (Msg_DB_CheckIfSntMsgIsDeleted (MsgCod)) if (Msg_DB_CheckIfRcvMsgIsDeletedForAllItsRecipients (MsgCod)) - Msg_MoveMsgContentToDeleted (MsgCod); + Msg_DB_MoveMsgContentToDeleted (MsgCod); /***** Mark possible notifications as removed *****/ Ntf_MarkNotifToOneUsrAsRemoved (Ntf_EVENT_MESSAGE,MsgCod,UsrCod); @@ -1363,125 +1360,7 @@ static void Msg_MoveSntMsgToDeleted (long MsgCod) /***** If message content is not longer necessary, move it to msg_content_deleted *****/ if (Msg_DB_CheckIfRcvMsgIsDeletedForAllItsRecipients (MsgCod)) - Msg_MoveMsgContentToDeleted (MsgCod); - } - -/*****************************************************************************/ -/*************** Delete the subject and content of a message *****************/ -/*****************************************************************************/ - -static void Msg_MoveMsgContentToDeleted (long MsgCod) - { - /***** Move message from msg_content to msg_content_deleted *****/ - /* Insert message content into msg_content_deleted */ - DB_QueryINSERT ("can not remove the content of a message", - "INSERT IGNORE INTO msg_content_deleted" - " (MsgCod,Subject,Content,MedCod)" - " SELECT MsgCod," - "Subject," - "Content," - "MedCod" - " FROM msg_content" - " WHERE MsgCod=%ld", - MsgCod); - - /* TODO: Messages in msg_content_deleted older than a certain time - should be deleted to ensure the protection of personal data */ - - /* Delete message from msg_content *****/ - DB_QueryDELETE ("can not remove the content of a message", - "DELETE FROM msg_content" - " WHERE MsgCod=%ld", - MsgCod); - } - -/*****************************************************************************/ -/******** Get number of received messages that haven't been read by me *******/ -/*****************************************************************************/ - -static unsigned Msg_DB_GetNumUnreadMsgs (const struct Msg_Messages *Messages, - const char *FilterFromToSubquery) - { - char *SubQuery; - unsigned NumMsgs; - - /***** Get number of unread messages from database *****/ - if (Messages->FilterCrsCod >= 0) // If origin course selected - { - if (FilterFromToSubquery[0]) - { - if (asprintf (&SubQuery,"SELECT msg_rcv.MsgCod" - " FROM msg_rcv," - "msg_snt," - "usr_data" - " WHERE msg_rcv.UsrCod=%ld" - " AND msg_rcv.Open='N'" - " AND msg_rcv.MsgCod=msg_snt.MsgCod" - " AND msg_snt.CrsCod=%ld" - " AND msg_snt.UsrCod=usr_data.UsrCod%s", - Gbl.Usrs.Me.UsrDat.UsrCod, - Messages->FilterCrsCod, - FilterFromToSubquery) < 0) - Err_NotEnoughMemoryExit (); - } - else - { - if (asprintf (&SubQuery,"SELECT msg_rcv.MsgCod" - " FROM msg_rcv," - "msg_snt" - " WHERE msg_rcv.UsrCod=%ld" - " AND msg_rcv.Open='N'" - " AND msg_rcv.MsgCod=msg_snt.MsgCod" - " AND msg_snt.CrsCod=%ld", - Gbl.Usrs.Me.UsrDat.UsrCod, - Messages->FilterCrsCod) < 0) - Err_NotEnoughMemoryExit (); - } - } - else // If no origin course selected - { - if (FilterFromToSubquery[0]) - { - if (asprintf (&SubQuery,"SELECT msg_rcv.MsgCod" - " FROM msg_rcv,msg_snt,usr_data" - " WHERE msg_rcv.UsrCod=%ld" - " AND msg_rcv.Open='N'" - " AND msg_rcv.MsgCod=msg_snt.MsgCod" - " AND msg_snt.UsrCod=usr_data.UsrCod%s", - Gbl.Usrs.Me.UsrDat.UsrCod, - FilterFromToSubquery) < 0) - Err_NotEnoughMemoryExit (); - } - else - { - if (asprintf (&SubQuery,"SELECT MsgCod" - " FROM msg_rcv" - " WHERE UsrCod=%ld" - " AND Open='N'", - Gbl.Usrs.Me.UsrDat.UsrCod) < 0) - Err_NotEnoughMemoryExit (); - } - } - - if (Messages->FilterContent[0]) - NumMsgs = (unsigned) - DB_QueryCOUNT ("can not get number of unread messages", - "SELECT COUNT(*)" - " FROM msg_content" - " WHERE MsgCod IN (%s)" - " AND MATCH (Subject,Content) AGAINST ('%s')", - SubQuery, - Messages->FilterContent); - else - NumMsgs = (unsigned) - DB_QueryCOUNT ("can not get number of unread messages", - "SELECT COUNT(*)" - " FROM (%s) AS T", - SubQuery); - - free (SubQuery); - - return NumMsgs; + Msg_DB_MoveMsgContentToDeleted (MsgCod); } /*****************************************************************************/ @@ -1537,7 +1416,7 @@ static void Msg_ShowSntOrRcvMessages (struct Msg_Messages *Messages) extern const char *The_ClassFormLinkInBoxBold[The_NUM_THEMES]; extern const char *Txt_Filter; extern const char *Txt_Update_messages; - char FilterFromToSubquery[Msg_MAX_BYTES_MESSAGES_QUERY + 1]; + char FilterFromToSubquery[Msg_DB_MAX_BYTES_MESSAGES_QUERY + 1]; MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumMsg; @@ -1586,7 +1465,7 @@ static void Msg_ShowSntOrRcvMessages (struct Msg_Messages *Messages) case Msg_RECEIVED: Messages->ShowOnlyUnreadMsgs = Msg_GetParamOnlyUnreadMsgs (); NumUnreadMsgs = Msg_DB_GetNumUnreadMsgs (Messages, - FilterFromToSubquery); + FilterFromToSubquery); break; case Msg_SENT: NumUnreadMsgs = 0; @@ -2700,14 +2579,13 @@ static void Msg_WriteMsgTo (struct Msg_Messages *Messages,long MsgCod) NumRcp < NumRecipients.ToShow; NumRcp++) { - /* Get user's code */ row = mysql_fetch_row (mysql_res); + + /* Get user's code (row[0]) */ UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]); - /* Get if message has been deleted by recipient */ + /* Get if message has been deleted (row[1]) and read (row[2]) by recipient */ Deleted = (row[1][0] == 'Y'); - - /* Get if message has been read by recipient */ OpenByDst = (row[2][0] == 'Y'); /* Get user's data */ diff --git a/swad_message_database.c b/swad_message_database.c index c0a2a2b8..e0cf6de6 100644 --- a/swad_message_database.c +++ b/swad_message_database.c @@ -26,36 +26,14 @@ /*****************************************************************************/ #define _GNU_SOURCE // For asprintf -// #include // For PATH_MAX -// #include // For NULL #include // For asprintf -// #include // For free #include // For string functions -// #include // For time -// #include "swad_action.h" -// #include "swad_box.h" -// #include "swad_config.h" -// #include "swad_course.h" #include "swad_database.h" #include "swad_error.h" -// #include "swad_figure.h" -// #include "swad_form.h" -// #include "swad_forum.h" #include "swad_global.h" -// #include "swad_group.h" -// #include "swad_hierarchy.h" -// #include "swad_hierarchy_level.h" -// #include "swad_HTML.h" -// #include "swad_ID.h" #include "swad_message.h" #include "swad_message_database.h" -// #include "swad_notification.h" -// #include "swad_pagination.h" -// #include "swad_parameter.h" -// #include "swad_photo.h" -// #include "swad_profile.h" -// #include "swad_user.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -322,7 +300,7 @@ unsigned Msg_DB_GetDistinctCrssInMySntMsgs (MYSQL_RES **mysql_res) /*****************************************************************************/ void Msg_DB_MakeFilterFromToSubquery (const struct Msg_Messages *Messages, - char FilterFromToSubquery[Msg_MAX_BYTES_MESSAGES_QUERY + 1]) + char FilterFromToSubquery[Msg_DB_MAX_BYTES_MESSAGES_QUERY + 1]) { const char *Ptr; char SearchWord[Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME + 1]; @@ -333,22 +311,113 @@ void Msg_DB_MakeFilterFromToSubquery (const struct Msg_Messages *Messages, Ptr = Messages->FilterFromTo; Str_Copy (FilterFromToSubquery, " AND CONCAT(usr_data.FirstName,' ',usr_data.Surname1,' ',usr_data.Surname2) LIKE '", - Msg_MAX_BYTES_MESSAGES_QUERY); + Msg_DB_MAX_BYTES_MESSAGES_QUERY); while (*Ptr) { Str_GetNextStringUntilSpace (&Ptr,SearchWord,Usr_MAX_BYTES_FIRSTNAME_OR_SURNAME); if (strlen (FilterFromToSubquery) + strlen (SearchWord) + 512 > - Msg_MAX_BYTES_MESSAGES_QUERY) // Prevent string overflow + Msg_DB_MAX_BYTES_MESSAGES_QUERY) // Prevent string overflow break; - Str_Concat (FilterFromToSubquery,"%",Msg_MAX_BYTES_MESSAGES_QUERY); - Str_Concat (FilterFromToSubquery,SearchWord,Msg_MAX_BYTES_MESSAGES_QUERY); + Str_Concat (FilterFromToSubquery,"%",Msg_DB_MAX_BYTES_MESSAGES_QUERY); + Str_Concat (FilterFromToSubquery,SearchWord,Msg_DB_MAX_BYTES_MESSAGES_QUERY); } - Str_Concat (FilterFromToSubquery,"%'",Msg_MAX_BYTES_MESSAGES_QUERY); + Str_Concat (FilterFromToSubquery,"%'",Msg_DB_MAX_BYTES_MESSAGES_QUERY); } else FilterFromToSubquery[0] = '\0'; } +/*****************************************************************************/ +/******** Get number of received messages that haven't been read by me *******/ +/*****************************************************************************/ + +unsigned Msg_DB_GetNumUnreadMsgs (const struct Msg_Messages *Messages, + const char FilterFromToSubquery[Msg_DB_MAX_BYTES_MESSAGES_QUERY + 1]) + { + char *SubQuery; + unsigned NumMsgs; + + /***** Get number of unread messages from database *****/ + if (Messages->FilterCrsCod > 0) // If origin course selected + { + if (FilterFromToSubquery[0]) + { + if (asprintf (&SubQuery,"SELECT msg_rcv.MsgCod" + " FROM msg_rcv," + "msg_snt," + "usr_data" + " WHERE msg_rcv.UsrCod=%ld" + " AND msg_rcv.Open='N'" + " AND msg_rcv.MsgCod=msg_snt.MsgCod" + " AND msg_snt.CrsCod=%ld" + " AND msg_snt.UsrCod=usr_data.UsrCod%s", + Gbl.Usrs.Me.UsrDat.UsrCod, + Messages->FilterCrsCod, + FilterFromToSubquery) < 0) + Err_NotEnoughMemoryExit (); + } + else + { + if (asprintf (&SubQuery,"SELECT msg_rcv.MsgCod" + " FROM msg_rcv," + "msg_snt" + " WHERE msg_rcv.UsrCod=%ld" + " AND msg_rcv.Open='N'" + " AND msg_rcv.MsgCod=msg_snt.MsgCod" + " AND msg_snt.CrsCod=%ld", + Gbl.Usrs.Me.UsrDat.UsrCod, + Messages->FilterCrsCod) < 0) + Err_NotEnoughMemoryExit (); + } + } + else // If no origin course selected + { + if (FilterFromToSubquery[0]) + { + if (asprintf (&SubQuery,"SELECT msg_rcv.MsgCod" + " FROM msg_rcv," + "msg_snt," + "usr_data" + " WHERE msg_rcv.UsrCod=%ld" + " AND msg_rcv.Open='N'" + " AND msg_rcv.MsgCod=msg_snt.MsgCod" + " AND msg_snt.UsrCod=usr_data.UsrCod%s", + Gbl.Usrs.Me.UsrDat.UsrCod, + FilterFromToSubquery) < 0) + Err_NotEnoughMemoryExit (); + } + else + { + if (asprintf (&SubQuery,"SELECT MsgCod" + " FROM msg_rcv" + " WHERE UsrCod=%ld" + " AND Open='N'", + Gbl.Usrs.Me.UsrDat.UsrCod) < 0) + Err_NotEnoughMemoryExit (); + } + } + + if (Messages->FilterContent[0]) + NumMsgs = (unsigned) + DB_QueryCOUNT ("can not get number of unread messages", + "SELECT COUNT(*)" + " FROM msg_content" + " WHERE MsgCod IN (%s)" + " AND MATCH (Subject,Content) AGAINST ('%s')", + SubQuery, + Messages->FilterContent); + else + NumMsgs = (unsigned) + DB_QueryCOUNT ("can not get number of unread messages", + "SELECT COUNT(*)" + " FROM (%s) AS T", + SubQuery); + + free (SubQuery); + + return NumMsgs; + } + /*****************************************************************************/ /********* Generate a query to select messages received or sent **************/ /*****************************************************************************/ @@ -356,7 +425,7 @@ void Msg_DB_MakeFilterFromToSubquery (const struct Msg_Messages *Messages, unsigned Msg_DB_GetSntOrRcvMsgs (MYSQL_RES **mysql_res, const struct Msg_Messages *Messages, long UsrCod, - const char *FilterFromToSubquery) + const char FilterFromToSubquery[Msg_DB_MAX_BYTES_MESSAGES_QUERY + 1]) { char *SubQuery; const char *StrUnreadMsg; @@ -1251,6 +1320,35 @@ void Msg_DB_RemoveAllRecAndSntMsgsUsr (long UsrCod) UsrCod); } +/*****************************************************************************/ +/*************** Delete the subject and content of a message *****************/ +/*****************************************************************************/ + +void Msg_DB_MoveMsgContentToDeleted (long MsgCod) + { + /***** Move message from msg_content to msg_content_deleted *****/ + /* Insert message content into msg_content_deleted */ + DB_QueryINSERT ("can not remove the content of a message", + "INSERT IGNORE INTO msg_content_deleted" + " (MsgCod,Subject,Content,MedCod)" + " SELECT MsgCod," + "Subject," + "Content," + "MedCod" + " FROM msg_content" + " WHERE MsgCod=%ld", + MsgCod); + + /* TODO: Messages in msg_content_deleted older than a certain time + should be deleted to ensure the protection of personal data */ + + /* Delete message from msg_content *****/ + DB_QueryDELETE ("can not remove the content of a message", + "DELETE FROM msg_content" + " WHERE MsgCod=%ld", + MsgCod); + } + /*****************************************************************************/ /***** Delete the subject and content of all completely deleted messages *****/ /*****************************************************************************/ diff --git a/swad_message_database.h b/swad_message_database.h index 6b5a6dc5..89fb0d6e 100644 --- a/swad_message_database.h +++ b/swad_message_database.h @@ -29,16 +29,13 @@ #include // To access MySQL databases -// #include "swad_course.h" #include "swad_hierarchy_level.h" -// #include "swad_notification.h" -// #include "swad_statistic.h" /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Msg_MAX_BYTES_MESSAGES_QUERY (4 * 1024 - 1) +#define Msg_DB_MAX_BYTES_MESSAGES_QUERY (4 * 1024 - 1) /*****************************************************************************/ /******************************** Public types *******************************/ @@ -63,11 +60,13 @@ void Msg_DB_MoveSntMsgToDeleted (long MsgCod); unsigned Msg_DB_GetDistinctCrssInMyRcvMsgs (MYSQL_RES **mysql_res); unsigned Msg_DB_GetDistinctCrssInMySntMsgs (MYSQL_RES **mysql_res); void Msg_DB_MakeFilterFromToSubquery (const struct Msg_Messages *Messages, - char FilterFromToSubquery[Msg_MAX_BYTES_MESSAGES_QUERY + 1]); + char FilterFromToSubquery[Msg_DB_MAX_BYTES_MESSAGES_QUERY + 1]); +unsigned Msg_DB_GetNumUnreadMsgs (const struct Msg_Messages *Messages, + const char FilterFromToSubquery[Msg_DB_MAX_BYTES_MESSAGES_QUERY + 1]); unsigned Msg_DB_GetSntOrRcvMsgs (MYSQL_RES **mysql_res, const struct Msg_Messages *Messages, long UsrCod, - const char *FilterFromToSubquery); + const char FilterFromToSubquery[Msg_DB_MAX_BYTES_MESSAGES_QUERY + 1]); unsigned Msg_DB_GetSubjectAndContent (MYSQL_RES **mysql_res,long MsgCod); void Msg_DB_GetMsgSubject (long MsgCod,char Subject[Cns_MAX_BYTES_SUBJECT + 1]); unsigned Msg_DB_GetMsgContent (MYSQL_RES **mysql_res,long MsgCod); @@ -87,6 +86,7 @@ unsigned Msg_DB_GetNumMsgsSentByUsr (long UsrCod); void Msg_DB_RemoveRcvMsg (long MsgCod,long UsrCod); void Msg_DB_RemoveSntMsg (long MsgCod); void Msg_DB_RemoveAllRecAndSntMsgsUsr (long UsrCod); +void Msg_DB_MoveMsgContentToDeleted (long MsgCod); void Msg_DB_MoveUnusedMsgsContentToDeleted (void); //--------------------------- Users banned ------------------------------------