swad-core/swad_forum.c

4772 lines
177 KiB
C
Raw Normal View History

2014-12-01 23:55:08 +01:00
// swad_forum.c: forums
/*
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.
2021-02-09 12:43:45 +01:00
Copyright (C) 1999-2021 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 ***********************************/
/*****************************************************************************/
2018-10-22 00:31:44 +02:00
#define _GNU_SOURCE // For asprintf
2014-12-01 23:55:08 +01:00
#include <malloc.h> // For malloc
#include <mysql/mysql.h> // To access MySQL databases
2019-12-29 12:39:00 +01:00
#include <stddef.h> // For NULL
2018-10-22 00:31:44 +02:00
#include <stdio.h> // For asprintf
2014-12-01 23:55:08 +01:00
#include <string.h>
#include <time.h> // For time_t
#include "swad_action.h"
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
2014-12-01 23:55:08 +01:00
#include "swad_config.h"
#include "swad_database.h"
2020-04-14 17:15:17 +02:00
#include "swad_figure.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2014-12-01 23:55:08 +01:00
#include "swad_forum.h"
#include "swad_global.h"
2021-02-11 23:27:48 +01:00
#include "swad_hierarchy.h"
2019-10-23 19:05:05 +02:00
#include "swad_HTML.h"
2014-12-01 23:55:08 +01:00
#include "swad_layout.h"
2015-01-17 20:06:25 +01:00
#include "swad_logo.h"
2020-04-14 17:15:17 +02:00
#include "swad_message.h"
2014-12-01 23:55:08 +01:00
#include "swad_notification.h"
2020-04-07 03:01:41 +02:00
#include "swad_pagination.h"
2014-12-01 23:55:08 +01:00
#include "swad_parameter.h"
2015-03-14 17:39:04 +01:00
#include "swad_profile.h"
2016-12-13 13:32:19 +01:00
#include "swad_role.h"
2019-03-12 21:25:55 +01:00
#include "swad_timeline.h"
#include "swad_timeline_database.h"
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
2019-11-21 11:39:30 +01:00
/************************ Public constants and types *************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
const Act_Action_t For_ActionsSeeFor[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActSeeForCrsUsr,
[For_FORUM_COURSE_TCHS] = ActSeeForCrsTch,
[For_FORUM_DEGREE_USRS] = ActSeeForDegUsr,
[For_FORUM_DEGREE_TCHS] = ActSeeForDegTch,
[For_FORUM_CENTER_USRS] = ActSeeForCtrUsr,
[For_FORUM_CENTER_TCHS] = ActSeeForCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActSeeForInsUsr,
[For_FORUM_INSTIT_TCHS] = ActSeeForInsTch,
[For_FORUM_GLOBAL_USRS] = ActSeeForGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActSeeForGenTch,
[For_FORUM__SWAD__USRS] = ActSeeForSWAUsr,
[For_FORUM__SWAD__TCHS] = ActSeeForSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
2014-12-01 23:55:08 +01:00
};
2019-11-21 11:39:30 +01:00
2014-12-01 23:55:08 +01:00
const Act_Action_t For_ActionsSeePstFor[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActSeePstForCrsUsr,
[For_FORUM_COURSE_TCHS] = ActSeePstForCrsTch,
[For_FORUM_DEGREE_USRS] = ActSeePstForDegUsr,
[For_FORUM_DEGREE_TCHS] = ActSeePstForDegTch,
[For_FORUM_CENTER_USRS] = ActSeePstForCtrUsr,
[For_FORUM_CENTER_TCHS] = ActSeePstForCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActSeePstForInsUsr,
[For_FORUM_INSTIT_TCHS] = ActSeePstForInsTch,
[For_FORUM_GLOBAL_USRS] = ActSeePstForGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActSeePstForGenTch,
[For_FORUM__SWAD__USRS] = ActSeePstForSWAUsr,
[For_FORUM__SWAD__TCHS] = ActSeePstForSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
2014-12-01 23:55:08 +01:00
};
2019-11-21 11:39:30 +01:00
2014-12-01 23:55:08 +01:00
const Act_Action_t For_ActionsRecThrFor[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActRcvThrForCrsUsr,
[For_FORUM_COURSE_TCHS] = ActRcvThrForCrsTch,
[For_FORUM_DEGREE_USRS] = ActRcvThrForDegUsr,
[For_FORUM_DEGREE_TCHS] = ActRcvThrForDegTch,
[For_FORUM_CENTER_USRS] = ActRcvThrForCtrUsr,
[For_FORUM_CENTER_TCHS] = ActRcvThrForCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActRcvThrForInsUsr,
[For_FORUM_INSTIT_TCHS] = ActRcvThrForInsTch,
[For_FORUM_GLOBAL_USRS] = ActRcvThrForGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActRcvThrForGenTch,
[For_FORUM__SWAD__USRS] = ActRcvThrForSWAUsr,
[For_FORUM__SWAD__TCHS] = ActRcvThrForSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
2014-12-01 23:55:08 +01:00
};
2019-11-21 11:39:30 +01:00
2014-12-01 23:55:08 +01:00
const Act_Action_t For_ActionsRecRepFor[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActRcvRepForCrsUsr,
[For_FORUM_COURSE_TCHS] = ActRcvRepForCrsTch,
[For_FORUM_DEGREE_USRS] = ActRcvRepForDegUsr,
[For_FORUM_DEGREE_TCHS] = ActRcvRepForDegTch,
[For_FORUM_CENTER_USRS] = ActRcvRepForCtrUsr,
[For_FORUM_CENTER_TCHS] = ActRcvRepForCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActRcvRepForInsUsr,
[For_FORUM_INSTIT_TCHS] = ActRcvRepForInsTch,
[For_FORUM_GLOBAL_USRS] = ActRcvRepForGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActRcvRepForGenTch,
[For_FORUM__SWAD__USRS] = ActRcvRepForSWAUsr,
[For_FORUM__SWAD__TCHS] = ActRcvRepForSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
2014-12-01 23:55:08 +01:00
};
2019-11-21 11:39:30 +01:00
2014-12-01 23:55:08 +01:00
const Act_Action_t For_ActionsReqDelThr[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActReqDelThrCrsUsr,
[For_FORUM_COURSE_TCHS] = ActReqDelThrCrsTch,
[For_FORUM_DEGREE_USRS] = ActReqDelThrDegUsr,
[For_FORUM_DEGREE_TCHS] = ActReqDelThrDegTch,
[For_FORUM_CENTER_USRS] = ActReqDelThrCtrUsr,
[For_FORUM_CENTER_TCHS] = ActReqDelThrCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActReqDelThrInsUsr,
[For_FORUM_INSTIT_TCHS] = ActReqDelThrInsTch,
[For_FORUM_GLOBAL_USRS] = ActReqDelThrGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActReqDelThrGenTch,
[For_FORUM__SWAD__USRS] = ActReqDelThrSWAUsr,
[For_FORUM__SWAD__TCHS] = ActReqDelThrSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
2014-12-01 23:55:08 +01:00
};
2019-11-21 11:39:30 +01:00
2014-12-01 23:55:08 +01:00
const Act_Action_t For_ActionsDelThrFor[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActDelThrForCrsUsr,
[For_FORUM_COURSE_TCHS] = ActDelThrForCrsTch,
[For_FORUM_DEGREE_USRS] = ActDelThrForDegUsr,
[For_FORUM_DEGREE_TCHS] = ActDelThrForDegTch,
[For_FORUM_CENTER_USRS] = ActDelThrForCtrUsr,
[For_FORUM_CENTER_TCHS] = ActDelThrForCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActDelThrForInsUsr,
[For_FORUM_INSTIT_TCHS] = ActDelThrForInsTch,
[For_FORUM_GLOBAL_USRS] = ActDelThrForGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActDelThrForGenTch,
[For_FORUM__SWAD__USRS] = ActDelThrForSWAUsr,
[For_FORUM__SWAD__TCHS] = ActDelThrForSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
2014-12-01 23:55:08 +01:00
};
2019-11-21 11:39:30 +01:00
2014-12-01 23:55:08 +01:00
const Act_Action_t For_ActionsCutThrFor[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActCutThrForCrsUsr,
[For_FORUM_COURSE_TCHS] = ActCutThrForCrsTch,
[For_FORUM_DEGREE_USRS] = ActCutThrForDegUsr,
[For_FORUM_DEGREE_TCHS] = ActCutThrForDegTch,
[For_FORUM_CENTER_USRS] = ActCutThrForCtrUsr,
[For_FORUM_CENTER_TCHS] = ActCutThrForCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActCutThrForInsUsr,
[For_FORUM_INSTIT_TCHS] = ActCutThrForInsTch,
[For_FORUM_GLOBAL_USRS] = ActCutThrForGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActCutThrForGenTch,
[For_FORUM__SWAD__USRS] = ActCutThrForSWAUsr,
[For_FORUM__SWAD__TCHS] = ActCutThrForSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
2014-12-01 23:55:08 +01:00
};
2019-11-21 11:39:30 +01:00
2014-12-01 23:55:08 +01:00
const Act_Action_t For_ActionsPasThrFor[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActPasThrForCrsUsr,
[For_FORUM_COURSE_TCHS] = ActPasThrForCrsTch,
[For_FORUM_DEGREE_USRS] = ActPasThrForDegUsr,
[For_FORUM_DEGREE_TCHS] = ActPasThrForDegTch,
[For_FORUM_CENTER_USRS] = ActPasThrForCtrUsr,
[For_FORUM_CENTER_TCHS] = ActPasThrForCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActPasThrForInsUsr,
[For_FORUM_INSTIT_TCHS] = ActPasThrForInsTch,
[For_FORUM_GLOBAL_USRS] = ActPasThrForGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActPasThrForGenTch,
[For_FORUM__SWAD__USRS] = ActPasThrForSWAUsr,
[For_FORUM__SWAD__TCHS] = ActPasThrForSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
2014-12-01 23:55:08 +01:00
};
2019-11-21 11:39:30 +01:00
2014-12-01 23:55:08 +01:00
const Act_Action_t For_ActionsDelPstFor[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActDelPstForCrsUsr,
[For_FORUM_COURSE_TCHS] = ActDelPstForCrsTch,
[For_FORUM_DEGREE_USRS] = ActDelPstForDegUsr,
[For_FORUM_DEGREE_TCHS] = ActDelPstForDegTch,
[For_FORUM_CENTER_USRS] = ActDelPstForCtrUsr,
[For_FORUM_CENTER_TCHS] = ActDelPstForCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActDelPstForInsUsr,
[For_FORUM_INSTIT_TCHS] = ActDelPstForInsTch,
[For_FORUM_GLOBAL_USRS] = ActDelPstForGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActDelPstForGenTch,
[For_FORUM__SWAD__USRS] = ActDelPstForSWAUsr,
[For_FORUM__SWAD__TCHS] = ActDelPstForSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
2014-12-01 23:55:08 +01:00
};
2019-11-21 11:39:30 +01:00
2014-12-01 23:55:08 +01:00
const Act_Action_t For_ActionsEnbPstFor[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActEnbPstForCrsUsr,
[For_FORUM_COURSE_TCHS] = ActEnbPstForCrsTch,
[For_FORUM_DEGREE_USRS] = ActEnbPstForDegUsr,
[For_FORUM_DEGREE_TCHS] = ActEnbPstForDegTch,
[For_FORUM_CENTER_USRS] = ActEnbPstForCtrUsr,
[For_FORUM_CENTER_TCHS] = ActEnbPstForCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActEnbPstForInsUsr,
[For_FORUM_INSTIT_TCHS] = ActEnbPstForInsTch,
[For_FORUM_GLOBAL_USRS] = ActEnbPstForGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActEnbPstForGenTch,
[For_FORUM__SWAD__USRS] = ActEnbPstForSWAUsr,
[For_FORUM__SWAD__TCHS] = ActEnbPstForSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
2014-12-01 23:55:08 +01:00
};
2019-11-21 11:39:30 +01:00
2014-12-01 23:55:08 +01:00
const Act_Action_t For_ActionsDisPstFor[For_NUM_TYPES_FORUM] =
{
2019-11-21 11:39:30 +01:00
[For_FORUM_COURSE_USRS] = ActDisPstForCrsUsr,
[For_FORUM_COURSE_TCHS] = ActDisPstForCrsTch,
[For_FORUM_DEGREE_USRS] = ActDisPstForDegUsr,
[For_FORUM_DEGREE_TCHS] = ActDisPstForDegTch,
[For_FORUM_CENTER_USRS] = ActDisPstForCtrUsr,
[For_FORUM_CENTER_TCHS] = ActDisPstForCtrTch,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = ActDisPstForInsUsr,
[For_FORUM_INSTIT_TCHS] = ActDisPstForInsTch,
[For_FORUM_GLOBAL_USRS] = ActDisPstForGenUsr,
[For_FORUM_GLOBAL_TCHS] = ActDisPstForGenTch,
[For_FORUM__SWAD__USRS] = ActDisPstForSWAUsr,
[For_FORUM__SWAD__TCHS] = ActDisPstForSWATch,
[For_FORUM_UNKNOWN ] = ActSeeFor,
};
/*****************************************************************************/
/*********************** Private constants and types *************************/
/*****************************************************************************/
#define For_FORUM_MAX_LEVELS 4
static const unsigned PermissionThreadDeletion[For_NUM_TYPES_FORUM] =
{
[For_FORUM_COURSE_USRS] = 0x3F0,
[For_FORUM_COURSE_TCHS] = 0x3F0,
[For_FORUM_DEGREE_USRS] = 0x3E0,
[For_FORUM_DEGREE_TCHS] = 0x3E0,
[For_FORUM_CENTER_USRS] = 0x3C0,
[For_FORUM_CENTER_TCHS] = 0x3C0,
2019-11-21 11:39:30 +01:00
[For_FORUM_INSTIT_USRS] = 0x380,
[For_FORUM_INSTIT_TCHS] = 0x380,
[For_FORUM_GLOBAL_USRS] = 0x300,
[For_FORUM_GLOBAL_TCHS] = 0x300,
[For_FORUM__SWAD__USRS] = 0x300,
[For_FORUM__SWAD__TCHS] = 0x300,
[For_FORUM_UNKNOWN ] = 0x000,
2014-12-01 23:55:08 +01:00
};
2017-04-11 14:27:45 +02:00
// Links to go to <section>
2017-05-25 13:43:54 +02:00
#define For_REMOVE_THREAD_SECTION_ID "remove_thread"
#define For_FORUM_THREADS_SECTION_ID "forum_threads"
#define For_NEW_THREAD_SECTION_ID "new_thread"
#define For_FORUM_POSTS_SECTION_ID "thread_posts"
#define For_NEW_POST_SECTION_ID "new_post"
2017-04-10 12:41:26 +02:00
2016-04-10 14:09:50 +02:00
// Forum images will be saved with:
// - maximum width of For_IMAGE_SAVED_MAX_HEIGHT
// - maximum height of For_IMAGE_SAVED_MAX_HEIGHT
// - maintaining the original aspect ratio (aspect ratio recommended: 3:2)
#define For_IMAGE_SAVED_MAX_WIDTH 768
2020-02-13 22:33:31 +01:00
#define For_IMAGE_SAVED_MAX_HEIGHT 768
#define For_IMAGE_SAVED_QUALITY 90 // 1 to 100
2016-04-10 14:09:50 +02:00
2020-04-07 03:01:41 +02:00
/*****************************************************************************/
/***************************** Private types ***************************/
/*****************************************************************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/***************************** Private prototypes ***************************/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static bool For_GetIfForumPstExists (long PstCod);
static bool For_GetIfPstIsEnabled (long PstCod);
static void For_DeletePstFromDisabledPstTable (long PstCod);
static void For_InsertPstIntoBannedPstTable (long PstCod);
static long For_InsertForumPst (long ThrCod,long UsrCod,
const char *Subject,const char *Content,
2021-02-11 00:58:53 +01:00
struct Med_Media *Media);
2019-03-18 15:42:22 +01:00
static bool For_RemoveForumPst (long PstCod,long MedCod);
2016-04-10 19:19:20 +02:00
static unsigned For_NumPstsInThrWithPstCod (long PstCod,long *ThrCod);
2020-04-07 03:01:41 +02:00
static long For_InsertForumThread (const struct For_Forums *Forums,
long FirstPstCod);
2016-04-10 19:19:20 +02:00
static void For_RemoveThreadOnly (long ThrCod);
static void For_RemoveThreadAndItsPsts (long ThrCod);
2017-01-17 03:10:43 +01:00
static void For_GetThrSubject (long ThrCod,char Subject[Cns_MAX_BYTES_SUBJECT + 1]);
2017-04-18 19:55:56 +02:00
2016-04-10 19:19:20 +02:00
static void For_UpdateThrFirstAndLastPst (long ThrCod,long FirstPstCod,long LastPstCod);
static void For_UpdateThrLastPst (long ThrCod,long LastPstCod);
static long For_GetLastPstCod (long ThrCod);
2017-04-19 12:34:38 +02:00
static void For_UpdateThrReadTime (long ThrCod,
time_t CreatTimeUTCOfTheMostRecentPostRead);
2015-10-24 20:12:03 +02:00
static unsigned For_GetNumOfReadersOfThr (long ThrCod);
static unsigned For_GetNumOfWritersInThr (long ThrCod);
static unsigned For_GetNumPstsInThr (long ThrCod);
static unsigned For_GetNumMyPstInThr (long ThrCod);
static time_t For_GetThrReadTime (long ThrCod);
2017-04-16 23:48:05 +02:00
static void For_DeleteThrFromReadThrs (long ThrCod);
2020-04-07 03:01:41 +02:00
static void For_ShowPostsOfAThread (struct For_Forums *Forums,
Ale_AlertType_t AlertType,const char *Message);
static void For_PutIconNewPost (void *Forums);
static void For_PutAllHiddenParamsNewPost (void *Forums);
2016-11-07 10:53:03 +01:00
2020-10-14 00:59:24 +02:00
static void For_ShowAForumPost (struct For_Forums *Forums,
unsigned PstNum,
2017-01-17 03:10:43 +01:00
bool LastPst,char LastSubject[Cns_MAX_BYTES_SUBJECT + 1],
2016-11-07 10:53:03 +01:00
bool NewPst,bool ICanModerateForum);
static void For_GetPstData (long PstCod,long *UsrCod,time_t *CreatTimeUTC,
char Subject[Cns_MAX_BYTES_SUBJECT + 1],
2017-01-17 03:10:43 +01:00
char Content[Cns_MAX_BYTES_LONG_TEXT + 1],
2021-02-11 00:58:53 +01:00
struct Med_Media *Media);
2020-04-07 03:01:41 +02:00
static void For_WriteNumberOfPosts (const struct For_Forums *Forums,long UsrCod);
2016-11-07 10:53:03 +01:00
2020-10-14 00:59:24 +02:00
static void For_PutParamsForum (void *Forums);
2017-04-18 01:25:44 +02:00
static void For_PutParamForumSet (For_ForumSet_t ForumSet);
static void For_PutParamForumLocation (long Location);
static void For_PutHiddenParamThrCod (long ThrCod);
static void For_PutHiddenParamPstCod (long PstCod);
2017-04-17 12:19:58 +02:00
2020-04-07 03:01:41 +02:00
static void For_ShowForumList (struct For_Forums *Forums);
2020-04-08 03:41:05 +02:00
static void For_PutIconsForums (__attribute__((unused)) void *Args);
2020-04-07 03:01:41 +02:00
static void For_PutFormWhichForums (const struct For_Forums *Forums);
2017-04-16 13:45:11 +02:00
2020-04-07 03:01:41 +02:00
static void For_WriteLinksToGblForums (const struct For_Forums *Forums,
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS]);
static void For_WriteLinksToPlatformForums (const struct For_Forums *Forums,
bool IsLastForum,
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS]);
2020-04-07 03:01:41 +02:00
static long For_WriteLinksToInsForums (const struct For_Forums *Forums,
long InsCod,bool IsLastIns,
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS]);
2020-04-07 03:01:41 +02:00
static long For_WriteLinksToCtrForums (const struct For_Forums *Forums,
long CtrCod,bool IsLastCtr,
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS]);
2020-04-07 03:01:41 +02:00
static long For_WriteLinksToDegForums (const struct For_Forums *Forums,
long DegCod,bool IsLastDeg,
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS]);
2020-04-07 03:01:41 +02:00
static long For_WriteLinksToCrsForums (const struct For_Forums *Forums,
long CrsCod,bool IsLastCrs,
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS]);
2020-04-07 03:01:41 +02:00
static void For_WriteLinkToForum (const struct For_Forums *Forums,
const struct For_Forum *Forum,
2019-11-18 17:59:02 +01:00
bool Highlight,
2017-04-19 12:34:38 +02:00
unsigned Level,
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS]);
static unsigned For_GetNumThrsWithNewPstsInForum (const struct For_Forum *Forum,
2017-04-16 23:48:05 +02:00
unsigned NumThreads);
static unsigned For_GetNumOfThreadsInForumNewerThan (const struct For_Forum *Forum,
2017-04-16 23:48:05 +02:00
const char *Time);
2014-12-01 23:55:08 +01:00
static unsigned For_GetNumOfUnreadPostsInThr (long ThrCod,unsigned NumPostsInThr);
static unsigned For_GetNumOfPostsInThrNewerThan (long ThrCod,const char *Time);
2015-04-11 14:00:23 +02:00
2019-11-18 17:59:02 +01:00
static void For_WriteNumberOfThrs (unsigned NumThrs);
2020-04-07 03:01:41 +02:00
static void For_ShowForumThreadsHighlightingOneThread (struct For_Forums *Forums,
2017-05-11 23:45:46 +02:00
Ale_AlertType_t AlertType,const char *Message);
2020-04-07 03:01:41 +02:00
static void For_PutIconNewThread (void *Forums);
static void For_PutAllHiddenParamsNewThread (void *Forums);
static unsigned For_GetNumThrsInForum (const struct For_Forum *Forum);
2020-04-10 19:14:08 +02:00
static void For_ListForumThrs (struct For_Forums *Forums,
2020-04-07 03:01:41 +02:00
long ThrCods[Pag_ITEMS_PER_PAGE],
2017-04-14 01:02:33 +02:00
long ThrCodHighlighted,
2017-04-13 23:53:57 +02:00
struct Pagination *PaginationThrs);
2020-04-10 19:14:08 +02:00
static void For_GetThreadData (struct For_Thread *Thr);
2017-04-12 20:56:45 +02:00
2020-04-07 03:01:41 +02:00
static void For_GetParamsForums (struct For_Forums *Forums);
static void For_SetForumType (struct For_Forums *Forums);
static void For_RestrictAccess (const struct For_Forums *Forums);
2014-12-01 23:55:08 +01:00
2020-04-09 21:36:21 +02:00
static void For_WriteFormForumPst (struct For_Forums *Forums,
2020-04-07 03:01:41 +02:00
bool IsReply,const char *Subject);
2017-04-17 12:19:58 +02:00
static void For_UpdateNumUsrsNotifiedByEMailAboutPost (long PstCod,unsigned NumUsrsToBeNotifiedByEMail);
2020-04-07 03:01:41 +02:00
static void For_PutAllHiddenParamsRemThread (void *Forums);
2017-04-28 10:35:41 +02:00
2017-04-18 13:17:40 +02:00
static bool For_CheckIfICanMoveThreads (void);
2017-04-17 12:19:58 +02:00
static long For_GetThrInMyClipboard (void);
static bool For_CheckIfThrBelongsToForum (long ThrCod,const struct For_Forum *Forum);
2020-04-07 03:01:41 +02:00
static void For_MoveThrToCurrentForum (const struct For_Forums *Forums);
2017-04-17 12:19:58 +02:00
static void For_InsertThrInClipboard (long ThrCod);
static void For_RemoveExpiredThrsClipboards (void);
static void For_RemoveThrCodFromThrClipboard (long ThrCod);
2020-04-07 03:01:41 +02:00
/*****************************************************************************/
/********************************** Reset forum ******************************/
/*****************************************************************************/
void For_ResetForums (struct For_Forums *Forums)
{
2020-04-14 00:11:28 +02:00
Forums->ForumSet = For_DEFAULT_FORUM_SET;
Forums->ThreadsOrder = For_DEFAULT_ORDER;
Forums->CurrentPageThrs = 0;
Forums->CurrentPagePsts = 0;
2020-04-10 21:57:50 +02:00
2020-04-14 00:11:28 +02:00
Forums->Forum.Type = For_FORUM_UNKNOWN;
Forums->Forum.Location = -1L;
2020-04-10 19:14:08 +02:00
2020-11-11 01:14:53 +01:00
Forums->Thread.Selected =
Forums->Thread.Current =
Forums->Thread.ToMove = -1L;
2020-04-10 19:14:08 +02:00
2020-04-14 00:11:28 +02:00
Forums->PstCod = -1L;
2020-04-07 03:01:41 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/****************************** Enable a forum post **************************/
/*****************************************************************************/
2017-04-18 16:44:44 +02:00
void For_EnablePost (void)
2014-12-01 23:55:08 +01:00
{
2019-03-06 10:13:39 +01:00
extern const char *Txt_FORUM_Post_unbanned;
2020-04-07 03:01:41 +02:00
struct For_Forums Forums;
/***** Reset forum *****/
For_ResetForums (&Forums);
2014-12-01 23:55:08 +01:00
2017-04-16 13:45:11 +02:00
/***** Get parameters related to forum *****/
2020-04-07 03:01:41 +02:00
For_GetParamsForums (&Forums);
2014-12-01 23:55:08 +01:00
/***** Delete post from table of disabled posts *****/
2020-04-14 00:11:28 +02:00
For_DeletePstFromDisabledPstTable (Forums.PstCod);
2014-12-01 23:55:08 +01:00
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
/***** Show threads again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,NULL);
2017-04-18 13:17:40 +02:00
2014-12-01 23:55:08 +01:00
/***** Show the posts again *****/
2020-04-07 03:01:41 +02:00
For_ShowPostsOfAThread (&Forums,Ale_SUCCESS,Txt_FORUM_Post_unbanned);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************************** Disable a forum post **************************/
/*****************************************************************************/
2017-04-18 16:44:44 +02:00
void For_DisablePost (void)
2014-12-01 23:55:08 +01:00
{
2019-03-06 10:13:39 +01:00
extern const char *Txt_FORUM_Post_banned;
2020-04-07 03:01:41 +02:00
struct For_Forums Forums;
2014-12-01 23:55:08 +01:00
2020-04-07 03:01:41 +02:00
/***** Get parameters related to forums *****/
For_GetParamsForums (&Forums);
2014-12-01 23:55:08 +01:00
/***** Check if post really exists, if it has not been removed *****/
2020-04-14 00:11:28 +02:00
if (For_GetIfForumPstExists (Forums.PstCod))
2014-12-01 23:55:08 +01:00
{
/***** Insert post into table of banned posts *****/
2020-04-14 00:11:28 +02:00
For_InsertPstIntoBannedPstTable (Forums.PstCod);
2017-04-18 09:55:25 +02:00
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
/***** Show threads again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,NULL);
2017-04-18 13:17:40 +02:00
2017-04-18 09:55:25 +02:00
/***** Show the posts again *****/
2020-04-07 03:01:41 +02:00
For_ShowPostsOfAThread (&Forums,Ale_SUCCESS,Txt_FORUM_Post_banned);
2014-12-01 23:55:08 +01:00
}
else
Lay_WrongPostExit ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/******************** Get if a forum post exists in database *****************/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static bool For_GetIfForumPstExists (long PstCod)
2014-12-01 23:55:08 +01:00
{
/***** Get if a forum post exists from database *****/
2018-11-03 15:33:20 +01:00
return (DB_QueryCOUNT ("can not check if a post of a forum already existed",
"SELECT COUNT(*)"
" FROM for_posts"
" WHERE PstCod=%ld",
2018-11-03 15:33:20 +01:00
PstCod) != 0); // Post exists if it appears in table of forum posts
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*********************** Get if a forum post is enabled **********************/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static bool For_GetIfPstIsEnabled (long PstCod)
2014-12-01 23:55:08 +01:00
{
2016-12-30 01:20:49 +01:00
if (PstCod > 0)
/***** Get if post is disabled from database *****/
2018-11-03 15:33:20 +01:00
return (DB_QueryCOUNT ("can not check if a post of a forum is disabled",
"SELECT COUNT(*)"
" FROM for_disabled"
2018-11-03 15:33:20 +01:00
" WHERE PstCod=%ld",
PstCod) == 0); // Post is enabled if it does not appear in table of disabled posts
2016-12-30 01:20:49 +01:00
else
return false;
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****************** Delete post from table of disabled posts *****************/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static void For_DeletePstFromDisabledPstTable (long PstCod)
2014-12-01 23:55:08 +01:00
{
/***** Remove post from disabled posts table *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not unban a post of a forum",
"DELETE FROM for_disabled"
" WHERE PstCod=%ld",
2018-11-02 22:00:31 +01:00
PstCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/****************** Insert post into table of banned posts *******************/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static void For_InsertPstIntoBannedPstTable (long PstCod)
2014-12-01 23:55:08 +01:00
{
/***** Remove post from banned posts table *****/
2018-11-02 16:39:35 +01:00
DB_QueryREPLACE ("can not ban a post of a forum",
"REPLACE INTO for_disabled"
2018-11-02 16:39:35 +01:00
" (PstCod,UsrCod,DisableTime)"
" VALUES"
" (%ld,%ld,NOW())",
PstCod,
Gbl.Usrs.Me.UsrDat.UsrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************** Insert a post new in the table of posts of forums ************/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static long For_InsertForumPst (long ThrCod,long UsrCod,
const char *Subject,const char *Content,
2021-02-11 00:58:53 +01:00
struct Med_Media *Media)
2014-12-01 23:55:08 +01:00
{
2016-04-10 19:19:20 +02:00
long PstCod;
2019-03-19 11:20:29 +01:00
/***** Store media in filesystem and database *****/
Med_RemoveKeepOrStoreMedia (-1L,Media);
2019-03-18 15:42:22 +01:00
2014-12-01 23:55:08 +01:00
/***** Insert forum post in the database *****/
2018-11-03 01:45:36 +01:00
PstCod =
DB_QueryINSERTandReturnCode ("can not create a new post in a forum",
"INSERT INTO for_posts"
2018-11-03 01:45:36 +01:00
" (ThrCod,UsrCod,CreatTime,ModifTime,NumNotif,"
"Subject,Content,MedCod)"
2018-11-03 01:45:36 +01:00
" VALUES"
" (%ld,%ld,NOW(),NOW(),0,"
"'%s','%s',%ld)",
ThrCod,
UsrCod,
Subject,
Content,Media->MedCod);
2016-04-10 19:19:20 +02:00
return PstCod;
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************** Delete a post from the forum post table *******************/
/*****************************************************************************/
// Return true if the post thread is deleted
2019-03-18 15:42:22 +01:00
static bool For_RemoveForumPst (long PstCod,long MedCod)
2014-12-01 23:55:08 +01:00
{
long ThrCod;
bool ThreadDeleted = false;
2019-03-02 21:49:11 +01:00
/***** Remove media file attached to forum post *****/
2019-03-18 15:42:22 +01:00
Med_RemoveMedia (MedCod);
2016-04-10 23:59:45 +02:00
2014-12-01 23:55:08 +01:00
/***** If the post is the only one in its thread, delete that thread *****/
if (For_NumPstsInThrWithPstCod (PstCod,&ThrCod) < 2)
{
For_RemoveThreadOnly (ThrCod);
ThreadDeleted = true;
}
/***** Delete post from forum post table *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove a post from a forum",
"DELETE FROM for_posts"
" WHERE PstCod=%ld",
2018-11-02 22:00:31 +01:00
PstCod);
2014-12-01 23:55:08 +01:00
/***** Delete the post from the table of disabled forum posts *****/
For_DeletePstFromDisabledPstTable (PstCod);
/***** Update the last post of the thread *****/
if (!ThreadDeleted)
For_UpdateThrLastPst (ThrCod,For_GetLastPstCod (ThrCod));
return ThreadDeleted;
}
/*****************************************************************************/
/*********** Get the number of posts in the thread than holds a post *********/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static unsigned For_NumPstsInThrWithPstCod (long PstCod,long *ThrCod)
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumPsts;
/***** Initialize default values *****/
*ThrCod = -1L;
NumPsts = 0;
/***** Trivial check: PstCod should be > 0 *****/
if (PstCod <= 0)
return NumPsts;
2014-12-01 23:55:08 +01:00
/***** Get number of posts in the thread that holds a post from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get number of posts in a thread",
"SELECT COUNT(PstCod)," // row[0]
"ThrCod" // row[1]
" FROM for_posts"
" WHERE ThrCod IN"
" (SELECT ThrCod"
" FROM for_posts"
" WHERE PstCod=%ld)"
" GROUP BY ThrCod;",
PstCod) == 1) // Result should have one row
{
row = mysql_fetch_row (mysql_res);
if (sscanf (row[0],"%u",&NumPsts) != 1)
Lay_ShowErrorAndExit ("Error when getting number of posts in a thread.");
if (sscanf (row[1],"%ld",ThrCod) != 1)
Lay_ShowErrorAndExit ("Error when getting number of posts in a thread.");
}
2014-12-01 23:55:08 +01:00
DB_FreeMySQLResult (&mysql_res);
return NumPsts;
}
/*****************************************************************************/
/*************** Insert a new thread in table of forum threads ***************/
/*****************************************************************************/
// Returns the code of the new inserted thread
2020-04-07 03:01:41 +02:00
static long For_InsertForumThread (const struct For_Forums *Forums,
long FirstPstCod)
2014-12-01 23:55:08 +01:00
{
/***** Insert new thread in the database *****/
2018-11-03 01:45:36 +01:00
return
DB_QueryINSERTandReturnCode ("can not create a new thread in a forum",
"INSERT INTO for_threads"
2018-11-03 01:45:36 +01:00
" (ForumType,Location,FirstPstCod,LastPstCod)"
" VALUES"
" (%u,%ld,%ld,%ld)",
2020-04-10 19:14:08 +02:00
(unsigned) Forums->Forum.Type,
Forums->Forum.Location,
FirstPstCod,
FirstPstCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************** Delete a thread from the forum thread table *****************/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static void For_RemoveThreadOnly (long ThrCod)
2014-12-01 23:55:08 +01:00
{
/***** Indicate that this thread has not been read by anyone *****/
For_DeleteThrFromReadThrs (ThrCod);
/***** Remove thread code from thread clipboard *****/
For_RemoveThrCodFromThrClipboard (ThrCod);
/***** Delete thread from forum thread table *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove a thread from a forum",
"DELETE FROM for_threads"
" WHERE ThrCod=%ld",
2018-11-02 22:00:31 +01:00
ThrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************** Delete a thread from the forum thread table *****************/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static void For_RemoveThreadAndItsPsts (long ThrCod)
2014-12-01 23:55:08 +01:00
{
/***** Delete banned posts in thread *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not unban the posts of a thread of a forum",
"DELETE FROM for_disabled"
"USING for_posts,"
"for_disabled"
" WHERE for_posts.ThrCod=%ld"
" AND for_posts.PstCod=for_disabled.PstCod",
2018-11-02 22:00:31 +01:00
ThrCod);
2014-12-01 23:55:08 +01:00
/***** Delete thread posts *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove the posts of a thread of a forum",
"DELETE FROM for_posts"
" WHERE ThrCod=%ld",
2018-11-02 22:00:31 +01:00
ThrCod);
2014-12-01 23:55:08 +01:00
/***** Delete thread from forum thread table *****/
For_RemoveThreadOnly (ThrCod);
}
/*****************************************************************************/
/********************* Get the thread subject from a thread ******************/
/*****************************************************************************/
2017-01-17 03:10:43 +01:00
static void For_GetThrSubject (long ThrCod,char Subject[Cns_MAX_BYTES_SUBJECT + 1])
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
/***** Get subject of a thread from database *****/
DB_QuerySELECT (&mysql_res,"can not get the subject of a thread of a forum",
"SELECT for_posts.Subject" // row[0]
" FROM for_threads,"
"for_posts"
" WHERE for_threads.ThrCod=%ld"
" AND for_threads.FirstPstCod=for_posts.PstCod",
2018-10-31 09:40:43 +01:00
ThrCod);
2014-12-01 23:55:08 +01:00
/***** Write the subject of the thread *****/
row = mysql_fetch_row (mysql_res);
Str_Copy (Subject,row[0],Cns_MAX_BYTES_SUBJECT);
2014-12-01 23:55:08 +01:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
2017-04-17 11:57:55 +02:00
/*************** Get the forum type and location of a post *******************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
void For_GetForumTypeAndLocationOfAPost (long PstCod,struct For_Forum *Forum)
2014-12-01 23:55:08 +01:00
{
2017-04-18 19:55:56 +02:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned UnsignedNum;
long LongNum;
/***** Set default forum type and location *****/
2017-04-19 12:34:38 +02:00
Forum->Type = For_FORUM_UNKNOWN;
Forum->Location = -1L;
2014-12-01 23:55:08 +01:00
/***** Check if there is a row with forum type *****/
2018-10-31 09:40:43 +01:00
if (DB_QuerySELECT (&mysql_res,"can not get forum type and location",
"SELECT for_threads.ForumType," // row[0]
"for_threads.Location" // row[1]
" FROM for_posts,"
"for_threads"
" WHERE for_posts.PstCod=%ld"
" AND for_posts.ThrCod=for_threads.ThrCod",
2018-10-31 09:40:43 +01:00
PstCod))
2014-12-01 23:55:08 +01:00
{
row = mysql_fetch_row (mysql_res);
2017-04-16 23:48:05 +02:00
/* Get forum type (row[0]) */
2017-04-18 19:55:56 +02:00
if (sscanf (row[0],"%u",&UnsignedNum) == 1)
if (UnsignedNum < For_NUM_TYPES_FORUM)
2017-04-19 12:34:38 +02:00
Forum->Type = (For_ForumType_t) UnsignedNum;
2017-04-16 23:48:05 +02:00
/* Get forum location (row[1]) */
2017-04-18 19:55:56 +02:00
if (sscanf (row[1],"%ld",&LongNum) == 1)
2017-04-19 12:34:38 +02:00
Forum->Location = LongNum;
2014-12-01 23:55:08 +01:00
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
/********* Modify the codes of the first and last posts of a thread **********/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static void For_UpdateThrFirstAndLastPst (long ThrCod,long FirstPstCod,long LastPstCod)
2014-12-01 23:55:08 +01:00
{
/***** Update the code of the first and last posts of a thread *****/
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not update a thread of a forum",
"UPDATE for_threads"
" SET FirstPstCod=%ld,"
"LastPstCod=%ld"
2018-11-03 12:16:40 +01:00
" WHERE ThrCod=%ld",
FirstPstCod,
LastPstCod,
ThrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************** Modify the code of the last post of a thread *****************/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static void For_UpdateThrLastPst (long ThrCod,long LastPstCod)
2014-12-01 23:55:08 +01:00
{
/***** Update the code of the last post of a thread *****/
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not update a thread of a forum",
"UPDATE for_threads"
" SET LastPstCod=%ld"
2018-11-03 12:16:40 +01:00
" WHERE ThrCod=%ld",
LastPstCod,
ThrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************** Get the code of the last post of a thread ******************/
/*****************************************************************************/
2016-04-10 19:19:20 +02:00
static long For_GetLastPstCod (long ThrCod)
2014-12-01 23:55:08 +01:00
{
long LastPstCod;
/***** Get the code of the last post of a thread from database *****/
LastPstCod = DB_QuerySELECTCode ("can not get the most recent post"
" of a thread of a forum",
"SELECT PstCod"
" FROM for_posts"
" WHERE ThrCod=%ld"
" ORDER BY CreatTime DESC"
" LIMIT 1",
ThrCod);
if (LastPstCod <= 0)
2014-12-01 23:55:08 +01:00
Lay_ShowErrorAndExit ("Error when getting the most recent post of a thread of a forum.");
return LastPstCod;
}
/*****************************************************************************/
/************* Update read date of a thread for the current user *************/
/*****************************************************************************/
// Update for_read table indicating that this thread page and previous ones
2014-12-01 23:55:08 +01:00
// have been read and have no new posts for the current user
// (even if any previous pages have been no read actually)
2017-04-19 12:34:38 +02:00
// Note that database is not updated with the current time,
// but with the creation time of the most recent post in this thread read by me.
2014-12-01 23:55:08 +01:00
2017-04-19 12:34:38 +02:00
static void For_UpdateThrReadTime (long ThrCod,
time_t CreatTimeUTCOfTheMostRecentPostRead)
2014-12-01 23:55:08 +01:00
{
/***** Insert or replace pair ThrCod-UsrCod in for_read *****/
2018-11-02 16:39:35 +01:00
DB_QueryREPLACE ("can not update the status of reading"
" of a thread of a forum",
"REPLACE INTO for_read"
2018-11-02 16:39:35 +01:00
" (ThrCod,UsrCod,ReadTime)"
" VALUES"
" (%ld,%ld,FROM_UNIXTIME(%ld))",
ThrCod,
Gbl.Usrs.Me.UsrDat.UsrCod,
2018-11-02 16:39:35 +01:00
(long) CreatTimeUTCOfTheMostRecentPostRead);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************** Get number of users that have read a thread ****************/
/*****************************************************************************/
2015-10-24 20:12:03 +02:00
static unsigned For_GetNumOfReadersOfThr (long ThrCod)
2014-12-01 23:55:08 +01:00
{
/***** Get number of distinct readers of a thread from database *****/
return (unsigned)
DB_QueryCOUNT ("can not get the number of readers of a thread of a forum",
"SELECT COUNT(*)"
" FROM for_read"
" WHERE ThrCod=%ld",
ThrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********** Get number of users that have write posts in a thread ************/
/*****************************************************************************/
2015-10-24 20:12:03 +02:00
static unsigned For_GetNumOfWritersInThr (long ThrCod)
2014-12-01 23:55:08 +01:00
{
/***** Get number of distinct writers in a thread from database *****/
return DB_QueryCOUNT ("can not get the number of writers in a thread of a forum",
"SELECT COUNT(DISTINCT UsrCod)"
" FROM for_posts"
" WHERE ThrCod=%ld",
ThrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************** Get number of posts in a thread **********************/
/*****************************************************************************/
2015-10-24 20:12:03 +02:00
static unsigned For_GetNumPstsInThr (long ThrCod)
2014-12-01 23:55:08 +01:00
{
/***** Get number of posts in a thread from database *****/
return (unsigned)
DB_QueryCOUNT ("can not get the number of posts in a thread of a forum",
"SELECT COUNT(*)"
" FROM for_posts"
" WHERE ThrCod=%ld",
ThrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************** Get whether there are posts of mine in a thread **************/
/*****************************************************************************/
2015-10-24 20:12:03 +02:00
static unsigned For_GetNumMyPstInThr (long ThrCod)
2014-12-01 23:55:08 +01:00
{
/***** Get if I have write posts in a thread from database *****/
return (unsigned)
DB_QueryCOUNT ("can not check if you have written posts in a thead of a forum",
"SELECT COUNT(*)"
" FROM for_posts"
" WHERE ThrCod=%ld"
" AND UsrCod=%ld",
ThrCod,
Gbl.Usrs.Me.UsrDat.UsrCod);
2014-12-01 23:55:08 +01:00
}
2015-03-09 18:27:24 +01:00
/*****************************************************************************/
/*********************** Get number of posts from a user *********************/
/*****************************************************************************/
unsigned For_GetNumPostsUsr (long UsrCod)
2015-03-09 18:27:24 +01:00
{
/***** Get number of posts from a user from database *****/
2019-03-06 13:14:40 +01:00
return DB_QueryCOUNT ("can not get number of forum posts from a user",
"SELECT COUNT(*)"
" FROM for_posts"
2018-11-04 20:51:38 +01:00
" WHERE UsrCod=%ld",
2018-11-03 15:33:20 +01:00
UsrCod);
2015-03-09 18:27:24 +01:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/****************** Get thread read time for the current user ****************/
/*****************************************************************************/
2015-10-24 20:12:03 +02:00
static time_t For_GetThrReadTime (long ThrCod)
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2015-10-24 20:12:03 +02:00
time_t ReadTimeUTC;
2014-12-01 23:55:08 +01:00
/***** Get read time of a thread from database *****/
2018-10-31 09:40:43 +01:00
if (DB_QuerySELECT (&mysql_res,"can not get date of reading"
" of a thread of a forum",
"SELECT UNIX_TIMESTAMP(ReadTime)" // row[0]
" FROM for_read"
" WHERE ThrCod=%ld"
" AND UsrCod=%ld",
2018-10-31 09:40:43 +01:00
ThrCod,Gbl.Usrs.Me.UsrDat.UsrCod))
2014-12-01 23:55:08 +01:00
{
2015-10-24 20:12:03 +02:00
/***** There is a row ==> get read time *****/
2014-12-01 23:55:08 +01:00
row = mysql_fetch_row (mysql_res);
2015-10-24 20:12:03 +02:00
ReadTimeUTC = Dat_GetUNIXTimeFromStr (row[0]);
2014-12-01 23:55:08 +01:00
}
else
2015-10-24 20:12:03 +02:00
ReadTimeUTC = (time_t) 0; // If there is no row for this thread and current user, then current user has not read this thread
2014-12-01 23:55:08 +01:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
2015-10-24 20:12:03 +02:00
return ReadTimeUTC;
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************* Delete thread read status for a thread ****************/
/*****************************************************************************/
2017-04-16 23:48:05 +02:00
static void For_DeleteThrFromReadThrs (long ThrCod)
2014-12-01 23:55:08 +01:00
{
/***** Delete pairs ThrCod-UsrCod in for_read for a thread *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove the status of reading"
" of a thread of a forum",
"DELETE FROM for_read"
" WHERE ThrCod=%ld",
2018-11-02 22:00:31 +01:00
ThrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************** Delete thread read status for an user ****************/
/*****************************************************************************/
void For_RemoveUsrFromReadThrs (long UsrCod)
{
/***** Delete pairs ThrCod-UsrCod in for_read for a user *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove the status of reading by a user"
" of all the threads of a forum",
"DELETE FROM for_read"
" WHERE UsrCod=%ld",
2018-11-02 22:00:31 +01:00
UsrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2017-04-13 20:09:22 +02:00
/************************ Show posts in a thread *****************************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_ShowPostsOfAThread (struct For_Forums *Forums,
Ale_AlertType_t AlertType,const char *Message)
2014-12-01 23:55:08 +01:00
{
2020-09-26 17:20:01 +02:00
extern const char *Hlp_COMMUNICATION_Forums_posts;
2015-04-11 14:00:23 +02:00
extern const char *Txt_Thread;
2020-04-14 00:11:28 +02:00
struct For_Thread Thread;
2017-04-11 19:05:15 +02:00
char LastSubject[Cns_MAX_BYTES_SUBJECT + 1];
char FrameTitle[128 + Cns_MAX_BYTES_SUBJECT];
2014-12-01 23:55:08 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumRow;
2014-12-01 23:55:08 +01:00
unsigned NumPst = 0; // Initialized to avoid warning
unsigned NumPsts;
2015-10-24 20:12:03 +02:00
time_t ReadTimeUTC; // Read time of thread for the current user
time_t CreatTimeUTC; // Creation time of post
2017-04-13 20:09:22 +02:00
struct Pagination PaginationPsts;
2014-12-01 23:55:08 +01:00
bool NewPst = false;
bool ICanModerateForum = false;
2017-04-16 13:45:11 +02:00
2014-12-01 23:55:08 +01:00
/***** Get data of the thread *****/
2020-11-11 01:14:53 +01:00
Thread.ThrCod =
Forums->Thread.Current =
Forums->Thread.Selected;
2020-04-14 00:11:28 +02:00
For_GetThreadData (&Thread);
2014-12-01 23:55:08 +01:00
2017-04-18 13:17:40 +02:00
/***** Get if there is a thread ready to be moved *****/
if (For_CheckIfICanMoveThreads ())
2020-11-11 01:14:53 +01:00
Forums->Thread.ToMove = For_GetThrInMyClipboard ();
2014-12-01 23:55:08 +01:00
2017-04-18 13:17:40 +02:00
/***** Get thread read time for the current user *****/
2020-04-14 00:11:28 +02:00
ReadTimeUTC = For_GetThrReadTime (Thread.ThrCod);
2014-12-01 23:55:08 +01:00
2017-04-18 09:55:25 +02:00
/***** Show alert after action *****/
2019-10-26 01:56:36 +02:00
HTM_SECTION_Begin (For_FORUM_POSTS_SECTION_ID);
2019-03-17 14:47:58 +01:00
Ale_ShowAlerts (For_FORUM_POSTS_SECTION_ID); // Possible pending alerts
2017-04-18 09:55:25 +02:00
if (Message)
if (Message[0])
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (AlertType,Message);
2017-04-18 09:55:25 +02:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
snprintf (FrameTitle,sizeof (FrameTitle),"%s: %s",
2020-04-14 00:11:28 +02:00
Txt_Thread,Thread.Subject);
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,FrameTitle,
2020-04-09 21:36:21 +02:00
For_PutIconNewPost,Forums,
2020-09-26 17:20:01 +02:00
Hlp_COMMUNICATION_Forums_posts,Box_NOT_CLOSABLE);
2017-04-11 19:05:15 +02:00
2014-12-01 23:55:08 +01:00
/***** Get posts of a thread from database *****/
NumPsts = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get posts of a thread",
"SELECT PstCod," // row[0]
"UNIX_TIMESTAMP(CreatTime)" // row[1]
" FROM for_posts"
" WHERE ThrCod=%ld"
" ORDER BY PstCod",
Thread.ThrCod);
2018-10-31 09:40:43 +01:00
2014-12-01 23:55:08 +01:00
LastSubject[0] = '\0';
if (NumPsts) // If there are posts...
{
/***** Check if I can moderate posts in forum *****/
2020-04-10 19:14:08 +02:00
switch (Forums->Forum.Type)
2014-12-01 23:55:08 +01:00
{
2017-04-17 11:57:55 +02:00
case For_FORUM_GLOBAL_USRS:
case For_FORUM_GLOBAL_TCHS:
2017-04-18 19:55:56 +02:00
case For_FORUM__SWAD__USRS:
case For_FORUM__SWAD__TCHS:
2017-06-04 18:18:54 +02:00
ICanModerateForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM);
2014-12-01 23:55:08 +01:00
break;
2017-04-17 11:57:55 +02:00
case For_FORUM_INSTIT_USRS:
case For_FORUM_INSTIT_TCHS:
2017-06-04 18:18:54 +02:00
ICanModerateForum = (Gbl.Usrs.Me.Role.Logged >= Rol_INS_ADM);
2017-04-18 19:55:56 +02:00
break;
case For_FORUM_CENTER_USRS:
case For_FORUM_CENTER_TCHS:
2017-06-04 18:18:54 +02:00
ICanModerateForum = (Gbl.Usrs.Me.Role.Logged >= Rol_CTR_ADM);
2014-12-01 23:55:08 +01:00
break;
2017-04-17 11:57:55 +02:00
case For_FORUM_DEGREE_USRS:
case For_FORUM_DEGREE_TCHS:
case For_FORUM_COURSE_TCHS:
2017-06-04 18:18:54 +02:00
ICanModerateForum = (Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM);
2014-12-01 23:55:08 +01:00
break;
case For_FORUM_COURSE_USRS:
2017-06-04 18:18:54 +02:00
ICanModerateForum = (Gbl.Usrs.Me.Role.Logged >= Rol_TCH);
2017-04-18 19:55:56 +02:00
break;
default:
ICanModerateForum = false;
2014-12-01 23:55:08 +01:00
break;
}
/***** Compute variables related to pagination *****/
2017-04-13 20:09:22 +02:00
PaginationPsts.NumItems = NumPsts;
2020-04-07 03:01:41 +02:00
PaginationPsts.CurrentPage = (int) Forums->CurrentPagePsts;
2017-04-13 20:09:22 +02:00
Pag_CalculatePagination (&PaginationPsts);
2017-05-25 13:43:54 +02:00
PaginationPsts.Anchor = For_FORUM_POSTS_SECTION_ID;
2020-04-07 03:01:41 +02:00
Forums->CurrentPagePsts = (unsigned) PaginationPsts.CurrentPage;
2014-12-01 23:55:08 +01:00
/***** Write links to pages *****/
2020-04-10 19:14:08 +02:00
Pag_WriteLinksToPagesCentered (Pag_POSTS_FORUM,&PaginationPsts,
2020-04-14 00:11:28 +02:00
Forums,Thread.ThrCod);
2014-12-01 23:55:08 +01:00
2019-10-20 22:00:28 +02:00
/***** Begin table *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginWidePadding (2);
2014-12-01 23:55:08 +01:00
2017-04-11 19:05:15 +02:00
/***** Show posts from this page, the author and the date of last reply *****/
2017-04-13 20:09:22 +02:00
mysql_data_seek (mysql_res,(my_ulonglong) (PaginationPsts.FirstItemVisible - 1));
2020-04-10 19:14:08 +02:00
for (NumRow = PaginationPsts.FirstItemVisible;
2017-04-13 20:09:22 +02:00
NumRow <= PaginationPsts.LastItemVisible;
2014-12-01 23:55:08 +01:00
NumRow++)
{
row = mysql_fetch_row (mysql_res);
2020-10-14 00:59:24 +02:00
if (sscanf (row[0],"%ld",&Forums->PstCod) != 1)
Lay_WrongPostExit ();
2014-12-01 23:55:08 +01:00
2015-10-24 20:12:03 +02:00
CreatTimeUTC = Dat_GetUNIXTimeFromStr (row[1]);
NumPst = NumRow;
2015-10-24 20:12:03 +02:00
NewPst = (CreatTimeUTC > ReadTimeUTC);
2014-12-01 23:55:08 +01:00
2017-04-13 20:09:22 +02:00
if (NewPst && NumRow == PaginationPsts.LastItemVisible)
/* Update for_read table indicating that this thread page and previous ones
2014-12-01 23:55:08 +01:00
have been read and have no new posts for the current user
2017-04-19 12:34:38 +02:00
(even if any previous pages have been no read actually).
Note that database is not updated with the current time,
but with the creation time of the most recent post
in this page of threads. */
2020-04-14 00:11:28 +02:00
For_UpdateThrReadTime (Thread.ThrCod,
2017-04-19 12:34:38 +02:00
CreatTimeUTC);
2014-12-01 23:55:08 +01:00
/* Show post */
2020-10-14 00:59:24 +02:00
For_ShowAForumPost (Forums,NumPst,
(NumRow == NumPsts),LastSubject,
2015-10-24 20:12:03 +02:00
NewPst,ICanModerateForum);
2014-12-01 23:55:08 +01:00
/* Mark possible notification as seen */
2020-04-10 19:14:08 +02:00
switch (Forums->Forum.Type)
2014-12-01 23:55:08 +01:00
{
case For_FORUM_COURSE_TCHS:
case For_FORUM_COURSE_USRS:
2016-01-04 01:56:28 +01:00
Ntf_MarkNotifAsSeen (Ntf_EVENT_FORUM_POST_COURSE,
2020-10-14 00:59:24 +02:00
Forums->PstCod,Gbl.Hierarchy.Crs.CrsCod,
2016-01-20 21:18:38 +01:00
Gbl.Usrs.Me.UsrDat.UsrCod);
2014-12-01 23:55:08 +01:00
break;
default:
break;
}
2020-04-14 00:11:28 +02:00
if (Thread.NumMyPosts)
2016-01-04 01:56:28 +01:00
Ntf_MarkNotifAsSeen (Ntf_EVENT_FORUM_REPLY,
2020-10-14 00:59:24 +02:00
Forums->PstCod,-1L,
2016-01-20 21:18:38 +01:00
Gbl.Usrs.Me.UsrDat.UsrCod);
2014-12-01 23:55:08 +01:00
}
2017-04-11 19:05:15 +02:00
/***** End table *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2014-12-01 23:55:08 +01:00
/***** Write again links to pages *****/
2020-04-10 19:14:08 +02:00
Pag_WriteLinksToPagesCentered (Pag_POSTS_FORUM,&PaginationPsts,
2020-04-14 00:11:28 +02:00
Forums,Thread.ThrCod);
2014-12-01 23:55:08 +01:00
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
2017-04-11 19:05:15 +02:00
2017-04-17 12:19:58 +02:00
/***** Form to write a new post in the thread *****/
2019-10-26 01:56:36 +02:00
HTM_SECTION_Begin (For_NEW_POST_SECTION_ID);
2020-04-07 03:01:41 +02:00
For_WriteFormForumPst (Forums,true,LastSubject);
2019-10-26 01:56:36 +02:00
HTM_SECTION_End ();
2017-04-11 19:05:15 +02:00
2017-06-12 14:16:33 +02:00
/***** End box *****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2019-10-26 01:56:36 +02:00
HTM_SECTION_End ();
2014-12-01 23:55:08 +01:00
}
2016-11-07 10:53:03 +01:00
/*****************************************************************************/
2017-04-17 12:19:58 +02:00
/*********************** Put icon to write a new post ************************/
2017-04-10 12:41:26 +02:00
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_PutIconNewPost (void *Forums)
2017-04-10 12:41:26 +02:00
{
2017-04-17 12:19:58 +02:00
extern const char *Txt_New_post;
2017-04-10 12:41:26 +02:00
2020-04-07 03:01:41 +02:00
if (Forums)
2020-04-10 19:14:08 +02:00
Ico_PutContextualIconToAdd (For_ActionsSeePstFor[((struct For_Forums *) Forums)->Forum.Type],
2020-03-26 02:54:30 +01:00
For_NEW_POST_SECTION_ID,
2020-04-09 21:36:21 +02:00
For_PutAllHiddenParamsNewPost,Forums,
2020-03-26 02:54:30 +01:00
Txt_New_post);
2017-04-10 12:41:26 +02:00
}
2020-04-07 03:01:41 +02:00
static void For_PutAllHiddenParamsNewPost (void *Forums)
2017-04-19 14:43:08 +02:00
{
2020-04-07 03:01:41 +02:00
if (Forums)
For_PutAllHiddenParamsForum (((struct For_Forums *) Forums)->CurrentPageThrs, // Page of threads = current
UINT_MAX, // Page of posts = last
((struct For_Forums *) Forums)->ForumSet,
((struct For_Forums *) Forums)->ThreadsOrder,
2020-04-10 19:14:08 +02:00
((struct For_Forums *) Forums)->Forum.Location,
2020-11-11 01:14:53 +01:00
((struct For_Forums *) Forums)->Thread.Current,
2020-03-26 02:54:30 +01:00
-1L);
2017-04-19 14:43:08 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/**************************** Show a post from forum *************************/
/*****************************************************************************/
2020-10-14 00:59:24 +02:00
static void For_ShowAForumPost (struct For_Forums *Forums,
unsigned PstNum,
2017-01-17 03:10:43 +01:00
bool LastPst,char LastSubject[Cns_MAX_BYTES_SUBJECT + 1],
2015-10-24 20:12:03 +02:00
bool NewPst,bool ICanModerateForum)
2014-12-01 23:55:08 +01:00
{
2017-04-13 20:09:22 +02:00
extern const char *Txt_MSG_New;
2015-07-21 20:20:59 +02:00
extern const char *Txt_MSG_Open;
2014-12-01 23:55:08 +01:00
extern const char *Txt_no_subject;
2019-03-06 10:13:39 +01:00
extern const char *Txt_FORUM_Post_X_allowed;
extern const char *Txt_FORUM_Post_banned;
extern const char *Txt_FORUM_Post_X_banned;
extern const char *Txt_FORUM_Post_X_allowed_Click_to_ban_it;
extern const char *Txt_FORUM_Post_X_banned_Click_to_unban_it;
2014-12-01 23:55:08 +01:00
extern const char *Txt_This_post_has_been_banned_probably_for_not_satisfy_the_rules_of_the_forums;
struct UsrData UsrDat;
2015-10-24 20:12:03 +02:00
time_t CreatTimeUTC; // Creation time of a post
2017-01-17 03:10:43 +01:00
char OriginalContent[Cns_MAX_BYTES_LONG_TEXT + 1];
char Subject[Cns_MAX_BYTES_SUBJECT + 1];
char Content[Cns_MAX_BYTES_LONG_TEXT + 1];
2021-02-11 00:58:53 +01:00
struct Med_Media Media;
2014-12-01 23:55:08 +01:00
bool Enabled;
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2016-04-10 19:19:20 +02:00
/***** Initialize image *****/
2019-03-02 21:49:11 +01:00
Med_MediaConstructor (&Media);
2016-04-10 19:19:20 +02:00
2014-12-01 23:55:08 +01:00
/***** Check if post is enabled *****/
2020-10-14 00:59:24 +02:00
Enabled = For_GetIfPstIsEnabled (Forums->PstCod);
2014-12-01 23:55:08 +01:00
/***** Get data of post *****/
2020-10-14 00:59:24 +02:00
For_GetPstData (Forums->PstCod,&UsrDat.UsrCod,&CreatTimeUTC,
2019-03-02 21:49:11 +01:00
Subject,OriginalContent,&Media);
2016-04-11 02:16:27 +02:00
2014-12-01 23:55:08 +01:00
if (Enabled)
/* Return this subject as last subject */
Str_Copy (LastSubject,Subject,Cns_MAX_BYTES_SUBJECT);
2014-12-01 23:55:08 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 15:15:55 +02:00
/***** Put an icon with post status *****/
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"CONTEXT_COL %s\"",
2019-10-10 23:14:13 +02:00
NewPst ? "MSG_TIT_BG_NEW" :
"MSG_TIT_BG");
2019-10-29 21:41:54 +01:00
Ico_PutIcon (NewPst ? "envelope.svg" :
"envelope-open-text.svg",
NewPst ? Txt_MSG_New :
Txt_MSG_Open,
"ICO16x16");
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write post number *****/
Msg_WriteMsgNumber ((unsigned long) PstNum,NewPst);
/***** Write date *****/
2015-10-24 20:12:03 +02:00
Msg_WriteMsgDate (CreatTimeUTC,NewPst ? "MSG_TIT_BG_NEW" :
"MSG_TIT_BG");
2014-12-01 23:55:08 +01:00
/***** Write subject *****/
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"%s LT\"",NewPst ? "MSG_TIT_BG_NEW" :
2019-10-10 23:14:13 +02:00
"MSG_TIT_BG");
2014-12-01 23:55:08 +01:00
if (Enabled)
{
if (Subject[0])
2019-11-10 12:36:37 +01:00
HTM_Txt (Subject);
2014-12-01 23:55:08 +01:00
else
2019-11-11 00:15:44 +01:00
HTM_TxtF ("[%s]",Txt_no_subject);
2014-12-01 23:55:08 +01:00
}
else
2019-11-11 00:15:44 +01:00
HTM_TxtF ("[%s]",Txt_FORUM_Post_banned);
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2017-04-18 16:44:44 +02:00
/***** Form to ban/unban post *****/
HTM_TD_Begin ("class=\"CONTEXT_COL\"");
2014-12-01 23:55:08 +01:00
if (ICanModerateForum)
{
Frm_StartFormAnchor (Enabled ? For_ActionsDisPstFor[Forums->Forum.Type] :
For_ActionsEnbPstFor[Forums->Forum.Type],
For_FORUM_POSTS_SECTION_ID);
For_PutParamsForum (Forums);
Ico_PutIconLink (Enabled ? "eye-green.svg" :
"eye-slash-red.svg",
Str_BuildStringLong (Enabled ? Txt_FORUM_Post_X_allowed_Click_to_ban_it :
Txt_FORUM_Post_X_banned_Click_to_unban_it,
(long) PstNum));
Str_FreeString ();
Frm_EndForm ();
}
else
{
Ico_PutIcon (Enabled ? "eye-green.svg" :
"eye-slash-red.svg",
Str_BuildStringLong (Enabled ? Txt_FORUM_Post_X_allowed :
Txt_FORUM_Post_X_banned,
(long) PstNum),
"ICO_HIDDEN ICO16x16");
Str_FreeString ();
}
2014-12-01 23:55:08 +01:00
/***** Form to remove post *****/
if (LastPst)
if (Usr_ItsMe (UsrDat.UsrCod))
// Post can be removed if post is the last (without answers) and it's mine
Ico_PutContextualIconToRemove (For_ActionsDelPstFor[Forums->Forum.Type],
PstNum == 1 ? For_FORUM_THREADS_SECTION_ID : // First and unique post in thread
For_FORUM_POSTS_SECTION_ID, // Last of several posts in thread
For_PutParamsForum,Forums);
2016-04-10 19:19:20 +02:00
HTM_TD_End ();
/***** Write author *****/
HTM_TD_Begin ("colspan=\"2\" class=\"AUTHOR_TXT LT\" style=\"width:150px;\"");
Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS);
Msg_WriteMsgAuthor (&UsrDat,Enabled,NULL);
if (Enabled)
/* Write number of posts from this user */
For_WriteNumberOfPosts (Forums,UsrDat.UsrCod);
HTM_TD_End ();
/***** Write post content *****/
HTM_TD_Begin ("class=\"MSG_TXT LT\"");
if (Enabled)
{
Str_Copy (Content,OriginalContent,sizeof (Content) - 1);
Msg_WriteMsgContent (Content,Cns_MAX_BYTES_LONG_TEXT,true,false);
/***** Show image *****/
Med_ShowMedia (&Media,"FOR_IMG_CONT","FOR_IMG");
}
else
HTM_Txt (Txt_This_post_has_been_banned_probably_for_not_satisfy_the_rules_of_the_forums);
HTM_TD_End ();
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
2016-04-10 19:19:20 +02:00
/***** Free image *****/
2019-03-02 21:49:11 +01:00
Med_MediaDestructor (&Media);
2016-04-10 19:19:20 +02:00
2014-12-01 23:55:08 +01:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
/*****************************************************************************/
/*************************** Get data of a forum post ************************/
/*****************************************************************************/
2015-10-24 20:12:03 +02:00
static void For_GetPstData (long PstCod,long *UsrCod,time_t *CreatTimeUTC,
char Subject[Cns_MAX_BYTES_SUBJECT + 1],
2017-01-17 03:10:43 +01:00
char Content[Cns_MAX_BYTES_LONG_TEXT + 1],
2021-02-11 00:58:53 +01:00
struct Med_Media *Media)
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
/***** Get data of a post from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get data of a post",
2019-03-02 21:49:11 +01:00
"SELECT UsrCod," // row[0]
"UNIX_TIMESTAMP(CreatTime)," // row[1]
"Subject," // row[2]
"Content," // row[3]
2019-03-18 15:42:22 +01:00
"MedCod" // row[4]
" FROM for_posts"
" WHERE PstCod=%ld",
PstCod) != 1)
Lay_WrongPostExit ();
2014-12-01 23:55:08 +01:00
/***** Get number of rows *****/
row = mysql_fetch_row (mysql_res);
2019-03-18 15:42:22 +01:00
/***** Get author code (row[1]) *****/
2014-12-01 23:55:08 +01:00
*UsrCod = Str_ConvertStrCodToLongCod (row[0]);
2019-03-18 15:42:22 +01:00
/***** Get creation time (row[1]) *****/
2015-10-24 20:12:03 +02:00
*CreatTimeUTC = Dat_GetUNIXTimeFromStr (row[1]);
2014-12-01 23:55:08 +01:00
/***** Get subject (row[2]) and location (row[3]) *****/
Str_Copy (Subject,row[2],Cns_MAX_BYTES_SUBJECT );
Str_Copy (Content,row[3],Cns_MAX_BYTES_LONG_TEXT);
2016-04-10 19:19:20 +02:00
2019-03-18 15:42:22 +01:00
/***** Get media (row[4]) *****/
Media->MedCod = Str_ConvertStrCodToLongCod (row[4]);
Med_GetMediaDataByCod (Media);
2014-12-01 23:55:08 +01:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
2015-12-28 19:22:56 +01:00
/***************** Get summary and content for a forum post ******************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2017-03-08 14:12:33 +01:00
void For_GetSummaryAndContentForumPst (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1],
2017-01-13 10:49:56 +01:00
char **ContentStr,
2017-03-06 13:01:16 +01:00
long PstCod,bool GetContent)
2014-12-01 23:55:08 +01:00
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2017-01-13 10:49:56 +01:00
size_t Length;
2014-12-01 23:55:08 +01:00
SummaryStr[0] = '\0'; // Return nothing on error
2020-02-24 12:43:18 +01:00
/***** Get post subject and content from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get subject and content",
"SELECT Subject," // row[0]
"Content" // row[1]
" FROM for_posts"
" WHERE PstCod=%ld",
PstCod) == 1)
2020-02-24 12:43:18 +01:00
{
/***** Get subject and content of the post *****/
row = mysql_fetch_row (mysql_res);
/***** Copy subject *****/
Str_Copy (SummaryStr,row[0],Ntf_MAX_BYTES_SUMMARY);
2020-02-24 12:43:18 +01:00
/***** Copy content *****/
if (GetContent)
{
Length = strlen (row[1]);
if ((*ContentStr = malloc (Length + 1)) == NULL)
Lay_NotEnoughMemoryExit ();
2020-02-24 12:43:18 +01:00
if (Length)
Str_Copy (*ContentStr,row[1],Length);
2020-02-24 12:43:18 +01:00
else
**ContentStr = '\0';
}
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************** Write number of posts in a forum of an user *****************/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_WriteNumberOfPosts (const struct For_Forums *Forums,long UsrCod)
2014-12-01 23:55:08 +01:00
{
2019-03-06 10:13:39 +01:00
extern const char *Txt_FORUM_post;
extern const char *Txt_FORUM_posts;
2014-12-01 23:55:08 +01:00
char SubQuery[256];
unsigned NumPsts;
/***** Star table cell *****/
2019-10-24 00:04:40 +02:00
HTM_DIV_Begin ("class=\"AUTHOR_TXT LT\"");
2014-12-01 23:55:08 +01:00
/***** Get number of posts from database *****/
2020-04-10 19:14:08 +02:00
if (Forums->Forum.Location > 0)
sprintf (SubQuery," AND for_threads.Location=%ld",
2020-04-10 19:14:08 +02:00
Forums->Forum.Location);
2017-04-16 23:48:05 +02:00
else
SubQuery[0] = '\0';
NumPsts = (unsigned)
DB_QueryCOUNT ("can not get the number of posts of a user in a forum",
"SELECT COUNT(*)"
" FROM for_posts,"
"for_threads"
" WHERE for_posts.UsrCod=%ld"
" AND for_posts.ThrCod=for_threads.ThrCod"
" AND for_threads.ForumType=%u"
"%s",
UsrCod,
(unsigned) Forums->Forum.Type,
SubQuery);
2014-12-01 23:55:08 +01:00
/***** Write number of threads and number of posts *****/
2019-11-11 00:15:44 +01:00
HTM_TxtF ("[%u %s]",NumPsts,NumPsts == 1 ? Txt_FORUM_post :
Txt_FORUM_posts);
2014-12-01 23:55:08 +01:00
/***** End table cell *****/
2019-10-23 20:07:56 +02:00
HTM_DIV_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2014-12-28 17:22:27 +01:00
/************ Put all the hidden parameters related to forums ****************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2020-10-14 00:59:24 +02:00
static void For_PutParamsForum (void *Forums)
{
if (Forums)
For_PutAllHiddenParamsForum (((struct For_Forums *) Forums)->CurrentPageThrs, // Page of threads = current
((struct For_Forums *) Forums)->CurrentPagePsts, // Page of posts = current
((struct For_Forums *) Forums)->ForumSet,
((struct For_Forums *) Forums)->ThreadsOrder,
((struct For_Forums *) Forums)->Forum.Location,
2020-11-11 01:14:53 +01:00
((struct For_Forums *) Forums)->Thread.Current,
2020-10-14 00:59:24 +02:00
((struct For_Forums *) Forums)->PstCod);
}
2017-04-18 16:44:44 +02:00
void For_PutAllHiddenParamsForum (unsigned NumPageThreads,
unsigned NumPagePosts,
For_ForumSet_t ForumSet,
2020-04-05 22:53:58 +02:00
Dat_StartEndTime_t Order,
2017-04-18 01:25:44 +02:00
long Location,
long ThrCod,
long PstCod)
{
2017-04-18 16:44:44 +02:00
Pag_PutHiddenParamPagNum (Pag_THREADS_FORUM,NumPageThreads);
Pag_PutHiddenParamPagNum (Pag_POSTS_FORUM,NumPagePosts);
2017-04-18 01:25:44 +02:00
For_PutParamForumSet (ForumSet);
2020-04-05 22:53:58 +02:00
Dat_PutHiddenParamOrder (Order);
2017-04-18 01:25:44 +02:00
For_PutParamForumLocation (Location);
For_PutHiddenParamThrCod (ThrCod);
For_PutHiddenParamPstCod (PstCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2017-04-17 19:03:21 +02:00
/********* Put a hidden parameter with set of forums I want to see ***********/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2017-04-18 01:25:44 +02:00
static void For_PutParamForumSet (For_ForumSet_t ForumSet)
2014-12-01 23:55:08 +01:00
{
2019-11-03 13:19:32 +01:00
Par_PutHiddenParamUnsigned (NULL,"ForumSet",(unsigned) ForumSet);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2017-04-16 23:48:05 +02:00
/************** Put hidden parameter with code of *****************/
/************** forum institution, center, degree and course *****************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2017-04-18 01:25:44 +02:00
static void For_PutParamForumLocation (long Location)
2014-12-01 23:55:08 +01:00
{
2017-04-18 01:25:44 +02:00
if (Location > 0)
/***** Put a hidden parameter with the
institution, center, degree or course of the forum *****/
2019-11-03 13:19:32 +01:00
Par_PutHiddenParamLong (NULL,"Location",Location);
2017-04-18 01:25:44 +02:00
}
/*****************************************************************************/
/************ Write a form parameter to specify a thread code ****************/
/*****************************************************************************/
static void For_PutHiddenParamThrCod (long ThrCod)
{
if (ThrCod > 0)
2019-11-03 13:19:32 +01:00
Par_PutHiddenParamLong (NULL,"ThrCod",ThrCod);
2017-04-18 01:25:44 +02:00
}
/*****************************************************************************/
/************* Write a form parameter to specify a post code *****************/
/*****************************************************************************/
static void For_PutHiddenParamPstCod (long PstCod)
{
if (PstCod > 0)
2019-11-03 13:19:32 +01:00
Par_PutHiddenParamLong (NULL,"PstCod",PstCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************** Show list of available forums ********************/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_ShowForumList (struct For_Forums *Forums)
2014-12-01 23:55:08 +01:00
{
2020-09-26 17:20:01 +02:00
extern const char *Hlp_COMMUNICATION_Forums;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Forums;
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS];
2014-12-01 23:55:08 +01:00
MYSQL_RES *mysql_resCtr;
MYSQL_RES *mysql_resDeg;
MYSQL_RES *mysql_resCrs;
MYSQL_ROW row;
2017-04-16 23:48:05 +02:00
long InsCod;
long CtrCod;
long DegCod;
long CrsCod;
unsigned NumMyIns;
unsigned NumCtr;
unsigned NumCtrs;
unsigned NumDeg;
unsigned NumDegs;
unsigned NumCrs;
unsigned NumCrss;
2014-12-01 23:55:08 +01:00
bool ICanSeeInsForum;
bool ICanSeeCtrForum;
bool ICanSeeDegForum;
/***** Get if there is a thread ready to be moved *****/
2017-04-18 13:17:40 +02:00
if (For_CheckIfICanMoveThreads ())
2020-11-11 01:14:53 +01:00
Forums->Thread.ToMove = For_GetThrInMyClipboard ();
2014-12-01 23:55:08 +01:00
/***** Fill the list with the institutions I belong to *****/
2016-10-28 10:03:37 +02:00
Usr_GetMyInstits ();
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_Forums,
2020-04-08 03:41:05 +02:00
For_PutIconsForums,NULL,
2020-09-26 17:20:01 +02:00
Hlp_COMMUNICATION_Forums,Box_NOT_CLOSABLE);
2014-12-01 23:55:08 +01:00
/***** Put a form to select which forums *****/
2020-04-07 03:01:41 +02:00
For_PutFormWhichForums (Forums);
2014-12-01 23:55:08 +01:00
2017-04-13 23:53:57 +02:00
/***** Start list *****/
2019-10-26 12:25:27 +02:00
HTM_UL_Begin ("class=\"LIST_TREE\"");
2014-12-01 23:55:08 +01:00
/***** Links to global forums *****/
2020-04-07 03:01:41 +02:00
For_WriteLinksToGblForums (Forums,IsLastItemInLevel);
switch (Forums->ForumSet)
2014-12-01 23:55:08 +01:00
{
case For_ONLY_CURRENT_FORUMS:
2019-04-03 20:57:04 +02:00
if (Gbl.Hierarchy.Ins.InsCod > 0)
2016-06-12 14:03:33 +02:00
{
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM)
2016-06-12 14:03:33 +02:00
ICanSeeInsForum = true;
else
2019-04-03 20:57:04 +02:00
ICanSeeInsForum = Usr_CheckIfIBelongToIns (Gbl.Hierarchy.Ins.InsCod);
2016-06-12 14:03:33 +02:00
}
2014-12-01 23:55:08 +01:00
else
2016-06-12 14:03:33 +02:00
ICanSeeInsForum = false;
2014-12-01 23:55:08 +01:00
/***** Links to forums about the platform *****/
2020-04-07 03:01:41 +02:00
For_WriteLinksToPlatformForums (Forums,!ICanSeeInsForum,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
if (ICanSeeInsForum)
{
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM)
2014-12-01 23:55:08 +01:00
ICanSeeCtrForum = true;
else
2019-04-03 20:57:04 +02:00
ICanSeeCtrForum = Usr_CheckIfIBelongToCtr (Gbl.Hierarchy.Ctr.CtrCod);
2014-12-01 23:55:08 +01:00
/***** Links to forums of current institution *****/
2020-04-07 03:01:41 +02:00
if (For_WriteLinksToInsForums (Forums,Gbl.Hierarchy.Ins.InsCod,
2017-04-16 23:48:05 +02:00
true,
IsLastItemInLevel) > 0)
2014-12-01 23:55:08 +01:00
if (ICanSeeCtrForum)
{
2017-06-04 18:18:54 +02:00
if (Gbl.Usrs.Me.Role.Logged >= Rol_DEG_ADM)
2014-12-01 23:55:08 +01:00
ICanSeeDegForum = true;
else
2019-04-03 20:57:04 +02:00
ICanSeeDegForum = Usr_CheckIfIBelongToDeg (Gbl.Hierarchy.Deg.DegCod);
2014-12-01 23:55:08 +01:00
/***** Links to forums of current center *****/
2020-04-07 03:01:41 +02:00
if (For_WriteLinksToCtrForums (Forums,
Gbl.Hierarchy.Ctr.CtrCod,
2017-04-16 23:48:05 +02:00
true,
IsLastItemInLevel) > 0)
2014-12-01 23:55:08 +01:00
if (ICanSeeDegForum)
/***** Links to forums of current degree *****/
2020-04-07 03:01:41 +02:00
if (For_WriteLinksToDegForums (Forums,
Gbl.Hierarchy.Deg.DegCod,
2017-04-16 23:48:05 +02:00
true,
IsLastItemInLevel) > 0)
2015-01-20 20:03:38 +01:00
if (Gbl.Usrs.Me.IBelongToCurrentCrs ||
2017-06-04 18:18:54 +02:00
Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM)
2014-12-01 23:55:08 +01:00
/***** Links to forums of current degree *****/
2020-04-07 03:01:41 +02:00
For_WriteLinksToCrsForums (Forums,
Gbl.Hierarchy.Crs.CrsCod,
2017-04-16 23:48:05 +02:00
true,
IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
}
}
break;
case For_ALL_MY_FORUMS:
/***** Links to forums about the platform *****/
2020-04-07 03:01:41 +02:00
For_WriteLinksToPlatformForums (Forums,(Gbl.Usrs.Me.MyInss.Num == 0),IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
/***** Links to forums of users from my institutions, the degrees in each institution and the courses in each degree *****/
for (NumMyIns = 0;
2016-10-28 10:03:37 +02:00
NumMyIns < Gbl.Usrs.Me.MyInss.Num;
2014-12-01 23:55:08 +01:00
NumMyIns++)
{
2017-04-16 23:48:05 +02:00
InsCod = Gbl.Usrs.Me.MyInss.Inss[NumMyIns].InsCod;
2014-12-01 23:55:08 +01:00
/* Links to forums of this institution */
2020-04-07 03:01:41 +02:00
For_WriteLinksToInsForums (Forums,
InsCod,
2017-04-16 23:48:05 +02:00
(NumMyIns == Gbl.Usrs.Me.MyInss.Num - 1),
IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
/* Get my centers in this institution from database */
NumCtrs = Usr_GetCtrsFromUsr (Gbl.Usrs.Me.UsrDat.UsrCod,
InsCod,&mysql_resCtr);
for (NumCtr = 0;
NumCtr < NumCtrs;
NumCtr++)
{
/* Get next center */
row = mysql_fetch_row (mysql_resCtr);
CtrCod = Str_ConvertStrCodToLongCod (row[0]);
/* Links to forums of this center */
if (For_WriteLinksToCtrForums (Forums,
CtrCod,
(NumCtr == NumCtrs - 1),
IsLastItemInLevel) > 0)
{
/* Get my degrees in this institution from database */
if ((NumDegs = Usr_GetDegsFromUsr (Gbl.Usrs.Me.UsrDat.UsrCod,
CtrCod,
&mysql_resDeg)) > 0) // Degrees found in this center
for (NumDeg = 0;
NumDeg < NumDegs;
NumDeg++)
{
/* Get next degree */
row = mysql_fetch_row (mysql_resDeg);
DegCod = Str_ConvertStrCodToLongCod (row[0]);
/* Links to forums of this degree */
if (For_WriteLinksToDegForums (Forums,
DegCod,
(NumDeg == NumDegs - 1),
IsLastItemInLevel) > 0)
2014-12-01 23:55:08 +01:00
{
/* Get my courses in this degree from database */
NumCrss = Usr_GetCrssFromUsr (Gbl.Usrs.Me.UsrDat.UsrCod,
DegCod,
&mysql_resCrs);
for (NumCrs = 0;
NumCrs < NumCrss;
NumCrs++)
2014-12-01 23:55:08 +01:00
{
/* Get next course */
row = mysql_fetch_row (mysql_resCrs);
CrsCod = Str_ConvertStrCodToLongCod (row[0]);
/* Links to forums of this course */
For_WriteLinksToCrsForums (Forums,
CrsCod,
(NumCrs == NumCrss - 1),
IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
}
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_resCrs);
2014-12-01 23:55:08 +01:00
}
}
2014-12-01 23:55:08 +01:00
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_resDeg);
}
}
2014-12-01 23:55:08 +01:00
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_resCtr);
}
break;
default:
break;
}
2017-04-13 23:53:57 +02:00
/***** End list *****/
2019-10-26 02:19:42 +02:00
HTM_UL_End ();
2017-04-13 23:53:57 +02: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
}
2017-04-17 12:19:58 +02:00
/*****************************************************************************/
/********************** Put contextual icons in forums ***********************/
/*****************************************************************************/
2020-04-08 03:41:05 +02:00
static void For_PutIconsForums (__attribute__((unused)) void *Args)
2017-04-17 12:19:58 +02:00
{
2020-04-08 03:41:05 +02:00
/***** Put icon to show a figure *****/
Fig_PutIconToShowFigure (Fig_FORUMS);
2017-04-17 12:19:58 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2017-02-24 00:42:20 +01:00
/*************** Put form to select which forums I want to see ***************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_PutFormWhichForums (const struct For_Forums *Forums)
2014-12-01 23:55:08 +01:00
{
2017-04-17 19:03:21 +02:00
extern const char *Txt_FORUM_WHICH_FORUM[For_NUM_FORUM_SETS];
2017-04-17 11:57:55 +02:00
For_ForumSet_t ForumSet;
2014-12-01 23:55:08 +01:00
2017-02-24 00:42:20 +01:00
/***** Form to select which forums I want to see:
- all my forums
- only the forums of current institution/degree/course *****/
Frm_BeginForm (ActSeeFor);
2020-04-07 03:01:41 +02:00
Dat_PutHiddenParamOrder (Forums->ThreadsOrder);
2019-10-24 00:04:40 +02:00
HTM_DIV_Begin ("class=\"SEL_BELOW_TITLE\"");
2019-10-26 12:25:27 +02:00
HTM_UL_Begin (NULL);
2014-12-27 21:09:34 +01:00
2019-12-15 20:02:34 +01:00
for (ForumSet = (For_ForumSet_t) 0;
ForumSet <= (For_ForumSet_t) (For_NUM_FORUM_SETS - 1);
2017-04-17 11:57:55 +02:00
ForumSet++)
2014-12-01 23:55:08 +01:00
{
2019-10-26 22:49:13 +02:00
HTM_LI_Begin (NULL);
2019-11-03 10:41:31 +01:00
HTM_LABEL_Begin (NULL);
2019-11-04 18:17:39 +01:00
HTM_INPUT_RADIO ("ForumSet",true,
"value=\"%u\"%s",
(unsigned) ForumSet,
2020-04-07 03:01:41 +02:00
(ForumSet == Forums->ForumSet) ? " checked=\"checked\"" :
"");
2019-11-10 12:36:37 +01:00
HTM_Txt (Txt_FORUM_WHICH_FORUM[ForumSet]);
2019-11-02 12:59:31 +01:00
HTM_LABEL_End ();
2019-10-26 22:49:13 +02:00
HTM_LI_End ();
2014-12-01 23:55:08 +01:00
}
2019-10-26 02:19:42 +02:00
HTM_UL_End ();
2019-10-23 20:07:56 +02:00
HTM_DIV_End ();
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************* Write links to global forums **********************/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_WriteLinksToGblForums (const struct For_Forums *Forums,
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS])
2014-12-01 23:55:08 +01:00
{
2017-04-11 13:53:17 +02:00
bool Highlight;
2017-05-23 20:42:38 +02:00
bool ICanSeeTeacherForum;
2020-04-07 03:01:41 +02:00
struct For_Forum Forum;
2017-04-11 13:53:17 +02:00
2017-05-23 20:42:38 +02:00
/***** Can I see teachers's forums? *****/
Rol_GetRolesInAllCrss (&Gbl.Usrs.Me.UsrDat);
2017-06-04 18:18:54 +02:00
ICanSeeTeacherForum = Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-06-08 15:32:33 +02:00
(Gbl.Usrs.Me.UsrDat.Roles.InCrss & ((1 << Rol_NET) |
2019-03-07 22:15:47 +01:00
(1 << Rol_TCH)));
2017-05-23 20:42:38 +02:00
2014-12-01 23:55:08 +01:00
/***** Link to forum global *****/
2017-04-19 12:34:38 +02:00
Forum.Type = For_FORUM_GLOBAL_USRS;
Forum.Location = -1L;
2020-04-10 19:14:08 +02:00
Highlight = (Forums->Forum.Type == For_FORUM_GLOBAL_USRS);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[1] = false;
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,0,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
/***** Link to forum of teachers global *****/
Rol_GetRolesInAllCrss (&Gbl.Usrs.Me.UsrDat);
2017-05-23 20:42:38 +02:00
if (ICanSeeTeacherForum)
2014-12-01 23:55:08 +01:00
{
2017-04-19 12:34:38 +02:00
Forum.Type = For_FORUM_GLOBAL_TCHS;
Forum.Location = -1L;
2020-04-10 19:14:08 +02:00
Highlight = (Forums->Forum.Type == For_FORUM_GLOBAL_TCHS);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[1] = false;
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,0,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/****************** Write links to forums about the platform *****************/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_WriteLinksToPlatformForums (const struct For_Forums *Forums,
bool IsLastForum,
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS])
2014-12-01 23:55:08 +01:00
{
2017-04-11 13:53:17 +02:00
bool Highlight;
2016-12-13 13:32:19 +01:00
bool ICanSeeTeacherForum;
2020-04-07 03:01:41 +02:00
struct For_Forum Forum;
2016-12-13 13:32:19 +01:00
/***** Can I see teachers's forums? *****/
Rol_GetRolesInAllCrss (&Gbl.Usrs.Me.UsrDat);
2017-06-04 18:18:54 +02:00
ICanSeeTeacherForum = Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-06-08 15:32:33 +02:00
(Gbl.Usrs.Me.UsrDat.Roles.InCrss & ((1 << Rol_NET) |
2019-03-07 22:15:47 +01:00
(1 << Rol_TCH)));
2014-12-01 23:55:08 +01:00
/***** Link to forum of users about the platform *****/
2017-04-19 12:34:38 +02:00
Forum.Type = For_FORUM__SWAD__USRS;
Forum.Location = -1L;
2020-04-10 19:14:08 +02:00
Highlight = (Forums->Forum.Type == For_FORUM__SWAD__USRS);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[1] = (IsLastForum && !ICanSeeTeacherForum);
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,0,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
/***** Link to forum of teachers about the platform *****/
if (ICanSeeTeacherForum)
{
2017-04-19 12:34:38 +02:00
Forum.Type = For_FORUM__SWAD__TCHS;
Forum.Location = -1L;
2020-04-10 19:14:08 +02:00
Highlight = (Forums->Forum.Type == For_FORUM__SWAD__TCHS);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[1] = IsLastForum;
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,0,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/********************** Write links to institution forums ********************/
/*****************************************************************************/
// Returns institution code
2020-04-07 03:01:41 +02:00
static long For_WriteLinksToInsForums (const struct For_Forums *Forums,
long InsCod,bool IsLastIns,
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS])
2014-12-01 23:55:08 +01:00
{
2017-04-11 13:53:17 +02:00
bool Highlight;
2017-05-23 20:42:38 +02:00
Rol_Role_t MaxRoleInIns;
2014-12-01 23:55:08 +01:00
bool ICanSeeTeacherForum;
2020-04-07 03:01:41 +02:00
struct For_Forum Forum;
2014-12-01 23:55:08 +01:00
if (InsCod > 0)
{
2017-05-23 20:42:38 +02:00
MaxRoleInIns = Rol_GetMyMaxRoleInIns (InsCod);
2017-06-04 18:18:54 +02:00
ICanSeeTeacherForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRoleInIns == Rol_NET ||
MaxRoleInIns == Rol_TCH);
2014-12-01 23:55:08 +01:00
/***** Link to the forum of users from this institution *****/
2017-04-19 12:34:38 +02:00
Forum.Type = For_FORUM_INSTIT_USRS;
Forum.Location = InsCod;
2020-04-10 19:14:08 +02:00
Highlight = (Forums->Forum.Type == For_FORUM_INSTIT_USRS &&
Forums->Forum.Location == InsCod);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[1] = (IsLastIns && !ICanSeeTeacherForum);
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,1,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
/***** Link to forum of teachers from this institution *****/
if (ICanSeeTeacherForum)
{
2017-04-19 12:34:38 +02:00
Forum.Type = For_FORUM_INSTIT_TCHS;
Forum.Location = InsCod;
2020-04-10 19:14:08 +02:00
Highlight = (Forums->Forum.Type == For_FORUM_INSTIT_TCHS &&
Forums->Forum.Location == InsCod);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[1] = IsLastIns;
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,1,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
}
}
return InsCod;
}
/*****************************************************************************/
/************************ Write links to center forums ***********************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
// Returns center code
2014-12-01 23:55:08 +01:00
2020-04-07 03:01:41 +02:00
static long For_WriteLinksToCtrForums (const struct For_Forums *Forums,
long CtrCod,bool IsLastCtr,
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS])
2014-12-01 23:55:08 +01:00
{
2017-04-11 13:53:17 +02:00
bool Highlight;
2017-05-23 20:42:38 +02:00
Rol_Role_t MaxRoleInCtr;
2014-12-01 23:55:08 +01:00
bool ICanSeeTeacherForum;
2020-04-07 03:01:41 +02:00
struct For_Forum Forum;
2014-12-01 23:55:08 +01:00
if (CtrCod > 0)
{
2017-05-23 20:42:38 +02:00
MaxRoleInCtr = Rol_GetMyMaxRoleInCtr (CtrCod);
2017-06-04 18:18:54 +02:00
ICanSeeTeacherForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRoleInCtr == Rol_NET ||
MaxRoleInCtr == Rol_TCH);
2014-12-01 23:55:08 +01:00
/***** Link to the forum of users from this center *****/
Forum.Type = For_FORUM_CENTER_USRS;
2017-04-19 12:34:38 +02:00
Forum.Location = CtrCod;
Highlight = (Forums->Forum.Type == For_FORUM_CENTER_USRS &&
2020-04-10 19:14:08 +02:00
Forums->Forum.Location == CtrCod);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[2] = (IsLastCtr && !ICanSeeTeacherForum);
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,2,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
/***** Link to forum of teachers from this center *****/
2014-12-01 23:55:08 +01:00
if (ICanSeeTeacherForum)
{
Forum.Type = For_FORUM_CENTER_TCHS;
2017-04-19 12:34:38 +02:00
Forum.Location = CtrCod;
Highlight = (Forums->Forum.Type == For_FORUM_CENTER_TCHS &&
2020-04-10 19:14:08 +02:00
Forums->Forum.Location == CtrCod);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[2] = IsLastCtr;
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,2,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
}
}
return CtrCod;
}
/*****************************************************************************/
/************************ Write links to degree forums ***********************/
/*****************************************************************************/
// Returns degree code
2020-04-07 03:01:41 +02:00
static long For_WriteLinksToDegForums (const struct For_Forums *Forums,
long DegCod,bool IsLastDeg,
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS])
2014-12-01 23:55:08 +01:00
{
2017-04-11 13:53:17 +02:00
bool Highlight;
2017-05-23 20:42:38 +02:00
Rol_Role_t MaxRoleInDeg;
2014-12-01 23:55:08 +01:00
bool ICanSeeTeacherForum;
2020-04-07 03:01:41 +02:00
struct For_Forum Forum;
2014-12-01 23:55:08 +01:00
if (DegCod > 0)
{
2017-05-23 20:42:38 +02:00
MaxRoleInDeg = Rol_GetMyMaxRoleInDeg (DegCod);
2017-06-04 18:18:54 +02:00
ICanSeeTeacherForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRoleInDeg == Rol_NET ||
MaxRoleInDeg == Rol_TCH);
2014-12-01 23:55:08 +01:00
/***** Link to the forum of users from this degree *****/
2017-04-19 12:34:38 +02:00
Forum.Type = For_FORUM_DEGREE_USRS;
Forum.Location = DegCod;
2020-04-10 19:14:08 +02:00
Highlight = (Forums->Forum.Type == For_FORUM_DEGREE_USRS &&
Forums->Forum.Location == DegCod);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[3] = (IsLastDeg && !ICanSeeTeacherForum);
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,3,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
/***** Link to forum of teachers from this degree *****/
if (ICanSeeTeacherForum)
{
2017-04-19 12:34:38 +02:00
Forum.Type = For_FORUM_DEGREE_TCHS;
Forum.Location = DegCod;
2020-04-10 19:14:08 +02:00
Highlight = (Forums->Forum.Type == For_FORUM_DEGREE_TCHS &&
Forums->Forum.Location == DegCod);
2017-04-11 13:53:17 +02:00
IsLastItemInLevel[3] = IsLastDeg;
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,3,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
}
}
return DegCod;
}
/*****************************************************************************/
/************************ Write links to course forums ***********************/
/*****************************************************************************/
// Returns course code
2020-04-07 03:01:41 +02:00
static long For_WriteLinksToCrsForums (const struct For_Forums *Forums,
long CrsCod,bool IsLastCrs,
2017-01-28 15:58:46 +01:00
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS])
2014-12-01 23:55:08 +01:00
{
2017-04-11 13:53:17 +02:00
bool Highlight;
2017-05-23 20:42:38 +02:00
Rol_Role_t MyRoleInCrs;
2014-12-01 23:55:08 +01:00
bool ICanSeeTeacherForum;
2020-04-07 03:01:41 +02:00
struct For_Forum Forum;
2014-12-01 23:55:08 +01:00
if (CrsCod > 0)
{
2017-05-23 20:42:38 +02:00
MyRoleInCrs = Rol_GetMyRoleInCrs (CrsCod);
2017-06-04 18:18:54 +02:00
ICanSeeTeacherForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MyRoleInCrs == Rol_NET ||
MyRoleInCrs == Rol_TCH);
2014-12-01 23:55:08 +01:00
/***** Link to the forum of users from this course *****/
2017-04-19 12:34:38 +02:00
Forum.Type = For_FORUM_COURSE_USRS;
Forum.Location = CrsCod;
2020-04-10 19:14:08 +02:00
Highlight = (Forums->Forum.Type == For_FORUM_COURSE_USRS &&
Forums->Forum.Location == CrsCod);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[4] = (IsLastCrs && !ICanSeeTeacherForum);
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,4,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
/***** Link to forum of teachers from this course *****/
if (ICanSeeTeacherForum)
{
2017-04-19 12:34:38 +02:00
Forum.Type = For_FORUM_COURSE_TCHS;
Forum.Location = CrsCod;
2020-04-10 19:14:08 +02:00
Highlight = (Forums->Forum.Type == For_FORUM_COURSE_TCHS &&
Forums->Forum.Location == CrsCod);
2014-12-01 23:55:08 +01:00
IsLastItemInLevel[4] = IsLastCrs;
2020-04-07 03:01:41 +02:00
For_WriteLinkToForum (Forums,&Forum,Highlight,4,IsLastItemInLevel);
2014-12-01 23:55:08 +01:00
}
}
return CrsCod;
}
/*****************************************************************************/
/********************** Write title and link to a forum **********************/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_WriteLinkToForum (const struct For_Forums *Forums,
const struct For_Forum *Forum,
2019-11-18 17:59:02 +01:00
bool Highlight,
unsigned Level,
bool IsLastItemInLevel[1 + For_FORUM_MAX_LEVELS])
2014-12-01 23:55:08 +01:00
{
2019-11-18 14:21:01 +01:00
extern const char *The_ClassFormLinkInBox[The_NUM_THEMES];
extern const char *The_ClassFormLinkInBoxBold[The_NUM_THEMES];
2017-04-19 12:34:38 +02:00
extern const char *Txt_Copy_not_allowed;
unsigned NumThrs;
unsigned NumThrsWithNewPosts;
2019-11-18 14:21:01 +01:00
const char *Class;
2017-01-13 10:49:56 +01:00
char ForumName[For_MAX_BYTES_FORUM_NAME + 1];
2014-12-01 23:55:08 +01:00
2017-04-19 12:34:38 +02:00
/***** Get number of threads and number of posts *****/
NumThrs = For_GetNumThrsInForum (Forum);
NumThrsWithNewPosts = For_GetNumThrsWithNewPstsInForum (Forum,NumThrs);
2019-11-18 14:21:01 +01:00
Class = (NumThrsWithNewPosts ? The_ClassFormLinkInBoxBold[Gbl.Prefs.Theme] :
The_ClassFormLinkInBox[Gbl.Prefs.Theme]);
2017-04-19 12:34:38 +02:00
/***** Start row *****/
2019-10-26 22:49:13 +02:00
HTM_LI_Begin (Highlight ? "class=\"LIGHT_BLUE\"" :
NULL);
2017-04-19 12:34:38 +02:00
/***** Indent forum title *****/
Lay_IndentDependingOnLevel (Level,IsLastItemInLevel);
/***** Write paste button used to move a thread in clipboard to this forum *****/
2020-11-11 01:14:53 +01:00
if (Forums->Thread.ToMove >= 0) // If I have permission to paste threads and there is a thread ready to be pasted...
2017-04-19 12:34:38 +02:00
{
/* Check if thread to move is yet in current forum */
2020-11-11 01:14:53 +01:00
if (For_CheckIfThrBelongsToForum (Forums->Thread.ToMove,Forum))
2019-10-29 21:41:54 +01:00
Ico_PutIcon ("paste.svg",Txt_Copy_not_allowed,"CONTEXT_OPT ICO_HIDDEN ICO16x16");
2017-04-19 12:34:38 +02:00
else
{
2018-11-09 20:47:39 +01:00
Frm_StartFormAnchor (For_ActionsPasThrFor[Forum->Type],
2017-05-25 13:43:54 +02:00
For_FORUM_THREADS_SECTION_ID);
2017-04-19 12:34:38 +02:00
For_PutAllHiddenParamsForum (1, // Page of threads = first
1, // Page of posts = first
2020-04-07 03:01:41 +02:00
Forums->ForumSet,
Forums->ThreadsOrder,
2017-04-19 12:34:38 +02:00
Forum->Location,
2020-11-11 01:14:53 +01:00
Forums->Thread.ToMove,
2017-04-19 12:34:38 +02:00
-1L);
2019-01-11 02:55:01 +01:00
Ico_PutIconPaste ();
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2017-04-19 12:34:38 +02:00
}
}
2014-12-01 23:55:08 +01:00
2017-04-19 12:34:38 +02:00
/***** Write link to forum *****/
2018-11-09 20:47:39 +01:00
Frm_StartFormAnchor (For_ActionsSeeFor[Forum->Type],
2017-05-25 13:43:54 +02:00
For_FORUM_THREADS_SECTION_ID);
2017-04-19 12:34:38 +02:00
For_PutAllHiddenParamsForum (1, // Page of threads = first
1, // Page of posts = first
2020-04-07 03:01:41 +02:00
Forums->ForumSet,
Forums->ThreadsOrder,
2017-04-19 12:34:38 +02:00
Forum->Location,
-1L,
-1L);
2020-01-02 13:35:37 +01:00
2020-01-02 13:58:13 +01:00
HTM_BUTTON_SUBMIT_Begin (Act_GetActionText (For_ActionsSeeFor[Forum->Type]),
Class,NULL);
2017-04-19 12:34:38 +02:00
For_SetForumName (Forum,ForumName,Gbl.Prefs.Language,true);
2017-04-18 01:25:44 +02:00
switch (Forum->Type)
2014-12-01 23:55:08 +01:00
{
case For_FORUM_GLOBAL_USRS:
case For_FORUM_GLOBAL_TCHS:
2019-10-29 21:41:54 +01:00
Ico_PutIcon ("comments.svg",ForumName,"ICO16x16");
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM__SWAD__USRS:
case For_FORUM__SWAD__TCHS:
2019-10-29 21:41:54 +01:00
Ico_PutIcon ("swad64x64.png",ForumName,"ICO16x16");
2017-04-19 12:34:38 +02:00
break;
case For_FORUM_INSTIT_USRS:
case For_FORUM_INSTIT_TCHS:
2021-02-11 22:57:09 +01:00
Lgo_DrawLogo (Hie_Lvl_INS,Forum->Location,ForumName,16,NULL,true);
2017-04-19 12:34:38 +02:00
break;
case For_FORUM_CENTER_USRS:
case For_FORUM_CENTER_TCHS:
2021-02-11 22:57:09 +01:00
Lgo_DrawLogo (Hie_Lvl_CTR,Forum->Location,ForumName,16,NULL,true);
2017-04-19 12:34:38 +02:00
break;
case For_FORUM_DEGREE_USRS:
case For_FORUM_DEGREE_TCHS:
2021-02-11 22:57:09 +01:00
Lgo_DrawLogo (Hie_Lvl_DEG,Forum->Location,ForumName,16,NULL,true);
2014-12-01 23:55:08 +01:00
break;
case For_FORUM_COURSE_USRS:
case For_FORUM_COURSE_TCHS:
2020-02-20 00:32:07 +01:00
Ico_PutIcon ("chalkboard-teacher.svg",ForumName,"ICO16x16");
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
default:
break;
2014-12-01 23:55:08 +01:00
}
2019-11-11 10:59:24 +01:00
HTM_TxtF ("&nbsp;%s",ForumName);
2017-04-19 12:34:38 +02:00
/***** Write total number of threads and posts in this forum *****/
2019-11-18 17:59:02 +01:00
if (NumThrs)
For_WriteNumberOfThrs (NumThrs);
2014-12-01 23:55:08 +01:00
2017-04-19 12:34:38 +02:00
/***** End row *****/
2019-11-19 00:17:23 +01:00
HTM_BUTTON_End ();
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2017-05-29 21:34:43 +02:00
/***** Put link to register students *****/
if (Forum->Type == For_FORUM_COURSE_USRS)
Enr_PutButtonInlineToRegisterStds (Forum->Location);
2019-10-26 22:49:13 +02:00
HTM_LI_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************** Set the name of a forum **************************/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
void For_SetForumName (const struct For_Forum *Forum,
2017-01-13 10:49:56 +01:00
char ForumName[For_MAX_BYTES_FORUM_NAME + 1],
2018-12-08 16:43:13 +01:00
Lan_Language_t Language,bool UseHTMLEntities)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_General;
2018-12-08 16:43:13 +01:00
extern const char *Txt_General_NO_HTML[1 + Lan_NUM_LANGUAGES];
2014-12-01 23:55:08 +01:00
extern const char *Txt_only_teachers;
2018-12-08 16:43:13 +01:00
extern const char *Txt_only_teachers_NO_HTML[1 + Lan_NUM_LANGUAGES];
2017-04-18 19:55:56 +02:00
extern const char *Txt_Unknown_FORUM;
2021-02-11 23:27:48 +01:00
struct Hie_Hierarchy Hie;
2014-12-01 23:55:08 +01:00
2017-04-18 01:25:44 +02:00
switch (Forum->Type)
2014-12-01 23:55:08 +01:00
{
2017-04-18 19:55:56 +02:00
case For_FORUM_GLOBAL_USRS:
Str_Copy (ForumName,UseHTMLEntities ? Txt_General :
Txt_General_NO_HTML[Language],
2017-01-17 03:10:43 +01:00
For_MAX_BYTES_FORUM_NAME);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_GLOBAL_TCHS:
snprintf (ForumName,For_MAX_BYTES_FORUM_NAME + 1,"%s%s",
2018-10-18 02:02:32 +02:00
UseHTMLEntities ? Txt_General :
Txt_General_NO_HTML[Language],
UseHTMLEntities ? Txt_only_teachers :
Txt_only_teachers_NO_HTML[Language]);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM__SWAD__USRS:
Str_Copy (ForumName,Cfg_PLATFORM_SHORT_NAME,For_MAX_BYTES_FORUM_NAME);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM__SWAD__TCHS:
snprintf (ForumName,For_MAX_BYTES_FORUM_NAME + 1,"%s%s",
Cfg_PLATFORM_SHORT_NAME,
2018-10-18 02:02:32 +02:00
UseHTMLEntities ? Txt_only_teachers :
Txt_only_teachers_NO_HTML[Language]);
2017-04-18 19:55:56 +02:00
break;
case For_FORUM_INSTIT_USRS:
2021-02-11 23:27:48 +01:00
Hie.Ins.InsCod = Forum->Location;
if (!Ins_GetDataOfInstitutionByCod (&Hie.Ins))
Lay_WrongInstitExit ();
Str_Copy (ForumName,Hie.Ins.ShrtName,For_MAX_BYTES_FORUM_NAME);
2017-04-18 19:55:56 +02:00
break;
case For_FORUM_INSTIT_TCHS:
2021-02-11 23:27:48 +01:00
Hie.Ins.InsCod = Forum->Location;
if (!Ins_GetDataOfInstitutionByCod (&Hie.Ins))
Lay_WrongInstitExit ();
snprintf (ForumName,For_MAX_BYTES_FORUM_NAME + 1,"%s%s",
Hie.Ins.ShrtName,
2018-10-18 02:02:32 +02:00
UseHTMLEntities ? Txt_only_teachers :
Txt_only_teachers_NO_HTML[Language]);
2014-12-01 23:55:08 +01:00
break;
case For_FORUM_CENTER_USRS:
2021-02-11 23:27:48 +01:00
Hie.Ctr.CtrCod = Forum->Location;
if (!Ctr_GetDataOfCenterByCod (&Hie.Ctr))
Lay_WrongCenterExit ();
Str_Copy (ForumName,Hie.Ctr.ShrtName,For_MAX_BYTES_FORUM_NAME);
2014-12-01 23:55:08 +01:00
break;
case For_FORUM_CENTER_TCHS:
2021-02-11 23:27:48 +01:00
Hie.Ctr.CtrCod = Forum->Location;
if (!Ctr_GetDataOfCenterByCod (&Hie.Ctr))
Lay_WrongCenterExit ();
snprintf (ForumName,For_MAX_BYTES_FORUM_NAME + 1,"%s%s",
Hie.Ctr.ShrtName,
2018-10-18 02:02:32 +02:00
UseHTMLEntities ? Txt_only_teachers :
Txt_only_teachers_NO_HTML[Language]);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_DEGREE_USRS:
2021-02-11 23:27:48 +01:00
Hie.Deg.DegCod = Forum->Location;
if (!Deg_GetDataOfDegreeByCod (&Hie.Deg))
Lay_WrongDegreeExit ();
Str_Copy (ForumName,Hie.Deg.ShrtName,For_MAX_BYTES_FORUM_NAME);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_DEGREE_TCHS:
2021-02-11 23:27:48 +01:00
Hie.Deg.DegCod = Forum->Location;
if (!Deg_GetDataOfDegreeByCod (&Hie.Deg))
Lay_WrongDegreeExit ();
snprintf (ForumName,For_MAX_BYTES_FORUM_NAME + 1,"%s%s",
Hie.Deg.ShrtName,
2018-10-18 02:02:32 +02:00
UseHTMLEntities ? Txt_only_teachers :
Txt_only_teachers_NO_HTML[Language]);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_COURSE_USRS:
2021-02-11 23:27:48 +01:00
Hie.Crs.CrsCod = Forum->Location;
if (!Crs_GetDataOfCourseByCod (&Hie.Crs))
Lay_WrongCourseExit ();
Str_Copy (ForumName,Hie.Crs.ShrtName,For_MAX_BYTES_FORUM_NAME);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_COURSE_TCHS:
2021-02-11 23:27:48 +01:00
Hie.Crs.CrsCod = Forum->Location;
if (!Crs_GetDataOfCourseByCod (&Hie.Crs))
Lay_WrongCourseExit ();
snprintf (ForumName,For_MAX_BYTES_FORUM_NAME + 1,"%s%s",
Hie.Crs.ShrtName,
2018-10-18 02:02:32 +02:00
UseHTMLEntities ? Txt_only_teachers :
Txt_only_teachers_NO_HTML[Language]);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
default:
Str_Copy (ForumName,Txt_Unknown_FORUM,For_MAX_BYTES_FORUM_NAME);
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/***** Get number of threads with new posts since my last read of a forum ****/
/*****************************************************************************/
static unsigned For_GetNumThrsWithNewPstsInForum (const struct For_Forum *Forum,
2017-04-16 23:48:05 +02:00
unsigned NumThreads)
2014-12-01 23:55:08 +01:00
{
char SubQuery[256];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumThrsWithNewPosts = NumThreads; // By default, all the threads are new to me
/***** Get last time I read this forum from database *****/
2017-04-19 12:34:38 +02:00
if (Forum->Location > 0)
sprintf (SubQuery," AND for_threads.Location=%ld",Forum->Location);
2017-04-16 23:48:05 +02:00
else
SubQuery[0] = '\0';
if (DB_QuerySELECT (&mysql_res,"can not get the date of reading of a forum",
"SELECT IFNULL(MAX(for_read.ReadTime)," // row[0]
"FROM_UNIXTIME(0))" // row[1]
" FROM for_read,"
"for_threads"
" WHERE for_read.UsrCod=%ld"
" AND for_read.ThrCod=for_threads.ThrCod"
" AND for_threads.ForumType=%u"
"%s",
Gbl.Usrs.Me.UsrDat.UsrCod,
(unsigned) Forum->Type,
SubQuery))
2014-12-01 23:55:08 +01:00
{
/***** Get number of threads with a last message modify time > newest read time (row[0]) *****/
row = mysql_fetch_row (mysql_res);
2017-04-19 12:34:38 +02:00
NumThrsWithNewPosts = For_GetNumOfThreadsInForumNewerThan (Forum,row[0]);
2014-12-01 23:55:08 +01:00
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return NumThrsWithNewPosts;
}
/*****************************************************************************/
/**** Get number of threads in forum with a modify time > a specified time ***/
/*****************************************************************************/
static unsigned For_GetNumOfThreadsInForumNewerThan (const struct For_Forum *Forum,
2017-04-16 23:48:05 +02:00
const char *Time)
2014-12-01 23:55:08 +01:00
{
char SubQuery[256];
2014-12-28 17:22:27 +01:00
/***** Get number of threads with a last message modify time
> specified time from database *****/
2017-04-19 12:34:38 +02:00
if (Forum->Location > 0)
sprintf (SubQuery," AND for_threads.Location=%ld",Forum->Location);
2017-04-16 23:48:05 +02:00
else
SubQuery[0] = '\0';
return (unsigned)
DB_QueryCOUNT ("can not check if there are new posts in a forum",
"SELECT COUNT(*)"
" FROM for_threads,"
"for_posts"
" WHERE for_threads.ForumType=%u"
"%s"
" AND for_threads.LastPstCod=for_posts.PstCod"
" AND for_posts.ModifTime>'%s'",
(unsigned) Forum->Type,
SubQuery,
Time);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/** Get number of unread posts in a thread since my last read of that thread */
/*****************************************************************************/
static unsigned For_GetNumOfUnreadPostsInThr (long ThrCod,unsigned NumPostsInThr)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumUnreadPosts = NumPostsInThr; // By default, all the posts are unread by me
/***** Get last time I read this thread from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get the date of reading of a thread",
"SELECT ReadTime" // row[0]
" FROM for_read"
" WHERE ThrCod=%ld"
" AND UsrCod=%ld",
ThrCod,
Gbl.Usrs.Me.UsrDat.UsrCod))
2014-12-01 23:55:08 +01:00
{
/***** Get the number of posts in thread with a modify time > newest read time for me (row[0]) *****/
row = mysql_fetch_row (mysql_res);
NumUnreadPosts = For_GetNumOfPostsInThrNewerThan (ThrCod,row[0]);
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return NumUnreadPosts;
}
/*****************************************************************************/
/**** Get number of posts in thread with a modify time > a specified time ****/
/*****************************************************************************/
static unsigned For_GetNumOfPostsInThrNewerThan (long ThrCod,const char *Time)
{
/***** Get the number of posts in thread with a modify time > a specified time from database *****/
return (unsigned)
DB_QueryCOUNT ("can not check if there are new posts in a thread of a forum",
"SELECT COUNT(*)"
" FROM for_posts"
" WHERE ThrCod=%ld"
" AND ModifTime>'%s'",
ThrCod,
Time);
2014-12-01 23:55:08 +01:00
}
2017-04-17 12:19:58 +02:00
/*****************************************************************************/
/************** Get and write total number of threads and posts **************/
/*****************************************************************************/
2019-11-18 17:59:02 +01:00
static void For_WriteNumberOfThrs (unsigned NumThrs)
2017-04-17 12:19:58 +02:00
{
extern const char *Txt_thread;
extern const char *Txt_threads;
/***** Write number of threads and number of posts *****/
2019-11-18 17:59:02 +01:00
HTM_TxtF (" [%u&nbsp;%s]",NumThrs,NumThrs == 1 ? Txt_thread :
Txt_threads);
2017-04-17 12:19:58 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********************** Show available threads of a forum ********************/
/*****************************************************************************/
2017-04-18 16:44:44 +02:00
void For_ShowForumTheads (void)
2017-04-14 01:02:33 +02:00
{
2020-04-07 03:01:41 +02:00
struct For_Forums Forums;
/***** Reset forum *****/
For_ResetForums (&Forums);
/***** Get parameters related to forums *****/
For_GetParamsForums (&Forums);
2017-04-16 13:45:11 +02:00
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
2017-04-16 13:45:11 +02:00
/***** Show forum threads with no one highlighted *****/
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,NULL);
2017-04-14 01:02:33 +02:00
}
2017-04-16 13:45:11 +02:00
/*****************************************************************************/
/********** Show available threads of a forum highlighting a thread **********/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_ShowForumThreadsHighlightingOneThread (struct For_Forums *Forums,
2017-05-11 23:45:46 +02:00
Ale_AlertType_t AlertType,const char *Message)
2014-12-01 23:55:08 +01:00
{
2020-09-26 17:20:01 +02:00
extern const char *Hlp_COMMUNICATION_Forums_threads;
2017-04-11 14:27:45 +02:00
extern const char *Txt_Forum;
2014-12-01 23:55:08 +01:00
extern const char *Txt_MSG_Subject;
2020-04-05 22:53:58 +02:00
extern const char *Txt_FORUM_THREAD_HELP_ORDER[Dat_NUM_START_END_TIME];
extern const char *Txt_FORUM_THREAD_ORDER[Dat_NUM_START_END_TIME];
2020-05-07 14:15:39 +02:00
extern const char *Txt_Number_BR_msgs;
2014-12-01 23:55:08 +01:00
extern const char *Txt_Unread_BR_msgs;
extern const char *Txt_WriBRters;
extern const char *Txt_ReaBRders;
char SubQuery[256];
MYSQL_RES *mysql_res;
2017-04-11 14:27:45 +02:00
char FrameTitle[128 + For_MAX_BYTES_FORUM_NAME];
char ForumName[For_MAX_BYTES_FORUM_NAME + 1];
2017-04-11 13:53:17 +02:00
unsigned NumThr;
unsigned NumThrs;
2014-12-01 23:55:08 +01:00
unsigned NumThrInScreen; // From 0 to Pag_ITEMS_PER_PAGE-1
2020-04-05 22:53:58 +02:00
Dat_StartEndTime_t Order;
2014-12-01 23:55:08 +01:00
long ThrCods[Pag_ITEMS_PER_PAGE];
struct Pagination PaginationThrs;
2017-04-11 13:53:17 +02:00
2017-04-11 14:27:45 +02:00
/***** Set forum name *****/
2020-04-10 19:14:08 +02:00
For_SetForumName (&Forums->Forum,
2017-04-11 14:27:45 +02:00
ForumName,Gbl.Prefs.Language,true);
2014-12-01 23:55:08 +01:00
/***** Get threads of a forum from database *****/
2020-04-10 19:14:08 +02:00
if (Forums->Forum.Location > 0)
sprintf (SubQuery," AND for_threads.Location=%ld",
2020-04-10 19:14:08 +02:00
Forums->Forum.Location);
2017-04-18 01:25:44 +02:00
else
SubQuery[0] = '\0';
2020-04-07 03:01:41 +02:00
switch (Forums->ThreadsOrder)
2014-12-01 23:55:08 +01:00
{
2020-04-05 22:53:58 +02:00
case Dat_START_TIME: // First post time
NumThrs = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get thread of a forum",
"SELECT for_threads.ThrCod" // row[0]
" FROM for_threads,"
"for_posts"
" WHERE for_threads.ForumType=%u"
"%s"
" AND for_threads.FirstPstCod=for_posts.PstCod"
" ORDER BY for_posts.CreatTime DESC",
(unsigned) Forums->Forum.Type,
SubQuery);
2014-12-01 23:55:08 +01:00
break;
2020-04-05 22:53:58 +02:00
case Dat_END_TIME: // Last post time
NumThrs = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get thread of a forum",
"SELECT for_threads.ThrCod" // row[0]
" FROM for_threads,"
"for_posts"
" WHERE for_threads.ForumType=%u"
"%s"
" AND for_threads.LastPstCod=for_posts.PstCod"
" ORDER BY for_posts.CreatTime DESC",
(unsigned) Forums->Forum.Type,
SubQuery);
2014-12-01 23:55:08 +01:00
break;
2018-10-31 09:40:43 +01:00
default: // Impossible
return;
2014-12-01 23:55:08 +01:00
}
/***** Compute variables related to pagination of threads *****/
PaginationThrs.NumItems = NumThrs;
2020-04-07 03:01:41 +02:00
PaginationThrs.CurrentPage = (int) Forums->CurrentPageThrs;
2014-12-01 23:55:08 +01:00
Pag_CalculatePagination (&PaginationThrs);
2017-05-25 13:43:54 +02:00
PaginationThrs.Anchor = For_FORUM_THREADS_SECTION_ID;
2020-04-07 03:01:41 +02:00
Forums->CurrentPageThrs = (unsigned) PaginationThrs.CurrentPage;
2014-12-01 23:55:08 +01:00
/***** Fill the list of threads for current page *****/
2016-10-26 01:23:02 +02:00
mysql_data_seek (mysql_res,(my_ulonglong) (PaginationThrs.FirstItemVisible - 1));
2014-12-01 23:55:08 +01:00
for (NumThr = PaginationThrs.FirstItemVisible, NumThrInScreen = 0;
NumThr <= PaginationThrs.LastItemVisible;
NumThr++, NumThrInScreen++)
/* Get thread code(row[0]) */
if ((ThrCods[NumThrInScreen] = DB_GetNextCode (mysql_res)) < 0)
2014-12-01 23:55:08 +01:00
Lay_ShowErrorAndExit ("Error when getting thread of a forum.");
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
2017-04-18 09:55:25 +02:00
/***** Show alert after action *****/
2019-10-26 01:56:36 +02:00
HTM_SECTION_Begin (For_FORUM_THREADS_SECTION_ID);
2017-04-18 09:55:25 +02:00
if (Message)
if (Message[0])
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (AlertType,Message);
2017-04-18 09:55:25 +02:00
2019-10-26 02:19:42 +02:00
/***** Begin box for threads of this forum *****/
snprintf (FrameTitle,sizeof (FrameTitle),"%s: %s",Txt_Forum,ForumName);
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,FrameTitle,
2020-04-07 03:01:41 +02:00
For_PutIconNewThread,Forums,
2020-09-26 17:20:01 +02:00
Hlp_COMMUNICATION_Forums_threads,Box_NOT_CLOSABLE);
2017-04-11 14:27:45 +02:00
2014-12-01 23:55:08 +01:00
/***** List the threads *****/
if (NumThrs)
{
/***** Write links to all the pages in the listing of threads *****/
2020-04-10 19:14:08 +02:00
Pag_WriteLinksToPagesCentered (Pag_THREADS_FORUM,&PaginationThrs,
Forums,-1L);
2014-12-01 23:55:08 +01:00
/***** Heading row *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginWideMarginPadding (2);
HTM_TR_Begin (NULL);
2019-10-12 00:07:52 +02:00
2019-10-23 19:05:05 +02:00
HTM_TH (1,1,"BT",NULL);
HTM_TH (1,1,"CONTEXT_COL",NULL); // Column for contextual icons
HTM_TH (1,1,"LM",Txt_MSG_Subject);
2019-10-12 00:07:52 +02:00
2020-04-05 22:53:58 +02:00
for (Order = Dat_START_TIME;
Order <= Dat_END_TIME;
2014-12-01 23:55:08 +01:00
Order++)
{
2019-10-23 19:05:05 +02:00
HTM_TH_Begin (1,2,"CM");
2019-10-13 15:24:06 +02:00
2020-04-10 19:14:08 +02:00
Frm_StartFormAnchor (For_ActionsSeeFor[Forums->Forum.Type],
2017-05-25 13:43:54 +02:00
For_FORUM_THREADS_SECTION_ID);
2020-04-07 03:01:41 +02:00
For_PutAllHiddenParamsForum (Forums->CurrentPageThrs, // Page of threads = current
2017-04-18 16:44:44 +02:00
1, // Page of posts = first
2020-04-07 03:01:41 +02:00
Forums->ForumSet,
2017-04-18 01:25:44 +02:00
Order,
2020-04-10 19:14:08 +02:00
Forums->Forum.Location,
2017-04-18 01:25:44 +02:00
-1L,
-1L);
2019-11-20 10:17:42 +01:00
HTM_BUTTON_SUBMIT_Begin (Txt_FORUM_THREAD_HELP_ORDER[Order],"BT_LINK TIT_TBL",NULL);
2020-04-07 03:01:41 +02:00
if (Order == Forums->ThreadsOrder)
2019-11-10 16:41:47 +01:00
HTM_U_Begin ();
2019-11-10 12:36:37 +01:00
HTM_Txt (Txt_FORUM_THREAD_ORDER[Order]);
2020-04-07 03:01:41 +02:00
if (Order == Forums->ThreadsOrder)
2019-11-10 16:41:47 +01:00
HTM_U_End ();
2019-11-18 14:21:01 +01:00
HTM_BUTTON_End ();
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2019-10-13 15:24:06 +02:00
2019-10-23 19:05:05 +02:00
HTM_TH_End ();
2014-12-01 23:55:08 +01:00
}
2019-10-12 00:07:52 +02:00
2020-05-07 14:15:39 +02:00
HTM_TH (1,1,"RM",Txt_Number_BR_msgs);
2019-10-23 19:05:05 +02:00
HTM_TH (1,1,"RM",Txt_Unread_BR_msgs);
HTM_TH (1,1,"RM",Txt_WriBRters);
HTM_TH (1,1,"RM",Txt_ReaBRders);
2019-10-12 00:07:52 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
/***** List the threads *****/
2020-11-11 01:14:53 +01:00
For_ListForumThrs (Forums,ThrCods,Forums->Thread.Current,&PaginationThrs);
2014-12-01 23:55:08 +01:00
/***** End table *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2014-12-01 23:55:08 +01:00
/***** Write links to all the pages in the listing of threads *****/
2020-04-10 19:14:08 +02:00
Pag_WriteLinksToPagesCentered (Pag_THREADS_FORUM,&PaginationThrs,
Forums,-1L);
2014-12-01 23:55:08 +01:00
}
2017-04-17 12:19:58 +02:00
/***** Put a form to write the first post of a new thread *****/
2019-10-26 01:56:36 +02:00
HTM_SECTION_Begin (For_NEW_THREAD_SECTION_ID);
2020-04-07 03:01:41 +02:00
For_WriteFormForumPst (Forums,false,NULL);
2019-10-26 01:56:36 +02:00
HTM_SECTION_End ();
2017-04-11 14:27:45 +02:00
2017-06-12 14:16:33 +02:00
/***** End box with threads of this forum ****/
2019-10-25 22:48:34 +02:00
Box_BoxEnd ();
2019-10-26 01:56:36 +02:00
HTM_SECTION_End ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2017-04-17 12:19:58 +02:00
/********************** Put icon to write a new thread ***********************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_PutIconNewThread (void *Forums)
2014-12-01 23:55:08 +01:00
{
2017-04-17 12:19:58 +02:00
extern const char *Txt_New_thread;
2014-12-01 23:55:08 +01:00
2020-04-07 03:01:41 +02:00
if (Forums)
2020-04-10 19:14:08 +02:00
Ico_PutContextualIconToAdd (For_ActionsSeeFor[((struct For_Forums *) Forums)->Forum.Type],
2020-03-26 02:54:30 +01:00
For_NEW_THREAD_SECTION_ID,
2020-04-07 03:01:41 +02:00
For_PutAllHiddenParamsNewThread,Forums,
2020-03-26 02:54:30 +01:00
Txt_New_thread);
2014-12-01 23:55:08 +01:00
}
2020-04-07 03:01:41 +02:00
static void For_PutAllHiddenParamsNewThread (void *Forums)
2017-04-19 14:43:08 +02:00
{
2020-04-07 03:01:41 +02:00
if (Forums)
2020-03-26 02:54:30 +01:00
For_PutAllHiddenParamsForum (1, // Page of threads = first
1, // Page of posts = first
2020-04-07 03:01:41 +02:00
((struct For_Forums *)Forums)->ForumSet,
((struct For_Forums *)Forums)->ThreadsOrder,
2020-04-10 19:14:08 +02:00
((struct For_Forums *)Forums)->Forum.Location,
2020-03-26 02:54:30 +01:00
-1L,
-1L);
2017-04-19 14:43:08 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********************** Get number of forums of a type ***********************/
/*****************************************************************************/
unsigned For_GetNumTotalForumsOfType (For_ForumType_t ForumType,
2015-03-09 01:25:59 +01:00
long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod)
2014-12-01 23:55:08 +01:00
{
/***** Get number of forums of a type from database *****/
switch (ForumType)
{
2017-04-18 19:55:56 +02:00
case For_FORUM_GLOBAL_USRS:
case For_FORUM_GLOBAL_TCHS:
case For_FORUM__SWAD__USRS:
case For_FORUM__SWAD__TCHS:
2014-12-01 23:55:08 +01:00
return 1; // Only one forum
2017-04-18 19:55:56 +02:00
case For_FORUM_INSTIT_USRS:
case For_FORUM_INSTIT_TCHS:
if (InsCod > 0)
// InsCod > 0 ==> 0 <= number of institutions forums for an institution <= 1
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT Location)"
" FROM for_threads"
" WHERE ForumType=%u"
" AND Location=%ld",
(unsigned) ForumType,
InsCod);
if (CtyCod > 0)
// InsCod <= 0 && CtyCod > 0 ==> Number of institution forums for a country
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT for_threads.Location)"
" FROM for_threads,"
"ins_instits"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld",
(unsigned) ForumType,
CtyCod);
// CtyCod <= 0 ==> Number of institutions forums for the whole platform
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT Location)"
" FROM for_threads"
" WHERE ForumType=%u",
(unsigned) ForumType);
case For_FORUM_CENTER_USRS:
case For_FORUM_CENTER_TCHS:
if (CtrCod > 0)
// CtrCod > 0 ==> 0 <= number of center forums for a center <= 1
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT Location)"
" FROM for_threads"
" WHERE ForumType=%u"
" AND Location=%ld",
(unsigned) ForumType,
CtrCod);
if (InsCod > 0)
// CtrCod <= 0 && InsCod > 0 ==> Number of center forums for an institution
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT for_threads.Location)"
" FROM for_threads,"
"ctr_centers"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=%ld",
(unsigned) ForumType,
InsCod);
if (CtyCod > 0)
// InsCod <= 0 && CtyCod > 0 ==> Number of center forums for a country
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT for_threads.Location)"
" FROM for_threads,"
"ctr_centers,"
"ins_instits"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld",
(unsigned) ForumType,
CtyCod);
// InsCod <= 0 ==> Number of center forums for the whole platform
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT Location)"
" FROM for_threads"
" WHERE ForumType=%u",
(unsigned) ForumType);
2017-04-18 19:55:56 +02:00
case For_FORUM_DEGREE_USRS:
case For_FORUM_DEGREE_TCHS:
if (DegCod > 0)
// DegCod > 0 ==> 0 <= number of degree forums for a degree <= 1
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT Location)"
" FROM for_threads"
" WHERE ForumType=%u"
" AND Location=%ld",
(unsigned) ForumType,
DegCod);
if (CtrCod > 0)
// DegCod <= 0 && CtrCod > 0 ==> Number of degree forums for a center
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT for_threads.Location)"
" FROM for_threads,"
"deg_degrees"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=%ld",
(unsigned) ForumType,
CtrCod);
if (InsCod > 0)
// CtrCod <= 0 && InsCod > 0 ==> Number of degree forums for an institution
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT for_threads.Location)"
" FROM for_threads,"
"deg_degrees,"
"ctr_centers"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=%ld",
(unsigned) ForumType,
InsCod);
if (CtyCod > 0)
// InsCod <= 0 && CtyCod > 0 ==> Number of degree forums for a country
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT for_threads.Location)"
" FROM for_threads,"
"deg_degrees,"
"ctr_centers,"
"ins_instits"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld",
(unsigned) ForumType,
CtyCod);
// InsCod <= 0 ==> Number of degree forums for the whole platform
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT Location)"
" FROM for_threads"
" WHERE ForumType=%u",
(unsigned) ForumType);
2017-04-18 19:55:56 +02:00
case For_FORUM_COURSE_USRS:
case For_FORUM_COURSE_TCHS:
if (CrsCod > 0)
// CrsCod > 0 ==> 0 <= number of course forums for a course <= 1
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT Location)"
" FROM for_threads"
" WHERE ForumType=%u"
" AND Location=%ld",
(unsigned) ForumType,
CrsCod);
if (DegCod > 0)
// CrsCod <= 0 && DegCod > 0 ==> Number of course forums for a degree
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT for_threads.Location)"
" FROM for_threads,"
"crs_courses"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=%ld",
(unsigned) ForumType,
DegCod);
if (CtrCod > 0)
// DegCod <= 0 && CtrCod > 0 ==> Number of course forums for a center
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT for_threads.Location)"
" FROM for_threads,"
"crs_courses,"
"deg_degrees"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=%ld",
(unsigned) ForumType,
CtrCod);
if (InsCod > 0)
// CtrCod <= 0 && InsCod > 0 ==> Number of course forums for an institution
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT for_threads.Location)"
" FROM for_threads,"
"crs_courses,"
"deg_degrees,"
"ctr_centers"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=%ld",
(unsigned) ForumType,
InsCod);
if (CtyCod > 0)
// InsCod <= 0 && CtyCod > 0 ==> Number of course forums for a country
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT for_threads.Location)"
" FROM for_threads,"
"crs_courses,"
"deg_degrees,"
"ctr_centers,"
"ins_instits"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld",
(unsigned) ForumType,
CtyCod);
// InsCod <= 0 ==> Number of course forums for the whole platform
return (unsigned)
DB_QueryCOUNT ("can not get number of forums of a type",
"SELECT COUNT(DISTINCT Location)"
" FROM for_threads"
" WHERE ForumType=%u",
(unsigned) ForumType);
2017-04-18 19:55:56 +02:00
default:
return 0;
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/*********** Get total number of threads in forums of this type **************/
/*****************************************************************************/
unsigned For_GetNumTotalThrsInForumsOfType (For_ForumType_t ForumType,
2015-03-09 01:25:59 +01:00
long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod)
2014-12-01 23:55:08 +01:00
{
/***** Get total number of threads in forums of this type from database *****/
switch (ForumType)
{
2017-04-18 19:55:56 +02:00
case For_FORUM_GLOBAL_USRS:
case For_FORUM_GLOBAL_TCHS:
case For_FORUM__SWAD__USRS:
case For_FORUM__SWAD__TCHS:
2014-12-01 23:55:08 +01:00
// Total number of threads in forums of this type
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ForumType=%u",
(unsigned) ForumType);
2017-04-18 19:55:56 +02:00
case For_FORUM_INSTIT_USRS:
case For_FORUM_INSTIT_TCHS:
if (InsCod > 0)
// InsCod > 0 ==> Number of threads in institution forums for an institution
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ForumType=%u"
" AND Location=%ld",
(unsigned) ForumType,
InsCod);
if (CtyCod > 0)
// InsCod <= 0 && CtyCod > 0 ==> Number of threads in institution forums for a country
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads,"
"ins_instits"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld",
(unsigned) ForumType,
CtyCod);
// InsCod <= 0 ==> Number of threads in institution forums for the whole platform
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ForumType=%u",
(unsigned) ForumType);
case For_FORUM_CENTER_USRS:
case For_FORUM_CENTER_TCHS:
if (CtrCod > 0)
// CtrCod > 0 ==> 0 <= Number of threads in center forums for a center <= 1
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ForumType=%u"
" AND Location=%ld",
(unsigned) ForumType,
CtrCod);
if (InsCod > 0)
// CtrCod <= 0 && InsCod > 0 ==> Number of threads in center forums for an institution
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads,"
"ctr_centers"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=%ld",
(unsigned) ForumType,
InsCod);
if (CtyCod > 0)
// InsCod <= 0 && CtyCod > 0 ==> Number of threads in center forums for a country
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads,"
"ctr_centers,"
"ins_instits"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld",
(unsigned) ForumType,
CtyCod);
// InsCod <= 0 ==> Number of threads in center forums for the whole platform
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ForumType=%u",
(unsigned) ForumType);
2017-04-18 19:55:56 +02:00
case For_FORUM_DEGREE_USRS:
case For_FORUM_DEGREE_TCHS:
if (DegCod > 0)
// DegCod > 0 ==> Number of threads in degree forums for a degree
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ForumType=%u"
" AND Location=%ld",
(unsigned) ForumType,
DegCod);
if (CtrCod > 0)
// DegCod <= 0 && CtrCod > 0 ==> Number of threads in degree forums for a center
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads,"
"deg_degrees"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=%ld",
(unsigned) ForumType,
CtrCod);
if (InsCod > 0)
// CtrCod <= 0 && InsCod > 0 ==> Number of threads in degree forums for an institution
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads,"
"deg_degrees,"
"ctr_centers"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=%ld",
(unsigned) ForumType,
InsCod);
if (CtyCod > 0) // InsCod <= 0 && CtyCod > 0 ==> Number of threads in degree forums for a country
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads,"
"deg_degrees,"
"ctr_centers,"
"ins_instits"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld",
(unsigned) ForumType,
CtyCod);
// InsCod <= 0 ==> Number of threads in degree forums for the whole platform
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ForumType=%u",
(unsigned) ForumType);
2017-04-18 19:55:56 +02:00
case For_FORUM_COURSE_USRS:
case For_FORUM_COURSE_TCHS:
if (CrsCod > 0)
// CrsCod > 0 ==> 0 <= Number of threads in course forums for a course
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ForumType=%u"
" AND Location=%ld",
(unsigned) ForumType,
CrsCod);
if (DegCod > 0)
// CrsCod <= 0 && DegCod > 0 ==> Number of threads in course forums for a degree
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads,"
"crs_courses"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=%ld",
(unsigned) ForumType,
DegCod);
if (CtrCod > 0)
// DegCod <= 0 && CtrCod > 0 ==> Number of threads in course forums for a center
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads,"
"crs_courses,"
"deg_degrees"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=%ld",
(unsigned) ForumType,
CtrCod);
if (InsCod > 0)
// CtrCod <= 0 && InsCod > 0 ==> Number of threads in course forums for an institution
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads,"
"crs_courses,"
"deg_degrees,"
"ctr_centers"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=%ld",
(unsigned) ForumType,
InsCod);
if (CtyCod > 0)
// InsCod <= 0 && CtyCod > 0 ==> Number of threads in course forums for a country
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads,"
"crs_courses,"
"deg_degrees,"
"ctr_centers,"
"ins_instits"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld",
(unsigned) ForumType,
CtyCod);
// InsCod <= 0 ==> Number of threads in course forums for the whole platform
return (unsigned)
DB_QueryCOUNT ("can not get the number of threads in forums of a type",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ForumType=%u",
(unsigned) ForumType);
2017-04-18 19:55:56 +02:00
default:
return 0;
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/******************* Get number of threads in a forum ************************/
/*****************************************************************************/
static unsigned For_GetNumThrsInForum (const struct For_Forum *Forum)
2014-12-01 23:55:08 +01:00
{
char SubQuery[256];
/***** Get number of threads in a forum from database *****/
2017-04-19 12:34:38 +02:00
if (Forum->Location > 0)
sprintf (SubQuery," AND Location=%ld",Forum->Location);
2017-04-16 23:48:05 +02:00
else
SubQuery[0] = '\0';
return (unsigned)
DB_QueryCOUNT ("can not get number of threads in a forum",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ForumType=%u"
"%s",
(unsigned) Forum->Type,
SubQuery);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************** Get total number of posts in forums of a type ****************/
/*****************************************************************************/
unsigned For_GetNumTotalPstsInForumsOfType (For_ForumType_t ForumType,
2015-03-09 01:25:59 +01:00
long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod,
2014-12-01 23:55:08 +01:00
unsigned *NumUsrsToBeNotifiedByEMail)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumPosts;
/***** Get total number of posts in forums of this type from database *****/
switch (ForumType)
{
2017-04-18 19:55:56 +02:00
case For_FORUM_GLOBAL_USRS:
case For_FORUM_GLOBAL_TCHS:
case For_FORUM__SWAD__USRS:
case For_FORUM__SWAD__TCHS:
2014-12-01 23:55:08 +01:00
// Total number of posts in forums of this type
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"for_posts "
" WHERE for_threads.ForumType=%u"
" AND for_threads.ThrCod=for_posts.ThrCod",
2018-10-31 09:40:43 +01:00
(unsigned) ForumType);
2014-12-01 23:55:08 +01:00
break;
2016-10-28 00:23:02 +02:00
case For_FORUM_INSTIT_USRS: case For_FORUM_INSTIT_TCHS:
2014-12-01 23:55:08 +01:00
if (InsCod > 0) // InsCod > 0 ==> Number of posts in institutions forums for an institution
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
InsCod);
2015-03-09 01:25:59 +01:00
else if (CtyCod > 0) // InsCod <= 0 && CtyCod > 0 ==> Number of posts in institutions forums for a country
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"ins_instits,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
CtyCod);
2014-12-01 23:55:08 +01:00
else // InsCod <= 0 ==> Number of posts in institution forums for the whole platform
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"for_posts "
" WHERE for_threads.ForumType=%u"
" AND for_threads.ThrCod=for_posts.ThrCod",
2018-10-31 09:40:43 +01:00
(unsigned) ForumType);
2014-12-01 23:55:08 +01:00
break;
case For_FORUM_CENTER_USRS:
case For_FORUM_CENTER_TCHS:
if (CtrCod > 0) // CtrCod > 0 ==> Number of posts in center forums for a center
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
CtrCod);
else if (InsCod > 0) // CtrCod <= 0 && InsCod > 0 ==> Number of posts in center forums for an institution
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"ctr_centers,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
InsCod);
else if (CtyCod > 0) // InsCod <= 0 && CtyCod > 0 ==> Number of posts in center forums for a country
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"ctr_centers,"
"ins_instits,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
CtyCod);
else // InsCod <= 0 ==> Number of posts in center forums for the whole platform
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.ThrCod=for_posts.ThrCod",
2018-10-31 09:40:43 +01:00
(unsigned) ForumType);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_DEGREE_USRS:
case For_FORUM_DEGREE_TCHS:
2014-12-01 23:55:08 +01:00
if (DegCod > 0) // DegCod > 0 ==> Number of posts in degree forums for a degree
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
DegCod);
else if (CtrCod > 0) // DegCod <= 0 && CtrCod > 0 ==> Number of posts in degree forums for a center
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"deg_degrees,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
CtrCod);
2014-12-01 23:55:08 +01:00
else if (InsCod > 0) // CtrCod <= 0 && InsCod > 0 ==> Number of posts in degree forums for an institution
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"deg_degrees,"
"ctr_centers,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
InsCod);
2015-03-09 01:25:59 +01:00
else if (CtyCod > 0) // InsCod <= 0 && CtyCod > 0 ==> Number of posts in degree forums for a country
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"deg_degrees,"
"ctr_centers,"
"ins_instits,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
CtyCod);
2014-12-01 23:55:08 +01:00
else // InsCod <= 0 ==> Number of posts in degree forums for the whole platform
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"for_posts "
" WHERE for_threads.ForumType=%u"
" AND for_threads.ThrCod=for_posts.ThrCod",
2018-10-31 09:40:43 +01:00
(unsigned) ForumType);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_COURSE_USRS:
case For_FORUM_COURSE_TCHS:
2014-12-01 23:55:08 +01:00
if (CrsCod > 0) // CrsCod > 0 ==> 0 <= number of posts in course forums for a course
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"for_posts "
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
CrsCod);
2014-12-01 23:55:08 +01:00
else if (DegCod > 0) // CrsCod <= 0 && DegCod > 0 ==> Number of posts in course forums for a degree
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"crs_courses,"
"for_posts "
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
DegCod);
else if (CtrCod > 0) // DegCod <= 0 && CtrCod > 0 ==> Number of posts in course forums for a center
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"crs_courses,"
"deg_degrees,"
"for_posts "
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
CtrCod);
2014-12-01 23:55:08 +01:00
else if (InsCod > 0) // CtrCod <= 0 && InsCod > 0 ==> Number of posts in course forums for an institution
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"crs_courses,"
"deg_degrees,"
"ctr_centers,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
InsCod);
2015-03-09 01:25:59 +01:00
else if (CtyCod > 0) // InsCod <= 0 && CtyCod > 0 ==> Number of posts in course forums for a country
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"crs_courses,"
"deg_degrees,"
"ctr_centers,"
"ins_instits,"
"for_posts"
" WHERE for_threads.ForumType=%u"
" AND for_threads.Location=crs_courses.CrsCod"
" AND crs_courses.DegCod=deg_degrees.DegCod"
" AND deg_degrees.CtrCod=ctr_centers.CtrCod"
" AND ctr_centers.InsCod=ins_instits.InsCod"
" AND ins_instits.CtyCod=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
(unsigned) ForumType,
CtyCod);
2014-12-01 23:55:08 +01:00
else // CrsCod <= 0 && DegCod <= 0 && CtrCod <= 0 ==> Number of posts in course forums for the whole platform
2018-10-31 09:40:43 +01:00
DB_QuerySELECT (&mysql_res,"can not get the total number"
" of forums of a type",
"SELECT COUNT(*)," // row[0]
"SUM(for_posts.NumNotif)" // row[1]
" FROM for_threads,"
"for_posts "
" WHERE for_threads.ForumType=%u"
" AND for_threads.ThrCod=for_posts.ThrCod",
2018-10-31 09:40:43 +01:00
(unsigned) ForumType);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
default:
return 0;
2014-12-01 23:55:08 +01:00
}
/* Get row with number of posts */
row = mysql_fetch_row (mysql_res);
/* Get number of posts (row[0]) */
if (sscanf (row[0],"%u",&NumPosts) != 1)
Lay_ShowErrorAndExit ("Error when getting the total number of forums of a type.");
/* Get number of users notified (row[1]) */
if (row[1])
{
if (sscanf (row[1],"%u",NumUsrsToBeNotifiedByEMail) != 1)
Lay_ShowErrorAndExit ("Error when getting the total number of forums of a type.");
}
else
*NumUsrsToBeNotifiedByEMail = 0;
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return NumPosts;
}
/*****************************************************************************/
/************************ List the threads of a forum ************************/
/*****************************************************************************/
2020-04-10 19:14:08 +02:00
static void For_ListForumThrs (struct For_Forums *Forums,
2020-04-07 03:01:41 +02:00
long ThrCods[Pag_ITEMS_PER_PAGE],
2017-04-14 01:02:33 +02:00
long ThrCodHighlighted,
2017-04-13 23:53:57 +02:00
struct Pagination *PaginationThrs)
2014-12-01 23:55:08 +01:00
{
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormInBox[The_NUM_THEMES];
extern const char *The_ClassFormInBoxBold[The_NUM_THEMES];
2014-12-01 23:55:08 +01:00
extern const char *Txt_Thread_with_posts_from_you;
extern const char *Txt_There_are_new_posts;
extern const char *Txt_No_new_posts;
unsigned NumThr;
unsigned NumThrInScreen; // From 0 to Pag_ITEMS_PER_PAGE-1
2020-04-14 00:11:28 +02:00
struct For_Thread Thr;
2015-10-24 20:46:11 +02:00
unsigned UniqueId;
2019-11-01 22:53:39 +01:00
char *Id;
2014-12-01 23:55:08 +01:00
struct UsrData UsrDat;
2020-04-05 22:53:58 +02:00
Dat_StartEndTime_t Order;
2015-10-24 20:12:03 +02:00
time_t TimeUTC;
2014-12-01 23:55:08 +01:00
struct Pagination PaginationPsts;
const char *Style;
long ThreadInMyClipboard = -1L;
unsigned Column;
2015-09-04 17:43:18 +02:00
const char *BgColor;
2017-04-18 13:17:40 +02:00
bool ICanMoveThreads;
2014-12-01 23:55:08 +01:00
/***** Get if there is a thread ready to be moved *****/
2017-04-18 13:17:40 +02:00
if ((ICanMoveThreads = For_CheckIfICanMoveThreads ()))
2014-12-01 23:55:08 +01:00
ThreadInMyClipboard = For_GetThrInMyClipboard ();
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
2020-12-01 09:58:21 +01:00
/***** List threads *****/
2020-04-14 00:11:28 +02:00
for (NumThr = PaginationThrs->FirstItemVisible, NumThrInScreen = 0, UniqueId = 0, Gbl.RowEvenOdd = 0;
2014-12-01 23:55:08 +01:00
NumThr <= PaginationThrs->LastItemVisible;
NumThr++, NumThrInScreen++, Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd)
{
/***** Get the data of this thread *****/
2020-04-14 00:11:28 +02:00
Thr.ThrCod = ThrCods[NumThrInScreen];
For_GetThreadData (&Thr);
2020-11-11 01:14:53 +01:00
Forums->Thread.Current = Thr.ThrCod;
2020-04-14 00:11:28 +02:00
Style = (Thr.NumUnreadPosts ? "AUTHOR_TXT_NEW" :
"AUTHOR_TXT");
BgColor = (Thr.ThrCod == ThreadInMyClipboard) ? "LIGHT_GREEN" :
((Thr.ThrCod == ThrCodHighlighted) ? "LIGHT_BLUE" :
Gbl.ColorRows[Gbl.RowEvenOdd]);
2014-12-01 23:55:08 +01:00
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-12 19:10:32 +02:00
/***** Show my photo if I have any posts in this thread *****/
HTM_TD_Begin ("class=\"BT %s\"",BgColor);
if (Thr.NumMyPosts)
HTM_IMG (Gbl.Usrs.Me.PhotoURL[0] ? Gbl.Usrs.Me.PhotoURL :
Cfg_URL_ICON_PUBLIC,
Gbl.Usrs.Me.PhotoURL[0] ? NULL :
"usr_bl.jpg",
Txt_Thread_with_posts_from_you,
"class=\"PHOTO15x20\"");
HTM_TD_End ();
HTM_TD_Begin ("class=\"CONTEXT_COL %s\"",BgColor);
/***** Put an icon with thread status *****/
Ico_PutIcon (Thr.NumUnreadPosts ? "envelope.svg" :
"envelope-open-text.svg",
Thr.NumUnreadPosts ? Txt_There_are_new_posts :
Txt_No_new_posts,
"ICO16x16");
/***** Put button to remove the thread *****/
if (PermissionThreadDeletion[Forums->Forum.Type] &
(1 << Gbl.Usrs.Me.Role.Logged)) // If I have permission to remove thread in this forum...
{
HTM_BR ();
Ico_PutContextualIconToRemove (For_ActionsReqDelThr[Forums->Forum.Type],For_REMOVE_THREAD_SECTION_ID,
For_PutParamsForum,Forums);
}
2014-12-01 23:55:08 +01:00
/***** Put button to cut the thread for moving it to another forum *****/
if (ICanMoveThreads)
{
HTM_BR ();
Frm_StartFormAnchor (For_ActionsCutThrFor[Forums->Forum.Type],
For_FORUM_THREADS_SECTION_ID);
For_PutAllHiddenParamsForum (Forums->CurrentPageThrs, // Page of threads = current
1, // Page of posts = first
Forums->ForumSet,
Forums->ThreadsOrder,
Forums->Forum.Location,
Thr.ThrCod,
-1L);
Ico_PutIconCut ();
Frm_EndForm ();
}
2014-12-01 23:55:08 +01:00
HTM_TD_End ();
/***** Write subject and links to thread pages *****/
HTM_TD_Begin ("class=\"LT %s\"",BgColor);
PaginationPsts.NumItems = Thr.NumPosts;
PaginationPsts.CurrentPage = 1; // First page
Pag_CalculatePagination (&PaginationPsts);
PaginationPsts.Anchor = For_FORUM_POSTS_SECTION_ID;
Pag_WriteLinksToPages (Pag_POSTS_FORUM,
&PaginationPsts,
Forums,Thr.ThrCod,
Thr.Enabled[Dat_START_TIME],
Thr.Subject,
Thr.NumUnreadPosts ? The_ClassFormInBoxBold[Gbl.Prefs.Theme] :
The_ClassFormInBox[Gbl.Prefs.Theme],
true);
HTM_TD_End ();
/***** Write the authors and date-times of first and last posts *****/
for (Order = Dat_START_TIME;
Order <= Dat_END_TIME;
Order++)
{
if (Order == Dat_START_TIME || Thr.NumPosts > 1) // Don't write twice the same author when thread has only one thread
{
/* Write the author of first or last message */
UsrDat.UsrCod = Thr.UsrCod[Order];
Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS);
HTM_TD_Begin ("class=\"%s LT %s\"",Style,BgColor);
Msg_WriteMsgAuthor (&UsrDat,Thr.Enabled[Order],BgColor);
HTM_TD_End ();
/* Write the date of first or last message (it's in YYYYMMDDHHMMSS format) */
TimeUTC = Thr.WriteTime[Order];
UniqueId++;
if (asprintf (&Id,"thr_date_%u",UniqueId) < 0)
Lay_NotEnoughMemoryExit ();
HTM_TD_Begin ("id=\"%s\" class=\"%s LT %s\"",Id,Style,BgColor);
Dat_WriteLocalDateHMSFromUTC (Id,TimeUTC,
Gbl.Prefs.DateFormat,Dat_SEPARATOR_BREAK,
true,true,false,0x6);
HTM_TD_End ();
free (Id);
}
else
for (Column = 1;
Column <= 2;
Column++)
{
HTM_TD_Begin ("class=\"%s LT %s\"",Style,BgColor);
HTM_TD_End ();
}
}
2014-12-01 23:55:08 +01:00
/***** Write number of posts in this thread *****/
HTM_TD_Begin ("class=\"%s RT %s\"",Style,BgColor);
HTM_TxtF ("%u&nbsp;",Thr.NumPosts);
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write number of new posts in this thread *****/
HTM_TD_Begin ("class=\"%s RT %s\"",Style,BgColor);
HTM_TxtF ("%u&nbsp;",Thr.NumUnreadPosts);
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write number of users who have write posts in this thread *****/
HTM_TD_Begin ("class=\"%s RT %s\"",Style,BgColor);
HTM_TxtF ("%u&nbsp;",Thr.NumWriters);
HTM_TD_End ();
2014-12-01 23:55:08 +01:00
/***** Write number of users who have read this thread *****/
HTM_TD_Begin ("class=\"%s RT %s\"",Style,BgColor);
HTM_TxtF ("%u&nbsp;",Thr.NumReaders);
HTM_TD_End ();
2019-10-07 15:15:55 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2014-12-01 23:55:08 +01:00
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
}
/*****************************************************************************/
/***************************** Get data of a thread **************************/
/*****************************************************************************/
2020-04-10 19:14:08 +02:00
static void For_GetThreadData (struct For_Thread *Thr)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_no_subject;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2020-04-05 22:53:58 +02:00
Dat_StartEndTime_t Order;
2014-12-01 23:55:08 +01:00
/***** Get data of a thread from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get data of a thread of a forum",
"SELECT m0.PstCod," // row[0]
"m1.PstCod," // row[1]
"m0.UsrCod," // row[2]
"m1.UsrCod," // row[3]
"UNIX_TIMESTAMP(m0.CreatTime)," // row[4]
"UNIX_TIMESTAMP(m1.CreatTime)," // row[5]
"m0.Subject"
" FROM for_threads,"
"for_posts AS m0,"
"for_posts AS m1"
" WHERE for_threads.ThrCod=%ld"
" AND for_threads.FirstPstCod=m0.PstCod"
" AND for_threads.LastPstCod=m1.PstCod",
Thr->ThrCod) != 1)
2014-12-01 23:55:08 +01:00
Lay_ShowErrorAndExit ("Error when getting data of a thread of a forum.");
row = mysql_fetch_row (mysql_res);
2016-12-30 01:20:49 +01:00
/***** Get the code of the first post in this thread (row[0]) *****/
2020-04-05 22:53:58 +02:00
Thr->PstCod[Dat_START_TIME] = Str_ConvertStrCodToLongCod (row[0]);
2016-12-30 01:20:49 +01:00
/***** Get the code of the last post in this thread (row[1]) *****/
2020-04-05 22:53:58 +02:00
Thr->PstCod[Dat_END_TIME ] = Str_ConvertStrCodToLongCod (row[1]);
2016-12-30 01:20:49 +01:00
/***** Get the code of the first message (row[0])
and the last message (row[1]) in this thread *****/
2020-04-05 22:53:58 +02:00
if (sscanf (row[0],"%ld",&(Thr->PstCod[Dat_START_TIME])) != 1)
Lay_WrongPostExit ();
2020-04-05 22:53:58 +02:00
if (sscanf (row[1],"%ld",&(Thr->PstCod[Dat_END_TIME])) != 1)
Lay_WrongPostExit ();
2014-12-01 23:55:08 +01:00
2016-12-30 01:20:49 +01:00
/***** Get the author of the first post in this thread (row[2]) *****/
2020-04-05 22:53:58 +02:00
Thr->UsrCod[Dat_START_TIME] = Str_ConvertStrCodToLongCod (row[2]);
2014-12-01 23:55:08 +01:00
2016-12-30 01:20:49 +01:00
/***** Get the author of the last post in this thread (row[3]) *****/
2020-04-05 22:53:58 +02:00
Thr->UsrCod[Dat_END_TIME ] = Str_ConvertStrCodToLongCod (row[3]);
2014-12-01 23:55:08 +01:00
2016-12-30 01:20:49 +01:00
/***** Get the date of the first post in this thread (row[4]) *****/
2020-04-05 22:53:58 +02:00
Thr->WriteTime[Dat_START_TIME] = Dat_GetUNIXTimeFromStr (row[4]);
2014-12-01 23:55:08 +01:00
2016-12-30 01:20:49 +01:00
/***** Get the date of the last post in this thread (row[5]) *****/
2020-04-05 22:53:58 +02:00
Thr->WriteTime[Dat_END_TIME ] = Dat_GetUNIXTimeFromStr (row[5]);
2014-12-01 23:55:08 +01:00
/***** Get the subject of this thread (row[6]) *****/
Str_Copy (Thr->Subject,row[6],sizeof (Thr->Subject) - 1);
2014-12-01 23:55:08 +01:00
if (!Thr->Subject[0])
snprintf (Thr->Subject,sizeof (Thr->Subject),"[%s]",Txt_no_subject);
2014-12-01 23:55:08 +01:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
/***** Get if first or last message are enabled *****/
2020-04-05 22:53:58 +02:00
for (Order = Dat_START_TIME;
Order <= Dat_END_TIME;
2014-12-01 23:55:08 +01:00
Order++)
2017-04-18 20:09:12 +02:00
Thr->Enabled[Order] = For_GetIfPstIsEnabled (Thr->PstCod[Order]);
// Thr->Enabled[Order] = true;
2014-12-01 23:55:08 +01:00
/***** Get number of posts in this thread *****/
Thr->NumPosts = For_GetNumPstsInThr (Thr->ThrCod);
/***** Get number of unread (by me) posts in this thread *****/
Thr->NumUnreadPosts = For_GetNumOfUnreadPostsInThr (Thr->ThrCod,Thr->NumPosts);
/***** Get number of posts that I have written in this thread *****/
Thr->NumMyPosts = For_GetNumMyPstInThr (Thr->ThrCod);
/***** Get number of users who have write posts in this thread *****/
Thr->NumWriters = For_GetNumOfWritersInThr (Thr->ThrCod);
/***** Get number of users who have read this thread *****/
Thr->NumReaders = For_GetNumOfReadersOfThr (Thr->ThrCod);
}
/*****************************************************************************/
/**************** Show posts of a thread in a discussion forum ***************/
/*****************************************************************************/
2017-04-18 16:44:44 +02:00
void For_ShowThreadPosts (void)
2014-12-01 23:55:08 +01:00
{
2020-04-07 03:01:41 +02:00
struct For_Forums Forums;
/***** Reset forum *****/
For_ResetForums (&Forums);
/***** Get parameters related to forums *****/
For_GetParamsForums (&Forums);
2014-12-01 23:55:08 +01:00
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
/***** Show threads again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,NULL);
2017-04-18 13:17:40 +02:00
2014-12-01 23:55:08 +01:00
/***** Show the posts of that thread *****/
2020-04-07 03:01:41 +02:00
For_ShowPostsOfAThread (&Forums,Ale_SUCCESS,NULL);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************* Get parameters related to a forum *********************/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_GetParamsForums (struct For_Forums *Forums)
2014-12-01 23:55:08 +01:00
{
2017-04-16 13:45:11 +02:00
/***** Set forum type *****/
2020-04-07 03:01:41 +02:00
For_SetForumType (Forums);
2017-04-16 13:45:11 +02:00
/***** Get parameter with code of course, degree, center or institution *****/
2020-04-10 19:14:08 +02:00
switch (Forums->Forum.Type)
2017-04-16 13:54:02 +02:00
{
case For_FORUM_INSTIT_USRS:
case For_FORUM_INSTIT_TCHS:
case For_FORUM_CENTER_USRS:
case For_FORUM_CENTER_TCHS:
2017-04-18 19:55:56 +02:00
case For_FORUM_DEGREE_USRS:
case For_FORUM_DEGREE_TCHS:
case For_FORUM_COURSE_USRS:
case For_FORUM_COURSE_TCHS:
2020-04-10 19:14:08 +02:00
Forums->Forum.Location = Par_GetParToLong ("Location");
2017-04-16 13:54:02 +02:00
break;
default:
2020-04-10 19:14:08 +02:00
Forums->Forum.Location = -1L;
2017-04-16 13:54:02 +02:00
break;
}
2017-04-17 19:03:21 +02:00
/***** Get optional parameter with code of a selected thread *****/
2020-11-11 01:14:53 +01:00
Forums->Thread.Current =
Forums->Thread.Selected = Par_GetParToLong ("ThrCod");
2017-04-18 01:25:44 +02:00
/***** Get optional parameter with code of a selected post *****/
2020-04-14 00:11:28 +02:00
Forums->PstCod = Par_GetParToLong ("PstCod");
2017-04-17 19:03:21 +02:00
2017-04-16 13:45:11 +02:00
/***** Get which forums I want to see *****/
2020-04-07 03:01:41 +02:00
Forums->ForumSet = (For_ForumSet_t)
Par_GetParToUnsignedLong ("ForumSet",
0,
For_NUM_FORUM_SETS - 1,
(unsigned long) For_DEFAULT_FORUM_SET);
2017-04-16 13:45:11 +02:00
/***** Get order type *****/
2020-04-07 03:01:41 +02:00
Forums->ThreadsOrder = (Dat_StartEndTime_t)
Par_GetParToUnsignedLong ("Order",
0,
Dat_NUM_START_END_TIME - 1,
(unsigned long) For_DEFAULT_ORDER);
2017-04-16 13:45:11 +02:00
2017-04-18 13:17:40 +02:00
/***** Get optional page numbers for threads and posts *****/
2020-04-07 03:01:41 +02:00
Forums->CurrentPageThrs = Pag_GetParamPagNum (Pag_THREADS_FORUM);
Forums->CurrentPagePsts = Pag_GetParamPagNum (Pag_POSTS_FORUM);
2017-04-18 13:17:40 +02:00
2017-04-16 13:45:11 +02:00
/***** Restrict access to forum *****/
2020-04-07 03:01:41 +02:00
For_RestrictAccess (Forums);
2017-04-16 13:45:11 +02:00
}
2017-04-14 00:27:38 +02:00
2017-04-16 13:45:11 +02:00
/*****************************************************************************/
/***************************** Set the type of forum *************************/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_SetForumType (struct For_Forums *Forums)
2017-04-16 13:45:11 +02:00
{
switch (Gbl.Action.Act)
{
case ActSeeFor:
case ActSeeForGenUsr: case ActSeePstForGenUsr:
case ActRcvThrForGenUsr: case ActRcvRepForGenUsr:
case ActReqDelThrGenUsr: case ActDelThrForGenUsr:
case ActCutThrForGenUsr: case ActPasThrForGenUsr:
case ActDelPstForGenUsr:
case ActEnbPstForGenUsr: case ActDisPstForGenUsr:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM_GLOBAL_USRS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForGenTch: case ActSeePstForGenTch:
case ActRcvThrForGenTch: case ActRcvRepForGenTch:
case ActReqDelThrGenTch: case ActDelThrForGenTch:
case ActCutThrForGenTch: case ActPasThrForGenTch:
case ActDelPstForGenTch:
case ActEnbPstForGenTch: case ActDisPstForGenTch:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM_GLOBAL_TCHS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForSWAUsr: case ActSeePstForSWAUsr:
case ActRcvThrForSWAUsr: case ActRcvRepForSWAUsr:
case ActReqDelThrSWAUsr: case ActDelThrForSWAUsr:
case ActCutThrForSWAUsr: case ActPasThrForSWAUsr:
case ActDelPstForSWAUsr:
case ActEnbPstForSWAUsr: case ActDisPstForSWAUsr:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM__SWAD__USRS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForSWATch: case ActSeePstForSWATch:
case ActRcvThrForSWATch: case ActRcvRepForSWATch:
case ActReqDelThrSWATch: case ActDelThrForSWATch:
case ActCutThrForSWATch: case ActPasThrForSWATch:
case ActDelPstForSWATch:
case ActEnbPstForSWATch: case ActDisPstForSWATch:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM__SWAD__TCHS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForInsUsr: case ActSeePstForInsUsr:
case ActRcvThrForInsUsr: case ActRcvRepForInsUsr:
case ActReqDelThrInsUsr: case ActDelThrForInsUsr:
case ActCutThrForInsUsr: case ActPasThrForInsUsr:
case ActDelPstForInsUsr:
case ActEnbPstForInsUsr: case ActDisPstForInsUsr:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM_INSTIT_USRS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForInsTch: case ActSeePstForInsTch:
case ActRcvThrForInsTch: case ActRcvRepForInsTch:
case ActReqDelThrInsTch: case ActDelThrForInsTch:
case ActCutThrForInsTch: case ActPasThrForInsTch:
case ActDelPstForInsTch:
case ActEnbPstForInsTch: case ActDisPstForInsTch:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM_INSTIT_TCHS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForCtrUsr: case ActSeePstForCtrUsr:
case ActRcvThrForCtrUsr: case ActRcvRepForCtrUsr:
case ActReqDelThrCtrUsr: case ActDelThrForCtrUsr:
case ActCutThrForCtrUsr: case ActPasThrForCtrUsr:
case ActDelPstForCtrUsr:
case ActEnbPstForCtrUsr: case ActDisPstForCtrUsr:
Forums->Forum.Type = For_FORUM_CENTER_USRS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForCtrTch: case ActSeePstForCtrTch:
case ActRcvThrForCtrTch: case ActRcvRepForCtrTch:
case ActReqDelThrCtrTch: case ActDelThrForCtrTch:
case ActCutThrForCtrTch: case ActPasThrForCtrTch:
case ActDelPstForCtrTch:
case ActEnbPstForCtrTch: case ActDisPstForCtrTch:
Forums->Forum.Type = For_FORUM_CENTER_TCHS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForDegUsr: case ActSeePstForDegUsr:
case ActRcvThrForDegUsr: case ActRcvRepForDegUsr:
case ActReqDelThrDegUsr: case ActDelThrForDegUsr:
case ActCutThrForDegUsr: case ActPasThrForDegUsr:
case ActDelPstForDegUsr:
case ActEnbPstForDegUsr: case ActDisPstForDegUsr:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM_DEGREE_USRS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForDegTch: case ActSeePstForDegTch:
case ActRcvThrForDegTch: case ActRcvRepForDegTch:
case ActReqDelThrDegTch: case ActDelThrForDegTch:
case ActCutThrForDegTch: case ActPasThrForDegTch:
case ActDelPstForDegTch:
case ActEnbPstForDegTch: case ActDisPstForDegTch:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM_DEGREE_TCHS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForCrsUsr: case ActSeePstForCrsUsr:
case ActRcvThrForCrsUsr: case ActRcvRepForCrsUsr:
case ActReqDelThrCrsUsr: case ActDelThrForCrsUsr:
case ActCutThrForCrsUsr: case ActPasThrForCrsUsr:
case ActDelPstForCrsUsr:
case ActEnbPstForCrsUsr: case ActDisPstForCrsUsr:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM_COURSE_USRS;
2017-04-16 13:45:11 +02:00
break;
case ActSeeForCrsTch: case ActSeePstForCrsTch:
case ActRcvThrForCrsTch: case ActRcvRepForCrsTch:
case ActReqDelThrCrsTch: case ActDelThrForCrsTch:
case ActCutThrForCrsTch: case ActPasThrForCrsTch:
case ActDelPstForCrsTch:
case ActEnbPstForCrsTch: case ActDisPstForCrsTch:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM_COURSE_TCHS;
2017-04-16 13:45:11 +02:00
break;
2017-04-18 19:55:56 +02:00
default:
2020-04-10 19:14:08 +02:00
Forums->Forum.Type = For_FORUM_UNKNOWN;
2017-04-14 00:27:38 +02:00
}
2014-12-01 23:55:08 +01:00
}
2017-04-16 13:45:11 +02:00
/*****************************************************************************/
/************************** Restrict access to forum *************************/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_RestrictAccess (const struct For_Forums *Forums)
2017-04-16 13:45:11 +02:00
{
2017-05-23 20:42:38 +02:00
Rol_Role_t MaxRole;
2017-04-18 19:55:56 +02:00
bool ICanSeeForum;
2017-04-16 13:45:11 +02:00
/***** Restrict access *****/
2020-04-10 19:14:08 +02:00
switch (Forums->Forum.Type)
2017-04-16 13:45:11 +02:00
{
2017-04-18 19:55:56 +02:00
case For_FORUM_GLOBAL_USRS:
case For_FORUM__SWAD__USRS:
ICanSeeForum = true;
2017-04-16 13:45:11 +02:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_GLOBAL_TCHS:
case For_FORUM__SWAD__TCHS:
Rol_GetRolesInAllCrss (&Gbl.Usrs.Me.UsrDat);
2017-06-08 15:32:33 +02:00
ICanSeeForum = (Gbl.Usrs.Me.UsrDat.Roles.InCrss & ((1 << Rol_NET) |
2019-03-07 22:15:47 +01:00
(1 << Rol_TCH)));
2017-04-16 13:45:11 +02:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_INSTIT_USRS:
2020-04-10 19:14:08 +02:00
MaxRole = Rol_GetMyMaxRoleInIns (Forums->Forum.Location);
2017-06-04 18:18:54 +02:00
ICanSeeForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRole == Rol_STD ||
MaxRole == Rol_NET ||
MaxRole == Rol_TCH);
2017-04-16 13:45:11 +02:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_INSTIT_TCHS:
2020-04-10 19:14:08 +02:00
MaxRole = Rol_GetMyMaxRoleInIns (Forums->Forum.Location);
2017-06-04 18:18:54 +02:00
ICanSeeForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRole == Rol_NET ||
MaxRole == Rol_TCH);
2017-04-16 13:45:11 +02:00
break;
case For_FORUM_CENTER_USRS:
2020-04-10 19:14:08 +02:00
MaxRole = Rol_GetMyMaxRoleInCtr (Forums->Forum.Location);
2017-06-04 18:18:54 +02:00
ICanSeeForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRole >= Rol_STD ||
MaxRole == Rol_NET ||
MaxRole == Rol_TCH);
2017-04-16 13:45:11 +02:00
break;
case For_FORUM_CENTER_TCHS:
2020-04-10 19:14:08 +02:00
MaxRole = Rol_GetMyMaxRoleInCtr (Forums->Forum.Location);
2017-06-04 18:18:54 +02:00
ICanSeeForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRole == Rol_NET ||
MaxRole == Rol_TCH);
2017-04-16 13:45:11 +02:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_DEGREE_USRS:
2020-04-10 19:14:08 +02:00
MaxRole = Rol_GetMyMaxRoleInDeg (Forums->Forum.Location);
2017-06-04 18:18:54 +02:00
ICanSeeForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRole >= Rol_STD ||
MaxRole == Rol_NET ||
MaxRole == Rol_TCH);
2017-04-16 13:45:11 +02:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_DEGREE_TCHS:
2020-04-10 19:14:08 +02:00
MaxRole = Rol_GetMyMaxRoleInDeg (Forums->Forum.Location);
2017-06-04 18:18:54 +02:00
ICanSeeForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRole == Rol_NET ||
MaxRole == Rol_TCH);
2017-04-16 13:45:11 +02:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_COURSE_USRS:
2020-04-10 19:14:08 +02:00
MaxRole = Rol_GetMyRoleInCrs (Forums->Forum.Location);
2017-06-04 18:18:54 +02:00
ICanSeeForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRole >= Rol_STD ||
MaxRole == Rol_NET ||
MaxRole == Rol_TCH);
2017-04-16 13:45:11 +02:00
break;
2017-04-18 19:55:56 +02:00
case For_FORUM_COURSE_TCHS:
2020-04-10 19:14:08 +02:00
MaxRole = Rol_GetMyRoleInCrs (Forums->Forum.Location);
2017-06-04 18:18:54 +02:00
ICanSeeForum = (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM ||
2017-05-23 20:42:38 +02:00
MaxRole == Rol_NET ||
MaxRole == Rol_TCH);
2017-04-16 13:45:11 +02:00
break;
2017-04-18 19:55:56 +02:00
default:
ICanSeeForum = false;
break;
2017-04-16 13:45:11 +02:00
}
if (!ICanSeeForum)
2019-10-26 01:56:36 +02:00
Lay_NoPermissionExit ();
2017-04-16 13:45:11 +02:00
}
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
/********************** Show an area to write a message **********************/
/*****************************************************************************/
2020-04-09 21:36:21 +02:00
static void For_WriteFormForumPst (struct For_Forums *Forums,
2020-04-07 03:01:41 +02:00
bool IsReply,const char *Subject)
2014-12-01 23:55:08 +01:00
{
2020-09-26 17:20:01 +02:00
extern const char *Hlp_COMMUNICATION_Forums_new_post;
extern const char *Hlp_COMMUNICATION_Forums_new_thread;
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormInBox[The_NUM_THEMES];
2017-04-17 14:18:57 +02:00
extern const char *Txt_New_post;
2014-12-01 23:55:08 +01:00
extern const char *Txt_New_thread;
extern const char *Txt_MSG_Subject;
2017-04-19 14:27:52 +02:00
extern const char *Txt_MSG_Content;
2017-04-17 14:18:57 +02:00
extern const char *Txt_Send;
2014-12-01 23:55:08 +01:00
2019-10-26 02:19:42 +02:00
/***** Begin box *****/
2017-06-11 22:26:40 +02:00
if (IsReply)
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_New_post,
NULL,NULL,
2020-09-26 17:20:01 +02:00
Hlp_COMMUNICATION_Forums_new_post,Box_NOT_CLOSABLE);
2017-06-11 22:26:40 +02:00
else
2020-03-26 02:54:30 +01:00
Box_BoxBegin (NULL,Txt_New_thread,
NULL,NULL,
2020-09-26 17:20:01 +02:00
Hlp_COMMUNICATION_Forums_new_thread,Box_NOT_CLOSABLE);
2016-04-09 18:23:15 +02:00
2019-10-20 22:00:28 +02:00
/***** Begin form *****/
2017-04-19 14:43:08 +02:00
if (IsReply) // Form to write a reply to a post of an existing thread
2014-12-01 23:55:08 +01:00
{
2020-04-10 19:14:08 +02:00
Frm_StartFormAnchor (For_ActionsRecRepFor[Forums->Forum.Type],
2017-05-25 13:43:54 +02:00
For_FORUM_POSTS_SECTION_ID);
2020-04-09 21:36:21 +02:00
For_PutAllHiddenParamsNewPost (Forums);
2014-12-01 23:55:08 +01:00
}
2017-04-19 14:43:08 +02:00
else // Form to write the first post of a new thread
2017-04-18 01:25:44 +02:00
{
2020-04-10 19:14:08 +02:00
Frm_StartFormAnchor (For_ActionsRecThrFor[Forums->Forum.Type],
2017-05-25 13:43:54 +02:00
For_FORUM_POSTS_SECTION_ID);
2020-04-09 21:36:21 +02:00
For_PutAllHiddenParamsNewThread (Forums);
2017-04-18 01:25:44 +02:00
}
2014-12-01 23:55:08 +01:00
2016-12-27 11:45:06 +01:00
/***** Subject and content *****/
2019-10-23 19:05:05 +02:00
HTM_TABLE_BeginCenterPadding (2);
2017-03-07 01:56:41 +01:00
2017-05-01 12:36:24 +02:00
// If writing a reply to a message of an existing thread ==> write subject
2017-03-07 01:56:41 +01:00
/* Subject */
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 15:15:55 +02:00
2019-12-27 21:10:39 +01:00
/* Label */
2019-12-27 15:45:19 +01:00
Frm_LabelColumn ("RT","Subject",Txt_MSG_Subject);
2019-10-07 15:15:55 +02:00
2019-12-27 21:10:39 +01:00
/* Data */
2019-12-26 22:29:04 +01:00
HTM_TD_Begin ("class=\"LT\"");
2019-11-04 12:25:48 +01:00
HTM_INPUT_TEXT ("Subject",Cns_MAX_CHARS_SUBJECT,
IsReply ? Subject :
2020-04-27 03:16:55 +02:00
"",
HTM_DONT_SUBMIT_ON_CHANGE,
2019-11-12 15:41:58 +01:00
"id=\"Subject\" class=\"MSG_SUBJECT\" required=\"required\"");
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2019-10-07 15:15:55 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2017-03-07 01:56:41 +01:00
/* Content */
2019-10-23 19:05:05 +02:00
HTM_TR_Begin (NULL);
2019-10-07 15:15:55 +02:00
2019-12-27 21:10:39 +01:00
/* Label */
2019-12-27 15:45:19 +01:00
Frm_LabelColumn ("RT","Content",Txt_MSG_Content);
2019-10-07 15:15:55 +02:00
2019-12-27 21:10:39 +01:00
/* Data */
2019-10-23 19:05:05 +02:00
HTM_TD_Begin ("class=\"LT\"");
2019-10-31 17:42:05 +01:00
HTM_TEXTAREA_Begin ("id=\"Content\" name=\"Content\" class=\"MSG_CONTENT\" rows=\"10\"");
HTM_TEXTAREA_End ();
2019-10-23 19:05:05 +02:00
HTM_TD_End ();
2019-10-07 15:15:55 +02:00
2019-10-23 19:05:05 +02:00
HTM_TR_End ();
2017-03-07 01:56:41 +01:00
2019-10-23 19:05:05 +02:00
HTM_TABLE_End ();
2016-04-09 18:15:54 +02:00
2015-04-11 23:46:21 +02:00
/***** Help for text editor *****/
2015-04-11 14:00:23 +02:00
Lay_HelpPlainEditor ();
2016-04-10 14:09:50 +02:00
/***** Attached image (optional) *****/
2019-03-16 19:28:32 +01:00
Med_PutMediaUploader (-1,"FOR_MED_INPUT");
2016-04-10 14:09:50 +02:00
2016-04-09 18:23:15 +02:00
/***** Send button *****/
2017-06-11 19:02:40 +02:00
Btn_PutCreateButton (Txt_Send);
2015-04-11 14:00:23 +02:00
/***** End form *****/
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2016-04-09 18:23:15 +02: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
}
/*****************************************************************************/
/************************** Receive message of a forum ***********************/
/*****************************************************************************/
2017-04-18 16:44:44 +02:00
void For_ReceiveForumPost (void)
2014-12-01 23:55:08 +01:00
{
2019-03-06 10:13:39 +01:00
extern const char *Txt_FORUM_Post_sent;
2020-04-07 03:01:41 +02:00
struct For_Forums Forums;
2017-04-18 16:44:44 +02:00
bool IsReply = false;
2014-12-01 23:55:08 +01:00
long PstCod = 0;
unsigned NumUsrsToBeNotifiedByEMail;
2020-04-11 15:21:30 +02:00
char Subject[Cns_MAX_BYTES_SUBJECT + 1];
2017-01-28 15:58:46 +01:00
char Content[Cns_MAX_BYTES_LONG_TEXT + 1];
2021-02-11 00:58:53 +01:00
struct Med_Media Media;
2014-12-01 23:55:08 +01:00
2020-04-07 03:01:41 +02:00
/***** Reset forum *****/
For_ResetForums (&Forums);
2017-04-16 13:45:11 +02:00
/***** Get parameters related to forum *****/
2020-04-07 03:01:41 +02:00
For_GetParamsForums (&Forums);
2014-12-01 23:55:08 +01:00
/***** Get the code of the thread y the n<>mero of page *****/
2016-01-17 15:10:54 +01:00
if (Gbl.Action.Act == ActRcvRepForCrsUsr || Gbl.Action.Act == ActRcvRepForCrsTch ||
Gbl.Action.Act == ActRcvRepForDegUsr || Gbl.Action.Act == ActRcvRepForDegTch ||
Gbl.Action.Act == ActRcvRepForCtrUsr || Gbl.Action.Act == ActRcvRepForCtrTch ||
Gbl.Action.Act == ActRcvRepForInsUsr || Gbl.Action.Act == ActRcvRepForInsTch ||
Gbl.Action.Act == ActRcvRepForGenUsr || Gbl.Action.Act == ActRcvRepForGenTch ||
Gbl.Action.Act == ActRcvRepForSWAUsr || Gbl.Action.Act == ActRcvRepForSWATch)
2017-04-18 16:44:44 +02:00
IsReply = true;
2014-12-01 23:55:08 +01:00
/***** Get message subject *****/
2020-04-11 15:21:30 +02:00
Par_GetParToHTML ("Subject",Subject,Cns_MAX_BYTES_SUBJECT);
2014-12-01 23:55:08 +01:00
/***** Get message body *****/
Par_GetParAndChangeFormat ("Content",Content,Cns_MAX_BYTES_LONG_TEXT,
Str_TO_RIGOROUS_HTML,false);
2019-03-17 14:47:58 +01:00
/***** Initialize media *****/
2019-03-02 21:49:11 +01:00
Med_MediaConstructor (&Media);
2016-04-10 14:09:50 +02:00
2019-03-17 14:47:58 +01:00
/***** Get attached media *****/
2019-03-02 21:49:11 +01:00
Media.Width = For_IMAGE_SAVED_MAX_WIDTH;
Media.Height = For_IMAGE_SAVED_MAX_HEIGHT;
Media.Quality = For_IMAGE_SAVED_QUALITY;
2020-03-17 00:35:11 +01:00
Med_GetMediaFromForm (-1L,-1L,-1,&Media,NULL,
2019-03-17 14:47:58 +01:00
For_FORUM_POSTS_SECTION_ID); // Alerts will be shown later in posts section
2016-04-10 14:09:50 +02:00
2014-12-01 23:55:08 +01:00
/***** Create a new message *****/
2017-04-18 16:44:44 +02:00
if (IsReply) // This post is a reply to another posts in the thread
2014-12-01 23:55:08 +01:00
{
2020-04-14 00:11:28 +02:00
// Forums.ThrCod has been received from form
2014-12-01 23:55:08 +01:00
/***** Create last message of the thread *****/
2020-11-11 01:14:53 +01:00
PstCod = For_InsertForumPst (Forums.Thread.Current,Gbl.Usrs.Me.UsrDat.UsrCod,
2020-04-11 15:21:30 +02:00
Subject,Content,&Media);
2014-12-01 23:55:08 +01:00
/***** Modify last message of the thread *****/
2020-11-11 01:14:53 +01:00
For_UpdateThrLastPst (Forums.Thread.Current,PstCod);
2014-12-01 23:55:08 +01:00
}
2016-04-10 19:19:20 +02:00
else // This post is the first of a new thread
2014-12-01 23:55:08 +01:00
{
/***** Create new thread with unknown first and last message codes *****/
2020-11-11 01:14:53 +01:00
Forums.Thread.Current =
Forums.Thread.Selected = For_InsertForumThread (&Forums,-1L);
2014-12-01 23:55:08 +01:00
/***** Create first (and last) message of the thread *****/
2020-11-11 01:14:53 +01:00
PstCod = For_InsertForumPst (Forums.Thread.Current,Gbl.Usrs.Me.UsrDat.UsrCod,
2020-04-11 15:21:30 +02:00
Subject,Content,&Media);
2014-12-01 23:55:08 +01:00
/***** Update first and last posts of new thread *****/
2020-11-11 01:14:53 +01:00
For_UpdateThrFirstAndLastPst (Forums.Thread.Current,PstCod,PstCod);
2014-12-01 23:55:08 +01:00
}
2019-03-18 15:42:22 +01:00
/***** Free media *****/
2019-03-02 21:49:11 +01:00
Med_MediaDestructor (&Media);
2016-04-10 14:09:50 +02:00
2015-03-11 12:38:47 +01:00
/***** Increment number of forum posts in my user's figures *****/
2015-03-14 17:39:04 +01:00
Prf_IncrementNumForPstUsr (Gbl.Usrs.Me.UsrDat.UsrCod);
2015-03-11 12:38:47 +01:00
2014-12-01 23:55:08 +01:00
/***** Notify the new post to users in course *****/
2020-04-10 19:14:08 +02:00
switch (Forums.Forum.Type)
2014-12-01 23:55:08 +01:00
{
case For_FORUM_COURSE_USRS:
case For_FORUM_COURSE_TCHS:
if ((NumUsrsToBeNotifiedByEMail = Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_FORUM_POST_COURSE,PstCod)))
For_UpdateNumUsrsNotifiedByEMailAboutPost (PstCod,NumUsrsToBeNotifiedByEMail);
break;
default:
break;
}
/***** Notify the new post to previous writers in this thread *****/
2017-04-18 16:44:44 +02:00
if (IsReply)
2014-12-01 23:55:08 +01:00
if ((NumUsrsToBeNotifiedByEMail = Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_FORUM_REPLY,PstCod)))
For_UpdateNumUsrsNotifiedByEMailAboutPost (PstCod,NumUsrsToBeNotifiedByEMail);
2015-12-31 14:25:28 +01:00
/***** Insert forum post into public social activity *****/
2020-04-10 19:14:08 +02:00
switch (Forums.Forum.Type) // Only if forum is public for any logged user
2015-12-28 20:46:48 +01:00
{
case For_FORUM_GLOBAL_USRS:
2017-04-18 19:55:56 +02:00
case For_FORUM__SWAD__USRS:
Tml_Not_StoreAndPublishNote (TL_NOTE_FORUM_POST,PstCod);
2015-12-28 20:46:48 +01:00
break;
default:
break;
}
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
/***** Show threads again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,NULL);
2017-04-18 13:17:40 +02:00
2014-12-01 23:55:08 +01:00
/***** Show again the posts of this thread of the forum *****/
2020-04-07 03:01:41 +02:00
For_ShowPostsOfAThread (&Forums,Ale_SUCCESS,Txt_FORUM_Post_sent);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********* Update number of users notified in table of forum posts **********/
/*****************************************************************************/
static void For_UpdateNumUsrsNotifiedByEMailAboutPost (long PstCod,unsigned NumUsrsToBeNotifiedByEMail)
{
/***** Update number of users notified *****/
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not update the number of notifications of a post",
"UPDATE for_posts"
" SET NumNotif=NumNotif+%u"
2018-11-03 12:16:40 +01:00
" WHERE PstCod=%ld",
NumUsrsToBeNotifiedByEMail,
PstCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/***************************** Delete a forum post ***************************/
/*****************************************************************************/
2017-04-18 16:44:44 +02:00
void For_RemovePost (void)
2014-12-01 23:55:08 +01:00
{
2019-03-06 10:13:39 +01:00
extern const char *Txt_FORUM_Post_and_thread_removed;
extern const char *Txt_FORUM_Post_removed;
2020-04-07 03:01:41 +02:00
struct For_Forums Forums;
2014-12-01 23:55:08 +01:00
struct UsrData UsrDat;
2015-10-24 20:12:03 +02:00
time_t CreatTimeUTC; // Creation time of a message
2017-01-28 15:58:46 +01:00
char Subject[Cns_MAX_BYTES_SUBJECT + 1];
char OriginalContent[Cns_MAX_BYTES_LONG_TEXT + 1];
2021-02-11 00:58:53 +01:00
struct Med_Media Media;
2018-10-10 23:56:42 +02:00
bool ItsMe;
2014-12-01 23:55:08 +01:00
bool ThreadDeleted = false;
2020-04-07 03:01:41 +02:00
/***** Reset forum *****/
For_ResetForums (&Forums);
2017-04-16 13:45:11 +02:00
/***** Get parameters related to forum *****/
2020-04-07 03:01:41 +02:00
For_GetParamsForums (&Forums);
2016-04-10 23:59:45 +02:00
/***** Initialize image *****/
2019-03-02 21:49:11 +01:00
Med_MediaConstructor (&Media);
2016-04-10 23:59:45 +02:00
/***** Get forum post data *****/
2020-04-14 00:11:28 +02:00
For_GetPstData (Forums.PstCod,&UsrDat.UsrCod,&CreatTimeUTC,
2019-03-02 21:49:11 +01:00
Subject,OriginalContent,&Media);
2016-04-10 23:59:45 +02:00
/***** Check if I can remove the post *****/
2014-12-01 23:55:08 +01:00
/* Check if the message really exists, if it has not been removed */
2020-04-14 00:11:28 +02:00
if (!For_GetIfForumPstExists (Forums.PstCod))
Lay_WrongPostExit ();
2014-12-01 23:55:08 +01:00
/* Check if I am the author of the message */
2018-10-10 23:56:42 +02:00
ItsMe = Usr_ItsMe (UsrDat.UsrCod);
if (!ItsMe)
2019-10-26 01:56:36 +02:00
Lay_NoPermissionExit ();
2014-12-01 23:55:08 +01:00
/* Check if the message is the last message in the thread */
2020-11-11 01:14:53 +01:00
if (Forums.PstCod != For_GetLastPstCod (Forums.Thread.Current))
2019-10-26 01:56:36 +02:00
Lay_NoPermissionExit ();
2014-12-01 23:55:08 +01:00
2016-04-10 23:59:45 +02:00
/***** Remove the post *****/
2020-04-14 00:11:28 +02:00
ThreadDeleted = For_RemoveForumPst (Forums.PstCod,Media.MedCod);
2016-04-10 23:59:45 +02:00
/***** Free image *****/
2019-03-02 21:49:11 +01:00
Med_MediaDestructor (&Media);
2014-12-01 23:55:08 +01:00
/***** Mark possible notifications as removed *****/
2020-04-14 00:11:28 +02:00
Ntf_MarkNotifAsRemoved (Ntf_EVENT_FORUM_POST_COURSE,Forums.PstCod);
Ntf_MarkNotifAsRemoved (Ntf_EVENT_FORUM_REPLY ,Forums.PstCod);
2014-12-01 23:55:08 +01:00
2016-01-03 19:45:15 +01:00
/***** Mark possible social note as unavailable *****/
2020-04-10 19:14:08 +02:00
switch (Forums.Forum.Type) // Only if forum is public for any logged user
2016-01-03 19:45:15 +01:00
{
case For_FORUM_GLOBAL_USRS:
2017-04-18 19:55:56 +02:00
case For_FORUM__SWAD__USRS:
Tml_DB_MarkNoteAsUnavailable (TL_NOTE_FORUM_POST,Forums.PstCod);
2016-01-03 19:45:15 +01:00
break;
default:
break;
}
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
2014-12-01 23:55:08 +01:00
if (ThreadDeleted)
2017-04-18 13:17:40 +02:00
/***** Show the remaining threads *****/
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,Txt_FORUM_Post_and_thread_removed);
2014-12-01 23:55:08 +01:00
else
2017-04-18 13:17:40 +02:00
{
/***** Show threads again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,NULL);
2017-04-18 13:17:40 +02:00
/***** Show the remaining posts *****/
2020-04-07 03:01:41 +02:00
For_ShowPostsOfAThread (&Forums,Ale_SUCCESS,Txt_FORUM_Post_removed);
2017-04-18 13:17:40 +02:00
}
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2017-04-18 01:25:44 +02:00
/***************** Request the removing of an existing thread ****************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2017-04-18 16:44:44 +02:00
void For_RequestRemoveThread (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_Do_you_really_want_to_remove_the_entire_thread_X;
extern const char *Txt_Do_you_really_want_to_remove_the_entire_thread;
extern const char *Txt_Remove_thread;
2020-04-07 03:01:41 +02:00
struct For_Forums Forums;
2017-01-17 03:10:43 +01:00
char Subject[Cns_MAX_BYTES_SUBJECT + 1];
2014-12-01 23:55:08 +01:00
2020-04-07 03:01:41 +02:00
/***** Reset forum *****/
For_ResetForums (&Forums);
2017-04-16 13:45:11 +02:00
/***** Get parameters related to forum *****/
2020-04-07 03:01:41 +02:00
For_GetParamsForums (&Forums);
2014-12-01 23:55:08 +01:00
2017-04-18 13:17:40 +02:00
/***** Get subject of the thread to delete *****/
2020-11-11 01:14:53 +01:00
For_GetThrSubject (Forums.Thread.Current,Subject);
2014-12-01 23:55:08 +01:00
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
2017-04-28 10:35:41 +02:00
/***** Show question and button to remove the thread *****/
2019-10-26 01:56:36 +02:00
HTM_SECTION_Begin (For_REMOVE_THREAD_SECTION_ID);
2014-12-01 23:55:08 +01:00
if (Subject[0])
2020-04-10 19:14:08 +02:00
Ale_ShowAlertAndButton (For_ActionsDelThrFor[Forums.Forum.Type],
2019-02-17 01:14:55 +01:00
For_FORUM_THREADS_SECTION_ID,NULL,
2020-04-09 21:36:21 +02:00
For_PutAllHiddenParamsRemThread,&Forums,
2019-02-17 01:14:55 +01:00
Btn_REMOVE_BUTTON,Txt_Remove_thread,
Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_entire_thread_X,
Subject);
2014-12-01 23:55:08 +01:00
else
2020-04-10 19:14:08 +02:00
Ale_ShowAlertAndButton (For_ActionsDelThrFor[Forums.Forum.Type],
2019-02-17 01:14:55 +01:00
For_FORUM_THREADS_SECTION_ID,NULL,
2020-04-09 21:36:21 +02:00
For_PutAllHiddenParamsRemThread,&Forums,
2019-02-17 01:14:55 +01:00
Btn_REMOVE_BUTTON,Txt_Remove_thread,
Ale_QUESTION,Txt_Do_you_really_want_to_remove_the_entire_thread);
2019-10-26 01:56:36 +02:00
HTM_SECTION_End ();
2017-04-28 10:35:41 +02:00
/***** Show the threads again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,NULL);
2017-04-28 10:35:41 +02:00
}
2020-04-07 03:01:41 +02:00
static void For_PutAllHiddenParamsRemThread (void *Forums)
2017-04-28 10:35:41 +02:00
{
2020-04-07 03:01:41 +02:00
if (Forums)
For_PutAllHiddenParamsForum (((struct For_Forums *) Forums)->CurrentPageThrs, // Page of threads = current
2020-03-26 02:54:30 +01:00
1, // Page of posts = first
2020-04-07 03:01:41 +02:00
((struct For_Forums *) Forums)->ForumSet,
((struct For_Forums *) Forums)->ThreadsOrder,
2020-04-10 19:14:08 +02:00
((struct For_Forums *) Forums)->Forum.Location,
2020-11-11 01:14:53 +01:00
((struct For_Forums *) Forums)->Thread.Current,
2020-03-26 02:54:30 +01:00
-1L);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************************** Remove an existing thread ***********************/
/*****************************************************************************/
2017-04-18 16:44:44 +02:00
void For_RemoveThread (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_Thread_X_removed;
extern const char *Txt_Thread_removed;
2020-04-07 03:01:41 +02:00
struct For_Forums Forums;
2017-01-28 15:58:46 +01:00
char Subject[Cns_MAX_BYTES_SUBJECT + 1];
2019-03-09 20:12:44 +01:00
char Message[256 + Cns_MAX_BYTES_SUBJECT + 1];
2014-12-01 23:55:08 +01:00
2020-04-07 03:01:41 +02:00
/***** Reset forum *****/
For_ResetForums (&Forums);
2017-04-16 13:45:11 +02:00
/***** Get parameters related to forum *****/
2020-04-07 03:01:41 +02:00
For_GetParamsForums (&Forums);
2014-12-01 23:55:08 +01:00
2020-04-10 19:14:08 +02:00
if (PermissionThreadDeletion[Forums.Forum.Type] &
2017-06-04 18:18:54 +02:00
(1 << Gbl.Usrs.Me.Role.Logged)) // If I have permission to remove thread in this forum...
2014-12-01 23:55:08 +01:00
{
/***** Get subject of thread to delete *****/
2020-11-11 01:14:53 +01:00
For_GetThrSubject (Forums.Thread.Current,Subject);
2014-12-01 23:55:08 +01:00
/***** Remove the thread and all its posts *****/
2020-11-11 01:14:53 +01:00
For_RemoveThreadAndItsPsts (Forums.Thread.Current);
2014-12-01 23:55:08 +01:00
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
/***** Show the threads again *****/
2014-12-01 23:55:08 +01:00
if (Subject[0])
{
2019-03-09 20:12:44 +01:00
snprintf (Message,sizeof (Message),
2018-10-16 21:56:01 +02:00
Txt_Thread_X_removed,Subject);
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,Message);
2017-04-18 09:55:25 +02:00
}
2014-12-01 23:55:08 +01:00
else
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,Txt_Thread_removed);
2014-12-01 23:55:08 +01:00
}
else
2019-10-26 01:56:36 +02:00
Lay_NoPermissionExit ();
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/*************** Cut a thread to move it to another forum ********************/
/*****************************************************************************/
2017-04-18 16:44:44 +02:00
void For_CutThread (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_Thread_X_marked_to_be_moved;
extern const char *Txt_Thread_marked_to_be_moved;
2020-04-07 03:01:41 +02:00
struct For_Forums Forums;
2017-01-28 15:58:46 +01:00
char Subject[Cns_MAX_BYTES_SUBJECT + 1];
2019-03-09 20:12:44 +01:00
char Message[256 + Cns_MAX_BYTES_SUBJECT + 1];
2014-12-01 23:55:08 +01:00
2020-04-07 03:01:41 +02:00
/***** Reset forum *****/
For_ResetForums (&Forums);
2017-04-16 13:45:11 +02:00
/***** Get parameters related to forum *****/
2020-04-07 03:01:41 +02:00
For_GetParamsForums (&Forums);
2014-12-01 23:55:08 +01:00
/***** Get subject of thread to cut *****/
2020-11-11 01:14:53 +01:00
For_GetThrSubject (Forums.Thread.Current,Subject);
2014-12-01 23:55:08 +01:00
/***** Mark the thread as cut *****/
2020-11-11 01:14:53 +01:00
For_InsertThrInClipboard (Forums.Thread.Current);
2014-12-01 23:55:08 +01:00
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
/***** Show the threads again *****/
2014-12-01 23:55:08 +01:00
if (Subject[0])
2017-04-18 09:55:25 +02:00
{
2019-03-09 20:12:44 +01:00
snprintf (Message,sizeof (Message),
Txt_Thread_X_marked_to_be_moved,Subject);
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,Message);
2017-04-18 09:55:25 +02:00
}
2014-12-01 23:55:08 +01:00
else
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,Txt_Thread_marked_to_be_moved);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************* Paste the thread in clipboard into current forum **************/
/*****************************************************************************/
2017-04-18 16:44:44 +02:00
void For_PasteThread (void)
2014-12-01 23:55:08 +01:00
{
extern const char *Txt_The_thread_X_is_already_in_this_forum;
extern const char *Txt_The_thread_is_already_in_this_forum;
extern const char *Txt_Thread_X_moved_to_this_forum;
extern const char *Txt_Thread_moved_to_this_forum;
2020-04-07 03:01:41 +02:00
struct For_Forums Forums;
2017-01-28 15:58:46 +01:00
char Subject[Cns_MAX_BYTES_SUBJECT + 1];
2019-03-09 20:12:44 +01:00
char Message[256 + Cns_MAX_BYTES_SUBJECT + 1];
2014-12-01 23:55:08 +01:00
2020-04-07 03:01:41 +02:00
/***** Reset forum *****/
For_ResetForums (&Forums);
2017-04-16 13:45:11 +02:00
/***** Get parameters related to forum *****/
2020-04-07 03:01:41 +02:00
For_GetParamsForums (&Forums);
2014-12-01 23:55:08 +01:00
/***** Get subject of thread to paste *****/
2020-11-11 01:14:53 +01:00
For_GetThrSubject (Forums.Thread.Current,Subject);
2014-12-01 23:55:08 +01:00
2017-04-18 09:55:25 +02:00
/***** Check if paste (move) the thread to current forum has sense *****/
2020-11-11 01:14:53 +01:00
if (For_CheckIfThrBelongsToForum (Forums.Thread.Current,&Forums.Forum))
2014-12-01 23:55:08 +01:00
{
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
2017-04-18 09:55:25 +02:00
/***** Show the threads again *****/
2014-12-01 23:55:08 +01:00
if (Subject[0])
2017-04-18 09:55:25 +02:00
{
2019-03-09 20:12:44 +01:00
snprintf (Message,sizeof (Message),
Txt_The_thread_X_is_already_in_this_forum,Subject);
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_WARNING,Message);
2017-04-18 09:55:25 +02:00
}
2014-12-01 23:55:08 +01:00
else
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_WARNING,Txt_The_thread_is_already_in_this_forum);
2014-12-01 23:55:08 +01:00
}
else
{
2017-04-18 09:55:25 +02:00
/***** Paste (move) the thread to current forum *****/
2020-04-07 03:01:41 +02:00
For_MoveThrToCurrentForum (&Forums);
2017-04-18 09:55:25 +02:00
2017-04-18 13:17:40 +02:00
/***** Show forum list again *****/
2020-04-07 03:01:41 +02:00
For_ShowForumList (&Forums);
2017-04-18 13:17:40 +02:00
2017-04-18 09:55:25 +02:00
/***** Show the threads again *****/
2014-12-01 23:55:08 +01:00
if (Subject[0])
2017-04-18 09:55:25 +02:00
{
2019-03-09 20:12:44 +01:00
snprintf (Message,sizeof (Message),
Txt_Thread_X_moved_to_this_forum,Subject);
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,Message);
2017-04-18 09:55:25 +02:00
}
2014-12-01 23:55:08 +01:00
else
2020-04-07 03:01:41 +02:00
For_ShowForumThreadsHighlightingOneThread (&Forums,Ale_SUCCESS,Txt_Thread_moved_to_this_forum);
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
2017-04-18 13:17:40 +02:00
/*********************** Check if I can move threads *************************/
/*****************************************************************************/
static bool For_CheckIfICanMoveThreads (void)
{
2017-06-04 18:18:54 +02:00
return (Gbl.Usrs.Me.Role.Logged == Rol_SYS_ADM); // If I have permission to move threads...
2017-04-18 13:17:40 +02:00
}
/*****************************************************************************/
/**************** Get if there is a thread ready to be moved *****************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
2017-04-16 23:48:05 +02:00
static long For_GetThrInMyClipboard (void)
2014-12-01 23:55:08 +01:00
{
/***** Get if there is a thread ready to move in my clipboard from database *****/
return DB_QuerySELECTCode ("can not check if there is"
" any thread ready to be moved",
"SELECT ThrCod"
" FROM for_clipboards"
" WHERE UsrCod=%ld",
Gbl.Usrs.Me.UsrDat.UsrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
2017-04-17 11:57:55 +02:00
/***************** Get if a thread belongs to current forum ******************/
2014-12-01 23:55:08 +01:00
/*****************************************************************************/
static bool For_CheckIfThrBelongsToForum (long ThrCod,const struct For_Forum *Forum)
2014-12-01 23:55:08 +01:00
{
char SubQuery[256];
/***** Get if a thread belong to current forum from database *****/
2017-04-19 12:34:38 +02:00
if (Forum->Location > 0)
sprintf (SubQuery," AND for_threads.Location=%ld",Forum->Location);
2017-04-16 23:48:05 +02:00
else
SubQuery[0] = '\0';
2018-11-03 20:52:00 +01:00
return (DB_QueryCOUNT ("can not get if a thread belong to current forum",
"SELECT COUNT(*)"
" FROM for_threads"
" WHERE ThrCod=%ld"
" AND ForumType=%u"
"%s",
ThrCod,
(unsigned) Forum->Type,
SubQuery) != 0);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************************ Move a thread to current forum *********************/
/*****************************************************************************/
2020-04-07 03:01:41 +02:00
static void For_MoveThrToCurrentForum (const struct For_Forums *Forums)
2014-12-01 23:55:08 +01:00
{
/***** Move a thread to current forum *****/
2020-04-10 19:14:08 +02:00
switch (Forums->Forum.Type)
2014-12-01 23:55:08 +01:00
{
2017-04-16 23:48:05 +02:00
case For_FORUM_GLOBAL_USRS:
case For_FORUM_GLOBAL_TCHS:
2017-04-18 19:55:56 +02:00
case For_FORUM__SWAD__USRS:
case For_FORUM__SWAD__TCHS:
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not move a thread to current forum",
"UPDATE for_threads"
" SET ForumType=%u,"
"Location=-1"
2018-11-03 12:16:40 +01:00
" WHERE ThrCod=%ld",
2020-04-10 19:14:08 +02:00
(unsigned) Forums->Forum.Type,
2020-11-11 01:14:53 +01:00
Forums->Thread.Current);
2014-12-01 23:55:08 +01:00
break;
2017-04-16 23:48:05 +02:00
case For_FORUM_INSTIT_USRS:
case For_FORUM_INSTIT_TCHS:
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not move a thread to current forum",
"UPDATE for_threads"
" SET ForumType=%u,"
"Location=%ld"
2018-11-03 12:16:40 +01:00
" WHERE ThrCod=%ld",
2020-04-10 19:14:08 +02:00
(unsigned) Forums->Forum.Type,
Forums->Forum.Location,
2020-11-11 01:14:53 +01:00
Forums->Thread.Current);
2014-12-01 23:55:08 +01:00
break;
case For_FORUM_CENTER_USRS:
case For_FORUM_CENTER_TCHS:
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not move a thread to current forum",
"UPDATE for_threads"
" SET ForumType=%u,"
"Location=%ld"
2018-11-03 12:16:40 +01:00
" WHERE ThrCod=%ld",
2020-04-10 19:14:08 +02:00
(unsigned) Forums->Forum.Type,
Forums->Forum.Location,
2020-11-11 01:14:53 +01:00
Forums->Thread.Current);
2014-12-01 23:55:08 +01:00
break;
2017-04-16 23:48:05 +02:00
case For_FORUM_DEGREE_USRS:
case For_FORUM_DEGREE_TCHS:
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not move a thread to current forum",
"UPDATE for_threads"
" SET ForumType=%u,"
"Location=%ld"
2018-11-03 12:16:40 +01:00
" WHERE ThrCod=%ld",
2020-04-10 19:14:08 +02:00
(unsigned) Forums->Forum.Type,
Forums->Forum.Location,
2020-11-11 01:14:53 +01:00
Forums->Thread.Current);
2014-12-01 23:55:08 +01:00
break;
2017-04-16 23:48:05 +02:00
case For_FORUM_COURSE_USRS:
case For_FORUM_COURSE_TCHS:
2018-11-03 12:16:40 +01:00
DB_QueryUPDATE ("can not move a thread to current forum",
"UPDATE for_threads"
" SET ForumType=%u,"
"Location=%ld"
2018-11-03 12:16:40 +01:00
" WHERE ThrCod=%ld",
2020-04-10 19:14:08 +02:00
(unsigned) Forums->Forum.Type,
Forums->Forum.Location,
2020-11-11 01:14:53 +01:00
Forums->Thread.Current);
2014-12-01 23:55:08 +01:00
break;
2017-04-18 19:55:56 +02:00
default:
Lay_WrongForumExit ();
2017-04-18 19:55:56 +02:00
break;
2014-12-01 23:55:08 +01:00
}
}
/*****************************************************************************/
/********************* Insert thread in thread clipboard ********************/
/*****************************************************************************/
2017-04-16 23:48:05 +02:00
static void For_InsertThrInClipboard (long ThrCod)
2014-12-01 23:55:08 +01:00
{
/***** Remove expired thread clipboards *****/
For_RemoveExpiredThrsClipboards ();
/***** Add thread to my clipboard *****/
2018-11-02 16:39:35 +01:00
DB_QueryREPLACE ("can not add thread to clipboard",
"REPLACE INTO for_clipboards"
2018-11-02 16:39:35 +01:00
" (ThrCod,UsrCod)"
" VALUES"
" (%ld,%ld)",
ThrCod,
Gbl.Usrs.Me.UsrDat.UsrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/************* Remove expired thread clipboards (from all users) *************/
/*****************************************************************************/
2017-04-16 23:48:05 +02:00
static void For_RemoveExpiredThrsClipboards (void)
2014-12-01 23:55:08 +01:00
{
/***** Remove all expired clipboards *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove old threads from clipboards",
"DELETE LOW_PRIORITY FROM for_clipboards"
2019-02-13 13:32:11 +01:00
" WHERE TimeInsert<FROM_UNIXTIME(UNIX_TIMESTAMP()-%lu)",
2018-11-02 22:00:31 +01:00
Cfg_TIME_TO_DELETE_THREAD_CLIPBOARD);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/**************** Remove thread code from thread clipboard *******************/
/*****************************************************************************/
2017-04-16 23:48:05 +02:00
static void For_RemoveThrCodFromThrClipboard (long ThrCod)
2014-12-01 23:55:08 +01:00
{
/***** Remove thread from thread clipboard *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove a thread from clipboard",
"DELETE FROM for_clipboards"
" WHERE ThrCod=%ld",
2018-11-02 22:00:31 +01:00
ThrCod);
2014-12-01 23:55:08 +01:00
}
/*****************************************************************************/
/********************* Remove thread clipboard of a user *********************/
/*****************************************************************************/
void For_RemoveUsrFromThrClipboard (long UsrCod)
{
/***** Remove clipboard of specified user *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove a thread from the clipboard of a user",
"DELETE FROM for_clipboards"
" WHERE UsrCod=%ld",
2018-11-02 22:00:31 +01:00
UsrCod);
2014-12-01 23:55:08 +01:00
}
2016-10-27 22:26:52 +02:00
2016-10-27 23:38:53 +02:00
/*****************************************************************************/
/********** Remove all the threads and posts in forums of a degree ***********/
/*****************************************************************************/
2021-02-11 22:57:09 +01:00
void For_RemoveForums (Hie_Lvl_Level_t Scope,long ForumLocation)
2016-10-27 22:26:52 +02:00
{
2016-10-28 00:23:02 +02:00
static const struct
{
For_ForumType_t Usrs;
For_ForumType_t Tchs;
2021-02-11 22:57:09 +01:00
} ForumType[Hie_Lvl_NUM_LEVELS] =
2016-10-28 00:23:02 +02:00
{
2021-02-11 22:57:09 +01:00
[Hie_Lvl_UNK] = {For_FORUM_GLOBAL_USRS,For_FORUM_GLOBAL_TCHS}, // No forums for this scope
[Hie_Lvl_SYS] = {For_FORUM_GLOBAL_USRS,For_FORUM_GLOBAL_TCHS}, // Not removable
[Hie_Lvl_CTY] = {For_FORUM_GLOBAL_USRS,For_FORUM_GLOBAL_TCHS}, // No forums for this scope
[Hie_Lvl_INS] = {For_FORUM_INSTIT_USRS,For_FORUM_INSTIT_TCHS},
[Hie_Lvl_CTR] = {For_FORUM_CENTER_USRS,For_FORUM_CENTER_TCHS},
2021-02-11 22:57:09 +01:00
[Hie_Lvl_DEG] = {For_FORUM_DEGREE_USRS,For_FORUM_DEGREE_TCHS},
[Hie_Lvl_CRS] = {For_FORUM_COURSE_USRS,For_FORUM_COURSE_TCHS},
2016-10-28 00:23:02 +02:00
};
2016-10-27 22:26:52 +02:00
/***** Remove disabled posts *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove the disabled posts in forums",
"DELETE FROM for_disabled"
" USING for_threads,"
"for_posts,"
"for_disabled"
2018-11-02 22:00:31 +01:00
" WHERE"
" (for_threads.ForumType=%u"
" OR"
" for_threads.ForumType=%u)"
" AND for_threads.Location=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod"
" AND for_posts.PstCod=for_disabled.PstCod",
2018-11-02 22:00:31 +01:00
ForumType[Scope].Usrs,
ForumType[Scope].Tchs,
ForumLocation);
2016-10-27 22:26:52 +02:00
/***** Remove posts *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove posts in forums",
"DELETE FROM for_posts"
" USING for_threads,"
"for_posts"
2018-11-02 22:00:31 +01:00
" WHERE"
" (for_threads.ForumType=%u"
" OR"
" for_threads.ForumType=%u)"
" AND for_threads.Location=%ld"
" AND for_threads.ThrCod=for_posts.ThrCod",
2018-11-02 22:00:31 +01:00
ForumType[Scope].Usrs,
ForumType[Scope].Tchs,
ForumLocation);
2016-10-27 22:26:52 +02:00
/***** Remove threads read *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove read threads in forums",
"DELETE FROM for_read"
" USING for_threads,"
"for_read"
2018-11-02 22:00:31 +01:00
" WHERE"
" (for_threads.ForumType=%u"
" OR"
" for_threads.ForumType=%u)"
" AND for_threads.Location=%ld"
" AND for_threads.ThrCod=for_read.ThrCod",
2018-11-02 22:00:31 +01:00
ForumType[Scope].Usrs,
ForumType[Scope].Tchs,
ForumLocation);
2016-10-27 22:26:52 +02:00
/***** Remove threads *****/
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove threads in forums",
"DELETE FROM for_threads"
2018-11-02 22:00:31 +01:00
" WHERE"
" (for_threads.ForumType=%u"
" OR"
" for_threads.ForumType=%u)"
" AND Location=%ld",
2018-11-02 22:00:31 +01:00
ForumType[Scope].Usrs,
ForumType[Scope].Tchs,
ForumLocation);
2016-10-27 22:26:52 +02:00
}