From 59ef8da15187961ba12ccb9db7f060cd847f8c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Wed, 18 Mar 2015 01:06:43 +0100 Subject: [PATCH] Version 14.95 --- Makefile | 2 +- sql/cambios.sql | 5 +- sql/swad.sql | 10 ++ swad_action.c | 9 ++ swad_action.h | 343 ++++++++++++++++++++++---------------------- swad_announcement.c | 4 +- swad_changelog.h | 10 +- swad_database.c | 20 +++ swad_follow.c | 134 +++++++++++++++++ swad_follow.h | 47 ++++++ swad_record.c | 55 +++++-- 11 files changed, 454 insertions(+), 185 deletions(-) create mode 100644 swad_follow.c create mode 100644 swad_follow.h diff --git a/Makefile b/Makefile index 889fb96f..fcd781dc 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ OBJS = swad_account.o swad_action.o swad_announcement.o swad_assignment.o swad_a swad_calendar.o swad_centre.o swad_chat.o swad_config.o swad_connected.o swad_country.o swad_course.o swad_cryptography.o \ swad_database.o swad_date.o swad_degree.o swad_department.o \ swad_enrollment.o swad_exam.o \ - swad_file.o swad_file_browser.o swad_forum.o \ + swad_file.o swad_file_browser.o swad_follow.o swad_forum.o \ swad_global.o swad_group.o \ swad_holiday.o \ swad_icon.o swad_ID.o swad_import.o swad_indicator.o swad_info.o swad_institution.o \ diff --git a/sql/cambios.sql b/sql/cambios.sql index 941df0b0..b05a5163 100644 --- a/sql/cambios.sql +++ b/sql/cambios.sql @@ -10525,6 +10525,7 @@ SELECT COUNT(*)+1 FROM (SELECT NumClicks/(DATEDIFF(NOW(),FirstClickTime)+1) AS N INSERT INTO usr_figures (UsrCod,FirstClickTime,NumClicks,NumFileViews,NumForPst,NumMsgSnt) SELECT UsrCod,0,-1,-1,-1,-1 FROM usr_data WHERE UsrCod>0 AND UsrCod NOT IN (SELECT UsrCod FROM usr_figures); +--------------- Hecho: UPDATE usr_figures,((SELECT UsrCod,COUNT(*) AS N FROM forum_post WHERE UsrCod>=@USRCODMIN AND UsrCod<=@USRCODMAX GROUP BY UsrCod) UNION (SELECT UsrCod,'0' AS N FROM usr_figures WHERE UsrCod>=@USRCODMIN AND UsrCod<=@USRCODMAX AND UsrCod NOT IN (SELECT UsrCod FROM forum_post))) AS FP SET usr_figures.NumForPst=FP.N WHERE usr_figures.UsrCod>=@USRCODMIN AND usr_figures.UsrCod<=@USRCODMAX AND usr_figures.NumForPst<0 AND usr_figures.UsrCod=FP.UsrCod; @@ -10541,6 +10542,8 @@ SET @USRCODMIN=0; SET @USRCODMAX=1000; UPDATE usr_figures,((SELECT UsrCod,SUM(NumViews) AS N FROM file_view WHERE UsrCod>=@USRCODMIN AND UsrCod<=@USRCODMAX GROUP BY UsrCod) UNION (SELECT UsrCod,'0' AS N FROM usr_figures WHERE UsrCod>=@USRCODMIN AND UsrCod<=@USRCODMAX AND UsrCod NOT IN (SELECT UsrCod FROM file_view))) AS FV SET usr_figures.NumFileViews=FV.N WHERE usr_figures.UsrCod>=@USRCODMIN AND usr_figures.UsrCod<=@USRCODMAX AND usr_figures.NumFileViews<0 AND usr_figures.UsrCod=FV.UsrCod; - +--------------- + +CREATE TABLE IF NOT EXISTS usr_follow (FollowerCod INT NOT NULL,FollowedCod NIT NOT NULL,FollowTime DATETIME NOT NULL,UNIQUE INDEX (FollowerCod,FollowedCod),UNIQUE INDEX (FollowedCod,FollowerCod),INDEX (FollowTime)); diff --git a/sql/swad.sql b/sql/swad.sql index 72da3ccf..d5df4277 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -1183,6 +1183,16 @@ CREATE TABLE IF NOT EXISTS usr_figures ( INDEX(FirstClickTime), INDEX(NumClicks)); -- +-- Table usr_follow: stores followers and followed +-- +CREATE TABLE IF NOT EXISTS usr_follow ( + FollowerCod INT NOT NULL, + FollowedCod INT NOT NULL, + FollowTime DATETIME NOT NULL, + UNIQUE INDEX (FollowerCod,FollowedCod), + UNIQUE INDEX (FollowedCod,FollowerCod), + INDEX (FollowTime)); +-- -- Table usr_last: stores some variable data related to users -- CREATE TABLE IF NOT EXISTS usr_last ( diff --git a/swad_action.c b/swad_action.c index 86dda8ee..1da249d0 100644 --- a/swad_action.c +++ b/swad_action.c @@ -43,6 +43,7 @@ #include "swad_database.h" #include "swad_exam.h" #include "swad_enrollment.h" +#include "swad_follow.h" #include "swad_global.h" #include "swad_ID.h" #include "swad_indicator.h" @@ -951,6 +952,9 @@ Users: ---. ActCalNumFileViews Calculate number of file views and store into user's figures ---. ActCalNumForPst Calculate number of forum posts and store into user's figures ---. ActCalNumMsgSnt Calculate number of messages sent from log and store into user's figures + + ---. ActFolUsr Follow another user + ---. ActUnfUsr Unfollow another user Messages: 794. ActSeeNtf Show my recent notifications 795. ActSeeAnn Show global announcements @@ -2337,6 +2341,9 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActCalNumForPst */{1408,-1,TabUsr,ActReqPubPrf ,0x1FF,0x1FF,0x1FF,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Prf_CalculateNumForPst ,NULL}, /* ActCalNumMsgSnt */{1407,-1,TabUsr,ActReqPubPrf ,0x1FF,0x1FF,0x1FF,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Prf_CalculateNumMsgSnt ,NULL}, + /* ActFolUsr */{1410,-1,TabUsr,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Fol_FollowUsr ,NULL}, + /* ActUnfUsr */{1411,-1,TabUsr,ActReqPubPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Fol_UnfollowUsr ,NULL}, + // TabMsg ****************************************************************** // Actions in menu: /* ActSeeNtf */{ 990, 0,TabMsg,ActSeeNtf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Ntf_ShowMyNotifications ,"bell" }, @@ -4075,6 +4082,8 @@ Act_Action_t Act_FromActCodToAction[1+Act_MAX_ACTION_COD] = // Do not reuse uniq ActCalNumMsgSnt, // #1407 ActCalNumForPst, // #1408 ActCalNumFilVie, // #1409 + ActFolUsr, // #1410 + ActUnfUsr, // #1411 }; /*****************************************************************************/ diff --git a/swad_action.h b/swad_action.h index d9787081..060af1f9 100644 --- a/swad_action.h +++ b/swad_action.h @@ -69,9 +69,9 @@ typedef enum typedef int Act_Action_t; // Must be a signed type, because -1 is used to indicate obsolete action -#define Act_NUM_ACTIONS (7+52+15+90+73+68+204+184+105+168+28+77) +#define Act_NUM_ACTIONS (7+52+15+90+73+68+204+184+107+168+28+77) -#define Act_MAX_ACTION_COD 1409 +#define Act_MAX_ACTION_COD 1411 #define Act_MAX_OPTIONS_IN_MENU_PER_TAB 20 @@ -986,179 +986,182 @@ typedef int Act_Action_t; // Must be a signed type, because -1 is used to indica #define ActCalNumForPst (ActChgNumRowFooGrp+104) #define ActCalNumMsgSnt (ActChgNumRowFooGrp+105) +#define ActFolUsr (ActChgNumRowFooGrp+106) +#define ActUnfUsr (ActChgNumRowFooGrp+107) + /*****************************************************************************/ /******************************* Messages tab ********************************/ /*****************************************************************************/ // Actions in menu -#define ActSeeNtf (ActCalNumMsgSnt+ 1) -#define ActSeeAnn (ActCalNumMsgSnt+ 2) -#define ActSeeNot (ActCalNumMsgSnt+ 3) -#define ActSeeFor (ActCalNumMsgSnt+ 4) -#define ActSeeChtRms (ActCalNumMsgSnt+ 5) -#define ActReqMsgUsr (ActCalNumMsgSnt+ 6) -#define ActSeeRcvMsg (ActCalNumMsgSnt+ 7) -#define ActSeeSntMsg (ActCalNumMsgSnt+ 8) -#define ActMaiStd (ActCalNumMsgSnt+ 9) +#define ActSeeNtf (ActUnfUsr+ 1) +#define ActSeeAnn (ActUnfUsr+ 2) +#define ActSeeNot (ActUnfUsr+ 3) +#define ActSeeFor (ActUnfUsr+ 4) +#define ActSeeChtRms (ActUnfUsr+ 5) +#define ActReqMsgUsr (ActUnfUsr+ 6) +#define ActSeeRcvMsg (ActUnfUsr+ 7) +#define ActSeeSntMsg (ActUnfUsr+ 8) +#define ActMaiStd (ActUnfUsr+ 9) // Secondary actions -#define ActWriAnn (ActCalNumMsgSnt+ 10) -#define ActRcvAnn (ActCalNumMsgSnt+ 11) -#define ActRemAnn (ActCalNumMsgSnt+ 12) -#define ActShoNot (ActCalNumMsgSnt+ 13) -#define ActWriNot (ActCalNumMsgSnt+ 14) -#define ActRcvNot (ActCalNumMsgSnt+ 15) -#define ActHidNot (ActCalNumMsgSnt+ 16) -#define ActRevNot (ActCalNumMsgSnt+ 17) -#define ActRemNot (ActCalNumMsgSnt+ 18) -#define ActSeeNewNtf (ActCalNumMsgSnt+ 19) -#define ActMrkNtfSee (ActCalNumMsgSnt+ 20) -#define ActSeeForCrsUsr (ActCalNumMsgSnt+ 21) -#define ActSeeForCrsTch (ActCalNumMsgSnt+ 22) -#define ActSeeForDegUsr (ActCalNumMsgSnt+ 23) -#define ActSeeForDegTch (ActCalNumMsgSnt+ 24) -#define ActSeeForCtrUsr (ActCalNumMsgSnt+ 25) -#define ActSeeForCtrTch (ActCalNumMsgSnt+ 26) -#define ActSeeForInsUsr (ActCalNumMsgSnt+ 27) -#define ActSeeForInsTch (ActCalNumMsgSnt+ 28) -#define ActSeeForGenUsr (ActCalNumMsgSnt+ 29) -#define ActSeeForGenTch (ActCalNumMsgSnt+ 30) -#define ActSeeForSWAUsr (ActCalNumMsgSnt+ 31) -#define ActSeeForSWATch (ActCalNumMsgSnt+ 32) -#define ActSeePstForCrsUsr (ActCalNumMsgSnt+ 33) -#define ActSeePstForCrsTch (ActCalNumMsgSnt+ 34) -#define ActSeePstForDegUsr (ActCalNumMsgSnt+ 35) -#define ActSeePstForDegTch (ActCalNumMsgSnt+ 36) -#define ActSeePstForCtrUsr (ActCalNumMsgSnt+ 37) -#define ActSeePstForCtrTch (ActCalNumMsgSnt+ 38) -#define ActSeePstForInsUsr (ActCalNumMsgSnt+ 39) -#define ActSeePstForInsTch (ActCalNumMsgSnt+ 40) -#define ActSeePstForGenUsr (ActCalNumMsgSnt+ 41) -#define ActSeePstForGenTch (ActCalNumMsgSnt+ 42) -#define ActSeePstForSWAUsr (ActCalNumMsgSnt+ 43) -#define ActSeePstForSWATch (ActCalNumMsgSnt+ 44) -#define ActRcvThrForCrsUsr (ActCalNumMsgSnt+ 45) -#define ActRcvThrForCrsTch (ActCalNumMsgSnt+ 46) -#define ActRcvThrForDegUsr (ActCalNumMsgSnt+ 47) -#define ActRcvThrForDegTch (ActCalNumMsgSnt+ 48) -#define ActRcvThrForCtrUsr (ActCalNumMsgSnt+ 49) -#define ActRcvThrForCtrTch (ActCalNumMsgSnt+ 50) -#define ActRcvThrForInsUsr (ActCalNumMsgSnt+ 51) -#define ActRcvThrForInsTch (ActCalNumMsgSnt+ 52) -#define ActRcvThrForGenUsr (ActCalNumMsgSnt+ 53) -#define ActRcvThrForGenTch (ActCalNumMsgSnt+ 54) -#define ActRcvThrForSWAUsr (ActCalNumMsgSnt+ 55) -#define ActRcvThrForSWATch (ActCalNumMsgSnt+ 56) -#define ActRcvRepForCrsUsr (ActCalNumMsgSnt+ 57) -#define ActRcvRepForCrsTch (ActCalNumMsgSnt+ 58) -#define ActRcvRepForDegUsr (ActCalNumMsgSnt+ 59) -#define ActRcvRepForDegTch (ActCalNumMsgSnt+ 60) -#define ActRcvRepForCtrUsr (ActCalNumMsgSnt+ 61) -#define ActRcvRepForCtrTch (ActCalNumMsgSnt+ 62) -#define ActRcvRepForInsUsr (ActCalNumMsgSnt+ 63) -#define ActRcvRepForInsTch (ActCalNumMsgSnt+ 64) -#define ActRcvRepForGenUsr (ActCalNumMsgSnt+ 65) -#define ActRcvRepForGenTch (ActCalNumMsgSnt+ 66) -#define ActRcvRepForSWAUsr (ActCalNumMsgSnt+ 67) -#define ActRcvRepForSWATch (ActCalNumMsgSnt+ 68) -#define ActReqDelThrCrsUsr (ActCalNumMsgSnt+ 69) -#define ActReqDelThrCrsTch (ActCalNumMsgSnt+ 70) -#define ActReqDelThrDegUsr (ActCalNumMsgSnt+ 71) -#define ActReqDelThrDegTch (ActCalNumMsgSnt+ 72) -#define ActReqDelThrCtrUsr (ActCalNumMsgSnt+ 73) -#define ActReqDelThrCtrTch (ActCalNumMsgSnt+ 74) -#define ActReqDelThrInsUsr (ActCalNumMsgSnt+ 75) -#define ActReqDelThrInsTch (ActCalNumMsgSnt+ 76) -#define ActReqDelThrGenUsr (ActCalNumMsgSnt+ 77) -#define ActReqDelThrGenTch (ActCalNumMsgSnt+ 78) -#define ActReqDelThrSWAUsr (ActCalNumMsgSnt+ 79) -#define ActReqDelThrSWATch (ActCalNumMsgSnt+ 80) -#define ActDelThrForCrsUsr (ActCalNumMsgSnt+ 81) -#define ActDelThrForCrsTch (ActCalNumMsgSnt+ 82) -#define ActDelThrForDegUsr (ActCalNumMsgSnt+ 83) -#define ActDelThrForDegTch (ActCalNumMsgSnt+ 84) -#define ActDelThrForCtrUsr (ActCalNumMsgSnt+ 85) -#define ActDelThrForCtrTch (ActCalNumMsgSnt+ 86) -#define ActDelThrForInsUsr (ActCalNumMsgSnt+ 87) -#define ActDelThrForInsTch (ActCalNumMsgSnt+ 88) -#define ActDelThrForGenUsr (ActCalNumMsgSnt+ 89) -#define ActDelThrForGenTch (ActCalNumMsgSnt+ 90) -#define ActDelThrForSWAUsr (ActCalNumMsgSnt+ 91) -#define ActDelThrForSWATch (ActCalNumMsgSnt+ 92) -#define ActCutThrForCrsUsr (ActCalNumMsgSnt+ 93) -#define ActCutThrForCrsTch (ActCalNumMsgSnt+ 94) -#define ActCutThrForDegUsr (ActCalNumMsgSnt+ 95) -#define ActCutThrForDegTch (ActCalNumMsgSnt+ 96) -#define ActCutThrForCtrUsr (ActCalNumMsgSnt+ 97) -#define ActCutThrForCtrTch (ActCalNumMsgSnt+ 98) -#define ActCutThrForInsUsr (ActCalNumMsgSnt+ 99) -#define ActCutThrForInsTch (ActCalNumMsgSnt+100) -#define ActCutThrForGenUsr (ActCalNumMsgSnt+101) -#define ActCutThrForGenTch (ActCalNumMsgSnt+102) -#define ActCutThrForSWAUsr (ActCalNumMsgSnt+103) -#define ActCutThrForSWATch (ActCalNumMsgSnt+104) -#define ActPasThrForCrsUsr (ActCalNumMsgSnt+105) -#define ActPasThrForCrsTch (ActCalNumMsgSnt+106) -#define ActPasThrForDegUsr (ActCalNumMsgSnt+107) -#define ActPasThrForDegTch (ActCalNumMsgSnt+108) -#define ActPasThrForCtrUsr (ActCalNumMsgSnt+109) -#define ActPasThrForCtrTch (ActCalNumMsgSnt+110) -#define ActPasThrForInsUsr (ActCalNumMsgSnt+111) -#define ActPasThrForInsTch (ActCalNumMsgSnt+112) -#define ActPasThrForGenUsr (ActCalNumMsgSnt+113) -#define ActPasThrForGenTch (ActCalNumMsgSnt+114) -#define ActPasThrForSWAUsr (ActCalNumMsgSnt+115) -#define ActPasThrForSWATch (ActCalNumMsgSnt+116) -#define ActDelPstForCrsUsr (ActCalNumMsgSnt+117) -#define ActDelPstForCrsTch (ActCalNumMsgSnt+118) -#define ActDelPstForDegUsr (ActCalNumMsgSnt+119) -#define ActDelPstForDegTch (ActCalNumMsgSnt+120) -#define ActDelPstForCtrUsr (ActCalNumMsgSnt+121) -#define ActDelPstForCtrTch (ActCalNumMsgSnt+122) -#define ActDelPstForInsUsr (ActCalNumMsgSnt+123) -#define ActDelPstForInsTch (ActCalNumMsgSnt+124) -#define ActDelPstForGenUsr (ActCalNumMsgSnt+125) -#define ActDelPstForGenTch (ActCalNumMsgSnt+126) -#define ActDelPstForSWAUsr (ActCalNumMsgSnt+127) -#define ActDelPstForSWATch (ActCalNumMsgSnt+128) -#define ActEnbPstForCrsUsr (ActCalNumMsgSnt+129) -#define ActEnbPstForCrsTch (ActCalNumMsgSnt+130) -#define ActEnbPstForDegUsr (ActCalNumMsgSnt+131) -#define ActEnbPstForDegTch (ActCalNumMsgSnt+132) -#define ActEnbPstForCtrUsr (ActCalNumMsgSnt+133) -#define ActEnbPstForCtrTch (ActCalNumMsgSnt+134) -#define ActEnbPstForInsUsr (ActCalNumMsgSnt+135) -#define ActEnbPstForInsTch (ActCalNumMsgSnt+136) -#define ActEnbPstForGenUsr (ActCalNumMsgSnt+137) -#define ActEnbPstForGenTch (ActCalNumMsgSnt+138) -#define ActEnbPstForSWAUsr (ActCalNumMsgSnt+139) -#define ActEnbPstForSWATch (ActCalNumMsgSnt+140) -#define ActDisPstForCrsUsr (ActCalNumMsgSnt+141) -#define ActDisPstForCrsTch (ActCalNumMsgSnt+142) -#define ActDisPstForDegUsr (ActCalNumMsgSnt+143) -#define ActDisPstForDegTch (ActCalNumMsgSnt+144) -#define ActDisPstForCtrUsr (ActCalNumMsgSnt+145) -#define ActDisPstForCtrTch (ActCalNumMsgSnt+146) -#define ActDisPstForInsUsr (ActCalNumMsgSnt+147) -#define ActDisPstForInsTch (ActCalNumMsgSnt+148) -#define ActDisPstForGenUsr (ActCalNumMsgSnt+149) -#define ActDisPstForGenTch (ActCalNumMsgSnt+150) -#define ActDisPstForSWAUsr (ActCalNumMsgSnt+151) -#define ActDisPstForSWATch (ActCalNumMsgSnt+152) -#define ActRcvMsgUsr (ActCalNumMsgSnt+153) -#define ActReqDelAllSntMsg (ActCalNumMsgSnt+154) -#define ActReqDelAllRcvMsg (ActCalNumMsgSnt+155) -#define ActDelAllSntMsg (ActCalNumMsgSnt+156) -#define ActDelAllRcvMsg (ActCalNumMsgSnt+157) -#define ActDelSntMsg (ActCalNumMsgSnt+158) -#define ActDelRcvMsg (ActCalNumMsgSnt+159) -#define ActExpSntMsg (ActCalNumMsgSnt+160) -#define ActExpRcvMsg (ActCalNumMsgSnt+161) -#define ActConSntMsg (ActCalNumMsgSnt+162) -#define ActConRcvMsg (ActCalNumMsgSnt+163) -#define ActLstBanUsr (ActCalNumMsgSnt+164) -#define ActBanUsrMsg (ActCalNumMsgSnt+165) -#define ActUnbUsrMsg (ActCalNumMsgSnt+166) -#define ActUnbUsrLst (ActCalNumMsgSnt+167) -#define ActCht (ActCalNumMsgSnt+168) +#define ActWriAnn (ActUnfUsr+ 10) +#define ActRcvAnn (ActUnfUsr+ 11) +#define ActRemAnn (ActUnfUsr+ 12) +#define ActShoNot (ActUnfUsr+ 13) +#define ActWriNot (ActUnfUsr+ 14) +#define ActRcvNot (ActUnfUsr+ 15) +#define ActHidNot (ActUnfUsr+ 16) +#define ActRevNot (ActUnfUsr+ 17) +#define ActRemNot (ActUnfUsr+ 18) +#define ActSeeNewNtf (ActUnfUsr+ 19) +#define ActMrkNtfSee (ActUnfUsr+ 20) +#define ActSeeForCrsUsr (ActUnfUsr+ 21) +#define ActSeeForCrsTch (ActUnfUsr+ 22) +#define ActSeeForDegUsr (ActUnfUsr+ 23) +#define ActSeeForDegTch (ActUnfUsr+ 24) +#define ActSeeForCtrUsr (ActUnfUsr+ 25) +#define ActSeeForCtrTch (ActUnfUsr+ 26) +#define ActSeeForInsUsr (ActUnfUsr+ 27) +#define ActSeeForInsTch (ActUnfUsr+ 28) +#define ActSeeForGenUsr (ActUnfUsr+ 29) +#define ActSeeForGenTch (ActUnfUsr+ 30) +#define ActSeeForSWAUsr (ActUnfUsr+ 31) +#define ActSeeForSWATch (ActUnfUsr+ 32) +#define ActSeePstForCrsUsr (ActUnfUsr+ 33) +#define ActSeePstForCrsTch (ActUnfUsr+ 34) +#define ActSeePstForDegUsr (ActUnfUsr+ 35) +#define ActSeePstForDegTch (ActUnfUsr+ 36) +#define ActSeePstForCtrUsr (ActUnfUsr+ 37) +#define ActSeePstForCtrTch (ActUnfUsr+ 38) +#define ActSeePstForInsUsr (ActUnfUsr+ 39) +#define ActSeePstForInsTch (ActUnfUsr+ 40) +#define ActSeePstForGenUsr (ActUnfUsr+ 41) +#define ActSeePstForGenTch (ActUnfUsr+ 42) +#define ActSeePstForSWAUsr (ActUnfUsr+ 43) +#define ActSeePstForSWATch (ActUnfUsr+ 44) +#define ActRcvThrForCrsUsr (ActUnfUsr+ 45) +#define ActRcvThrForCrsTch (ActUnfUsr+ 46) +#define ActRcvThrForDegUsr (ActUnfUsr+ 47) +#define ActRcvThrForDegTch (ActUnfUsr+ 48) +#define ActRcvThrForCtrUsr (ActUnfUsr+ 49) +#define ActRcvThrForCtrTch (ActUnfUsr+ 50) +#define ActRcvThrForInsUsr (ActUnfUsr+ 51) +#define ActRcvThrForInsTch (ActUnfUsr+ 52) +#define ActRcvThrForGenUsr (ActUnfUsr+ 53) +#define ActRcvThrForGenTch (ActUnfUsr+ 54) +#define ActRcvThrForSWAUsr (ActUnfUsr+ 55) +#define ActRcvThrForSWATch (ActUnfUsr+ 56) +#define ActRcvRepForCrsUsr (ActUnfUsr+ 57) +#define ActRcvRepForCrsTch (ActUnfUsr+ 58) +#define ActRcvRepForDegUsr (ActUnfUsr+ 59) +#define ActRcvRepForDegTch (ActUnfUsr+ 60) +#define ActRcvRepForCtrUsr (ActUnfUsr+ 61) +#define ActRcvRepForCtrTch (ActUnfUsr+ 62) +#define ActRcvRepForInsUsr (ActUnfUsr+ 63) +#define ActRcvRepForInsTch (ActUnfUsr+ 64) +#define ActRcvRepForGenUsr (ActUnfUsr+ 65) +#define ActRcvRepForGenTch (ActUnfUsr+ 66) +#define ActRcvRepForSWAUsr (ActUnfUsr+ 67) +#define ActRcvRepForSWATch (ActUnfUsr+ 68) +#define ActReqDelThrCrsUsr (ActUnfUsr+ 69) +#define ActReqDelThrCrsTch (ActUnfUsr+ 70) +#define ActReqDelThrDegUsr (ActUnfUsr+ 71) +#define ActReqDelThrDegTch (ActUnfUsr+ 72) +#define ActReqDelThrCtrUsr (ActUnfUsr+ 73) +#define ActReqDelThrCtrTch (ActUnfUsr+ 74) +#define ActReqDelThrInsUsr (ActUnfUsr+ 75) +#define ActReqDelThrInsTch (ActUnfUsr+ 76) +#define ActReqDelThrGenUsr (ActUnfUsr+ 77) +#define ActReqDelThrGenTch (ActUnfUsr+ 78) +#define ActReqDelThrSWAUsr (ActUnfUsr+ 79) +#define ActReqDelThrSWATch (ActUnfUsr+ 80) +#define ActDelThrForCrsUsr (ActUnfUsr+ 81) +#define ActDelThrForCrsTch (ActUnfUsr+ 82) +#define ActDelThrForDegUsr (ActUnfUsr+ 83) +#define ActDelThrForDegTch (ActUnfUsr+ 84) +#define ActDelThrForCtrUsr (ActUnfUsr+ 85) +#define ActDelThrForCtrTch (ActUnfUsr+ 86) +#define ActDelThrForInsUsr (ActUnfUsr+ 87) +#define ActDelThrForInsTch (ActUnfUsr+ 88) +#define ActDelThrForGenUsr (ActUnfUsr+ 89) +#define ActDelThrForGenTch (ActUnfUsr+ 90) +#define ActDelThrForSWAUsr (ActUnfUsr+ 91) +#define ActDelThrForSWATch (ActUnfUsr+ 92) +#define ActCutThrForCrsUsr (ActUnfUsr+ 93) +#define ActCutThrForCrsTch (ActUnfUsr+ 94) +#define ActCutThrForDegUsr (ActUnfUsr+ 95) +#define ActCutThrForDegTch (ActUnfUsr+ 96) +#define ActCutThrForCtrUsr (ActUnfUsr+ 97) +#define ActCutThrForCtrTch (ActUnfUsr+ 98) +#define ActCutThrForInsUsr (ActUnfUsr+ 99) +#define ActCutThrForInsTch (ActUnfUsr+100) +#define ActCutThrForGenUsr (ActUnfUsr+101) +#define ActCutThrForGenTch (ActUnfUsr+102) +#define ActCutThrForSWAUsr (ActUnfUsr+103) +#define ActCutThrForSWATch (ActUnfUsr+104) +#define ActPasThrForCrsUsr (ActUnfUsr+105) +#define ActPasThrForCrsTch (ActUnfUsr+106) +#define ActPasThrForDegUsr (ActUnfUsr+107) +#define ActPasThrForDegTch (ActUnfUsr+108) +#define ActPasThrForCtrUsr (ActUnfUsr+109) +#define ActPasThrForCtrTch (ActUnfUsr+110) +#define ActPasThrForInsUsr (ActUnfUsr+111) +#define ActPasThrForInsTch (ActUnfUsr+112) +#define ActPasThrForGenUsr (ActUnfUsr+113) +#define ActPasThrForGenTch (ActUnfUsr+114) +#define ActPasThrForSWAUsr (ActUnfUsr+115) +#define ActPasThrForSWATch (ActUnfUsr+116) +#define ActDelPstForCrsUsr (ActUnfUsr+117) +#define ActDelPstForCrsTch (ActUnfUsr+118) +#define ActDelPstForDegUsr (ActUnfUsr+119) +#define ActDelPstForDegTch (ActUnfUsr+120) +#define ActDelPstForCtrUsr (ActUnfUsr+121) +#define ActDelPstForCtrTch (ActUnfUsr+122) +#define ActDelPstForInsUsr (ActUnfUsr+123) +#define ActDelPstForInsTch (ActUnfUsr+124) +#define ActDelPstForGenUsr (ActUnfUsr+125) +#define ActDelPstForGenTch (ActUnfUsr+126) +#define ActDelPstForSWAUsr (ActUnfUsr+127) +#define ActDelPstForSWATch (ActUnfUsr+128) +#define ActEnbPstForCrsUsr (ActUnfUsr+129) +#define ActEnbPstForCrsTch (ActUnfUsr+130) +#define ActEnbPstForDegUsr (ActUnfUsr+131) +#define ActEnbPstForDegTch (ActUnfUsr+132) +#define ActEnbPstForCtrUsr (ActUnfUsr+133) +#define ActEnbPstForCtrTch (ActUnfUsr+134) +#define ActEnbPstForInsUsr (ActUnfUsr+135) +#define ActEnbPstForInsTch (ActUnfUsr+136) +#define ActEnbPstForGenUsr (ActUnfUsr+137) +#define ActEnbPstForGenTch (ActUnfUsr+138) +#define ActEnbPstForSWAUsr (ActUnfUsr+139) +#define ActEnbPstForSWATch (ActUnfUsr+140) +#define ActDisPstForCrsUsr (ActUnfUsr+141) +#define ActDisPstForCrsTch (ActUnfUsr+142) +#define ActDisPstForDegUsr (ActUnfUsr+143) +#define ActDisPstForDegTch (ActUnfUsr+144) +#define ActDisPstForCtrUsr (ActUnfUsr+145) +#define ActDisPstForCtrTch (ActUnfUsr+146) +#define ActDisPstForInsUsr (ActUnfUsr+147) +#define ActDisPstForInsTch (ActUnfUsr+148) +#define ActDisPstForGenUsr (ActUnfUsr+149) +#define ActDisPstForGenTch (ActUnfUsr+150) +#define ActDisPstForSWAUsr (ActUnfUsr+151) +#define ActDisPstForSWATch (ActUnfUsr+152) +#define ActRcvMsgUsr (ActUnfUsr+153) +#define ActReqDelAllSntMsg (ActUnfUsr+154) +#define ActReqDelAllRcvMsg (ActUnfUsr+155) +#define ActDelAllSntMsg (ActUnfUsr+156) +#define ActDelAllRcvMsg (ActUnfUsr+157) +#define ActDelSntMsg (ActUnfUsr+158) +#define ActDelRcvMsg (ActUnfUsr+159) +#define ActExpSntMsg (ActUnfUsr+160) +#define ActExpRcvMsg (ActUnfUsr+161) +#define ActConSntMsg (ActUnfUsr+162) +#define ActConRcvMsg (ActUnfUsr+163) +#define ActLstBanUsr (ActUnfUsr+164) +#define ActBanUsrMsg (ActUnfUsr+165) +#define ActUnbUsrMsg (ActUnfUsr+166) +#define ActUnbUsrLst (ActUnfUsr+167) +#define ActCht (ActUnfUsr+168) /*****************************************************************************/ /****************************** Statistics tab *******************************/ diff --git a/swad_announcement.c b/swad_announcement.c index 4c7e8847..48ed29f5 100644 --- a/swad_announcement.c +++ b/swad_announcement.c @@ -435,12 +435,12 @@ void Ann_RemoveAnnouncement (void) /***** Remove announcement *****/ sprintf (Query,"DELETE FROM announcements WHERE AnnCod='%ld'", AnnCod); - DB_QueryREPLACE (Query,"can not remove announcement"); + DB_QueryDELETE (Query,"can not remove announcement"); /***** Remove users who have seen the announcement *****/ sprintf (Query,"DELETE FROM ann_seen WHERE AnnCod='%ld'", AnnCod); - DB_QueryREPLACE (Query,"can not remove announcement"); + DB_QueryDELETE (Query,"can not remove announcement"); /***** Write message of success *****/ Lay_ShowAlert (Lay_SUCCESS,Txt_Announcement_removed); diff --git a/swad_changelog.h b/swad_changelog.h index 8365d03e..39ec15af 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -103,11 +103,19 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 14.94.4 (2015/03/17)" +#define Log_PLATFORM_VERSION "SWAD 14.95 (2015/03/18)" // Number of lines (includes comments but not blank lines) has been got with the following command: // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1 /* + Version 14.95: Mar 18, 2015 New module swad_follow for follow users. (182903 lines) + 1 change necessary in Makefile: +Add swad_follow.o to list of object files + 3 changes necessary in database: +CREATE TABLE IF NOT EXISTS usr_follow (FollowerCod INT NOT NULL,FollowedCod INT NOT NULL,FollowTime DATETIME NOT NULL,UNIQUE INDEX (FollowerCod,FollowedCod),UNIQUE INDEX (FollowedCod,FollowerCod),INDEX (FollowTime)); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1410','es','N','Seguir a un usuario'); +INSERT INTO actions (ActCod,Language,Obsolete,Txt) VALUES ('1411','es','N','Dejar de seguir a un usuario'); + Version 14.94.4: Mar 17, 2015 Changes in ranking layout. (182679 lines) Version 14.94.3: Mar 17, 2015 Changes in record fonts. (182667 lines) Version 14.94.2: Mar 17, 2015 Fixed bug in ranking. (182668 lines) diff --git a/swad_database.c b/swad_database.c index 4771903d..32754ae1 100644 --- a/swad_database.c +++ b/swad_database.c @@ -2361,6 +2361,26 @@ mysql> DESCRIBE usr_figures; "NumMsgSnt INT NOT NULL DEFAULT -1," "PRIMARY KEY(UsrCod),INDEX(FirstClickTime),INDEX(NumClicks))"); + /***** Table usr_follow *****/ + /* +mysql> DESCRIBE usr_follow; ++-------------+----------+------+-----+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++-------------+----------+------+-----+---------+-------+ +| FollowerCod | int(11) | NO | PRI | NULL | | +| FollowedCod | int(11) | NO | PRI | NULL | | +| FollowTime | datetime | NO | MUL | NULL | | ++-------------+----------+------+-----+---------+-------+ +3 rows in set (0.00 sec) + */ + DB_CreateTable ("CREATE TABLE IF NOT EXISTS usr_follow (" + "FollowerCod INT NOT NULL," + "FollowedCod INT NOT NULL," + "FollowTime DATETIME NOT NULL," + "UNIQUE INDEX (FollowerCod,FollowedCod)," + "UNIQUE INDEX (FollowedCod,FollowerCod)," + "INDEX (FollowTime))"); + /***** Table usr_IDs *****/ /* mysql> DESCRIBE usr_IDs; diff --git a/swad_follow.c b/swad_follow.c new file mode 100644 index 00000000..bf1c9527 --- /dev/null +++ b/swad_follow.c @@ -0,0 +1,134 @@ +// 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. + Copyright (C) 1999-2015 Antonio Caņas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General 3 License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/*********************************** Headers *********************************/ +/*****************************************************************************/ + +#include // For sprintf + +#include "swad_bool.h" +#include "swad_database.h" +#include "swad_follow.h" +#include "swad_global.h" +#include "swad_user.h" + +/*****************************************************************************/ +/****************************** Public constants *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private constants *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/****************************** Internal types *******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/************** External global variables from others modules ****************/ +/*****************************************************************************/ + +extern struct Globals Gbl; + +/*****************************************************************************/ +/************************* Internal global variables *************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/***************************** Private prototypes ****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/*************** Check if a user is a follower of another user ***************/ +/*****************************************************************************/ + +bool Fol_CheckUsrIsFollowerOf (long FollowerCod,long FollowedCod) + { + char Query[256]; + + if (FollowerCod == FollowedCod) + return false; + + /***** Check if a user is a follower of another user *****/ + sprintf (Query,"SELECT COUNT(*) FROM usr_follow" + " WHERE FollowerCod='%ld' AND FollowedCod='%ld'", + FollowerCod,FollowedCod); + return (DB_QueryCOUNT (Query,"can not get if a user is a follower of another one") != 0); + } + + +/*****************************************************************************/ +/***************************** Follow another user ***************************/ +/*****************************************************************************/ + +void Fol_FollowUsr (void) + { + extern const char *Txt_User_not_found_or_you_do_not_have_permission_; + char Query[256]; + + /***** Get user to be removed *****/ + if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ()) + { + if (!Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Usrs.Other.UsrDat.UsrCod)) + { + /***** Follow user in database *****/ + sprintf (Query,"REPLACE INTO usr_follow" + " (FollowerCod,FollowedCod,FollowTime)" + " VALUES ('%ld','%ld',NOW())", + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Usrs.Other.UsrDat.UsrCod); + DB_QueryREPLACE (Query,"can not follow user"); + } + } + else + Lay_ShowAlert (Lay_WARNING,Txt_User_not_found_or_you_do_not_have_permission_); + } + +/*****************************************************************************/ +/***************************** Unfollow another user *************************/ +/*****************************************************************************/ + +void Fol_UnfollowUsr (void) + { + extern const char *Txt_User_not_found_or_you_do_not_have_permission_; + char Query[256]; + + /***** Get user to be removed *****/ + if (Usr_GetParamOtherUsrCodEncryptedAndGetUsrData ()) + { + if (Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Usrs.Other.UsrDat.UsrCod)) + { + /***** Follow user in database *****/ + sprintf (Query,"DELETE FROM usr_follow" + " WHERE FollowerCod='%ld' AND FollowedCod='%ld'", + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Usrs.Other.UsrDat.UsrCod); + DB_QueryREPLACE (Query,"can not unfollow user"); + } + } + else + Lay_ShowAlert (Lay_WARNING,Txt_User_not_found_or_you_do_not_have_permission_); + } diff --git a/swad_follow.h b/swad_follow.h new file mode 100644 index 00000000..d438d65a --- /dev/null +++ b/swad_follow.h @@ -0,0 +1,47 @@ +// swad_follow.h: user's followers and followed + +#ifndef _SWAD_FOL +#define _SWAD_FOL +/* + SWAD (Shared Workspace At a Distance in Spanish), + is a web platform developed at the University of Granada (Spain), + and used to support university teaching. + + This file is part of SWAD core. + Copyright (C) 1999-2015 Antonio Caņas Vargas + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ +/*****************************************************************************/ +/********************************** Headers **********************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/****************************** Public constants *****************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/******************************** Public types *******************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/****************************** Public prototypes ****************************/ +/*****************************************************************************/ + +bool Fol_CheckUsrIsFollowerOf (long FollowerCod,long FollowedCod); + +void Fol_FollowUsr (void); +void Fol_UnfollowUsr (void); + +#endif diff --git a/swad_record.c b/swad_record.c index 7d0066d5..252ffe07 100644 --- a/swad_record.c +++ b/swad_record.c @@ -34,6 +34,7 @@ #include "swad_config.h" #include "swad_database.h" #include "swad_enrollment.h" +#include "swad_follow.h" #include "swad_global.h" #include "swad_ID.h" #include "swad_logo.h" @@ -50,7 +51,6 @@ /*****************************************************************************/ extern struct Globals Gbl; -extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS]; extern const char *Usr_StringsSexDB[Usr_NUM_SEXS]; /*****************************************************************************/ @@ -551,10 +551,11 @@ long Rec_GetFieldCod (void) unsigned Rec_CountNumRecordsInCurrCrsWithField (long FieldCod) { - char Query[512]; + char Query[128]; /***** Get number of cards with a given field in a course from database *****/ - sprintf (Query,"SELECT COUNT(*) FROM crs_records WHERE FieldCod='%ld'",FieldCod); + sprintf (Query,"SELECT COUNT(*) FROM crs_records WHERE FieldCod='%ld'", + FieldCod); return (unsigned) DB_QueryCOUNT (Query,"can not get number of cards with a given field not empty in a course"); } @@ -2214,7 +2215,7 @@ void Rec_ShowSharedUsrRecord (Rec_RecordViewType_t TypeOfView, if (CommandForms) { - fprintf (Gbl.F.Out,"
"); + fprintf (Gbl.F.Out,"
"); /***** Button to view user's record card when: - viewing public profile && @@ -2233,7 +2234,7 @@ void Rec_ShowSharedUsrRecord (Rec_RecordViewType_t TypeOfView, Act_LinkFormSubmit (Txt_View_record_card,NULL); fprintf (Gbl.F.Out,"
" "\"%s\"" + " style=\"width:16px; height:16px; padding:0 2px;\" alt=\"%s\" />" "
" "", Gbl.Prefs.IconsURL, @@ -2254,7 +2255,7 @@ void Rec_ShowSharedUsrRecord (Rec_RecordViewType_t TypeOfView, Act_LinkFormSubmit (Txt_Admin_user,NULL); fprintf (Gbl.F.Out,"
" "\"%s\"" + " style=\"width:16px; height:16px; padding:0 2px;\" alt=\"%s\" />" "
" "", Gbl.Prefs.IconsURL, @@ -2279,7 +2280,7 @@ void Rec_ShowSharedUsrRecord (Rec_RecordViewType_t TypeOfView, Act_LinkFormSubmit (Txt_View_works,ClassData); fprintf (Gbl.F.Out,"
" "\"%s\"" + " style=\"width:16px; height:16px; padding:0 2px;\" alt=\"%s\" />" "
" "", Gbl.Prefs.IconsURL, @@ -2298,7 +2299,7 @@ void Rec_ShowSharedUsrRecord (Rec_RecordViewType_t TypeOfView, Act_LinkFormSubmit (Txt_See_exams,ClassData); fprintf (Gbl.F.Out,"
" "\"%s\"" + " style=\"width:16px; height:16px; padding:0 2px;\" alt=\"%s\" />" "
" "", Gbl.Prefs.IconsURL, @@ -2315,7 +2316,7 @@ void Rec_ShowSharedUsrRecord (Rec_RecordViewType_t TypeOfView, Act_LinkFormSubmit (Txt_Attendance,ClassData); fprintf (Gbl.F.Out,"
" "\"%s\"" + " style=\"width:16px; height:16px; padding:0 2px;\" alt=\"%s\" />" "
" "", Gbl.Prefs.IconsURL, @@ -2335,13 +2336,47 @@ void Rec_ShowSharedUsrRecord (Rec_RecordViewType_t TypeOfView, Act_LinkFormSubmit (Gbl.Title,ClassData); fprintf (Gbl.F.Out,"
" "\"%s\"" + " style=\"width:16px; height:16px; padding:0 2px;\" alt=\"%s\" />" "
" "", Gbl.Prefs.IconsURL, Gbl.Title); Act_FormEnd (); + /***** Button to follow / unfollow *****/ + if (Gbl.Usrs.Me.LoggedRole == Rol_ROLE_SYS_ADM) + if (!ItsMe) + { + if (Fol_CheckUsrIsFollowerOf (Gbl.Usrs.Me.UsrDat.UsrCod,UsrDat->UsrCod)) + { + Act_FormStart (ActUnfUsr); + Usr_PutParamOtherUsrCodEncrypted (UsrDat->EncryptedUsrCod); + Act_LinkFormSubmit ("Dejar de seguir",ClassData); + fprintf (Gbl.F.Out,"
" + "\"%s\"" + "
" + "", + Gbl.Prefs.IconsURL, + "Dejar de seguir"); + Act_FormEnd (); + } + else + { + Act_FormStart (ActFolUsr); + Usr_PutParamOtherUsrCodEncrypted (UsrDat->EncryptedUsrCod); + Act_LinkFormSubmit ("Seguir",ClassData); + fprintf (Gbl.F.Out,"
" + "\"%s\"" + "
" + "", + Gbl.Prefs.IconsURL, + "Seguir"); + Act_FormEnd (); + } + } + fprintf (Gbl.F.Out,"
"); }