diff --git a/swad_changelog.h b/swad_changelog.h index 370e95fe9..e1e3dd663 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -117,13 +117,15 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 15.90 (2016-01-02)" +#define Log_PLATFORM_VERSION "SWAD 15.91 (2016-01-02)" #define CSS_FILE "swad15.88.1.css" #define JS_FILE "swad15.77.7.js" // 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 15.91: Jan 02, 2016 Every social note can be shared. + Fixed bug when unsharing a social note. (190161 lines) Version 15.90: Jan 02, 2016 Change in fields of database table that stores social notes. (190122 lines) 6 changes necessary in database: ALTER TABLE social_notes ADD COLUMN HieCod INT NOT NULL DEFAULT -1 AFTER UsrCod; diff --git a/swad_social.c b/swad_social.c index 0ba855a60..36a2cc429 100644 --- a/swad_social.c +++ b/swad_social.c @@ -78,7 +78,7 @@ static const Act_Action_t Soc_DefaultActions[Soc_NUM_SOCIAL_NOTES] = /* Users tab */ /* Social tab */ - ActSeeSocTmlGbl, // Soc_NOTE_SOCIAL_POST (action not used) + ActUnk, // Soc_NOTE_SOCIAL_POST (action not used) ActSeeFor, // Soc_NOTE_FORUM_POST /* Messages tab */ @@ -153,12 +153,13 @@ static long Soc_GetParamPubCod (void); static void Soc_ShareSocialPublishing (void); static void Soc_UnshareSocialPublishing (void); +static void Soc_UnshareASocialPublishingFromDB (const struct SocialNote *SocNot); static void Soc_RequestRemovalSocialPublishing (void); static void Soc_RemoveSocialPublishing (void); - -static void Soc_DeleteASocialPublishingFromDB (const struct SocialPublishing *SocPub, +static void Soc_RemoveASocialPublishingFromDB (const struct SocialPublishing *SocPub, const struct SocialNote *SocNot); +static void Soc_CheckAndDeleteASocialNoteFromDB (const struct SocialNote *SocNot); static bool Soc_CheckIfNoteIsYetPublishedByMe (long NotCod); static unsigned long Soc_GetNumPubsOfANote (long NotCod); @@ -332,19 +333,19 @@ static void Soc_ShowTimeline (const char *Query,Act_Action_t UpdateAction) static void Soc_GetDataOfSocialPublishingFromRow (MYSQL_ROW row,struct SocialPublishing *SocPub) { /* Get social publishing code (row[0]) */ - SocPub->PubCod = Str_ConvertStrCodToLongCod (row[0]); + SocPub->PubCod = Str_ConvertStrCodToLongCod (row[0]); /* Get author's code (row[1]) */ - SocPub->AuthorCod = Str_ConvertStrCodToLongCod (row[1]); + SocPub->AuthorCod = Str_ConvertStrCodToLongCod (row[1]); /* Get publisher's code (row[2]) */ SocPub->PublisherCod = Str_ConvertStrCodToLongCod (row[2]); /* Get social note code (row[3]) */ - SocPub->NotCod = Str_ConvertStrCodToLongCod (row[3]); + SocPub->NotCod = Str_ConvertStrCodToLongCod (row[3]); /* Get time of the note (row[4]) */ - SocPub->DateTimeUTC = Dat_GetUNIXTimeFromStr (row[4]); + SocPub->DateTimeUTC = Dat_GetUNIXTimeFromStr (row[4]); } /*****************************************************************************/ @@ -404,7 +405,7 @@ static void Soc_WriteSocialNote (const struct SocialPublishing *SocPub, "PHOTO60x80",Pho_ZOOM); fprintf (Gbl.F.Out,""); - /***** Right: author's name, time and summary *****/ + /***** Right: author's name, time, summary and buttons *****/ fprintf (Gbl.F.Out,"
"); /* Write author's full name and nickname */ @@ -418,32 +419,13 @@ static void Soc_WriteSocialNote (const struct SocialPublishing *SocPub, /* Write date and time */ Soc_WriteNoteDate (SocNot->DateTimeUTC); + /* Write content of the note */ if (SocNot->NoteType == Soc_NOTE_SOCIAL_POST) { /* Write post content */ fprintf (Gbl.F.Out,"
"); Soc_GetAndWriteSocialPost (SocNot->Cod); fprintf (Gbl.F.Out,"
"); - - /***** Put icons to share/unshare/remove *****/ - if (Gbl.Usrs.Me.Logged) - { - if (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // I am the author - { - if (PutIconRemove) - /* Put icon to remove this publishing */ - Soc_PutFormToRemoveSocialPublishing (SocPub->PubCod); - } - else // I am not the author - { - if (Soc_CheckIfNoteIsYetPublishedByMe (SocNot->NotCod)) // I have yet published this social note - /* Put icon to unshare this publishing */ - Soc_PutFormToUnshareSocialPublishing (SocPub->PubCod); - else // I have not yet published this social note - /* Put icon to share this publishing */ - Soc_PutFormToShareSocialPublishing (SocPub->PubCod); - } - } } else { @@ -458,13 +440,14 @@ static void Soc_WriteSocialNote (const struct SocialPublishing *SocPub, fprintf (Gbl.F.Out,"
"); switch (SocNot->NoteType) - { + { case Soc_NOTE_INS_DOC_PUB_FILE: case Soc_NOTE_INS_SHA_PUB_FILE: /* Get institution data */ Ins.InsCod = SocNot->HieCod; Ins_GetDataOfInstitutionByCod (&Ins,Ins_GET_BASIC_DATA); + /* Write location (institution) in hierarchy */ fprintf (Gbl.F.Out,"
%s: %s
", Txt_Institution,Ins.ShortName); break; @@ -474,6 +457,7 @@ static void Soc_WriteSocialNote (const struct SocialPublishing *SocPub, Ctr.CtrCod = SocNot->HieCod; Ctr_GetDataOfCentreByCod (&Ctr); + /* Write location (centre) in hierarchy */ fprintf (Gbl.F.Out,"
%s: %s
", Txt_Centre,Ctr.ShortName); break; @@ -483,6 +467,7 @@ static void Soc_WriteSocialNote (const struct SocialPublishing *SocPub, Deg.DegCod = SocNot->HieCod; Deg_GetDataOfDegreeByCod (&Deg); + /* Write location (degree) in hierarchy */ fprintf (Gbl.F.Out,"
%s: %s
", Txt_Degree,Deg.ShortName); break; @@ -494,22 +479,46 @@ static void Soc_WriteSocialNote (const struct SocialPublishing *SocPub, Crs.CrsCod = SocNot->HieCod; Crs_GetDataOfCourseByCod (&Crs); + /* Write location (course) in hierarchy */ fprintf (Gbl.F.Out,"
%s: %s
", Txt_Course,Crs.ShortName); break; case Soc_NOTE_FORUM_POST: + /* Write forum name */ fprintf (Gbl.F.Out,"
%s: %s
", Txt_Forum,ForumName); break; default: break; - } + } - /* Write content of the note */ + /* Write note summary */ Soc_GetNoteSummary (SocNot,SummaryStr,Soc_MAX_BYTES_SUMMARY); fprintf (Gbl.F.Out,"
%s
",SummaryStr); } + /* Put icons to share/unshare/remove */ + if (Gbl.Usrs.Me.Logged) + { + if (UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // I am the author + { + if (PutIconRemove) + /* Put icon to remove this publishing */ + Soc_PutFormToRemoveSocialPublishing (SocPub->PubCod); + } + else // I am not the author + { + if (Soc_CheckIfNoteIsYetPublishedByMe (SocNot->NotCod)) + // I have yet published this social note + /* Put icon to unshare this publishing */ + Soc_PutFormToUnshareSocialPublishing (SocPub->PubCod); + else + // I have not yet published this social note + /* Put icon to share this publishing */ + Soc_PutFormToShareSocialPublishing (SocPub->PubCod); + } + } + /* End of right part */ fprintf (Gbl.F.Out,""); @@ -943,7 +952,7 @@ static void Soc_PutFormToShareSocialPublishing (long PubCod) static void Soc_PutFormToUnshareSocialPublishing (long PubCod) { - extern const char *Txt_Shared; + extern const char *Txt_SOCIAL_PUBLISHING_Shared; /***** Form to share social publishing *****/ if (Gbl.Usrs.Other.UsrDat.UsrCod > 0) @@ -961,8 +970,8 @@ static void Soc_PutFormToUnshareSocialPublishing (long PubCod) " class=\"ICON20x20\" />" "", Gbl.Prefs.IconsURL, - Txt_Shared, - Txt_Shared); + Txt_SOCIAL_PUBLISHING_Shared, + Txt_SOCIAL_PUBLISHING_Shared); Act_FormEnd (); } @@ -1057,7 +1066,7 @@ void Soc_ShareSocialPubUsr (void) static void Soc_ShareSocialPublishing (void) { - extern const char *Txt_Shared; + extern const char *Txt_SOCIAL_PUBLISHING_Shared; struct SocialPublishing SocPub; bool ICanShare; bool IHavePublishedThisNote; @@ -1081,7 +1090,7 @@ static void Soc_ShareSocialPublishing (void) Soc_PublishSocialNoteInTimeline (&SocPub); /***** Message of success *****/ - Lay_ShowAlert (Lay_SUCCESS,Txt_Shared); + Lay_ShowAlert (Lay_SUCCESS,Txt_SOCIAL_PUBLISHING_Shared); } } } @@ -1122,11 +1131,10 @@ void Soc_UnshareSocialPubUsr (void) static void Soc_UnshareSocialPublishing (void) { - extern const char *Txt_Unshared; + extern const char *Txt_SOCIAL_PUBLISHING_Unshared; struct SocialPublishing SocPub; struct SocialNote SocNot; bool ICanUnshare; - bool IHavePublishedThisNote; /***** Get the code of the social publishing to unshare *****/ SocPub.PubCod = Soc_GetParamPubCod (); @@ -1139,22 +1147,40 @@ static void Soc_UnshareSocialPublishing (void) Soc_GetDataOfSocialNoteByCod (&SocNot); ICanUnshare = (Gbl.Usrs.Me.Logged && - SocPub.AuthorCod != Gbl.Usrs.Me.UsrDat.UsrCod); // I am not the author + SocPub.AuthorCod != Gbl.Usrs.Me.UsrDat.UsrCod); // I have shared the note if (ICanUnshare) { - /***** Check if I have yet shared this social note *****/ - IHavePublishedThisNote = Soc_CheckIfNoteIsYetPublishedByMe (SocPub.NotCod); - if (IHavePublishedThisNote) - { - /***** Delete social publishing from database *****/ - Soc_DeleteASocialPublishingFromDB (&SocPub,&SocNot); + /***** Delete social publishing from database *****/ + Soc_UnshareASocialPublishingFromDB (&SocNot); - /***** Message of success *****/ - Lay_ShowAlert (Lay_SUCCESS,Txt_Unshared); - } + /***** Message of success *****/ + Lay_ShowAlert (Lay_SUCCESS,Txt_SOCIAL_PUBLISHING_Unshared); } } +/*****************************************************************************/ +/**************** Unshare a social publishing from database ******************/ +/*****************************************************************************/ + +static void Soc_UnshareASocialPublishingFromDB (const struct SocialNote *SocNot) + { + char Query[128]; + + /***** Remove social publishing *****/ + sprintf (Query,"DELETE FROM social_timeline" + " WHERE NotCod='%ld'" + " AND PublisherCod='%ld'" // I have share this note + " AND AuthorCod<>'%ld'", // I am not the author + SocNot->NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + DB_QueryDELETE (Query,"can not remove a social publishing"); + + /***** Check if this was the unique publishing of this note. + If so, remove the note *****/ + Soc_CheckAndDeleteASocialNoteFromDB (SocNot); + } + /*****************************************************************************/ /**************** Request the removal of a social publishing *****************/ /*****************************************************************************/ @@ -1209,8 +1235,7 @@ static void Soc_RequestRemovalSocialPublishing (void) Soc_GetDataOfSocialNoteByCod (&SocNot); ICanRemove = (Gbl.Usrs.Me.Logged && - SocPub.PublisherCod == Gbl.Usrs.Me.UsrDat.UsrCod && - SocNot.NoteType == Soc_NOTE_SOCIAL_POST); + SocPub.PublisherCod == Gbl.Usrs.Me.UsrDat.UsrCod); if (ICanRemove) { /***** Initialize structure with user's data *****/ @@ -1280,7 +1305,7 @@ void Soc_RemoveSocialPubUsr (void) static void Soc_RemoveSocialPublishing (void) { - extern const char *Txt_Comment_removed; + extern const char *Txt_SOCIAL_PUBLISHING_Removed; struct SocialPublishing SocPub; struct SocialNote SocNot; bool ICanRemove; @@ -1296,15 +1321,14 @@ static void Soc_RemoveSocialPublishing (void) Soc_GetDataOfSocialNoteByCod (&SocNot); ICanRemove = (Gbl.Usrs.Me.Logged && - SocPub.PublisherCod == Gbl.Usrs.Me.UsrDat.UsrCod && - SocNot.NoteType == Soc_NOTE_SOCIAL_POST); + SocPub.PublisherCod == Gbl.Usrs.Me.UsrDat.UsrCod); if (ICanRemove) { /***** Delete social publishing from database *****/ - Soc_DeleteASocialPublishingFromDB (&SocPub,&SocNot); + Soc_RemoveASocialPublishingFromDB (&SocPub,&SocNot); /***** Message of success *****/ - Lay_ShowAlert (Lay_SUCCESS,Txt_Comment_removed); + Lay_ShowAlert (Lay_SUCCESS,Txt_SOCIAL_PUBLISHING_Removed); } } @@ -1312,22 +1336,40 @@ static void Soc_RemoveSocialPublishing (void) /**************** Delete a social publishing from database *******************/ /*****************************************************************************/ -static void Soc_DeleteASocialPublishingFromDB (const struct SocialPublishing *SocPub, +static void Soc_RemoveASocialPublishingFromDB (const struct SocialPublishing *SocPub, const struct SocialNote *SocNot) + { + char Query[128]; + + /***** Remove social publishing *****/ + sprintf (Query,"DELETE FROM social_timeline" + " WHERE PubCod='%ld'" + " AND NotCod='%ld'" // Extra check: this is the note + " AND PublisherCod='%ld'" // Extra check: I have published this note + " AND AuthorCod='%ld'", // Extra check: I am the author + SocPub->PubCod, + SocNot->NotCod, + Gbl.Usrs.Me.UsrDat.UsrCod, + Gbl.Usrs.Me.UsrDat.UsrCod); + DB_QueryDELETE (Query,"can not remove a social publishing"); + + /***** Check if this was the unique publishing of this note. + If so, remove the note *****/ + Soc_CheckAndDeleteASocialNoteFromDB (SocNot); + } + +/*****************************************************************************/ +/**** Check if deletion is possible and delete a social note from database ***/ +/*****************************************************************************/ + +static void Soc_CheckAndDeleteASocialNoteFromDB (const struct SocialNote *SocNot) { char Query[128]; unsigned long NumPubs; - /***** Remove social publishing *****/ - sprintf (Query,"DELETE FROM social_timeline WHERE PubCod='%ld'", - SocPub->PubCod); - DB_QueryDELETE (Query,"can not remove a social publishing"); - - /***** Count number of times this note - is published in timeline after removal *****/ + /***** Count number of times this note is published *****/ NumPubs = Soc_GetNumPubsOfANote (SocNot->NotCod); - - if (NumPubs == 0) // This was the last publishing of this note + if (NumPubs == 0) // There are no publishings of this note { /***** Remove social note *****/ sprintf (Query,"DELETE FROM social_notes WHERE NotCod='%ld'", @@ -1386,7 +1428,7 @@ static void Soc_GetDataOfSocialPublishingByCod (struct SocialPublishing *SocPub) " FROM social_timeline" " WHERE PubCod='%ld'", SocPub->PubCod); - if (DB_QuerySELECT (Query,&mysql_res,"can not get data of social note")) + if (DB_QuerySELECT (Query,&mysql_res,"can not get data of social publishing")) { /***** Get social note *****/ row = mysql_fetch_row (mysql_res); @@ -1441,19 +1483,19 @@ static void Soc_GetDataOfSocialNoteByCod (struct SocialNote *SocNot) static void Soc_GetDataOfSocialNoteFromRow (MYSQL_ROW row,struct SocialNote *SocNot) { /* Get social code (row[0]) */ - SocNot->NotCod = Str_ConvertStrCodToLongCod (row[0]); + SocNot->NotCod = Str_ConvertStrCodToLongCod (row[0]); /* Get note type (row[1]) */ - SocNot->NoteType = Soc_GetSocialNoteFromDB ((const char *) row[1]); + SocNot->NoteType = Soc_GetSocialNoteFromDB ((const char *) row[1]); /* Get (from) user code (row[2]) */ - SocNot->UsrCod = Str_ConvertStrCodToLongCod (row[2]); + SocNot->UsrCod = Str_ConvertStrCodToLongCod (row[2]); /* Get hierarchy code (row[3]) */ - SocNot->HieCod = Str_ConvertStrCodToLongCod (row[3]); + SocNot->HieCod = Str_ConvertStrCodToLongCod (row[3]); /* Get file/post... code (row[4]) */ - SocNot->Cod = Str_ConvertStrCodToLongCod (row[4]); + SocNot->Cod = Str_ConvertStrCodToLongCod (row[4]); /* Get time of the note (row[5]) */ SocNot->DateTimeUTC = Dat_GetUNIXTimeFromStr (row[5]); diff --git a/swad_text.c b/swad_text.c index bd7bb3bd3..51ef7010e 100644 --- a/swad_text.c +++ b/swad_text.c @@ -4603,27 +4603,6 @@ const char *Txt_columns = "colunas"; #endif -const char *Txt_Comment_removed = -#if L==1 - "Comentari eliminat."; -#elif L==2 - "Kommentar entfernt."; -#elif L==3 - "Comment removed."; -#elif L==4 - "Comentario eliminado"; -#elif L==5 - "Commentaire supprimé."; -#elif L==6 - "Comentario eliminado."; // Okoteve traducción -#elif L==7 - "Commento rimosso."; -#elif L==8 - "Komentarz usuniete."; -#elif L==9 - "Comentário removido."; -#endif - const char *Txt_Comments = #if L==1 "Comentaris"; @@ -34658,27 +34637,6 @@ const char *Txt_Share = "Compartilhar"; #endif -const char *Txt_Shared = -#if L==1 - "Compartit"; -#elif L==2 - "Geteilt"; -#elif L==3 - "Shared"; -#elif L==4 - "Compartido"; -#elif L==5 - "Partagé"; -#elif L==6 - "Compartido"; // Okoteve traducción -#elif L==7 - "Condiviso"; -#elif L==8 - "Dzielone"; -#elif L==9 - "Compartilhado"; -#endif - const char *Txt_Shared_files_area = #if L==1 "Zona d'arxius compartits"; @@ -35573,6 +35531,69 @@ const char *Txt_SOCIAL_NOTE[Soc_NUM_SOCIAL_NOTES] = #endif }; +const char *Txt_SOCIAL_PUBLISHING_Removed = +#if L==1 + "Eliminat"; +#elif L==2 + "Entfernt"; +#elif L==3 + "Removed"; +#elif L==4 + "Rliminado"; +#elif L==5 + "Supprimé"; +#elif L==6 + "Eliminado"; // Okoteve traducción +#elif L==7 + "Rimosso"; +#elif L==8 + "Usuniete"; +#elif L==9 + "Removido"; +#endif + +const char *Txt_SOCIAL_PUBLISHING_Shared = +#if L==1 + "Compartit"; +#elif L==2 + "Geteilt"; +#elif L==3 + "Shared"; +#elif L==4 + "Compartido"; +#elif L==5 + "Partagé"; +#elif L==6 + "Compartido"; // Okoteve traducción +#elif L==7 + "Condiviso"; +#elif L==8 + "Dzielone"; +#elif L==9 + "Compartilhado"; +#endif + +const char *Txt_SOCIAL_PUBLISHING_Unshared = // No longer shared +#if L==1 + "No compartit"; +#elif L==2 + "Kein geteilt"; +#elif L==3 + "Unshared"; +#elif L==4 + "No compartido"; +#elif L==5 + "Non partagé"; +#elif L==6 + "No compartido"; // Okoteve traducción +#elif L==7 + "Non condiviso"; +#elif L==8 + "Niedzieloną"; +#elif L==9 + "Não compartilhado"; +#endif + const char *Txt_Sort_degrees_by = #if L==1 "Ordenar titulacions per"; @@ -46807,27 +46828,6 @@ const char *Txt_Unread_BR_msgs = "Não
lidas"; #endif -const char *Txt_Unshared = // No longer shared -#if L==1 - "No compartit"; -#elif L==2 - "Kein geteilt"; -#elif L==3 - "Unshared"; -#elif L==4 - "No compartido"; -#elif L==5 - "Non partagé"; -#elif L==6 - "No compartido"; // Okoteve traducción -#elif L==7 - "Non condiviso"; -#elif L==8 - "Niedzieloną"; -#elif L==9 - "Não compartilhado"; -#endif - const char *Txt_Update = #if L==1 "Actualitzar";