diff --git a/css/swad15.189.2.css b/css/swad15.189.2.css index b927309a4..4a79e70f5 100644 --- a/css/swad15.189.2.css +++ b/css/swad15.189.2.css @@ -1954,7 +1954,7 @@ a:hover img.CENTRE_PHOTO_SHOW color:#404040; font-size:13pt; } -.SOCIAL_IMG +.SOCIAL_IMG_POST { width:480px; border-radius:4px; @@ -2058,6 +2058,12 @@ a:hover img.CENTRE_PHOTO_SHOW margin:0; resize:none; } +.SOCIAL_IMG_COMMENT + { + width:440px; + border-radius:4px; + margin:10px 0; + } .SOCIAL_IMG_TIT_COMMENT { box-sizing:border-box; diff --git a/sql/swad.sql b/sql/swad.sql index 4139647c1..48cf25c48 100644 --- a/sql/swad.sql +++ b/sql/swad.sql @@ -916,6 +916,8 @@ CREATE TABLE IF NOT EXISTS sessions ( CREATE TABLE IF NOT EXISTS social_comments ( PubCod BIGINT NOT NULL, Content LONGTEXT NOT NULL, + ImageName VARCHAR(43) NOT NULL, + ImageTitle VARCHAR(255) NOT NULL, UNIQUE INDEX(PubCod), FULLTEXT(Content)) ENGINE = MYISAM; -- diff --git a/swad_action.c b/swad_action.c index 9ff94f097..cbcbdd27c 100644 --- a/swad_action.c +++ b/swad_action.c @@ -2344,7 +2344,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActSeeChtRms */{ 51, 3,TabSoc,ActSeeChtRms ,0x1FC,0x1FC,0x1FC,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Cht_ShowChatRooms ,"chat64x64.gif" }, /* ActRcvSocPstGbl */{1492,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_DATA,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_ReceiveSocialPostGbl ,NULL}, - /* ActRcvSocComGbl */{1503,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_ReceiveCommentGbl ,NULL}, + /* ActRcvSocComGbl */{1503,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_DATA,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_ReceiveCommentGbl ,NULL}, /* ActShaSocNotGbl */{1495,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_ShareSocialNoteGbl ,NULL}, /* ActUnsSocNotGbl */{1496,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_UnshareSocialNoteGbl ,NULL}, /* ActFavSocNotGbl */{1512,-1,TabSoc,ActSeeSocTmlGbl ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,Soc_MarkMyNotifAsSeen ,Soc_FavSocialNoteGbl ,NULL}, @@ -2359,7 +2359,7 @@ struct Act_Actions Act_Actions[Act_NUM_ACTIONS] = /* ActReqPubPrf */{1401,-1,TabSoc,ActSeeSocPrf ,0x1FF,0x1FF,0x1FF,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Prf_RequestUserProfile ,NULL}, /* ActRcvSocPstUsr */{1498,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_DATA,Act_MAIN_WINDOW,NULL ,Soc_ReceiveSocialPostUsr ,NULL}, - /* ActRcvSocComUsr */{1504,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ReceiveCommentUsr ,NULL}, + /* ActRcvSocComUsr */{1504,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_DATA,Act_MAIN_WINDOW,NULL ,Soc_ReceiveCommentUsr ,NULL}, /* ActShaSocNotUsr */{1499,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_ShareSocialNoteUsr ,NULL}, /* ActUnsSocNotUsr */{1500,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_UnshareSocialNoteUsr ,NULL}, /* ActFavSocNotUsr */{1514,-1,TabSoc,ActSeeSocPrf ,0x1FE,0x1FE,0x1FE,Act_CONTENT_NORM,Act_MAIN_WINDOW,NULL ,Soc_FavSocialNoteUsr ,NULL}, diff --git a/swad_changelog.h b/swad_changelog.h index 411f0bf11..141f5f8ca 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -133,13 +133,18 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 15.189.2 (2016-04-08)" -#define CSS_FILE "swad15.189.2.css" +#define Log_PLATFORM_VERSION "SWAD 15.190 (2016-04-08)" +#define CSS_FILE "swad15.190.css" #define JS_FILE "swad15.186.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.190: Apr 08, 2016 Get image attached to a social comment. (199142 lines) + 2 changes necessary in database: +ALTER TABLE social_comments ADD COLUMN ImageName VARCHAR(43) NOT NULL AFTER Content; +ALTER TABLE social_comments ADD COLUMN ImageTitle VARCHAR(255) NOT NULL AFTER ImageName; + Version 15.189.2: Apr 08, 2016 Remove file of the image attached to a social post when the post is removed. (199017 lines) Version 15.189.1: Apr 08, 2016 Change in layout of form to write a new social post. (198997 lines) Version 15.189: Apr 08, 2016 Get image attached to a social post. (198991 lines) diff --git a/swad_database.c b/swad_database.c index 1f507c8f2..42c279dc5 100644 --- a/swad_database.c +++ b/swad_database.c @@ -1935,17 +1935,21 @@ mysql> DESCRIBE sessions; /***** Table social_comments *****/ /* mysql> DESCRIBE social_comments; -+---------+------------+------+-----+---------+-------+ -| Field | Type | Null | Key | Default | Extra | -+---------+------------+------+-----+---------+-------+ -| PubCod | bigint(20) | NO | PRI | NULL | | -| Content | longtext | NO | MUL | NULL | | -+---------+------------+------+-----+---------+-------+ -2 rows in set (0.00 sec) ++------------+--------------+------+-----+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++------------+--------------+------+-----+---------+-------+ +| PubCod | bigint(20) | NO | PRI | NULL | | +| Content | longtext | NO | MUL | NULL | | +| ImageName | varchar(43) | NO | | NULL | | +| ImageTitle | varchar(255) | NO | | NULL | | ++------------+--------------+------+-----+---------+-------+ +4 rows in set (0.00 sec) */ DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_comments (" "PubCod BIGINT NOT NULL," "Content LONGTEXT NOT NULL," + "ImageName VARCHAR(43) NOT NULL," + "ImageTitle VARCHAR(255) NOT NULL," "UNIQUE INDEX(PubCod)," "FULLTEXT(Content)) ENGINE = MYISAM;"); diff --git a/swad_image.c b/swad_image.c index 7ba3bf99b..f4f635f94 100644 --- a/swad_image.c +++ b/swad_image.c @@ -63,17 +63,42 @@ extern struct Globals Gbl; /***************************** Internal prototypes ***************************/ /*****************************************************************************/ +static void Img_FreeImageTitle (struct Image *Image); + static void Img_ProcessImage (const char *FileNameImgOriginal, const char *FileNameImgProcessed, unsigned Width,unsigned Height,unsigned Quality); +/*****************************************************************************/ +/*************************** Reset image fields ******************************/ +/*****************************************************************************/ +// Every struct Image must be initialized to zero where it is declared +// Every call to Img_InitImage must have a call to Img_FreeImage + +void Img_ImageConstructor (struct Image *Image) + { + Image->Action = Img_ACTION_NO_IMAGE; + Image->Status = Img_FILE_NONE; + Image->Name[0] = '\0'; + Image->Title = NULL; + } + +/*****************************************************************************/ +/******************************** Free image *********************************/ +/*****************************************************************************/ + +void Img_ImageDestructor (struct Image *Image) + { + Img_FreeImageTitle (Image); + } + /*****************************************************************************/ /*************************** Reset image title *******************************/ /*****************************************************************************/ -void Img_FreeImageTitle (struct Image *Image) +static void Img_FreeImageTitle (struct Image *Image) { - // Image->Title must be initialized to NULL + // Image->Title must be initialized to NULL after declaration if (Image->Title) { free ((void *) Image->Title); @@ -99,7 +124,10 @@ void Img_GetImageNameAndTitleFromRow (const char *Name,const char *Title, Img_FILE_NONE; /***** Copy image title to struct *****/ + // Image->Title can be empty or filled with a previous title + // If filled ==> free it Img_FreeImageTitle (Image); + if (Title[0]) { /* Get and limit length of the title */ @@ -126,12 +154,13 @@ void Img_GetImageFromForm (unsigned NumOpt,struct Image *Image, char Title[Img_MAX_BYTES_TITLE+1]; size_t Length; - /***** Reset image *****/ + /***** First, get action and initialize image + (except title, that will be get after the image file) *****/ Image->Action = Img_GetImageActionFromForm (ParamAction); Image->Status = Img_FILE_NONE; Image->Name[0] = '\0'; - Img_FreeImageTitle (Image); // Reset to NULL + /***** Secondly, get the image name and the file *****/ switch (Image->Action) { case Img_ACTION_NO_IMAGE: // Do not use image (remove current image if exists) @@ -163,9 +192,11 @@ void Img_GetImageFromForm (unsigned NumOpt,struct Image *Image, break; } - /***** Get image title from form *****/ + /***** By last, get image title from form *****/ Par_GetParToHTML (ParamTitle,Title,Img_MAX_BYTES_TITLE); - if ((Length = strlen (Title)) > 0) // If title comming from the form is not empty + /* If the title coming from the form is empty, keep current image title unchanged + If not empty, copy it to current image title */ + if ((Length = strlen (Title)) > 0) { /* Overwrite current title (empty or coming from database) with the title coming from the form */ diff --git a/swad_image.h b/swad_image.h index befa138e2..89a41c2c7 100644 --- a/swad_image.h +++ b/swad_image.h @@ -95,7 +95,9 @@ struct Image /***************************** Public prototypes *****************************/ /*****************************************************************************/ -void Img_FreeImageTitle (struct Image *Image); +void Img_ImageConstructor (struct Image *Image); +void Img_ImageDestructor (struct Image *Image); + void Img_GetImageNameAndTitleFromRow (const char *Name,const char *Title, struct Image *Image); diff --git a/swad_social.c b/swad_social.c index 95f7fe1f8..f718cbb74 100644 --- a/swad_social.c +++ b/swad_social.c @@ -115,6 +115,7 @@ struct SocialComment time_t DateTimeUTC; unsigned NumFavs; // Number of times (users) this comment has been favourited char Content[Cns_MAX_BYTES_LONG_TEXT+1]; + struct Image Image; }; /*****************************************************************************/ @@ -226,6 +227,7 @@ static long Soc_GetPubCodOfOriginalSocialNote (long NotCod); static void Soc_RequestRemovalSocialComment (void); static void Soc_RemoveSocialComment (void); +static void Soc_RemoveImgFileFromSocialComment (long PubCod); static void Soc_RemoveASocialCommentFromDB (struct SocialComment *SocCom); static bool Soc_CheckIfNoteIsSharedByUsr (long NotCod,long UsrCod); @@ -1153,12 +1155,8 @@ static void Soc_WriteSocialNote (const struct SocialNote *SocNot, /* 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,"
"); - } else { /* Get location in hierarchy */ @@ -1210,9 +1208,7 @@ static void Soc_WriteSocialNote (const struct SocialNote *SocNot, } /* Write note type */ - fprintf (Gbl.F.Out,"
"); Soc_PutFormGoToAction (SocNot); - fprintf (Gbl.F.Out,"
"); /* Write location in hierarchy */ if (!SocNot->Unavailable) @@ -1460,10 +1456,7 @@ static void Soc_GetAndWriteSocialPost (long PstCod) struct Image Image; /***** Initialize image *****/ - Image.Action = Img_ACTION_NO_IMAGE; - Image.Status = Img_FILE_NONE; - Image.Name[0] = '\0'; - Image.Title = NULL; + Img_ImageConstructor (&Image); /***** Get social post from database *****/ sprintf (Query,"SELECT Content,ImageName,ImageTitle" @@ -1490,13 +1483,15 @@ static void Soc_GetAndWriteSocialPost (long PstCod) DB_FreeMySQLResult (&mysql_res); /***** Write content *****/ + fprintf (Gbl.F.Out,"
"); Msg_WriteMsgContent (Content,Cns_MAX_BYTES_LONG_TEXT,true,false); + fprintf (Gbl.F.Out,"
"); /***** Show image *****/ - Img_ShowImage (&Image,"SOCIAL_IMG"); + Img_ShowImage (&Image,"SOCIAL_IMG_POST"); - /***** Free allocated memory for the title/attribution of the image *****/ - Img_FreeImageTitle (&Image); + /***** Free image *****/ + Img_ImageDestructor (&Image); } /*****************************************************************************/ @@ -1590,14 +1585,16 @@ static void Soc_PutFormGoToAction (const struct SocialNote *SocNot) Gbl.Form.Inside) // Inside another form { /***** Do not put form *****/ - fprintf (Gbl.F.Out,"%s", + fprintf (Gbl.F.Out,"
%s", Txt_SOCIAL_NOTE[SocNot->NoteType]); if (SocNot->Unavailable) fprintf (Gbl.F.Out," (%s)",Txt_not_available); - fprintf (Gbl.F.Out,""); + fprintf (Gbl.F.Out,"
"); } else // Not inside another form { + fprintf (Gbl.F.Out,"
"); + /***** Parameters depending on the type of note *****/ switch (SocNot->NoteType) { @@ -1666,6 +1663,8 @@ static void Soc_PutFormGoToAction (const struct SocialNote *SocNot) Txt_SOCIAL_NOTE[SocNot->NoteType], Txt_SOCIAL_NOTE[SocNot->NoteType]); Act_FormEnd (); + + fprintf (Gbl.F.Out,"
"); } } @@ -2113,11 +2112,10 @@ static long Soc_ReceiveSocialPost (void) Par_GetParAndChangeFormat ("Content",Content,Cns_MAX_BYTES_LONG_TEXT, Str_TO_RIGOROUS_HTML,true); + /***** Initialize image *****/ + Img_ImageConstructor (&Image); + /***** Get attached image (action, file and title) *****/ - /* Initialize to zero */ - // Image.Name[0] = '\0'; - // Image.Title = NULL; // Initialized to NULL in order to not trying - // to free it when no memory allocated Img_GetImageFromForm (0,&Image,NULL, "ImgAct","ImgFil","ImgTit", Soc_IMAGE_SAVED_MAX_WIDTH, @@ -2158,13 +2156,12 @@ static long Soc_ReceiveSocialPost (void) /***** Analyze content and store notifications about mentions *****/ Str_AnalyzeTxtAndStoreNotifyEventToMentionedUsrs (SocPub.PubCod,Content); - } - else + else // Text and image are empty SocPub.NotCod = -1L; - /***** Free allocated memory for the title/attribution of the image *****/ - Img_FreeImageTitle (&Image); + /***** Free image *****/ + Img_ImageDestructor (&Image); return SocPub.NotCod; } @@ -2294,7 +2291,8 @@ static void Soc_WriteCommentsInSocialNote (const struct SocialNote *SocNot) sprintf (Query,"SELECT social_pubs.PubCod,social_pubs.PublisherCod," "social_pubs.NotCod," "UNIX_TIMESTAMP(social_pubs.TimePublish)," - "social_comments.Content" + "social_comments.Content," + "social_comments.ImageName,social_comments.ImageTitle" " FROM social_pubs,social_comments" " WHERE social_pubs.NotCod='%ld'" " AND social_pubs.PubType='%u'" @@ -2314,6 +2312,9 @@ static void Soc_WriteCommentsInSocialNote (const struct SocialNote *SocNot) NumCom < NumComments; NumCom++) { + /* Initialize image */ + Img_ImageConstructor (&SocCom.Image); + /* Get data of social comment */ row = mysql_fetch_row (mysql_res); Soc_GetDataOfSocialCommentFromRow (row,&SocCom); @@ -2322,6 +2323,9 @@ static void Soc_WriteCommentsInSocialNote (const struct SocialNote *SocNot) Soc_WriteSocialComment (&SocCom, Soc_TOP_MESSAGE_NONE,-1L, false); + + /* Free image */ + Img_ImageDestructor (&SocCom.Image); } /***** End list *****/ @@ -2395,7 +2399,7 @@ static void Soc_WriteSocialComment (struct SocialComment *SocCom, "PHOTO30x40",Pho_ZOOM,true); // Use unique id fprintf (Gbl.F.Out,""); - /***** Right: author's name, time, summary and buttons *****/ + /***** Right: author's name, time, content, image and buttons *****/ fprintf (Gbl.F.Out,"
"); /* Write author's full name and nickname */ @@ -2409,6 +2413,9 @@ static void Soc_WriteSocialComment (struct SocialComment *SocCom, Msg_WriteMsgContent (SocCom->Content,Cns_MAX_BYTES_LONG_TEXT,true,false); fprintf (Gbl.F.Out,"
"); + /* Show image */ + Img_ShowImage (&SocCom->Image,"SOCIAL_IMG_COMMENT"); + /* Put icon to mark this social comment as favourite */ if (IAmTheAuthor) // I am the author Soc_PutDisabledIconFav (SocCom->NumFavs); @@ -2846,7 +2853,8 @@ static long Soc_ReceiveComment (void) { extern const char *Txt_The_original_post_no_longer_exists; char Content[Cns_MAX_BYTES_LONG_TEXT+1]; - char Query[128+Cns_MAX_BYTES_LONG_TEXT]; + struct Image Image; + char *Query; struct SocialNote SocNot; struct SocialPublishing SocPub; @@ -2860,8 +2868,32 @@ static long Soc_ReceiveComment (void) Par_GetParAndChangeFormat ("Content",Content,Cns_MAX_BYTES_LONG_TEXT, Str_TO_RIGOROUS_HTML,true); - if (Content[0]) + /***** Initialize image *****/ + Img_ImageConstructor (&Image); + + /***** Get attached image (action, file and title) *****/ + Img_GetImageFromForm (0,&Image,NULL, + "ImgAct","ImgFil","ImgTit", + Soc_IMAGE_SAVED_MAX_WIDTH, + Soc_IMAGE_SAVED_MAX_HEIGHT, + Soc_IMAGE_SAVED_QUALITY); + + if (Content[0] || // Text not empty + Image.Name[0]) // An image is attached { + /***** Allocate space for query *****/ + if ((Query = malloc (256 + + strlen (Content) + + Cry_LENGTH_ENCRYPTED_STR_SHA256_BASE64+ + Img_MAX_BYTES_TITLE)) == NULL) + Lay_ShowErrorAndExit ("Not enough memory to store database query."); + + /***** Check if image is received and processed *****/ + if (Image.Action == Img_ACTION_NEW_IMAGE && // Upload new image + Image.Status == Img_FILE_PROCESSED) // The new image received has been processed + /* Move processed image to definitive directory */ + Img_MoveImageToDefinitiveDirectory (&Image); + /***** Publish *****/ /* Insert into publishings */ SocPub.NotCod = SocNot.NotCod; @@ -2870,12 +2902,19 @@ static long Soc_ReceiveComment (void) Soc_PublishSocialNoteInTimeline (&SocPub); // Set SocPub.PubCod /* Insert comment content in the database */ - sprintf (Query,"INSERT INTO social_comments (PubCod,Content)" - " VALUES ('%ld','%s')", + sprintf (Query,"INSERT INTO social_comments" + " (PubCod,Content,ImageName,ImageTitle)" + " VALUES ('%ld','%s','%s','%s')", SocPub.PubCod, - Content); + Content, + Image.Name, + (Image.Name[0] && // Save image title only if image attached + Image.Title) ? Image.Title : ""); DB_QueryINSERT (Query,"can not store comment content"); + /***** Free space used for query *****/ + free ((void *) Query); + /***** Store notifications about the new comment *****/ Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_TIMELINE_COMMENT,SocPub.PubCod); @@ -2887,6 +2926,9 @@ static long Soc_ReceiveComment (void) Soc_TOP_MESSAGE_COMMENTED,Gbl.Usrs.Me.UsrDat.UsrCod, true,true); } + + /***** Free image *****/ + Img_ImageDestructor (&Image); } else Lay_ShowAlert (Lay_WARNING,Txt_The_original_post_no_longer_exists); @@ -3100,6 +3142,9 @@ static long Soc_FavSocialComment (void) struct SocialComment SocCom; char Query[256]; + /***** Initialize image *****/ + Img_ImageConstructor (&SocCom.Image); + /***** Get data of social comment *****/ SocCom.PubCod = Soc_GetParamPubCod (); Soc_GetDataOfSocialComByCod (&SocCom); @@ -3134,6 +3179,9 @@ static long Soc_FavSocialComment (void) else Lay_ShowAlert (Lay_WARNING,Txt_The_comment_no_longer_exists); + /***** Free image *****/ + Img_ImageDestructor (&SocCom.Image); + return SocCom.NotCod; } @@ -3388,6 +3436,9 @@ static long Soc_UnfavSocialComment (void) struct SocialComment SocCom; char Query[256]; + /***** Initialize image *****/ + Img_ImageConstructor (&SocCom.Image); + /***** Get data of social comment *****/ SocCom.PubCod = Soc_GetParamPubCod (); Soc_GetDataOfSocialComByCod (&SocCom); @@ -3422,6 +3473,9 @@ static long Soc_UnfavSocialComment (void) else Lay_ShowAlert (Lay_WARNING,Txt_The_comment_no_longer_exists); + /***** Free image *****/ + Img_ImageDestructor (&SocCom.Image); + return SocCom.NotCod; } @@ -3793,6 +3847,9 @@ static void Soc_RequestRemovalSocialComment (void) extern const char *Txt_Remove; struct SocialComment SocCom; + /***** Initialize image *****/ + Img_ImageConstructor (&SocCom.Image); + /***** Get data of social comment *****/ SocCom.PubCod = Soc_GetParamPubCod (); Soc_GetDataOfSocialComByCod (&SocCom); @@ -3829,6 +3886,9 @@ static void Soc_RequestRemovalSocialComment (void) } else Lay_ShowAlert (Lay_WARNING,Txt_The_comment_no_longer_exists); + + /***** Free image *****/ + Img_ImageDestructor (&SocCom.Image); } /*****************************************************************************/ @@ -3871,6 +3931,9 @@ static void Soc_RemoveSocialComment (void) extern const char *Txt_Comment_removed; struct SocialComment SocCom; + /***** Initialize image *****/ + Img_ImageConstructor (&SocCom.Image); + /***** Get data of social comment *****/ SocCom.PubCod = Soc_GetParamPubCod (); Soc_GetDataOfSocialComByCod (&SocCom); @@ -3880,6 +3943,9 @@ static void Soc_RemoveSocialComment (void) if (Gbl.Usrs.Me.Logged && SocCom.UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod) // I am the author of this comment { + /***** Remove image file associated to social post *****/ + Soc_RemoveImgFileFromSocialComment (SocCom.PubCod); + /***** Delete social comment from database *****/ Soc_RemoveASocialCommentFromDB (&SocCom); @@ -3889,6 +3955,35 @@ static void Soc_RemoveSocialComment (void) } else Lay_ShowAlert (Lay_WARNING,Txt_The_comment_no_longer_exists); + + /***** Free image *****/ + Img_ImageDestructor (&SocCom.Image); + } + +/*****************************************************************************/ +/************* Remove one file associated to a social comment ****************/ +/*****************************************************************************/ + +static void Soc_RemoveImgFileFromSocialComment (long PubCod) + { + char Query[128]; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + + /***** Get name of image associated to a social post from database *****/ + sprintf (Query,"SELECT ImageName FROM social_comments WHERE PubCod='%ld'", + PubCod); + if (DB_QuerySELECT (Query,&mysql_res,"can not get image")) + { + /***** Get image name (row[0]) *****/ + row = mysql_fetch_row (mysql_res); + + /***** Remove image file *****/ + Img_RemoveImageFile (row[0]); + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); } /*****************************************************************************/ @@ -4309,7 +4404,8 @@ static void Soc_GetDataOfSocialComByCod (struct SocialComment *SocCom) sprintf (Query,"SELECT social_pubs.PubCod,social_pubs.PublisherCod," "social_pubs.NotCod," "UNIX_TIMESTAMP(social_pubs.TimePublish)," - "social_comments.Content" + "social_comments.Content," + "social_comments.ImageName,social_comments.ImageTitle" " FROM social_pubs,social_comments" " WHERE social_pubs.PubCod='%ld'" " AND social_pubs.PubType='%u'" @@ -4434,6 +4530,15 @@ static Soc_NoteType_t Soc_GetNoteTypeFromStr (const char *Str) static void Soc_GetDataOfSocialCommentFromRow (MYSQL_ROW row,struct SocialComment *SocCom) { + /* + row[0]: PubCod + row[1]: PublisherCod + row[2]: NotCod + row[3]: TimePublish + row[4]: Content + row[5]: ImageName + row[6]: ImageTitle + */ /***** Get code of social comment (row[0]) *****/ SocCom->PubCod = Str_ConvertStrCodToLongCod (row[0]); @@ -4452,6 +4557,9 @@ static void Soc_GetDataOfSocialCommentFromRow (MYSQL_ROW row,struct SocialCommen /***** Get number of times this comment has been favourited *****/ SocCom->NumFavs = Soc_GetNumTimesACommHasBeenFav (SocCom); + + /****** Get image name (row[5]) and title (row[6]) *****/ + Img_GetImageNameAndTitleFromRow (row[5],row[6],&SocCom->Image); } /*****************************************************************************/ @@ -4591,6 +4699,7 @@ void Soc_GetNotifSocialPublishing (char *SummaryStr,char **ContentStr,long PubCo if (SocNot.NoteType == Soc_NOTE_SOCIAL_POST) { /***** Get content of social post from database *****/ + // TODO: What happens if content is empty and an image is attached? sprintf (Query,"SELECT Content FROM social_posts" " WHERE PstCod='%ld'", SocNot.Cod); @@ -4624,6 +4733,7 @@ void Soc_GetNotifSocialPublishing (char *SummaryStr,char **ContentStr,long PubCo break; case Soc_PUB_COMMENT_TO_NOTE: /***** Get content of social post from database *****/ + // TODO: What happens if content is empty and an image is attached? sprintf (Query,"SELECT Content FROM social_comments" " WHERE PubCod='%ld'", SocPub.PubCod); diff --git a/swad_test.c b/swad_test.c index b832cec56..85fba05f0 100644 --- a/swad_test.c +++ b/swad_test.c @@ -221,7 +221,7 @@ static void Tst_PutFormEditOneQst (char *Stem,char *Feedback); static void Tst_FreeTextChoiceAnswers (void); static void Tst_FreeTextChoiceAnswer (unsigned NumOpt); -static void Tst_InitImagesOfQuestion (void); +// static void Tst_InitImagesOfQuestion (void); static void Tst_FreeImagesOfQuestion (void); static void Tst_GetQstDataFromDB (char *Stem,char *Feedback); @@ -4775,6 +4775,10 @@ void Tst_QstConstructor (void) Gbl.Test.AnswerType = Tst_ANS_UNIQUE_CHOICE; Gbl.Test.Answer.NumOptions = 0; Gbl.Test.Answer.TF = ' '; + + /***** Initialize image attached to stem *****/ + Img_ImageConstructor (&Gbl.Test.Image); + for (NumOpt = 0; NumOpt < Tst_MAX_OPTIONS_PER_QUESTION; NumOpt++) @@ -4782,12 +4786,13 @@ void Tst_QstConstructor (void) Gbl.Test.Answer.Options[NumOpt].Correct = false; Gbl.Test.Answer.Options[NumOpt].Text = NULL; Gbl.Test.Answer.Options[NumOpt].Feedback = NULL; + + /***** Initialize image attached to option *****/ + Img_ImageConstructor (&Gbl.Test.Answer.Options[NumOpt].Image); } Gbl.Test.Answer.Integer = 0; Gbl.Test.Answer.FloatingPoint[0] = Gbl.Test.Answer.FloatingPoint[1] = 0.0; - - Tst_InitImagesOfQuestion (); } /*****************************************************************************/ @@ -4861,26 +4866,21 @@ static void Tst_FreeTextChoiceAnswer (unsigned NumOpt) /*****************************************************************************/ /***************** Initialize images of a question to zero *******************/ /*****************************************************************************/ - +/* static void Tst_InitImagesOfQuestion (void) { unsigned NumOpt; - Gbl.Test.Image.Action = Img_ACTION_NO_IMAGE; - Gbl.Test.Image.Status = Img_FILE_NONE; - Gbl.Test.Image.Name[0] = '\0'; - Gbl.Test.Image.Title = NULL; + ***** Initialize image ***** + Img_ResetImage (&Gbl.Test.Image); + for (NumOpt = 0; NumOpt < Tst_MAX_OPTIONS_PER_QUESTION; NumOpt++) - { - Gbl.Test.Answer.Options[NumOpt].Image.Action = Img_ACTION_NO_IMAGE; - Gbl.Test.Answer.Options[NumOpt].Image.Status = Img_FILE_NONE; - Gbl.Test.Answer.Options[NumOpt].Image.Name[0] = '\0'; - Gbl.Test.Answer.Options[NumOpt].Image.Title = NULL; - } + ***** Initialize image ***** + Img_ResetImage (&Gbl.Test.Answer.Options[NumOpt].Image); } - +*/ /*****************************************************************************/ /*********************** Free images of a question ***************************/ /*****************************************************************************/ @@ -4889,11 +4889,11 @@ static void Tst_FreeImagesOfQuestion (void) { unsigned NumOpt; - Img_FreeImageTitle (&Gbl.Test.Image); + Img_ImageDestructor (&Gbl.Test.Image); for (NumOpt = 0; NumOpt < Tst_MAX_OPTIONS_PER_QUESTION; NumOpt++) - Img_FreeImageTitle (&Gbl.Test.Answer.Options[NumOpt].Image); + Img_ImageDestructor (&Gbl.Test.Answer.Options[NumOpt].Image); } /*****************************************************************************/ @@ -5129,7 +5129,7 @@ void Tst_ReceiveQst (void) else // Question is wrong { /***** Whether images has been received or not, reset images *****/ - Tst_InitImagesOfQuestion (); + // Tst_InitImagesOfQuestion (); /***** Put form to edit question again *****/ Tst_PutFormEditOneQst (Stem,Feedback);