swad-core/swad_follow.c

1539 lines
54 KiB
C
Raw Normal View History

2015-03-18 01:06:43 +01:00
// swad_follow.c: user's followers and followed
/*
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.
2019-01-07 21:52:19 +01:00
Copyright (C) 1999-2019 Antonio Ca<EFBFBD>as Vargas
2015-03-18 01:06:43 +01:00
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General 3 License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/*********************************** Headers *********************************/
/*****************************************************************************/
2015-10-16 02:24:29 +02:00
#include <stdbool.h> // For boolean type
2015-03-24 00:01:40 +01:00
#include <string.h> // For string functions
2015-03-18 01:06:43 +01:00
2017-06-10 21:38:10 +02:00
#include "swad_box.h"
2015-03-18 01:06:43 +01:00
#include "swad_database.h"
#include "swad_follow.h"
2018-11-09 20:47:39 +01:00
#include "swad_form.h"
2015-03-18 01:06:43 +01:00
#include "swad_global.h"
2015-03-24 00:01:40 +01:00
#include "swad_notification.h"
2016-12-09 13:59:33 +01:00
#include "swad_privacy.h"
2015-03-18 02:11:23 +01:00
#include "swad_profile.h"
2015-03-18 01:06:43 +01:00
#include "swad_user.h"
/*****************************************************************************/
/****************************** Public constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
2015-12-12 19:47:10 +01:00
#define Fol_NUM_COLUMNS_FOLLOW 3
2015-03-19 12:32:45 +01:00
2017-05-25 13:43:54 +02:00
#define Fol_FOLLOW_SECTION_ID "follow_section"
2015-03-18 01:06:43 +01:00
/*****************************************************************************/
/****************************** Internal types *******************************/
/*****************************************************************************/
2019-03-24 15:03:00 +01:00
typedef enum
{
Fol_SUGGEST_ONLY_USERS_WITH_PHOTO,
Fol_SUGGEST_ANY_USER,
} Fol_WhichUsersSuggestToFollowThem_t;
2015-03-18 01:06:43 +01:00
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/************************* Internal global variables *************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
2019-03-24 15:03:00 +01:00
static unsigned long Fol_GetUsrsToFollow (unsigned long MaxUsrsToShow,
Fol_WhichUsersSuggestToFollowThem_t WhichUsersSuggestToFollowThem,
MYSQL_RES **mysql_res);
2017-02-16 17:58:37 +01:00
2016-11-07 10:45:03 +01:00
static void Fol_PutIconsWhoToFollow (void);
2016-03-24 13:50:57 +01:00
static void Fol_PutIconToUpdateWhoToFollow (void);
2016-03-24 13:40:05 +01:00
2015-03-21 19:55:00 +01:00
static void Fol_ShowNumberOfFollowingOrFollowers (const struct UsrData *UsrDat,
unsigned NumUsrs,
Act_Action_t Action,
const char *Title);
2016-06-12 19:55:33 +02:00
static void Fol_ListFollowingUsr (struct UsrData *UsrDat);
static void Fol_ListFollowersUsr (struct UsrData *UsrDat);
2016-12-13 13:32:19 +01:00
static void Fol_ShowFollowedOrFollower (struct UsrData *UsrDat);
2017-02-16 20:22:13 +01:00
static void Fol_WriteRowUsrToFollowOnRightColumn (struct UsrData *UsrDat);
static void Fol_PutInactiveIconToFollowUnfollow (void);
static void Fol_PutIconToFollow (struct UsrData *UsrDat);
static void Fol_PutIconToUnfollow (struct UsrData *UsrDat);
2015-03-19 00:28:37 +01:00
2019-03-12 01:46:40 +01:00
static void Fol_RequestFollowUsrs (Act_Action_t NextAction,void (*FuncParams) ());
static void Fol_RequestUnfollowUsrs (Act_Action_t NextAction,void (*FuncParams) ());
static void Fol_GetFollowedFromSelectedUsrs (unsigned *NumFollowed,
unsigned *NumNotFollowed);
static void Fol_PutParamsFollowSelectedStds (void);
static void Fol_PutParamsFollowSelectedTchs (void);
static void Fol_PutParamsUnfollowSelectedStds (void);
static void Fol_PutParamsUnfollowSelectedTchs (void);
static void Fol_FollowUsr (struct UsrData *UsrDat);
static void Fol_UnfollowUsr (struct UsrData *UsrDat);
2016-01-27 22:31:36 +01:00
/*****************************************************************************/
2016-01-27 23:40:16 +01:00
/********************** Put link to show users to follow **********************/
2016-01-27 22:31:36 +01:00
/*****************************************************************************/
void Fol_PutLinkWhoToFollow (void)
{
extern const char *Txt_Who_to_follow;
2019-01-12 03:00:59 +01:00
Lay_PutContextualLinkIconText (ActSeeSocPrf,NULL,NULL,
"user-plus.svg",
Txt_Who_to_follow);
2016-01-27 22:31:36 +01:00
}
/*****************************************************************************/
2017-02-16 20:22:13 +01:00
/****************** Show several users to follow on main zone ****************/
2016-01-27 22:31:36 +01:00
/*****************************************************************************/
2017-02-16 20:22:13 +01:00
#define Fol_MAX_USRS_TO_FOLLOW_MAIN_ZONE (Fol_NUM_COLUMNS_FOLLOW * 3)
void Fol_SuggestUsrsToFollowMainZone (void)
2016-01-27 22:31:36 +01:00
{
2019-03-12 21:25:55 +01:00
extern const char *Hlp_START_Profiles_who_to_follow;
2016-01-28 21:31:11 +01:00
extern const char *Txt_Who_to_follow;
2016-01-27 23:28:53 +01:00
extern const char *Txt_No_user_to_whom_you_can_follow_Try_again_later;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2018-10-31 09:40:43 +01:00
unsigned long NumUsrs;
unsigned long NumUsr;
2016-01-27 23:28:53 +01:00
struct UsrData UsrDat;
2016-01-27 23:04:27 +01:00
2017-02-17 01:59:58 +01:00
/***** Put links to request my public profile and another user's profile *****/
fprintf (Gbl.F.Out,"<div class=\"CONTEXT_MENU\">");
Prf_PutLinkMyPublicProfile ();
Prf_PutLinkRequestAnotherUserProfile ();
fprintf (Gbl.F.Out,"</div>");
2016-01-29 00:41:52 +01:00
2017-02-16 17:58:37 +01:00
/***** Get users *****/
2019-03-24 15:03:00 +01:00
if ((NumUsrs = Fol_GetUsrsToFollow (Fol_MAX_USRS_TO_FOLLOW_MAIN_ZONE,
Fol_SUGGEST_ANY_USER,
&mysql_res)))
2017-02-16 17:58:37 +01:00
{
2017-06-12 14:16:33 +02:00
/***** Start box and table *****/
2017-06-10 21:38:10 +02:00
Box_StartBoxTable ("560px",Txt_Who_to_follow,Fol_PutIconsWhoToFollow,
2019-03-12 21:25:55 +01:00
Hlp_START_Profiles_who_to_follow,Box_NOT_CLOSABLE,2);
2017-02-16 17:58:37 +01:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** List users *****/
for (NumUsr = 0;
NumUsr < NumUsrs;
NumUsr++)
{
/***** Get user *****/
row = mysql_fetch_row (mysql_res);
/* Get user's code (row[0]) */
UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
/***** Show user *****/
if ((NumUsr % Fol_NUM_COLUMNS_FOLLOW) == 0)
fprintf (Gbl.F.Out,"<tr>");
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS))
2017-02-16 17:58:37 +01:00
Fol_ShowFollowedOrFollower (&UsrDat);
if ((NumUsr % Fol_NUM_COLUMNS_FOLLOW) == (Fol_NUM_COLUMNS_FOLLOW-1) ||
NumUsr == NumUsrs - 1)
fprintf (Gbl.F.Out,"</tr>");
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
2017-06-10 21:38:10 +02:00
Box_EndBoxTable ();
2017-02-16 17:58:37 +01:00
}
else
2019-02-16 14:37:34 +01:00
Ale_ShowAlert (Ale_INFO,Txt_No_user_to_whom_you_can_follow_Try_again_later);
2017-02-16 17:58:37 +01:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
2017-02-16 20:22:13 +01:00
/*****************************************************************************/
/**************** Show several users to follow on right column ***************/
/*****************************************************************************/
#define Fol_MAX_USRS_TO_FOLLOW_RIGHT_COLUMN 3
void Fol_SuggestUsrsToFollowMainZoneOnRightColumn (void)
{
extern const char *Txt_Who_to_follow;
extern const char *Txt_No_user_to_whom_you_can_follow_Try_again_later;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2018-10-31 09:40:43 +01:00
unsigned long NumUsrs;
unsigned long NumUsr;
2017-02-16 20:22:13 +01:00
struct UsrData UsrDat;
/***** Get users *****/
2019-03-24 15:03:00 +01:00
if ((NumUsrs = Fol_GetUsrsToFollow (Fol_MAX_USRS_TO_FOLLOW_RIGHT_COLUMN,
Fol_SUGGEST_ONLY_USERS_WITH_PHOTO,
&mysql_res)))
2017-02-16 20:22:13 +01:00
{
/***** Start container *****/
2017-03-04 20:23:45 +01:00
fprintf (Gbl.F.Out,"<div class=\"CONNECTED\">");
2017-02-16 20:22:13 +01:00
/***** Title with link to suggest more users to follow *****/
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActSeeSocPrf);
Frm_LinkFormSubmit (Txt_Who_to_follow,"CONNECTED_TXT",NULL);
2017-02-16 20:22:13 +01:00
fprintf (Gbl.F.Out,"%s</a>",Txt_Who_to_follow);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2017-02-16 20:22:13 +01:00
/***** Start table *****/
fprintf (Gbl.F.Out,"<table>");
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** List users *****/
for (NumUsr = 0;
NumUsr < NumUsrs;
NumUsr++)
{
/***** Get user *****/
row = mysql_fetch_row (mysql_res);
/* Get user's code (row[0]) */
UsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
/***** Show user *****/
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS))
2017-02-16 20:22:13 +01:00
Fol_WriteRowUsrToFollowOnRightColumn (&UsrDat);
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
/***** End table *****/
fprintf (Gbl.F.Out,"</table>");
/***** End container *****/
fprintf (Gbl.F.Out,"</div>");
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
2017-02-16 17:58:37 +01:00
/*****************************************************************************/
/*************************** Get users to follow *****************************/
/*****************************************************************************/
2019-03-24 15:03:00 +01:00
static unsigned long Fol_GetUsrsToFollow (unsigned long MaxUsrsToShow,
Fol_WhichUsersSuggestToFollowThem_t WhichUsersSuggestToFollowThem,
MYSQL_RES **mysql_res)
2017-02-16 17:58:37 +01:00
{
extern const char *Pri_VisibilityDB[Pri_NUM_OPTIONS_PRIVACY];
2017-02-17 02:42:00 +01:00
char SubQuery1[256];
char SubQuery2[256];
char SubQuery3[256];
char SubQuery4[256];
/***** Build subqueries related to photos *****/
2019-03-24 15:03:00 +01:00
switch (WhichUsersSuggestToFollowThem)
2017-02-17 02:42:00 +01:00
{
2019-03-24 15:03:00 +01:00
case Fol_SUGGEST_ONLY_USERS_WITH_PHOTO:
// Photo visibility should be >= profile visibility in every subquery
sprintf (SubQuery1, // 1. Users followed by my followed
" AND usr_data.PhotoVisibility IN ('%s','%s')"
" AND usr_data.Photo<>''",
Pri_VisibilityDB[Pri_VISIBILITY_SYSTEM],
Pri_VisibilityDB[Pri_VISIBILITY_WORLD ]);
sprintf (SubQuery2, // 2. Users who share any course with me
" AND usr_data.PhotoVisibility IN ('%s','%s','%s')"
" AND usr_data.Photo<>''",
Pri_VisibilityDB[Pri_VISIBILITY_COURSE],
Pri_VisibilityDB[Pri_VISIBILITY_SYSTEM],
Pri_VisibilityDB[Pri_VISIBILITY_WORLD ]);
sprintf (SubQuery3, // 3. Users who share any course with me with another role
" AND usr_data.PhotoVisibility IN ('%s','%s','%s','%s')"
" AND usr_data.Photo<>''",
Pri_VisibilityDB[Pri_VISIBILITY_USER ],
Pri_VisibilityDB[Pri_VISIBILITY_COURSE],
Pri_VisibilityDB[Pri_VISIBILITY_SYSTEM],
Pri_VisibilityDB[Pri_VISIBILITY_WORLD ]);
sprintf (SubQuery4, // 4. Add some likely unknown random users
" AND usr_data.PhotoVisibility IN ('%s','%s')"
" AND usr_data.Photo<>''",
Pri_VisibilityDB[Pri_VISIBILITY_SYSTEM],
Pri_VisibilityDB[Pri_VISIBILITY_WORLD ]);
break;
case Fol_SUGGEST_ANY_USER:
SubQuery1[0] = '\0';
SubQuery2[0] = '\0';
SubQuery3[0] = '\0';
SubQuery4[0] = '\0';
break;
2017-02-17 02:42:00 +01:00
}
2017-02-16 17:58:37 +01:00
/***** Build query to get users to follow *****/
2016-06-12 13:20:52 +02:00
// Get only users with surname 1 and first name
2018-10-31 09:40:43 +01:00
return DB_QuerySELECT (mysql_res,"can not get users to follow",
"SELECT DISTINCT UsrCod FROM"
" ("
/***** Likely known users *****/
"(SELECT DISTINCT UsrCod FROM"
" ("
2019-03-24 15:03:00 +01:00
// 1. Users followed by my followed
2018-10-31 09:40:43 +01:00
"("
"SELECT DISTINCT usr_follow.FollowedCod AS UsrCod"
" FROM usr_follow,"
"(SELECT FollowedCod FROM usr_follow"
" WHERE FollowerCod=%ld) AS my_followed,"
" usr_data"
" WHERE usr_follow.FollowerCod=my_followed.FollowedCod"
" AND usr_follow.FollowedCod<>%ld"
" AND usr_follow.FollowedCod=usr_data.UsrCod"
" AND usr_data.Surname1<>''" // Surname 1 not empty
" AND usr_data.FirstName<>''" // First name not empty
"%s" // SubQuery1
")"
" UNION "
2019-03-24 15:03:00 +01:00
// 2. Users who share any course with me
2018-10-31 09:40:43 +01:00
"("
"SELECT DISTINCT crs_usr.UsrCod"
" FROM crs_usr,"
"(SELECT CrsCod FROM crs_usr"
" WHERE UsrCod=%ld) AS my_crs,"
" usr_data"
" WHERE crs_usr.CrsCod=my_crs.CrsCod"
" AND crs_usr.UsrCod<>%ld"
" AND crs_usr.UsrCod=usr_data.UsrCod"
" AND usr_data.Surname1<>''" // Surname 1 not empty
" AND usr_data.FirstName<>''" // First name not empty
"%s" // SubQuery2
")"
" UNION "
2019-03-24 15:03:00 +01:00
// 3. Users who share any course with me with another role
2018-10-31 09:40:43 +01:00
"("
"SELECT DISTINCT crs_usr.UsrCod"
" FROM crs_usr,"
"(SELECT CrsCod,Role FROM crs_usr"
" WHERE UsrCod=%ld) AS my_crs_role,"
" usr_data"
" WHERE crs_usr.CrsCod=my_crs_role.CrsCod"
" AND crs_usr.Role<>my_crs_role.Role"
" AND crs_usr.UsrCod=usr_data.UsrCod"
" AND usr_data.Surname1<>''" // Surname 1 not empty
" AND usr_data.FirstName<>''" // First name not empty
"%s" // SubQuery3
")"
") AS LikelyKnownUsrsToFollow"
// Do not select my followed
" WHERE UsrCod NOT IN"
" (SELECT FollowedCod FROM usr_follow"
" WHERE FollowerCod=%ld)"
2019-03-24 15:03:00 +01:00
// Get only MaxUsrsToShow * 3 users
2018-10-31 09:40:43 +01:00
" ORDER BY RAND() LIMIT %lu"
")"
" UNION "
"("
2019-03-24 19:35:48 +01:00
/***** Likely unknown userd *****/
// 4. Add some likely unknown random user
// Be careful with the method to get some random users
// from the big table of users.
// It's much faster getting a random code and then get the first users
// with codes >= that random code
// that getting all users and then ordering by rand.
"SELECT usr_data.UsrCod"
" FROM usr_data,"
"(SELECT ROUND(RAND()*(SELECT MAX(UsrCod) FROM usr_data)) AS RandomUsrCod)" // a random user code
" AS random_usr"
" WHERE usr_data.UsrCod<>%ld"
" AND usr_data.Surname1<>''" // Surname 1 not empty
" AND usr_data.FirstName<>''" // First name not empty
2018-10-31 09:40:43 +01:00
"%s" // SubQuery4
// Do not select my followed
2019-03-24 19:35:48 +01:00
" AND usr_data.UsrCod NOT IN"
2018-10-31 09:40:43 +01:00
" (SELECT FollowedCod FROM usr_follow"
" WHERE FollowerCod=%ld)"
2019-03-24 19:35:48 +01:00
" AND usr_data.UsrCod>=random_usr.RandomUsrCod" // random user code could not exists in table of users
2018-10-31 09:40:43 +01:00
// Get only MaxUsrsToShow users
2019-03-24 19:35:48 +01:00
" LIMIT %lu"
2018-10-31 09:40:43 +01:00
")"
") AS UsrsToFollow"
// Get only MaxUsrsToShow users
" ORDER BY RAND() LIMIT %lu",
Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Usrs.Me.UsrDat.UsrCod,
SubQuery1,
Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Usrs.Me.UsrDat.UsrCod,
SubQuery2,
Gbl.Usrs.Me.UsrDat.UsrCod,
SubQuery3,
Gbl.Usrs.Me.UsrDat.UsrCod,
2019-03-24 19:35:48 +01:00
MaxUsrsToShow * 2, // 2/3 likely known users
2018-10-31 09:40:43 +01:00
Gbl.Usrs.Me.UsrDat.UsrCod,
SubQuery4,
Gbl.Usrs.Me.UsrDat.UsrCod,
2019-03-24 19:35:48 +01:00
MaxUsrsToShow, // 1/3 likely unknown users
2018-10-31 09:40:43 +01:00
MaxUsrsToShow);
2016-01-27 22:31:36 +01:00
}
2016-11-07 10:45:03 +01:00
/*****************************************************************************/
/****************** Put contextual icons in "who to follow" ******************/
/*****************************************************************************/
static void Fol_PutIconsWhoToFollow (void)
{
/***** Put icon to update who to follow *****/
Fol_PutIconToUpdateWhoToFollow ();
/***** Put icon to show a figure *****/
2019-02-12 14:46:14 +01:00
Gbl.Figures.FigureType = Fig_FOLLOW;
Fig_PutIconToShowFigure ();
2016-11-07 10:45:03 +01:00
}
2016-03-24 13:40:05 +01:00
/*****************************************************************************/
/********************* Put icon to update who to follow **********************/
/*****************************************************************************/
2016-03-24 13:50:57 +01:00
static void Fol_PutIconToUpdateWhoToFollow (void)
2016-03-24 13:40:05 +01:00
{
extern const char *Txt_Update;
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActSeeSocPrf);
2019-02-22 21:47:50 +01:00
Frm_LinkFormSubmitAnimated (Txt_Update,NULL,NULL);
2017-06-11 19:13:28 +02:00
Ico_PutCalculateIcon (Txt_Update);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2016-03-24 13:40:05 +01:00
}
2015-03-18 01:06:43 +01:00
/*****************************************************************************/
/*************** Check if a user is a follower of another user ***************/
/*****************************************************************************/
bool Fol_CheckUsrIsFollowerOf (long FollowerCod,long FollowedCod)
{
if (FollowerCod == FollowedCod)
return false;
/***** Check if a user is a follower of another user *****/
2018-11-03 15:33:20 +01:00
return (DB_QueryCOUNT ("can not get if a user is a follower of another one",
"SELECT COUNT(*) FROM usr_follow"
" WHERE FollowerCod=%ld AND FollowedCod=%ld",
FollowerCod,FollowedCod) != 0);
2015-03-18 01:06:43 +01:00
}
2015-12-29 14:24:37 +01:00
/*****************************************************************************/
/*************************** Get number of followed **************************/
/*****************************************************************************/
2019-02-22 14:04:54 +01:00
void Fol_FlushCacheFollow (void)
2015-12-29 14:24:37 +01:00
{
2019-02-22 14:04:54 +01:00
Gbl.Cache.Follow.UsrCod = -1L;
Gbl.Cache.Follow.NumFollowing =
Gbl.Cache.Follow.NumFollowers = 0;
2015-12-29 14:24:37 +01:00
}
2019-02-22 14:04:54 +01:00
void Fol_GetNumFollow (long UsrCod,
unsigned *NumFollowing,unsigned *NumFollowers)
2015-12-29 14:24:37 +01:00
{
2019-02-22 14:04:54 +01:00
/***** 1. Fast check: trivial cases *****/
if (UsrCod <= 0)
{
*NumFollowing = *NumFollowers = 0;
return;
}
/***** 2. Fast check: Is number of following already calculated? *****/
if (UsrCod == Gbl.Cache.Follow.UsrCod)
{
*NumFollowing = Gbl.Cache.Follow.NumFollowing;
*NumFollowers = Gbl.Cache.Follow.NumFollowers;
return;
}
/***** 3. Slow check: Get number of following/followers from database *****/
Gbl.Cache.Follow.UsrCod = UsrCod;
*NumFollowing = Gbl.Cache.Follow.NumFollowing =
(unsigned) DB_QueryCOUNT ("can not get number of followed",
"SELECT COUNT(*) FROM usr_follow"
" WHERE FollowerCod=%ld",
UsrCod);
*NumFollowers = Gbl.Cache.Follow.NumFollowers =
(unsigned) DB_QueryCOUNT ("can not get number of followers",
"SELECT COUNT(*) FROM usr_follow"
" WHERE FollowedCod=%ld",
UsrCod);
2015-12-29 14:24:37 +01:00
}
2015-03-19 00:28:37 +01:00
/*****************************************************************************/
/**************** Show following and followers of a user *********************/
/*****************************************************************************/
2015-12-29 14:24:37 +01:00
void Fol_ShowFollowingAndFollowers (const struct UsrData *UsrDat,
2015-12-29 19:40:38 +01:00
unsigned NumFollowing,unsigned NumFollowers,
bool UsrFollowsMe,bool IFollowUsr)
2015-03-19 00:28:37 +01:00
{
2015-12-29 20:39:06 +01:00
extern const char *Txt_FOLLOWS_YOU;
2015-03-19 00:28:37 +01:00
extern const char *Txt_Following;
extern const char *Txt_Followers;
2015-12-29 19:40:38 +01:00
extern const char *Txt_Following_unfollow;
extern const char *Txt_Unfollow;
extern const char *Txt_Follow;
2018-10-10 23:56:42 +02:00
bool ItsMe = Usr_ItsMe (UsrDat->UsrCod);
2015-03-19 00:28:37 +01:00
2015-12-12 19:47:10 +01:00
/***** Start section *****/
2017-05-25 13:43:54 +02:00
Lay_StartSection (Fol_FOLLOW_SECTION_ID);
2015-03-19 00:28:37 +01:00
2015-03-19 12:32:45 +01:00
/***** Followed users *****/
2015-12-29 19:40:38 +01:00
fprintf (Gbl.F.Out,"<div id=\"following_side\">"
"<div class=\"FOLLOW_SIDE\">");
/* User follows me? */
fprintf (Gbl.F.Out,"<div id=\"follows_me\" class=\"DAT_LIGHT\">");
if (UsrFollowsMe)
2015-12-29 20:39:06 +01:00
fprintf (Gbl.F.Out,"%s",Txt_FOLLOWS_YOU);
2015-12-29 19:40:38 +01:00
fprintf (Gbl.F.Out,"</div>");
/* Number of followed */
2015-03-21 19:55:00 +01:00
Fol_ShowNumberOfFollowingOrFollowers (UsrDat,
2015-12-29 14:24:37 +01:00
NumFollowing,
2015-03-21 19:55:00 +01:00
ActSeeFlg,Txt_Following);
2015-12-29 19:40:38 +01:00
/* End following side */
fprintf (Gbl.F.Out,"</div>"
"</div>");
2015-03-21 19:55:00 +01:00
/***** Followers *****/
2015-12-29 19:40:38 +01:00
fprintf (Gbl.F.Out,"<div id=\"followers_side\">"
"<div class=\"FOLLOW_SIDE\">");
/* Number of followers */
2015-03-21 19:55:00 +01:00
Fol_ShowNumberOfFollowingOrFollowers (UsrDat,
2015-12-29 14:24:37 +01:00
NumFollowers,
2015-03-21 19:55:00 +01:00
ActSeeFlr,Txt_Followers);
2015-12-29 19:40:38 +01:00
/* I follow user? */
fprintf (Gbl.F.Out,"<div id=\"follow_usr\">");
2018-11-20 12:06:25 +01:00
if (Gbl.Usrs.Me.Logged && // Logged
!ItsMe) // Not me!
2015-12-29 19:40:38 +01:00
{
2015-12-30 09:56:06 +01:00
if (IFollowUsr) // I follow this user
2015-12-29 19:40:38 +01:00
{
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActUnfUsr);
2015-12-29 19:40:38 +01:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Txt_Following_unfollow,"REC_DAT_BOLD",NULL);
2016-11-14 10:05:41 +01:00
fprintf (Gbl.F.Out,"<div class=\"ICO_HIGHLIGHT\""
2015-12-29 19:40:38 +01:00
" style=\"display:inline;\" >"
2019-01-09 15:36:02 +01:00
"<img src=\"%s/user-check.svg\""
2015-12-29 19:40:38 +01:00
" alt=\"%s\" title=\"%s\""
2016-11-14 10:05:41 +01:00
" class=\"ICO40x40\" />"
2015-12-29 19:40:38 +01:00
"</div>"
"</a>",
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,
2015-12-29 19:40:38 +01:00
Txt_Unfollow,Txt_Following_unfollow);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2015-12-29 19:40:38 +01:00
}
2015-12-30 09:56:06 +01:00
else // I do not follow this user
2015-12-29 19:40:38 +01:00
{
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActFolUsr);
2015-12-29 19:40:38 +01:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Txt_Follow,"REC_DAT_BOLD",NULL);
2016-11-14 10:05:41 +01:00
fprintf (Gbl.F.Out,"<div class=\"ICO_HIGHLIGHT\""
2015-12-29 19:40:38 +01:00
" style=\"display:inline;\" >"
2019-01-09 15:36:02 +01:00
"<img src=\"%s/user-plus.svg\""
2015-12-29 19:40:38 +01:00
" alt=\"%s\" title=\"%s\""
2016-11-14 10:05:41 +01:00
" class=\"ICO40x40\" />"
2015-12-29 19:40:38 +01:00
"</div>"
"</a>",
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,
2015-12-29 19:40:38 +01:00
Txt_Follow,Txt_Follow);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2015-12-29 19:40:38 +01:00
}
}
2015-12-12 19:47:10 +01:00
fprintf (Gbl.F.Out,"</div>");
2015-03-21 19:55:00 +01:00
2015-12-29 19:40:38 +01:00
/* End followers side */
fprintf (Gbl.F.Out,"</div>"
"</div>");
2015-12-12 19:47:10 +01:00
/***** End section *****/
2017-05-25 13:43:54 +02:00
Lay_EndSection ();
2015-03-21 19:55:00 +01:00
}
/*****************************************************************************/
/**************** Show following and followers of a user *********************/
/*****************************************************************************/
static void Fol_ShowNumberOfFollowingOrFollowers (const struct UsrData *UsrDat,
unsigned NumUsrs,
Act_Action_t Action,
const char *Title)
{
2019-02-22 21:47:50 +01:00
extern const char *The_ClassFormOutBox[The_NUM_THEMES];
extern const char *The_ClassFormOutBoxBold[The_NUM_THEMES];
2015-03-21 19:55:00 +01:00
2015-12-12 19:47:10 +01:00
/***** Start container *****/
2015-12-29 19:40:38 +01:00
fprintf (Gbl.F.Out,"<div class=\"FOLLOW_BOX\">");
2015-03-21 19:55:00 +01:00
2015-12-12 19:47:10 +01:00
/***** Number *****/
2015-03-21 19:55:00 +01:00
if (NumUsrs)
2015-03-19 12:32:45 +01:00
{
2015-12-12 02:01:20 +01:00
/* Form to list users */
2018-11-09 20:47:39 +01:00
Frm_StartFormAnchor (Action,Fol_FOLLOW_SECTION_ID);
2015-04-02 18:39:49 +02:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Title,
2016-01-17 15:10:54 +01:00
(Gbl.Action.Act == Action) ? "FOLLOW_NUM_B" :
2016-07-01 17:13:41 +02:00
"FOLLOW_NUM",NULL);
2015-03-19 12:32:45 +01:00
}
2015-12-14 01:25:20 +01:00
else
fprintf (Gbl.F.Out,"<span class=\"%s\">",
2016-01-17 15:10:54 +01:00
(Gbl.Action.Act == Action) ? "FOLLOW_NUM_B" :
2015-12-14 01:25:20 +01:00
"FOLLOW_NUM");
2015-03-21 19:55:00 +01:00
fprintf (Gbl.F.Out,"%u",NumUsrs);
if (NumUsrs)
2015-03-19 12:32:45 +01:00
{
fprintf (Gbl.F.Out,"</a>");
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2015-03-19 12:32:45 +01:00
}
2015-12-14 01:25:20 +01:00
else
fprintf (Gbl.F.Out,"</span>");
2015-03-19 00:28:37 +01:00
2015-12-12 19:47:10 +01:00
/***** Text *****/
fprintf (Gbl.F.Out,"<div class=\"%s\">",
2019-02-22 21:47:50 +01:00
(Gbl.Action.Act == Action) ? The_ClassFormOutBoxBold[Gbl.Prefs.Theme] :
The_ClassFormOutBox [Gbl.Prefs.Theme]);
2015-03-21 19:55:00 +01:00
if (NumUsrs)
2015-03-19 12:32:45 +01:00
{
2015-12-12 02:01:20 +01:00
/* Form to list users */
2018-11-09 20:47:39 +01:00
Frm_StartFormAnchor (Action,Fol_FOLLOW_SECTION_ID);
2015-04-02 18:39:49 +02:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Title,
2019-02-22 21:47:50 +01:00
(Gbl.Action.Act == Action) ? The_ClassFormOutBoxBold[Gbl.Prefs.Theme] :
The_ClassFormOutBox [Gbl.Prefs.Theme],
NULL);
2015-03-19 12:32:45 +01:00
}
2015-03-21 19:55:00 +01:00
fprintf (Gbl.F.Out,"%s",Title);
if (NumUsrs)
2015-03-19 12:32:45 +01:00
{
fprintf (Gbl.F.Out,"</a>");
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2015-03-19 12:32:45 +01:00
}
2015-12-12 19:47:10 +01:00
fprintf (Gbl.F.Out,"</div>");
/***** End container *****/
fprintf (Gbl.F.Out,"</div>");
2015-03-19 00:28:37 +01:00
}
2015-03-19 01:59:08 +01:00
/*****************************************************************************/
/***************************** List followed users ***************************/
/*****************************************************************************/
void Fol_ListFollowing (void)
2016-06-12 19:55:33 +02:00
{
/***** Get user to view user he/she follows *****/
Usr_GetParamOtherUsrCodEncryptedAndGetListIDs ();
if (Gbl.Usrs.Other.UsrDat.UsrCod > 0)
{
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat,Usr_DONT_GET_PREFS))
2016-06-12 19:55:33 +02:00
Fol_ListFollowingUsr (&Gbl.Usrs.Other.UsrDat);
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2016-06-12 19:55:33 +02:00
}
else // If user not specified, view my profile
Fol_ListFollowingUsr (&Gbl.Usrs.Me.UsrDat);
}
static void Fol_ListFollowingUsr (struct UsrData *UsrDat)
2015-03-19 01:59:08 +01:00
{
2016-01-28 21:38:24 +01:00
extern const char *Txt_Following;
2015-03-19 01:59:08 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2018-10-31 09:40:43 +01:00
unsigned long NumUsrs;
unsigned long NumUsr;
2016-06-12 19:55:33 +02:00
struct UsrData FollowingUsrDat;
2015-03-19 01:59:08 +01:00
2016-06-12 19:55:33 +02:00
/***** Show user's profile *****/
if (Prf_ShowUserProfile (UsrDat))
2015-03-19 01:59:08 +01:00
{
2016-06-12 19:55:33 +02:00
/***** Check if a user is a follower of another user *****/
2018-10-31 09:40:43 +01:00
NumUsrs = DB_QuerySELECT (&mysql_res,"can not get followed users",
"SELECT FollowedCod FROM usr_follow"
" WHERE FollowerCod=%ld"
" ORDER BY FollowTime DESC",
UsrDat->UsrCod);
2016-06-12 19:55:33 +02:00
if (NumUsrs)
2015-03-19 01:59:08 +01:00
{
2016-06-12 19:55:33 +02:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&FollowingUsrDat);
2017-06-12 14:16:33 +02:00
/***** Start box and table *****/
2017-06-10 21:38:10 +02:00
Box_StartBoxTable ("560px",Txt_Following,NULL,
2017-06-12 15:03:29 +02:00
NULL,Box_NOT_CLOSABLE,2);
2016-06-12 19:55:33 +02:00
for (NumUsr = 0;
NumUsr < NumUsrs;
NumUsr++)
2015-03-19 01:59:08 +01:00
{
2016-06-12 19:55:33 +02:00
/***** Get user *****/
row = mysql_fetch_row (mysql_res);
/* Get user's code (row[0]) */
FollowingUsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
/***** Show user *****/
if ((NumUsr % Fol_NUM_COLUMNS_FOLLOW) == 0)
fprintf (Gbl.F.Out,"<tr>");
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&FollowingUsrDat,Usr_DONT_GET_PREFS))
2016-06-12 19:55:33 +02:00
Fol_ShowFollowedOrFollower (&FollowingUsrDat);
if ((NumUsr % Fol_NUM_COLUMNS_FOLLOW) == (Fol_NUM_COLUMNS_FOLLOW-1) ||
NumUsr == NumUsrs - 1)
fprintf (Gbl.F.Out,"</tr>");
2015-03-19 01:59:08 +01:00
}
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
2017-06-10 21:38:10 +02:00
Box_EndBoxTable ();
2016-06-12 19:55:33 +02:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&FollowingUsrDat);
2015-03-19 01:59:08 +01:00
}
2016-06-12 19:55:33 +02:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
2015-03-19 01:59:08 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2015-03-19 01:59:08 +01:00
}
/*****************************************************************************/
/******************************* List followers ******************************/
/*****************************************************************************/
void Fol_ListFollowers (void)
2016-06-12 19:55:33 +02:00
{
/***** Get user to view user he/she follows *****/
Usr_GetParamOtherUsrCodEncryptedAndGetListIDs ();
if (Gbl.Usrs.Other.UsrDat.UsrCod > 0)
{
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat,Usr_DONT_GET_PREFS))
2016-06-12 19:55:33 +02:00
Fol_ListFollowersUsr (&Gbl.Usrs.Other.UsrDat);
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2016-06-12 19:55:33 +02:00
}
else // If user not specified, view my profile
Fol_ListFollowersUsr (&Gbl.Usrs.Me.UsrDat);
}
static void Fol_ListFollowersUsr (struct UsrData *UsrDat)
2015-03-19 01:59:08 +01:00
{
2016-01-28 21:38:24 +01:00
extern const char *Txt_Followers;
2015-03-19 01:59:08 +01:00
MYSQL_RES *mysql_res;
MYSQL_ROW row;
2018-10-31 09:40:43 +01:00
unsigned long NumUsrs;
unsigned long NumUsr;
2016-06-12 19:55:33 +02:00
struct UsrData FollowerUsrDat;
2018-10-10 23:56:42 +02:00
bool ItsMe;
2015-03-19 01:59:08 +01:00
2016-06-12 19:55:33 +02:00
/***** Show user's profile *****/
if (Prf_ShowUserProfile (UsrDat))
2015-03-19 01:59:08 +01:00
{
2016-06-12 19:55:33 +02:00
/***** Check if a user is a follower of another user *****/
2018-10-31 09:40:43 +01:00
NumUsrs = DB_QuerySELECT (&mysql_res,"can not get followers",
"SELECT FollowerCod FROM usr_follow"
" WHERE FollowedCod=%ld"
" ORDER BY FollowTime DESC",
UsrDat->UsrCod);
2016-06-12 19:55:33 +02:00
if (NumUsrs)
2015-03-19 01:59:08 +01:00
{
2016-06-12 19:55:33 +02:00
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&FollowerUsrDat);
2017-06-12 14:16:33 +02:00
/***** Start box and table *****/
2017-06-10 21:38:10 +02:00
Box_StartBoxTable ("560px",Txt_Followers,NULL,
2017-06-12 15:03:29 +02:00
NULL,Box_NOT_CLOSABLE,2);
2016-06-12 19:55:33 +02:00
for (NumUsr = 0;
NumUsr < NumUsrs;
NumUsr++)
2015-03-19 01:59:08 +01:00
{
2016-06-12 19:55:33 +02:00
/***** Get user and number of clicks *****/
row = mysql_fetch_row (mysql_res);
/* Get user's code (row[0]) */
FollowerUsrDat.UsrCod = Str_ConvertStrCodToLongCod (row[0]);
/***** Show user *****/
if ((NumUsr % Fol_NUM_COLUMNS_FOLLOW) == 0)
fprintf (Gbl.F.Out,"<tr>");
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&FollowerUsrDat,Usr_DONT_GET_PREFS))
2016-06-12 19:55:33 +02:00
Fol_ShowFollowedOrFollower (&FollowerUsrDat);
if ((NumUsr % Fol_NUM_COLUMNS_FOLLOW) == (Fol_NUM_COLUMNS_FOLLOW-1) ||
NumUsr == NumUsrs - 1)
fprintf (Gbl.F.Out,"</tr>");
2015-03-19 01:59:08 +01:00
}
2017-06-12 14:16:33 +02:00
/***** End table and box *****/
2017-06-10 21:38:10 +02:00
Box_EndBoxTable ();
2015-03-24 00:01:40 +01:00
2016-06-12 19:55:33 +02:00
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&FollowerUsrDat);
2015-03-19 01:59:08 +01:00
}
2016-06-12 19:55:33 +02:00
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
/***** If it's me, mark possible notification as seen *****/
2018-10-10 23:56:42 +02:00
ItsMe = Usr_ItsMe (UsrDat->UsrCod);
if (ItsMe)
2016-06-12 19:55:33 +02:00
Ntf_MarkNotifAsSeen (Ntf_EVENT_FOLLOWER,
-1L,-1L,
Gbl.Usrs.Me.UsrDat.UsrCod);
2015-03-19 01:59:08 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlertUserNotFoundOrYouDoNotHavePermission ();
2015-03-19 01:59:08 +01:00
}
/*****************************************************************************/
2015-12-12 02:01:20 +01:00
/************************* Show followed or follower *************************/
2015-03-19 01:59:08 +01:00
/*****************************************************************************/
2016-12-13 13:32:19 +01:00
static void Fol_ShowFollowedOrFollower (struct UsrData *UsrDat)
2015-03-19 01:59:08 +01:00
{
2017-02-17 01:59:58 +01:00
extern const char *Txt_Another_user_s_profile;
2015-03-19 01:59:08 +01:00
bool ShowPhoto;
2017-01-28 15:58:46 +01:00
char PhotoURL[PATH_MAX + 1];
2019-03-22 15:21:46 +01:00
bool Visible = Pri_ShowingIsAllowed (UsrDat->BaPrfVisibility,UsrDat);
2018-10-10 23:56:42 +02:00
bool ItsMe = Usr_ItsMe (UsrDat->UsrCod);
2015-03-19 01:59:08 +01:00
2016-06-12 19:55:33 +02:00
/***** Show user's photo *****/
2017-03-05 14:46:56 +01:00
fprintf (Gbl.F.Out,"<td class=\"FOLLOW_PHOTO\">");
2015-03-19 01:59:08 +01:00
if (Visible)
{
2017-01-28 15:58:46 +01:00
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (UsrDat,PhotoURL);
2015-03-19 01:59:08 +01:00
Pho_ShowUsrPhoto (UsrDat,ShowPhoto ? PhotoURL :
NULL,
2016-01-28 10:39:25 +01:00
"PHOTO60x80",Pho_ZOOM,false);
2015-03-19 01:59:08 +01:00
}
2016-06-12 19:55:33 +02:00
fprintf (Gbl.F.Out,"</td>");
2015-03-19 01:59:08 +01:00
2016-06-12 19:55:33 +02:00
/***** Show user's name and icon to follow/unfollow *****/
2017-03-05 14:46:56 +01:00
fprintf (Gbl.F.Out,"<td class=\"FOLLOW_USR\">");
2016-01-29 10:58:16 +01:00
if (Visible)
2015-03-19 01:59:08 +01:00
{
2016-06-12 19:55:33 +02:00
/* Put form to go to public profile */
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActSeeOthPubPrf);
2015-04-02 18:39:49 +02:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
2017-03-05 15:12:48 +01:00
fprintf (Gbl.F.Out,"<div class=\"FOLLOW_USR_NAME\">"); // Limited width
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Txt_Another_user_s_profile,"DAT",NULL);
2017-03-05 15:12:48 +01:00
Usr_WriteFirstNameBRSurnames (UsrDat);
2017-03-05 14:46:56 +01:00
fprintf (Gbl.F.Out,"</a>"
"</div>");
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2016-06-12 19:55:33 +02:00
}
2016-01-29 00:41:52 +01:00
2018-10-10 23:56:42 +02:00
ItsMe = Usr_ItsMe (UsrDat->UsrCod);
2018-10-10 14:03:06 +02:00
if (!Gbl.Usrs.Me.Logged || // Not logged
ItsMe) // It's me
2016-06-12 19:55:33 +02:00
/* Inactive icon to follow/unfollow */
2017-02-16 20:22:13 +01:00
Fol_PutInactiveIconToFollowUnfollow ();
2018-10-10 14:03:06 +02:00
else // It's not me
2016-06-12 19:55:33 +02:00
{
/* Put form to follow / unfollow */
if (Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod,UsrDat->UsrCod)) // I follow user
/* Form to unfollow */
2017-02-16 20:22:13 +01:00
Fol_PutIconToUnfollow (UsrDat);
2016-06-12 19:55:33 +02:00
else if (Visible) // I do not follow this user and I can follow
/* Form to follow */
2017-02-16 20:22:13 +01:00
Fol_PutIconToFollow (UsrDat);
2016-01-29 00:41:52 +01:00
}
2015-03-19 01:59:08 +01:00
fprintf (Gbl.F.Out,"</td>");
}
2017-02-16 20:22:13 +01:00
/*****************************************************************************/
/********************* Write the name of a connected user ********************/
/*****************************************************************************/
static void Fol_WriteRowUsrToFollowOnRightColumn (struct UsrData *UsrDat)
{
2017-02-17 01:59:58 +01:00
extern const char *Txt_Another_user_s_profile;
2017-02-16 20:22:13 +01:00
bool ShowPhoto;
char PhotoURL[PATH_MAX + 1];
2019-03-22 15:21:46 +01:00
bool Visible = Pri_ShowingIsAllowed (UsrDat->BaPrfVisibility,UsrDat);
2018-10-10 23:56:42 +02:00
bool ItsMe = Usr_ItsMe (UsrDat->UsrCod);
2017-02-16 20:22:13 +01:00
/***** Show user's photo *****/
fprintf (Gbl.F.Out,"<tr>"
2019-03-08 12:48:07 +01:00
"<td class=\"CON_PHOTO COLOR%u\">",
2017-02-16 20:22:13 +01:00
Gbl.RowEvenOdd);
if (Visible)
{
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (UsrDat,PhotoURL);
Pho_ShowUsrPhoto (UsrDat,ShowPhoto ? PhotoURL :
NULL,
"PHOTO21x28",Pho_ZOOM,false);
}
fprintf (Gbl.F.Out,"</td>");
/***** User's name *****/
2019-03-08 12:48:07 +01:00
fprintf (Gbl.F.Out,"<td class=\"CON_NAME_FOLLOW CON_CRS COLOR%u\">",
2017-02-16 20:22:13 +01:00
Gbl.RowEvenOdd);
if (Visible)
{
/* Put form to go to public profile */
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActSeeOthPubPrf);
2017-02-16 20:22:13 +01:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
2019-03-08 12:48:07 +01:00
fprintf (Gbl.F.Out,"<div class=\"CON_NAME_FOLLOW\">"); // Limited width
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Txt_Another_user_s_profile,"CON_CRS",NULL);
2017-03-05 15:12:48 +01:00
Usr_WriteFirstNameBRSurnames (UsrDat);
2017-03-05 14:46:56 +01:00
fprintf (Gbl.F.Out,"</a>"
"</div>");
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2017-02-16 20:22:13 +01:00
}
fprintf (Gbl.F.Out,"</td>");
/***** Icon to follow *****/
2019-03-08 12:48:07 +01:00
fprintf (Gbl.F.Out,"<td class=\"CON_ICON_FOLLOW RIGHT_MIDDLE COLOR%u\">",
2017-02-16 20:22:13 +01:00
Gbl.RowEvenOdd);
2018-10-10 14:03:06 +02:00
if (!Gbl.Usrs.Me.Logged || // Not logged
ItsMe) // It's me
2017-02-16 20:22:13 +01:00
/* Inactive icon to follow/unfollow */
Fol_PutInactiveIconToFollowUnfollow ();
2018-10-10 14:03:06 +02:00
else // It's not me
2017-02-16 20:22:13 +01:00
{
/* Put form to follow / unfollow */
if (Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod,UsrDat->UsrCod)) // I follow user
/* Form to unfollow */
Fol_PutIconToUnfollow (UsrDat);
else if (Visible) // I do not follow this user and I can follow
/* Form to follow */
Fol_PutIconToFollow (UsrDat);
}
fprintf (Gbl.F.Out,"</td>"
"</tr>");
Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd;
}
/*****************************************************************************/
/*********************** Put icon to unfollow another user *********************/
/*****************************************************************************/
static void Fol_PutInactiveIconToFollowUnfollow (void)
{
/***** Inactive icon to follow/unfollow *****/
fprintf (Gbl.F.Out,"<div class=\"FOLLOW_USR_ICO ICO_HIDDEN\">"
2019-01-09 01:41:54 +01:00
"<img src=\"%s/user.svg\""
2017-02-16 20:22:13 +01:00
" alt=\"\""
2019-01-09 01:41:54 +01:00
" class=\"ICO16x16\" />"
2017-02-16 20:22:13 +01:00
"</div>",
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC);
2017-02-16 20:22:13 +01:00
}
/*****************************************************************************/
/*********************** Put icon to unfollow another user *********************/
/*****************************************************************************/
static void Fol_PutIconToFollow (struct UsrData *UsrDat)
{
extern const char *Txt_Follow;
/***** Form to unfollow *****/
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActFolUsr);
2017-02-16 20:22:13 +01:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Txt_Follow,NULL,NULL);
2017-02-16 20:22:13 +01:00
fprintf (Gbl.F.Out,"<div class=\"FOLLOW_USR_ICO ICO_HIGHLIGHT\">"
2019-01-09 15:36:02 +01:00
"<img src=\"%s/user-plus.svg\""
2017-02-16 20:22:13 +01:00
" alt=\"%s\" title=\"%s\""
2019-01-09 15:36:02 +01:00
" class=\"ICO16x16\" />"
2017-02-16 20:22:13 +01:00
"</div>"
"</a>",
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,
2017-02-16 20:22:13 +01:00
Txt_Follow,Txt_Follow);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2017-02-16 20:22:13 +01:00
}
/*****************************************************************************/
/********************** Put icon to unfollow another user ********************/
/*****************************************************************************/
static void Fol_PutIconToUnfollow (struct UsrData *UsrDat)
{
extern const char *Txt_Unfollow;
/* Form to follow */
2018-11-09 20:47:39 +01:00
Frm_StartForm (ActUnfUsr);
2017-02-16 20:22:13 +01:00
Usr_PutParamUsrCodEncrypted (UsrDat->EncryptedUsrCod);
2018-11-09 20:47:39 +01:00
Frm_LinkFormSubmit (Txt_Unfollow,NULL,NULL);
2017-02-16 20:22:13 +01:00
fprintf (Gbl.F.Out,"<div class=\"FOLLOW_USR_ICO ICO_HIGHLIGHT\">"
2019-01-09 15:36:02 +01:00
"<img src=\"%s/user-check.svg\""
2017-02-16 20:22:13 +01:00
" alt=\"%s\" title=\"%s\""
2019-01-09 15:36:02 +01:00
" class=\"ICO16x16\" />"
2017-02-16 20:22:13 +01:00
"</div>"
"</a>",
2019-03-20 01:36:36 +01:00
Cfg_URL_ICON_PUBLIC,
2017-02-16 20:22:13 +01:00
Txt_Unfollow,Txt_Unfollow);
2018-11-09 20:47:39 +01:00
Frm_EndForm ();
2017-02-16 20:22:13 +01:00
}
2015-03-18 01:06:43 +01:00
/*****************************************************************************/
/***************************** Follow another user ***************************/
/*****************************************************************************/
2017-02-17 02:42:00 +01:00
void Fol_FollowUsr1 (void)
2015-03-18 01:06:43 +01:00
{
2015-03-19 01:59:08 +01:00
/***** Get user to be followed *****/
2015-03-18 01:06:43 +01:00
if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ())
{
2019-03-12 01:46:40 +01:00
// Follow only if I do not follow him/her
if (!Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Usrs.Other.UsrDat.UsrCod))
Fol_FollowUsr (&Gbl.Usrs.Other.UsrDat);
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_SUCCESS,NULL,""); // Txt not used
2015-03-18 01:06:43 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-02-17 02:42:00 +01:00
}
2015-03-18 02:11:23 +01:00
2017-02-17 02:42:00 +01:00
void Fol_FollowUsr2 (void)
{
2019-03-09 20:12:44 +01:00
if (Ale_GetTypeOfLastAlert () == Ale_SUCCESS)
2019-03-10 00:34:16 +01:00
{
2017-02-17 02:42:00 +01:00
/***** Show user's profile again *****/
2017-05-09 20:56:02 +02:00
if (!Prf_ShowUserProfile (&Gbl.Usrs.Other.UsrDat))
2019-03-10 00:34:16 +01:00
/* 1) I had permission to follow the user and I've just follow him/her
2) User restricted permission, so now I can not view his/her profile
3) Now I can not view his/her profile ==> show users I follow */
Fol_ListFollowingUsr (&Gbl.Usrs.Me.UsrDat); // List users I follow
}
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlerts (NULL);
2015-03-18 01:06:43 +01:00
}
/*****************************************************************************/
/***************************** Unfollow another user *************************/
/*****************************************************************************/
2017-02-17 02:42:00 +01:00
void Fol_UnfollowUsr1 (void)
2015-03-18 01:06:43 +01:00
{
2015-03-19 01:59:08 +01:00
/***** Get user to be unfollowed *****/
2015-03-18 01:06:43 +01:00
if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ())
{
2015-03-19 12:47:05 +01:00
// Unfollow only if I follow him/her
2015-03-18 01:06:43 +01:00
if (Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Usrs.Other.UsrDat.UsrCod))
2019-03-12 01:46:40 +01:00
Fol_UnfollowUsr (&Gbl.Usrs.Other.UsrDat);
2019-02-22 14:04:54 +01:00
2019-03-09 20:12:44 +01:00
Ale_CreateAlert (Ale_SUCCESS,NULL,""); // Txt not used
2017-02-17 02:42:00 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_CreateAlertUserNotFoundOrYouDoNotHavePermission ();
2017-02-17 02:42:00 +01:00
}
void Fol_UnfollowUsr2 (void)
{
/***** Get user to be unfollowed *****/
2019-03-09 20:12:44 +01:00
if (Ale_GetTypeOfLastAlert () == Ale_SUCCESS)
2017-02-17 02:42:00 +01:00
{
2015-03-18 02:11:23 +01:00
/***** Show user's profile again *****/
2016-06-12 19:55:33 +02:00
if (!Prf_ShowUserProfile (&Gbl.Usrs.Other.UsrDat)) // I can not view user's profile
/* 1) I followed a user when I had permission
2) User restricted permission, so now I can not view his/her profile
3) Now I can not view his/her profile ==> show users I follow */
2016-09-28 13:12:11 +02:00
Fol_ListFollowingUsr (&Gbl.Usrs.Me.UsrDat); // List users I follow
2015-03-18 01:06:43 +01:00
}
else
2019-03-09 20:12:44 +01:00
Ale_ShowAlerts (NULL);
2015-03-18 01:06:43 +01:00
}
2015-03-23 10:35:15 +01:00
2019-03-12 01:46:40 +01:00
/*****************************************************************************/
/***************** Request follow/unfollow several users *********************/
/*****************************************************************************/
void Fol_RequestFollowStds (void)
{
Fol_RequestFollowUsrs (ActFolSevStd,Fol_PutParamsFollowSelectedStds);
}
void Fol_RequestFollowTchs (void)
{
Fol_RequestFollowUsrs (ActFolSevTch,Fol_PutParamsFollowSelectedTchs);
}
static void Fol_RequestFollowUsrs (Act_Action_t NextAction,void (*FuncParams) ())
{
extern const char *Txt_Follow;
extern const char *Txt_Do_you_want_to_follow_the_selected_user_whom_you_do_not_follow_yet;
extern const char *Txt_Do_you_want_to_follow_the_X_selected_users_whom_you_do_not_follow_yet;
unsigned NumFollowed;
unsigned NumNotFollowed;
// List of selected users is already got
/***** Go through list of selected users
getting the number of followed and not followed ****/
Fol_GetFollowedFromSelectedUsrs (&NumFollowed,&NumNotFollowed);
/***** Show question to confirm ****/
if (NumNotFollowed)
{
if (NumNotFollowed == 1)
Ale_ShowAlertAndButton (NextAction,NULL,NULL,
FuncParams,
Btn_CREATE_BUTTON,Txt_Follow,
Ale_QUESTION,Txt_Do_you_want_to_follow_the_selected_user_whom_you_do_not_follow_yet);
else
Ale_ShowAlertAndButton (NextAction,NULL,NULL,
FuncParams,
Btn_CREATE_BUTTON,Txt_Follow,
Ale_QUESTION,Txt_Do_you_want_to_follow_the_X_selected_users_whom_you_do_not_follow_yet,
NumNotFollowed);
}
/***** Free memory used by list of selected users' codes *****/
Usr_FreeListsSelectedUsrsCods ();
}
void Fol_RequestUnfollowStds (void)
{
Fol_RequestUnfollowUsrs (ActUnfSevStd,Fol_PutParamsUnfollowSelectedStds);
}
void Fol_RequestUnfollowTchs (void)
{
Fol_RequestUnfollowUsrs (ActUnfSevTch,Fol_PutParamsUnfollowSelectedTchs);
}
static void Fol_RequestUnfollowUsrs (Act_Action_t NextAction,void (*FuncParams) ())
{
extern const char *Txt_Do_you_want_to_stop_following_the_selected_user_whom_you_follow;
extern const char *Txt_Do_you_want_to_stop_following_the_X_selected_users_whom_you_follow;
extern const char *Txt_Unfollow;
unsigned NumFollowed;
unsigned NumNotFollowed;
// List of selected users is already got
/***** Go through list of selected users
getting the number of followed and not followed ****/
Fol_GetFollowedFromSelectedUsrs (&NumFollowed,&NumNotFollowed);
/***** Show question to confirm ****/
if (NumFollowed)
{
if (NumFollowed == 1)
Ale_ShowAlertAndButton (NextAction,NULL,NULL,
FuncParams,
Btn_CREATE_BUTTON,Txt_Unfollow,
Ale_QUESTION,Txt_Do_you_want_to_stop_following_the_selected_user_whom_you_follow);
else
Ale_ShowAlertAndButton (NextAction,NULL,NULL,
FuncParams,
Btn_CREATE_BUTTON,Txt_Unfollow,
Ale_QUESTION,Txt_Do_you_want_to_stop_following_the_X_selected_users_whom_you_follow,
NumFollowed);
}
/***** Free memory used by list of selected users' codes *****/
Usr_FreeListsSelectedUsrsCods ();
}
/*****************************************************************************/
/**** Go through the list getting the number of followed and not followed ****/
/*****************************************************************************/
static void Fol_GetFollowedFromSelectedUsrs (unsigned *NumFollowed,
unsigned *NumNotFollowed)
{
extern const char *Txt_Select_users_X_Followed_Y_Not_followed_Z;
struct UsrData UsrDat;
const char *Ptr;
bool IFollowUsr;
unsigned NumUsrs = 0;
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** Check users to know if I follow them *****/
*NumFollowed = 0;
Ptr = Gbl.Usrs.Selected.List[Rol_UNK];
while (*Ptr)
{
Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod,
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat);
if (Gbl.Usrs.Me.UsrDat.UsrCod != UsrDat.UsrCod) // Skip me
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS)) // Get from the database the data of the student
2019-03-12 01:46:40 +01:00
if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat))
{
/* Check if I follow this user */
IFollowUsr = Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod,
UsrDat.UsrCod);
/* Update number of users */
if (IFollowUsr)
(*NumFollowed)++;
NumUsrs++;
}
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
/***** Show alert ****/
*NumNotFollowed = NumUsrs - *NumFollowed;
Ale_ShowAlert (Ale_INFO,Txt_Select_users_X_Followed_Y_Not_followed_Z,
NumUsrs,*NumFollowed,*NumNotFollowed);
}
/*****************************************************************************/
/********************** Follow/unfollow several users ************************/
/*****************************************************************************/
void Fol_FollowUsrs ()
{
extern const char *Txt_You_have_followed_one_user;
extern const char *Txt_You_have_followed_X_users;
const char *Ptr;
struct UsrData UsrDat;
unsigned NumFollowed = 0;
/***** Get list of selected users if not already got *****/
Usr_GetListsSelectedUsrsCods ();
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** Check users to know if I follow them *****/
Ptr = Gbl.Usrs.Selected.List[Rol_UNK];
while (*Ptr)
{
Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod,
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat);
if (Gbl.Usrs.Me.UsrDat.UsrCod != UsrDat.UsrCod) // Skip me
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS)) // Get from the database the data of the student
2019-03-12 01:46:40 +01:00
if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat))
/* If I don't follow this user ==> follow him/her */
if (!Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod,
UsrDat.UsrCod))
{
Fol_FollowUsr (&UsrDat);
NumFollowed++;
}
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
/***** Free memory used by list of selected users' codes *****/
Usr_FreeListsSelectedUsrsCods ();
/***** Show alert *****/
if (NumFollowed == 1)
Ale_ShowAlert (Ale_SUCCESS,Txt_You_have_followed_one_user);
else
Ale_ShowAlert (Ale_SUCCESS,Txt_You_have_followed_X_users,
NumFollowed);
}
void Fol_UnfollowUsrs (void)
{
extern const char *Txt_You_have_stopped_following_one_user;
extern const char *Txt_You_have_stopped_following_X_users;
const char *Ptr;
struct UsrData UsrDat;
unsigned NumUnfollowed = 0;
/***** Get list of selected users if not already got *****/
Usr_GetListsSelectedUsrsCods ();
/***** Initialize structure with user's data *****/
Usr_UsrDataConstructor (&UsrDat);
/***** Check users to know if I follow them *****/
Ptr = Gbl.Usrs.Selected.List[Rol_UNK];
while (*Ptr)
{
Par_GetNextStrUntilSeparParamMult (&Ptr,UsrDat.EncryptedUsrCod,
Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64);
Usr_GetUsrCodFromEncryptedUsrCod (&UsrDat);
if (Gbl.Usrs.Me.UsrDat.UsrCod != UsrDat.UsrCod) // Skip me
2019-03-19 13:22:14 +01:00
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat,Usr_DONT_GET_PREFS)) // Get from the database the data of the student
2019-03-12 01:46:40 +01:00
if (Usr_CheckIfUsrBelongsToCurrentCrs (&UsrDat))
/* If I follow this user ==> unfollow him/her */
if (Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod,
UsrDat.UsrCod))
{
Fol_UnfollowUsr (&UsrDat);
NumUnfollowed++;
}
}
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
/***** Free memory used by list of selected users' codes *****/
Usr_FreeListsSelectedUsrsCods ();
/***** Show alert *****/
if (NumUnfollowed == 1)
Ale_ShowAlert (Ale_SUCCESS,Txt_You_have_stopped_following_one_user);
else
Ale_ShowAlert (Ale_SUCCESS,Txt_You_have_stopped_following_X_users,
NumUnfollowed);
}
/*****************************************************************************/
/**************** Put parameter with list of selected users ******************/
/*****************************************************************************/
static void Fol_PutParamsFollowSelectedStds (void)
{
/***** Hidden parameter with the encrypted codes of users selected *****/
Usr_PutHiddenParUsrCodAll (ActFolSevStd,Gbl.Usrs.Selected.List[Rol_UNK]);
}
static void Fol_PutParamsFollowSelectedTchs (void)
{
/***** Hidden parameter with the encrypted codes of users selected *****/
Usr_PutHiddenParUsrCodAll (ActFolSevTch,Gbl.Usrs.Selected.List[Rol_UNK]);
}
static void Fol_PutParamsUnfollowSelectedStds (void)
{
/***** Hidden parameter with the encrypted codes of users selected *****/
Usr_PutHiddenParUsrCodAll (ActUnfSevStd,Gbl.Usrs.Selected.List[Rol_UNK]);
}
static void Fol_PutParamsUnfollowSelectedTchs (void)
{
/***** Hidden parameter with the encrypted codes of users selected *****/
Usr_PutHiddenParUsrCodAll (ActUnfSevTch,Gbl.Usrs.Selected.List[Rol_UNK]);
}
/*****************************************************************************/
/******************************** Follow user ********************************/
/*****************************************************************************/
static void Fol_FollowUsr (struct UsrData *UsrDat)
{
bool CreateNotif;
bool NotifyByEmail;
/***** Avoid wrong cases *****/
if (Gbl.Usrs.Me.UsrDat.UsrCod <= 0 ||
UsrDat->UsrCod <= 0 ||
Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod) // Skip me
return;
/***** Follow user in database *****/
DB_QueryREPLACE ("can not follow user",
"REPLACE INTO usr_follow"
" (FollowerCod,FollowedCod,FollowTime)"
" VALUES"
" (%ld,%ld,NOW())",
Gbl.Usrs.Me.UsrDat.UsrCod,
UsrDat->UsrCod);
/***** Flush cache *****/
Fol_FlushCacheFollow ();
/***** This follow must be notified by email? *****/
2019-03-19 13:22:14 +01:00
CreateNotif = (UsrDat->NtfEvents.CreateNotif & (1 << Ntf_EVENT_FOLLOWER));
2019-03-12 01:46:40 +01:00
NotifyByEmail = CreateNotif &&
2019-03-19 13:22:14 +01:00
(UsrDat->NtfEvents.SendEmail & (1 << Ntf_EVENT_FOLLOWER));
2019-03-12 01:46:40 +01:00
/***** Create notification for this followed.
If this followed wants to receive notifications by email,
activate the sending of a notification *****/
if (CreateNotif)
Ntf_StoreNotifyEventToOneUser (Ntf_EVENT_FOLLOWER,UsrDat,Gbl.Usrs.Me.UsrDat.UsrCod,
(Ntf_Status_t) (NotifyByEmail ? Ntf_STATUS_BIT_EMAIL :
0));
}
/*****************************************************************************/
/******************************* Unfollow user *******************************/
/*****************************************************************************/
static void Fol_UnfollowUsr (struct UsrData *UsrDat)
{
/***** Avoid wrong cases *****/
if (Gbl.Usrs.Me.UsrDat.UsrCod <= 0 ||
UsrDat->UsrCod <= 0 ||
Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat->UsrCod) // Skip me
return;
/***** Unfollow user in database *****/
DB_QueryDELETE ("can not unfollow user",
"DELETE FROM usr_follow"
" WHERE FollowerCod=%ld AND FollowedCod=%ld",
Gbl.Usrs.Me.UsrDat.UsrCod,
UsrDat->UsrCod);
/***** Flush cache *****/
Fol_FlushCacheFollow ();
}
2015-03-23 10:35:15 +01:00
/*****************************************************************************/
/****** Get and show ranking of users attending to number of followers *******/
/*****************************************************************************/
void Fol_GetAndShowRankingFollowers (void)
{
2018-11-01 19:23:52 +01:00
MYSQL_RES *mysql_res;
unsigned NumUsrs = 0; // Initialized to avoid warning
2015-03-23 10:35:15 +01:00
/***** Get ranking from database *****/
switch (Gbl.Scope.Current)
{
2019-04-03 20:57:04 +02:00
case Hie_SYS:
2018-11-01 19:23:52 +01:00
NumUsrs =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get ranking",
"SELECT FollowedCod,COUNT(FollowerCod) AS N"
" FROM usr_follow"
" GROUP BY FollowedCod"
" ORDER BY N DESC,FollowedCod LIMIT 100");
2015-03-23 10:35:15 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_CTY:
2018-11-01 19:23:52 +01:00
NumUsrs =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get ranking",
"SELECT usr_follow.FollowedCod,COUNT(DISTINCT usr_follow.FollowerCod) AS N"
" FROM institutions,centres,degrees,courses,crs_usr,usr_follow"
" WHERE institutions.CtyCod=%ld"
" AND institutions.InsCod=centres.InsCod"
" AND centres.CtrCod=degrees.CtrCod"
" AND degrees.DegCod=courses.DegCod"
" AND courses.CrsCod=crs_usr.CrsCod"
" AND crs_usr.UsrCod=usr_follow.FollowedCod"
" GROUP BY usr_follow.FollowedCod"
" ORDER BY N DESC,usr_follow.FollowedCod LIMIT 100",
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Cty.CtyCod);
2015-03-23 10:35:15 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_INS:
2018-11-01 19:23:52 +01:00
NumUsrs =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get ranking",
"SELECT usr_follow.FollowedCod,COUNT(DISTINCT usr_follow.FollowerCod) AS N"
" FROM centres,degrees,courses,crs_usr,usr_follow"
" WHERE centres.InsCod=%ld"
" AND centres.CtrCod=degrees.CtrCod"
" AND degrees.DegCod=courses.DegCod"
" AND courses.CrsCod=crs_usr.CrsCod"
" AND crs_usr.UsrCod=usr_follow.FollowedCod"
" GROUP BY usr_follow.FollowedCod"
" ORDER BY N DESC,usr_follow.FollowedCod LIMIT 100",
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Ins.InsCod);
2015-03-23 10:35:15 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_CTR:
2018-11-01 19:23:52 +01:00
NumUsrs =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get ranking",
"SELECT usr_follow.FollowedCod,COUNT(DISTINCT usr_follow.FollowerCod) AS N"
" FROM degrees,courses,crs_usr,usr_follow"
" WHERE degrees.CtrCod=%ld"
" AND degrees.DegCod=courses.DegCod"
" AND courses.CrsCod=crs_usr.CrsCod"
" AND crs_usr.UsrCod=usr_follow.FollowedCod"
" GROUP BY usr_follow.FollowedCod"
" ORDER BY N DESC,usr_follow.FollowedCod LIMIT 100",
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Ctr.CtrCod);
2015-03-23 10:35:15 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_DEG:
2018-11-01 19:23:52 +01:00
NumUsrs =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get ranking",
"SELECT usr_follow.FollowedCod,COUNT(DISTINCT usr_follow.FollowerCod) AS N"
" FROM courses,crs_usr,usr_follow"
" WHERE courses.DegCod=%ld"
" AND courses.CrsCod=crs_usr.CrsCod"
" AND crs_usr.UsrCod=usr_follow.FollowedCod"
" GROUP BY usr_follow.FollowedCod"
" ORDER BY N DESC,usr_follow.FollowedCod LIMIT 100",
2019-04-03 20:57:04 +02:00
Gbl.Hierarchy.Deg.DegCod);
2015-03-23 10:35:15 +01:00
break;
2019-04-03 20:57:04 +02:00
case Hie_CRS:
2018-11-01 19:23:52 +01:00
NumUsrs =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get ranking",
"SELECT usr_follow.FollowedCod,COUNT(DISTINCT usr_follow.FollowerCod) AS N"
" FROM crs_usr,usr_follow"
" WHERE crs_usr.CrsCod=%ld"
" AND crs_usr.UsrCod=usr_follow.FollowedCod"
" GROUP BY usr_follow.FollowedCod"
" ORDER BY N DESC,usr_follow.FollowedCod LIMIT 100",
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.CrsCod);
2015-03-23 10:35:15 +01:00
break;
default:
2018-10-24 23:03:11 +02:00
Lay_WrongScopeExit ();
2015-03-23 10:35:15 +01:00
break;
}
2018-11-01 19:23:52 +01:00
Prf_ShowRankingFigure (&mysql_res,NumUsrs);
2015-03-23 10:35:15 +01:00
}
2015-03-24 00:01:40 +01:00
/*****************************************************************************/
/********************* Get notification of a new follower ********************/
/*****************************************************************************/
// This function may be called inside a web service, so don't report error
2017-03-08 14:12:33 +01:00
void Fol_GetNotifFollower (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1],
2017-01-15 22:58:26 +01:00
char **ContentStr)
2015-03-24 00:01:40 +01:00
{
2017-03-06 13:01:16 +01:00
SummaryStr[0] = '\0'; // Return nothing on error
2015-03-24 00:01:40 +01:00
if ((*ContentStr = (char *) malloc (1)))
2017-01-13 10:49:56 +01:00
*ContentStr[0] = '\0';
2015-03-24 00:01:40 +01:00
}
2015-12-12 02:01:20 +01:00
/*****************************************************************************/
/*********************** Remove user from user follow ************************/
/*****************************************************************************/
void Fol_RemoveUsrFromUsrFollow (long UsrCod)
{
2018-11-02 22:00:31 +01:00
DB_QueryDELETE ("can not remove user from followers and followed",
"DELETE FROM usr_follow"
" WHERE FollowerCod=%ld OR FollowedCod=%ld",
UsrCod,UsrCod);
2019-02-22 14:04:54 +01:00
/***** Flush cache *****/
Fol_FlushCacheFollow ();
2015-12-12 02:01:20 +01:00
}