diff --git a/css/swad18.80.css b/css/swad18.80.css
index 9803e505..b173092d 100644
--- a/css/swad18.80.css
+++ b/css/swad18.80.css
@@ -2991,7 +2991,7 @@ a:hover img.CENTRE_PHOTO_SHOW
.TL_POST_MED
{
box-sizing:border-box;
- border-radius:8px;
+ border-radius:4px;
}
.TL_COMMENT_CONTAINER
{
@@ -3017,7 +3017,7 @@ a:hover img.CENTRE_PHOTO_SHOW
.TL_COMMENT_MED
{
box-sizing:border-box;
- border-radius:8px;
+ border-radius:4px;
}
.TL_FORM_NEW_COMMENT
{
diff --git a/sql/swad.sql b/sql/swad.sql
index 87812d78..a0505f4c 100644
--- a/sql/swad.sql
+++ b/sql/swad.sql
@@ -1334,6 +1334,7 @@ CREATE TABLE IF NOT EXISTS usr_data (
Comments TEXT NOT NULL DEFAULT '',
Menu TINYINT NOT NULL DEFAULT 0,
SideCols TINYINT NOT NULL DEFAULT 3,
+ ThirdPartyCookies ENUM('N','Y') NOT NULL DEFAULT 'N',
NotifNtfEvents INT NOT NULL DEFAULT 0,
EmailNtfEvents INT NOT NULL DEFAULT 0,
PRIMARY KEY(UsrCod),
@@ -1351,7 +1352,8 @@ CREATE TABLE IF NOT EXISTS usr_data (
INDEX(DptCod),
INDEX(CtrCod),
INDEX(Menu),
- INDEX(SideCols));
+ INDEX(SideCols),
+ INDEX(ThirdPartyCookies));
--
-- Table usr_duplicated: stores informs of users possibly duplicated
--
diff --git a/swad_changelog.h b/swad_changelog.h
index 61403a41..a890504b 100644
--- a/swad_changelog.h
+++ b/swad_changelog.h
@@ -436,6 +436,8 @@ Lo de mutear anuncios, en principio prefiero hacer una opci
// TODO: Los usuarios que no tienes permiso para ver su perfil público, se debería mostrar algo, una mínima ficha sin tinmeline o algo así
+// TODO: Para acelerar la carga, todas las preferencias de usuarios no deberían obtenerse siempre, sino en una llamada especial pues en general sólo interesan para el usuario identificado
+
// TODO: Allow timeline posting only for users belonging to courses or admins to avoid user who create accounts only to post
/*****************************************************************************/
@@ -457,10 +459,51 @@ En OpenSWAD:
ps2pdf source.ps destination.pdf
*/
-#define Log_PLATFORM_VERSION "SWAD 18.80 (2019-03-17)"
+#define Log_PLATFORM_VERSION "SWAD 18.81 (2019-03-18)"
#define CSS_FILE "swad18.80.css"
#define JS_FILE "swad18.80.js"
/*
+TODO: Remove unused fields MediaName,MediaType,MediaTitle,MediaURL,Media from tables:
+// ALTER TABLE forum_post DROP COLUMN MediaName,DROP COLUMN MediaType,DROP COLUMN MediaTitle,DROP COLUMN MediaURL;
+// ALTER TABLE msg_content DROP COLUMN MediaName,DROP COLUMN MediaType,DROP COLUMN MediaTitle,DROP COLUMN MediaURL;
+// ALTER TABLE msg_content_deleted DROP COLUMN MediaName,DROP COLUMN MediaType,DROP COLUMN MediaTitle,DROP COLUMN MediaURL;
+// ALTER TABLE social_comments DROP COLUMN MediaName,DROP COLUMN MediaType,DROP COLUMN MediaTitle,DROP COLUMN MediaURL;
+// ALTER TABLE social_posts DROP COLUMN MediaName,DROP COLUMN MediaType,DROP COLUMN MediaTitle,DROP COLUMN MediaURL;
+// ALTER TABLE tst_answers DROP COLUMN MediaName,DROP COLUMN MediaType,DROP COLUMN MediaTitle,DROP COLUMN MediaURL;
+// ALTER TABLE tst_questions DROP COLUMN MediaName,DROP COLUMN MediaType,DROP COLUMN MediaTitle,DROP COLUMN MediaURL;
+// ALTER TABLE media DROP COLUMN T,DROP COLUMN Cod;
+
+ Version 18.81: Mar 18, 2019 New database table media to store images and videos.
+ Fixed bugs in removal of publications in timeline. (240704 lines)
+ 1 change necessary in database:
+CREATE TABLE IF NOT EXISTS media (MedCod INT NOT NULL AUTO_INCREMENT,Type ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',Name VARCHAR(43) NOT NULL DEFAULT '',URL VARCHAR(255) NOT NULL DEFAULT '',Title VARCHAR(2047) NOT NULL DEFAULT '',T VARCHAR (2047) NOT NULL DEFAULT '',Cod INT NOT NULL DEFAULT -1,UNIQUE INDEX(MedCod),INDEX(Type));
+Only if you use MyISAM:
+ALTER TABLE media ENGINE=MyISAM;
+ 21 changes necessary in database:
+ALTER TABLE forum_post ADD COLUMN MedCod INT NOT NULL DEFAULT -1 AFTER Content,ADD INDEX (MedCod);
+ALTER TABLE msg_content ADD COLUMN MedCod INT NOT NULL DEFAULT -1 AFTER Content,ADD INDEX (MedCod);
+ALTER TABLE msg_content_deleted ADD COLUMN MedCod INT NOT NULL DEFAULT -1 AFTER Content,ADD INDEX (MedCod);
+ALTER TABLE social_comments ADD COLUMN MedCod INT NOT NULL DEFAULT -1 AFTER Content,ADD INDEX (MedCod);
+ALTER TABLE social_posts ADD COLUMN MedCod INT NOT NULL DEFAULT -1 AFTER Content,ADD INDEX (MedCod);
+ALTER TABLE tst_answers ADD COLUMN MedCod INT NOT NULL DEFAULT -1 AFTER Feedback,ADD INDEX (MedCod);
+ALTER TABLE tst_questions ADD COLUMN MedCod INT NOT NULL DEFAULT -1 AFTER Feedback,ADD INDEX (MedCod);
+
+INSERT INTO media (Type,Name,URL,Title,T,Cod) SELECT MediaType,MediaName,MediaURL,MediaTitle,'forum_post',PstCod FROM forum_post WHERE MediaType<>'none';
+INSERT INTO media (Type,Name,URL,Title,T,Cod) SELECT MediaType,MediaName,MediaURL,MediaTitle,'msg_content',MsgCod FROM msg_content WHERE MediaType<>'none';
+INSERT INTO media (Type,Name,URL,Title,T,Cod) SELECT MediaType,MediaName,MediaURL,MediaTitle,'msg_content_deleted',MsgCod FROM msg_content_deleted WHERE MediaType<>'none';
+INSERT INTO media (Type,Name,URL,Title,T,Cod) SELECT MediaType,MediaName,MediaURL,MediaTitle,'social_comments',PubCod FROM social_comments WHERE MediaType<>'none';
+INSERT INTO media (Type,Name,URL,Title,T,Cod) SELECT MediaType,MediaName,MediaURL,MediaTitle,'social_posts',PstCod FROM social_posts WHERE MediaType<>'none';
+INSERT INTO media (Type,Name,URL,Title,T,Cod) SELECT MediaType,MediaName,MediaURL,MediaTitle,'tst_answers',QstCod*10+AnsInd FROM tst_answers WHERE MediaType<>'none';
+INSERT INTO media (Type,Name,URL,Title,T,Cod) SELECT MediaType,MediaName,MediaURL,MediaTitle,'tst_questions',QstCod FROM tst_questions WHERE MediaType<>'none';
+
+UPDATE forum_post,media SET forum_post.MedCod=media.MedCod WHERE media.T='forum_post' AND forum_post.PstCod=media.Cod;
+UPDATE msg_content,media SET msg_content.MedCod=media.MedCod WHERE media.T='msg_content' AND msg_content.MsgCod=media.Cod;
+UPDATE msg_content_deleted,media SET msg_content_deleted.MedCod=media.MedCod WHERE media.T='msg_content_deleted' AND msg_content_deleted.MsgCod=media.Cod;
+UPDATE social_comments,media SET social_comments.MedCod=media.MedCod WHERE media.T='social_comments' AND social_comments.PubCod=media.Cod;
+UPDATE social_posts,media SET social_posts.MedCod=media.MedCod WHERE media.T='social_posts' AND social_posts.PstCod=media.Cod;
+UPDATE tst_answers,media SET tst_answers.MedCod=media.MedCod WHERE media.T='tst_answers' AND tst_answers.QstCod*10+AnsInd=media.Cod;
+UPDATE tst_questions,media SET tst_questions.MedCod=media.MedCod WHERE media.T='tst_questions' AND tst_questions.QstCod=media.Cod;
+
Version 18.80: Mar 17, 2019 Figure about cookies. (240647 lines)
Version 18.79.1: Mar 17, 2019 YouTube videos are not shown if user doesn't accept third party cookies. (240541 lines)
Version 18.79: Mar 17, 2019 New module swad_cookies for user's preference about cookies. (240494 lines)
diff --git a/swad_database.c b/swad_database.c
index 124dde08..ebf3cbc5 100644
--- a/swad_database.c
+++ b/swad_database.c
@@ -1218,12 +1218,13 @@ mysql> DESCRIBE forum_post;
| NumNotif | int(11) | NO | | 0 | |
| Subject | text | NO | | NULL | |
| Content | longtext | NO | | NULL | |
+| MedCod | int(11) | NO | MUL | -1 | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
+------------+-------------------------------------------------------+------+-----+---------+----------------+
-12 rows in set (0.00 sec)
+13 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS forum_post ("
"PstCod INT NOT NULL AUTO_INCREMENT,"
@@ -1234,6 +1235,7 @@ mysql> DESCRIBE forum_post;
"NumNotif INT NOT NULL DEFAULT 0,"
"Subject TEXT NOT NULL," // Cns_MAX_BYTES_SUBJECT
"Content LONGTEXT NOT NULL," // Cns_MAX_BYTES_LONG_TEXT
+ "MedCod INT NOT NULL DEFAULT -1,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
@@ -1242,7 +1244,8 @@ mysql> DESCRIBE forum_post;
"INDEX(ThrCod),"
"INDEX(UsrCod),"
"INDEX(CreatTime),"
- "INDEX(ModifTime))");
+ "INDEX(ModifTime),"
+ "INDEX(MedCod))");
/***** Table forum_thr_clip *****/
/*
@@ -1714,6 +1717,29 @@ mysql> DESCRIBE marks_properties;
"Footer INT NOT NULL,"
"UNIQUE INDEX(FilCod))");
+ /***** Table media *****/
+/*
+mysql> DESCRIBE media;
++--------+-------------------------------------------------------+------+-----+---------+----------------+
+| Field | Type | Null | Key | Default | Extra |
++--------+-------------------------------------------------------+------+-----+---------+----------------+
+| MedCod | int(11) | NO | PRI | NULL | auto_increment |
+| Type | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | MUL | none | |
+| Name | varchar(43) | NO | | | |
+| URL | varchar(255) | NO | | | |
+| Title | varchar(2047) | NO | | | |
++--------+-------------------------------------------------------+------+-----+---------+----------------+
+5 rows in set (0.00 sec)
+*/
+ DB_CreateTable ("CREATE TABLE IF NOT EXISTS media ("
+ "MedCod INT NOT NULL AUTO_INCREMENT,"
+ "Type ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
+ "Name VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
+ "URL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
+ "Title VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
+ "UNIQUE INDEX(MedCod),"
+ "INDEX(Type))");
+
/***** Table msg_banned *****/
/*
mysql> DESCRIBE msg_banned;
@@ -1739,23 +1765,26 @@ mysql> DESCRIBE msg_content;
| MsgCod | int(11) | NO | PRI | NULL | auto_increment |
| Subject | text | NO | MUL | NULL | |
| Content | longtext | NO | | NULL | |
+| MedCod | int(11) | NO | MUL | -1 | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
+------------+-------------------------------------------------------+------+-----+---------+----------------+
-7 rows in set (0.00 sec)
+8 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS msg_content ("
"MsgCod INT NOT NULL AUTO_INCREMENT,"
"Subject TEXT NOT NULL,"
"Content LONGTEXT NOT NULL,"
+ "MedCod INT NOT NULL DEFAULT -1,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"UNIQUE INDEX(MsgCod),"
- "FULLTEXT(Subject,Content)) ENGINE = MYISAM;");
+ "FULLTEXT(Subject,Content),"
+ "INDEX(MedCod)) ENGINE = MYISAM;");
/***** Table msg_content_deleted *****/
/*
@@ -1766,23 +1795,26 @@ mysql> DESCRIBE msg_content_deleted;
| MsgCod | int(11) | NO | PRI | NULL | |
| Subject | text | NO | MUL | NULL | |
| Content | longtext | NO | | NULL | |
+| MedCod | int(11) | NO | MUL | -1 | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
+------------+-------------------------------------------------------+------+-----+---------+-------+
-7 rows in set (0.00 sec)
+8 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS msg_content_deleted ("
"MsgCod INT NOT NULL,"
"Subject TEXT NOT NULL,"
"Content LONGTEXT NOT NULL,"
+ "MedCod INT NOT NULL DEFAULT -1,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"UNIQUE INDEX(MsgCod),"
- "FULLTEXT(Subject,Content)) ENGINE = MYISAM;");
+ "FULLTEXT(Subject,Content),"
+ "INDEX(MedCod)) ENGINE = MYISAM;");
/***** Table msg_rcv *****/
/*
@@ -2181,22 +2213,25 @@ mysql> DESCRIBE social_comments;
+------------+-------------------------------------------------------+------+-----+---------+-------+
| PubCod | bigint(20) | NO | PRI | NULL | |
| Content | longtext | NO | MUL | NULL | |
+| MedCod | int(11) | NO | MUL | -1 | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
+------------+-------------------------------------------------------+------+-----+---------+-------+
-6 rows in set (0.00 sec)
+7 rows in set (0.01 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_comments ("
"PubCod BIGINT NOT NULL,"
"Content LONGTEXT NOT NULL,"
+ "MedCod INT NOT NULL DEFAULT -1,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"UNIQUE INDEX(PubCod),"
- "FULLTEXT(Content)) ENGINE = MYISAM;");
+ "FULLTEXT(Content),"
+ "INDEX(MedCod)) ENGINE = MYISAM;");
/***** Table social_comments_fav *****/
/*
@@ -2279,22 +2314,25 @@ mysql> DESCRIBE social_posts;
+------------+-------------------------------------------------------+------+-----+---------+----------------+
| PstCod | int(11) | NO | PRI | NULL | auto_increment |
| Content | longtext | NO | MUL | NULL | |
+| MedCod | int(11) | NO | MUL | -1 | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
+------------+-------------------------------------------------------+------+-----+---------+----------------+
-6 rows in set (0.00 sec)
+7 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_posts ("
"PubCod INT NOT NULL AUTO_INCREMENT,"
"Content LONGTEXT NOT NULL,"
+ "MedCod INT NOT NULL DEFAULT -1,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"UNIQUE INDEX(PubCod),"
- "FULLTEXT(Content)) ENGINE = MYISAM;");
+ "FULLTEXT(Content),"
+ "INDEX(MedCod)) ENGINE = MYISAM;");
/***** Table social_pubs *****/
/*
@@ -2554,25 +2592,28 @@ mysql> DESCRIBE tst_answers;
| AnsInd | tinyint(4) | NO | | NULL | |
| Answer | text | NO | | NULL | |
| Feedback | text | NO | | NULL | |
+| MedCod | int(11) | NO | MUL | -1 | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
| Correct | enum('N','Y') | NO | | NULL | |
+------------+-------------------------------------------------------+------+-----+---------+-------+
-9 rows in set (0.00 sec)
+10 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS tst_answers ("
"QstCod INT NOT NULL,"
"AnsInd TINYINT NOT NULL,"
"Answer TEXT NOT NULL," // Tst_MAX_BYTES_ANSWER_OR_FEEDBACK
"Feedback TEXT NOT NULL," // Tst_MAX_BYTES_ANSWER_OR_FEEDBACK
+ "MedCod INT NOT NULL DEFAULT -1,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"Correct ENUM('N','Y') NOT NULL,"
- "INDEX(QstCod))");
+ "INDEX(QstCod),"
+ "INDEX(MedCod))");
/***** Table tst_config *****/
/*
@@ -2684,6 +2725,7 @@ mysql> DESCRIBE tst_questions;
| Shuffle | enum('N','Y') | NO | | NULL | |
| Stem | text | NO | | NULL | |
| Feedback | text | NO | | NULL | |
+| MedCod | int(11) | NO | MUL | -1 | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('none','jpg','gif','mp4','webm','ogg','youtube') | NO | | none | |
| MediaTitle | varchar(2047) | NO | | | |
@@ -2692,7 +2734,7 @@ mysql> DESCRIBE tst_questions;
| NumHitsNotBlank | int(11) | NO | | 0 | |
| Score | double | NO | | 0 | |
+-----------------+---------------------------------------------------------------------------+------+-----+---------+----------------+
-14 rows in set (0.00 sec)
+15 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS tst_questions ("
"QstCod INT NOT NULL AUTO_INCREMENT,"
@@ -2702,6 +2744,7 @@ mysql> DESCRIBE tst_questions;
"Shuffle ENUM('N','Y') NOT NULL,"
"Stem TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
"Feedback TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
+ "MedCod INT NOT NULL DEFAULT -1,"
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('none','jpg','gif','mp4','webm','ogg','youtube') NOT NULL DEFAULT 'none',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
@@ -2710,7 +2753,8 @@ mysql> DESCRIBE tst_questions;
"NumHitsNotBlank INT NOT NULL DEFAULT 0,"
"Score DOUBLE PRECISION NOT NULL DEFAULT 0,"
"UNIQUE INDEX(QstCod),"
- "INDEX(CrsCod,EditTime))");
+ "INDEX(CrsCod,EditTime),"
+ "INDEX(MedCod))");
/***** Table tst_status *****/
/*
@@ -2865,7 +2909,7 @@ mysql> DESCRIBE usr_data;
"INDEX(CtrCod),"
"INDEX(Menu),"
"INDEX(SideCols),"
- "INDEX(ThirdPartyCookies)");
+ "INDEX(ThirdPartyCookies))");
/***** Table usr_duplicated *****/
/*
diff --git a/swad_forum.c b/swad_forum.c
index 095e2013..4986554d 100644
--- a/swad_forum.c
+++ b/swad_forum.c
@@ -283,7 +283,7 @@ static void For_InsertPstIntoBannedPstTable (long PstCod);
static long For_InsertForumPst (long ThrCod,long UsrCod,
const char *Subject,const char *Content,
struct Media *Media);
-static bool For_RemoveForumPst (long PstCod,struct Media *Media);
+static bool For_RemoveForumPst (long PstCod,long MedCod);
static unsigned For_NumPstsInThrWithPstCod (long PstCod,long *ThrCod);
static long For_InsertForumThread (long FirstPstCod);
@@ -501,28 +501,29 @@ static long For_InsertForumPst (long ThrCod,long UsrCod,
long PstCod;
/***** Check if image is received and processed *****/
+ Media->MedCod = -1L;
if (Media->Action == Med_ACTION_NEW_MEDIA && // New media
Media->Status == Med_PROCESSED) // The new media received has been processed
+ {
/* Move processed media to definitive directory */
Med_MoveMediaToDefinitiveDir (Media);
+ /* Store media in database */
+ if (Media->Status == Med_MOVED)
+ Med_StoreMediaInDB (Media); // Set Media->MedCod
+ }
+
/***** Insert forum post in the database *****/
PstCod =
DB_QueryINSERTandReturnCode ("can not create a new post in a forum",
"INSERT INTO forum_post"
" (ThrCod,UsrCod,CreatTime,ModifTime,NumNotif,"
- "Subject,Content,"
- "MediaName,MediaType,MediaTitle,MediaURL)"
+ "Subject,Content,MedCod)"
" VALUES"
" (%ld,%ld,NOW(),NOW(),0,"
- "'%s','%s',"
- "'%s','%s','%s','%s')",
+ "'%s','%s',%ld)",
ThrCod,UsrCod,
- Subject,Content,
- Media->Name,
- Med_GetStringTypeForDB (Media->Type),
- Media->Title ? Media->Title : "",
- Media->URL ? Media->URL : "");
+ Subject,Content,Media->MedCod);
return PstCod;
}
@@ -532,13 +533,13 @@ static long For_InsertForumPst (long ThrCod,long UsrCod,
/*****************************************************************************/
// Return true if the post thread is deleted
-static bool For_RemoveForumPst (long PstCod,struct Media *Media)
+static bool For_RemoveForumPst (long PstCod,long MedCod)
{
long ThrCod;
bool ThreadDeleted = false;
/***** Remove media file attached to forum post *****/
- Med_RemoveMediaFiles (Media->Name,Media->Type);
+ Med_RemoveMedia (MedCod);
/***** If the post is the only one in its thread, delete that thread *****/
if (For_NumPstsInThrWithPstCod (PstCod,&ThrCod) < 2)
@@ -1345,10 +1346,7 @@ static void For_GetPstData (long PstCod,long *UsrCod,time_t *CreatTimeUTC,
"UNIX_TIMESTAMP(CreatTime)," // row[1]
"Subject," // row[2]
"Content," // row[3]
- "MediaName," // row[4]
- "MediaType," // row[5]
- "MediaTitle," // row[6]
- "MediaURL" // row[7]
+ "MedCod" // row[4]
" FROM forum_post WHERE PstCod=%ld",
PstCod);
@@ -1359,22 +1357,23 @@ static void For_GetPstData (long PstCod,long *UsrCod,time_t *CreatTimeUTC,
/***** Get number of rows *****/
row = mysql_fetch_row (mysql_res);
- /****** Get author code (row[1]) *****/
+ /***** Get author code (row[1]) *****/
*UsrCod = Str_ConvertStrCodToLongCod (row[0]);
- /****** Get creation time (row[1]) *****/
+ /***** Get creation time (row[1]) *****/
*CreatTimeUTC = Dat_GetUNIXTimeFromStr (row[1]);
- /****** Get subject (row[2]) *****/
+ /***** Get subject (row[2]) *****/
Str_Copy (Subject,row[2],
Cns_MAX_BYTES_SUBJECT);
- /****** Get location (row[3]) *****/
+ /***** Get location (row[3]) *****/
Str_Copy (Content,row[3],
Cns_MAX_BYTES_LONG_TEXT);
- /****** Get media data (row[4], row[5], row[6], row[7]) *****/
- Med_GetMediaDataFromRow (row[4],row[5],row[6],row[7],Media);
+ /***** Get media (row[4]) *****/
+ Media->MedCod = Str_ConvertStrCodToLongCod (row[4]);
+ Med_GetMediaDataByCod (Media);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@@ -4089,7 +4088,7 @@ void For_ReceiveForumPost (void)
For_UpdateThrFirstAndLastPst (Gbl.Forum.ForumSelected.ThrCod,PstCod,PstCod);
}
- /***** Free image *****/
+ /***** Free media *****/
Med_MediaDestructor (&Media);
/***** Increment number of forum posts in my user's figures *****/
@@ -4188,7 +4187,7 @@ void For_RemovePost (void)
Lay_ShowErrorAndExit ("You can not remove post because it is not the last of the thread.");
/***** Remove the post *****/
- ThreadDeleted = For_RemoveForumPst (Gbl.Forum.ForumSelected.PstCod,&Media);
+ ThreadDeleted = For_RemoveForumPst (Gbl.Forum.ForumSelected.PstCod,Media.MedCod);
/***** Free image *****/
Med_MediaDestructor (&Media);
diff --git a/swad_game.c b/swad_game.c
index 0146f8f0..7aac49a5 100644
--- a/swad_game.c
+++ b/swad_game.c
@@ -2734,10 +2734,7 @@ static void Gam_ListGameQuestions (struct Game *Game)
"tst_questions.AnsType," // row[1]
"tst_questions.Stem," // row[2]
"tst_questions.Feedback," // row[3]
- "tst_questions.MediaName," // row[4]
- "tst_questions.MediaType," // row[5]
- "tst_questions.MediaTitle," // row[6]
- "tst_questions.MediaURL" // row[7]
+ "tst_questions.MedCod" // row[4]
" FROM gam_questions,tst_questions"
" WHERE gam_questions.GamCod=%ld"
" AND gam_questions.QstCod=tst_questions.QstCod"
@@ -2842,10 +2839,7 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game,
row[1] AnsType
row[2] Stem
row[3] Feedback
- row[4] MediaName
- row[5] MediaType
- row[6] MediaTitle
- row[7] MediaURL
+ row[4] MedCod
*/
/***** Create test question *****/
Tst_QstConstructor ();
@@ -2923,16 +2917,24 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game,
Tst_GetAndWriteTagsQst (Gbl.Test.QstCod);
fprintf (Gbl.F.Out,"");
- /* Write stem (row[2]), media data (row[4], row[5], row[6], row[7]),
- feedback (row[3]) and answers */
+ /* Write stem (row[2]) */
fprintf (Gbl.F.Out,"
",
Gbl.RowEvenOdd);
Tst_WriteQstStem (row[2],"TEST_EDI");
- Med_GetMediaDataFromRow (row[4],row[5],row[6],row[7],&Gbl.Test.Media);
+
+ /* Get media (row[4]) */
+ Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[4]);
+ Med_GetMediaDataByCod (&Gbl.Test.Media);
+
+ /* Show media */
Med_ShowMedia (&Gbl.Test.Media,
"TEST_IMG_EDIT_LIST_STEM_CONTAINER",
"TEST_IMG_EDIT_LIST_STEM");
+
+ /* Show feedback (row[3]) */
Tst_WriteQstFeedback (row[3],"TEST_EDI_LIGHT");
+
+ /* Show answers */
Tst_WriteAnswersGameResult (Game,NumQst,QstCod,
"TEST_EDI",true); // Show result
@@ -3531,10 +3533,7 @@ static void Gam_PlayGameShowQuestionAndAnswers (bool ShowAnswers)
"SELECT tst_questions.QstCod," // row[0]
"tst_questions.AnsType," // row[1]
"tst_questions.Stem," // row[2]
- "tst_questions.MediaName," // row[3]
- "tst_questions.MediaType," // row[4]
- "tst_questions.MediaTitle," // row[5]
- "tst_questions.MediaURL" // row[6]
+ "tst_questions.MedCod" // row[3]
" FROM gam_questions,tst_questions"
" WHERE gam_questions.GamCod=%ld"
" AND gam_questions.QstInd=%u"
@@ -3553,9 +3552,14 @@ static void Gam_PlayGameShowQuestionAndAnswers (bool ShowAnswers)
fprintf (Gbl.F.Out,"");
- /* Write stem (row[2]) and media data (row[3], row[4], row[5], row[6]) */
+ /* Write stem (row[2]) */
Tst_WriteQstStem (row[2],"GAM_PLAY_QST");
- Med_GetMediaDataFromRow (row[3],row[4],row[5],row[6],&Gbl.Test.Media);
+
+ /* Get media (row[3]) */
+ Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[3]);
+ Med_GetMediaDataByCod (&Gbl.Test.Media);
+
+ /* Show media */
Med_ShowMedia (&Gbl.Test.Media,
"TEST_IMG_EDIT_LIST_STEM_CONTAINER",
"TEST_IMG_EDIT_LIST_STEM");
diff --git a/swad_media.c b/swad_media.c
index cd80fa4b..e9b240cb 100644
--- a/swad_media.c
+++ b/swad_media.c
@@ -38,6 +38,7 @@
#include "swad_config.h"
#include "swad_cookie.h"
+#include "swad_database.h"
#include "swad_global.h"
#include "swad_file.h"
#include "swad_file_browser.h"
@@ -153,8 +154,10 @@ static void Med_ShowVideo (struct Media *Media,
const char *ClassMedia);
static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia);
+static Med_Type_t Med_GetTypeFromStrInDB (const char *Str);
static Med_Type_t Med_GetTypeFromExtAndMIME (const char *Extension,
const char *MIMEType);
+static const char *Med_GetStringTypeForDB (Med_Type_t Type);
/*****************************************************************************/
/********************** Media (image/video) constructor **********************/
@@ -197,6 +200,7 @@ void Med_ResetMedia (struct Media *Media)
static void Med_ResetMediaExceptURLAndTitle (struct Media *Media)
{
+ Media->MedCod = -1L;
Media->Action = Med_ACTION_NO_MEDIA;
Media->Status = Med_STATUS_NONE;
Media->Name[0] = '\0';
@@ -235,58 +239,81 @@ static void Med_FreeMediaTitle (struct Media *Media)
/**** Get media name, title and URL from a query result and copy to struct ***/
/*****************************************************************************/
-void Med_GetMediaDataFromRow (const char *Name,
- const char *TypeStr,
- const char *Title,
- const char *URL,
- struct Media *Media)
+void Med_GetMediaDataByCod (struct Media *Media)
{
+ MYSQL_RES *mysql_res;
+ MYSQL_ROW row;
+ unsigned NumRows;
size_t Length;
- /***** Copy image name to struct *****/
- Str_Copy (Media->Name,Name,
- Med_BYTES_NAME);
+ /***** Get data of a media from database *****/
+ NumRows = DB_QuerySELECT (&mysql_res,"can not get data of a post",
+ "SELECT Type," // row[0]
+ "Name," // row[1]
+ "URL," // row[2]
+ "Title" // row[3]
+ " FROM media WHERE MedCod=%ld",
+ Media->MedCod);
- /***** Convert type string to type *****/
- Media->Type = Med_GetTypeFromStrInDB (TypeStr);
-
- /***** Set status of media file *****/
- Media->Status = (Media->Type != Med_TYPE_NONE) ? Med_STORED_IN_DB :
- Med_STATUS_NONE;
-
- /***** Copy image URL to struct *****/
- // Media->URL can be empty or filled with previous value
- // If filled ==> free it
- Med_FreeMediaURL (Media);
- if (URL[0])
+ /***** Result should have a unique row *****/
+ if (NumRows == 0) // Media not found
+ /***** Reset media data *****/
+ Med_ResetMedia (Media);
+ else if (NumRows == 1)
{
- /* Get and limit length of the URL */
- Length = strlen (URL);
- if (Length > Cns_MAX_BYTES_WWW)
- Length = Cns_MAX_BYTES_WWW;
+ /***** Get row *****/
+ row = mysql_fetch_row (mysql_res);
- if ((Media->URL = (char *) malloc (Length + 1)) == NULL)
- Lay_ShowErrorAndExit ("Error allocating memory for image URL.");
- Str_Copy (Media->URL,URL,
- Length);
+ /***** Convert type string (row[0]) to type *****/
+ Media->Type = Med_GetTypeFromStrInDB (row[0]);
+
+ /***** Set status of media file *****/
+ Media->Status = (Media->Type != Med_TYPE_NONE) ? Med_STORED_IN_DB :
+ Med_STATUS_NONE;
+
+ /***** Copy media name (row[1]) to struct *****/
+ Str_Copy (Media->Name,row[1],
+ Med_BYTES_NAME);
+
+ /***** Copy media URL (row[2]) to struct *****/
+ // Media->URL can be empty or filled with previous value
+ // If filled ==> free it
+ Med_FreeMediaURL (Media);
+ if (row[2][0])
+ {
+ /* Get and limit length of the URL */
+ Length = strlen (row[2]);
+ if (Length > Cns_MAX_BYTES_WWW)
+ Length = Cns_MAX_BYTES_WWW;
+
+ if ((Media->URL = (char *) malloc (Length + 1)) == NULL)
+ Lay_ShowErrorAndExit ("Error allocating memory for image URL.");
+ Str_Copy (Media->URL,row[2],
+ Length);
+ }
+
+ /***** Copy media title (row[3]) to struct *****/
+ // Media->Title can be empty or filled with previous value
+ // If filled ==> free it
+ Med_FreeMediaTitle (Media);
+ if (row[3][0])
+ {
+ /* Get and limit length of the title */
+ Length = strlen (row[3]);
+ if (Length > Med_MAX_BYTES_TITLE)
+ Length = Med_MAX_BYTES_TITLE;
+
+ if ((Media->Title = (char *) malloc (Length + 1)) == NULL)
+ Lay_ShowErrorAndExit ("Error allocating memory for image title.");
+ Str_Copy (Media->Title,row[3],
+ Length);
+ }
}
+ else
+ Lay_ShowErrorAndExit ("Internal error in database when getting media data.");
- /***** Copy image title to struct *****/
- // Media->Title can be empty or filled with previous value
- // If filled ==> free it
- Med_FreeMediaTitle (Media);
- if (Title[0])
- {
- /* Get and limit length of the title */
- Length = strlen (Title);
- if (Length > Med_MAX_BYTES_TITLE)
- Length = Med_MAX_BYTES_TITLE;
-
- if ((Media->Title = (char *) malloc (Length + 1)) == NULL)
- Lay_ShowErrorAndExit ("Error allocating memory for image title.");
- Str_Copy (Media->Title,Title,
- Length);
- }
+ /***** Free structure that stores the query result *****/
+ DB_FreeMySQLResult (&mysql_res);
}
/*****************************************************************************/
@@ -980,7 +1007,6 @@ static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
/***** Get embed URL from form *****/
Usr_GetURLFromForm (ParamURL,Media);
- // Ale_ShowAlert (Ale_INFO,"DEBUG: Media->URL = '%s'",Media->URL);
/***** Process URL trying to convert it to a YouTube embed URL *****/
if (Media->URL)
@@ -1007,7 +1033,6 @@ static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
if (PtrHost[0])
{
/***** Step 2: Skip host *****/
- // Ale_ShowAlert (Ale_INFO,"DEBUG: PtrHost = '%s'",PtrHost);
if (!strncasecmp (PtrHost,"youtu.be/" , 9)) // Host starts by youtu.be/
{
YouTube = SHORT;
@@ -1035,7 +1060,6 @@ static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
if (YouTube != WRONG)
{
- // Ale_ShowAlert (Ale_INFO,"DEBUG: PtrPath = '%s'",PtrPath);
/***** Step 3: Skip path *****/
if (YouTube == FULL)
{
@@ -1063,7 +1087,6 @@ static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
if (YouTube != WRONG)
{
- // Ale_ShowAlert (Ale_INFO,"DEBUG: PtrParams = '%s'",PtrParams);
/***** Step 4: Search for video code *****/
switch (YouTube)
{
@@ -1095,7 +1118,6 @@ static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
if (YouTube != WRONG)
{
- // Ale_ShowAlert (Ale_INFO,"DEBUG: PtrCode = '%s'",PtrCode);
/***** Step 5: Get video code *****/
CodeLength = strspn (PtrCode,Str_BIN_TO_BASE64URL);
if (CodeLength > 0 &&
@@ -1105,7 +1127,6 @@ static void Med_GetAndProcessEmbedFromForm (const char *ParamURL,
/* Copy code */
strncpy (Media->Name,PtrCode,CodeLength);
Media->Name[CodeLength] = '\0';
- // Ale_ShowAlert (Ale_INFO,"DEBUG: Media->Name = '%s'",Media->Name);
Media->Type = Med_YOUTUBE;
Media->Status = Med_PROCESSED;
@@ -1126,56 +1147,63 @@ void Med_MoveMediaToDefinitiveDir (struct Media *Media)
char PathMedPrivTmp[PATH_MAX + 1];
char PathMedPriv[PATH_MAX + 1];
- /***** Check trivial cases *****/
- if (Media->Status != Med_PROCESSED)
- return;
- if (Media->Type == Med_YOUTUBE)
- return; // Nothing to do with files
-
- /***** Build temporary path *****/
- snprintf (PathMedPrivTmp,sizeof (PathMedPrivTmp),
- "%s/%s/%s",
- Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA,Cfg_FOLDER_IMG_TMP);
-
- /***** Create private subdirectory for media if it does not exist *****/
- snprintf (PathMedPriv,sizeof (PathMedPriv),
- "%s/%s/%c%c",
- Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA,
- Media->Name[0],
- Media->Name[1]);
- Fil_CreateDirIfNotExists (PathMedPriv);
-
- /***** Move files *****/
- switch (Media->Type)
+ /***** Check trivial case *****/
+ if (Media->Status == Med_PROCESSED)
{
- case Med_JPG:
- /* Move JPG */
- if (!Med_MoveTmpFileToDefDir (Media,PathMedPrivTmp,PathMedPriv,
- Med_Extensions[Med_JPG]))
- return; // Fail
- break;
- case Med_GIF:
- /* Move PNG */
- if (!Med_MoveTmpFileToDefDir (Media,PathMedPrivTmp,PathMedPriv,
- "png"))
- return; // Fail
- /* Move GIF */
- if (!Med_MoveTmpFileToDefDir (Media,PathMedPrivTmp,PathMedPriv,
- Med_Extensions[Med_GIF]))
- return; // Fail
- break;
- case Med_MP4:
- case Med_WEBM:
- case Med_OGG:
- /* Move MP4 or WEBM or OGG */
- if (!Med_MoveTmpFileToDefDir (Media,PathMedPrivTmp,PathMedPriv,
- Med_Extensions[Media->Type]))
- return; // Fail
- break;
- default:
- Lay_ShowErrorAndExit ("Wrong media type.");
- break;
+ if (Media->Type == Med_YOUTUBE)
+ // Nothing to do with files ==> Processing successfully finished
+ Media->Status = Med_MOVED; // Success
+ else
+ {
+ /***** Build temporary path *****/
+ snprintf (PathMedPrivTmp,sizeof (PathMedPrivTmp),
+ "%s/%s/%s",
+ Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA,Cfg_FOLDER_IMG_TMP);
+
+ /***** Create private subdirectory for media if it does not exist *****/
+ snprintf (PathMedPriv,sizeof (PathMedPriv),
+ "%s/%s/%c%c",
+ Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA,
+ Media->Name[0],
+ Media->Name[1]);
+ Fil_CreateDirIfNotExists (PathMedPriv);
+
+ /***** Move files *****/
+ switch (Media->Type)
+ {
+ case Med_JPG:
+ /* Move JPG */
+ if (Med_MoveTmpFileToDefDir (Media,PathMedPrivTmp,PathMedPriv,
+ Med_Extensions[Med_JPG]))
+ Media->Status = Med_MOVED; // Success
+ break;
+ case Med_GIF:
+ /* Move PNG */
+ if (Med_MoveTmpFileToDefDir (Media,PathMedPrivTmp,PathMedPriv,
+ "png"))
+ /* Move GIF */
+ if (Med_MoveTmpFileToDefDir (Media,PathMedPrivTmp,PathMedPriv,
+ Med_Extensions[Med_GIF]))
+ Media->Status = Med_MOVED; // Success
+ break;
+ case Med_MP4:
+ case Med_WEBM:
+ case Med_OGG:
+ /* Move MP4 or WEBM or OGG */
+ if (Med_MoveTmpFileToDefDir (Media,PathMedPrivTmp,PathMedPriv,
+ Med_Extensions[Media->Type]))
+ Media->Status = Med_MOVED; // Success
+ break;
+ default:
+ Lay_ShowErrorAndExit ("Wrong media type.");
+ break; // Not reached
+ }
+ }
}
+
+ /***** If fail ==> reset media *****/
+ if (Media->Status != Med_MOVED) // Fail
+ Med_ResetMedia (Media);
}
/*****************************************************************************/
@@ -1212,6 +1240,32 @@ static bool Med_MoveTmpFileToDefDir (struct Media *Media,
return true; // Success
}
+/*****************************************************************************/
+/************************ Store media into database **************************/
+/*****************************************************************************/
+
+void Med_StoreMediaInDB (struct Media *Media)
+ {
+ /***** Trivial case *****/
+ if (Media->Status != Med_MOVED)
+ {
+ Med_ResetMedia (Media); // No media inserted in database
+ return;
+ }
+
+ /***** Insert media into database *****/
+ Media->MedCod = DB_QueryINSERTandReturnCode ("can not create media",
+ "INSERT INTO media"
+ " (Type,Name,URL,Title)"
+ " VALUES"
+ " ('%s','%s','%s','%s')",
+ Med_GetStringTypeForDB (Media->Type),
+ Media->Name,
+ Media->URL ? Media->URL : "",
+ Media->Title ? Media->Title : "");
+ Media->Status = Med_STORED_IN_DB;
+ }
+
/*****************************************************************************/
/****** Show a user uploaded media (in a test question, timeline, etc.) ******/
/*****************************************************************************/
@@ -1542,10 +1596,10 @@ static void Med_ShowYoutube (struct Media *Media,const char *ClassMedia)
}
/*****************************************************************************/
-/*** Remove private files with an image/video, given the image/video name ****/
+/**************** Remove media files and entries in database *****************/
/*****************************************************************************/
-void Med_RemoveMediaFilesFromAllRows (unsigned NumMedia,MYSQL_RES *mysql_res)
+void Med_RemoveMediaFromAllRows (unsigned NumMedia,MYSQL_RES *mysql_res)
{
unsigned NumMed;
@@ -1553,87 +1607,106 @@ void Med_RemoveMediaFilesFromAllRows (unsigned NumMedia,MYSQL_RES *mysql_res)
for (NumMed = 0;
NumMed < NumMedia;
NumMed++)
- Med_RemoveMediaFilesFromRow (mysql_res);
+ Med_RemoveMediaFromRow (mysql_res);
}
-void Med_RemoveMediaFilesFromRow (MYSQL_RES *mysql_res)
+void Med_RemoveMediaFromRow (MYSQL_RES *mysql_res)
{
MYSQL_ROW row;
+ long MedCod;
- /***** Get media name (row[0]) and type (row[1]) *****/
+ /***** Get media code (row[0]) *****/
row = mysql_fetch_row (mysql_res);
+ MedCod = Str_ConvertStrCodToLongCod (row[0]);
- /***** Remove image file *****/
- Med_RemoveMediaFiles (row[0],Med_GetTypeFromStrInDB (row[1]));
+ /***** Remove media files *****/
+ Med_RemoveMedia (MedCod);
}
-void Med_RemoveMediaFiles (const char *Name,Med_Type_t Type)
+void Med_RemoveMedia (long MedCod)
{
char PathMedPriv[PATH_MAX + 1];
char FullPathMediaPriv[PATH_MAX + 1];
+ struct Media Media;
- /***** Trivial cases *****/
- if (Name == NULL)
- return;
- if (!Name[0])
- return;
- if (Type == Med_YOUTUBE)
+ /***** Trivial case *****/
+ if (MedCod <= 0)
return;
- /***** Build path to private directory with the media *****/
- snprintf (PathMedPriv,sizeof (PathMedPriv),
- "%s/%s/%c%c",
- Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA,
- Name[0],
- Name[1]);
+ /***** Initialize media *****/
+ Med_MediaConstructor (&Media);
- /***** Remove files *****/
- switch (Type)
+ /***** Get media *****/
+ Media.MedCod = MedCod;
+ Med_GetMediaDataByCod (&Media);
+
+ /***** Step 1. Remove files *****/
+ if (Media.Type != Med_TYPE_NONE &&
+ Media.Type != Med_YOUTUBE &&
+ Media.Name[0])
{
- case Med_JPG:
- /***** Remove private JPG file *****/
- snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
- "%s/%s.%s",
- PathMedPriv,Name,Med_Extensions[Med_JPG]);
- unlink (FullPathMediaPriv);
+ /***** Build path to private directory with the media *****/
+ snprintf (PathMedPriv,sizeof (PathMedPriv),
+ "%s/%s/%c%c",
+ Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA,
+ Media.Name[0],
+ Media.Name[1]);
- break;
- case Med_GIF:
- /***** Remove private GIF file *****/
- snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
- "%s/%s.%s",
- PathMedPriv,Name,Med_Extensions[Med_GIF]);
- unlink (FullPathMediaPriv);
+ /***** Remove files *****/
+ switch (Media.Type)
+ {
+ case Med_JPG:
+ /***** Remove private JPG file *****/
+ snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
+ "%s/%s.%s",
+ PathMedPriv,Media.Name,Med_Extensions[Med_JPG]);
+ unlink (FullPathMediaPriv);
- /***** Remove private PNG file *****/
- snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
- "%s/%s.png",
- PathMedPriv,Name);
- unlink (FullPathMediaPriv);
+ break;
+ case Med_GIF:
+ /***** Remove private GIF file *****/
+ snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
+ "%s/%s.%s",
+ PathMedPriv,Media.Name,Med_Extensions[Med_GIF]);
+ unlink (FullPathMediaPriv);
- break;
- case Med_MP4:
- case Med_WEBM:
- case Med_OGG:
- /***** Remove private video file *****/
- snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
- "%s/%s.%s",
- PathMedPriv,Name,Med_Extensions[Type]);
- unlink (FullPathMediaPriv);
+ /***** Remove private PNG file *****/
+ snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
+ "%s/%s.png",
+ PathMedPriv,Media.Name);
+ unlink (FullPathMediaPriv);
- break;
- default:
- break;
+ break;
+ case Med_MP4:
+ case Med_WEBM:
+ case Med_OGG:
+ /***** Remove private video file *****/
+ snprintf (FullPathMediaPriv,sizeof (FullPathMediaPriv),
+ "%s/%s.%s",
+ PathMedPriv,Media.Name,Med_Extensions[Media.Type]);
+ unlink (FullPathMediaPriv);
+
+ break;
+ default:
+ break;
+ }
+ // Public links are removed automatically after a period
}
- // Public links are removed automatically after a period
+ /***** Step 2. Remove entry for this media from database *****/
+ DB_QueryDELETE ("can not remove media",
+ "DELETE FROM media WHERE MedCod=%ld",
+ MedCod);
+
+ /***** Free media *****/
+ Med_MediaDestructor (&Media);
}
/*****************************************************************************/
/************************ Get media type from string *************************/
/*****************************************************************************/
-Med_Type_t Med_GetTypeFromStrInDB (const char *Str)
+static Med_Type_t Med_GetTypeFromStrInDB (const char *Str)
{
Med_Type_t Type;
@@ -1708,7 +1781,7 @@ static Med_Type_t Med_GetTypeFromExtAndMIME (const char *Extension,
/*************** Get string media type in database from type *****************/
/*****************************************************************************/
-const char *Med_GetStringTypeForDB (Med_Type_t Type)
+static const char *Med_GetStringTypeForDB (Med_Type_t Type)
{
/***** Check if type is out of valid range *****/
if (Type > (Med_Type_t) (Med_NUM_TYPES - 1))
diff --git a/swad_media.h b/swad_media.h
index f0a7ed5d..b2f3b3ad 100644
--- a/swad_media.h
+++ b/swad_media.h
@@ -58,7 +58,7 @@ typedef enum
No file Original file Temporary Definitive Name of the image/video
uploaded uploaded by user processed file processed file stored in database
--------- --------------------------- ------------------ ------------------ ---------------------
-Med_STATUS_NONE Med_PROCESSED Med_NAME_STORED_IN_DB
+Med_STATUS_NONE Med_PROCESSED Med_MOVED Med_NAME_STORED_IN_DB
--------- --------------------------- ------------------ ------------------ ---------------------
upload-file process file move file insert in database
--------- --------------------------- ------------------ ------------------ ---------------------
@@ -82,6 +82,7 @@ typedef enum
{
Med_STATUS_NONE,
Med_PROCESSED,
+ Med_MOVED,
Med_STORED_IN_DB,
} Med_Status_t;
@@ -100,6 +101,7 @@ typedef enum
/***** Struct used to get images/videos from forms *****/
struct Media
{
+ long MedCod;
Med_Action_t Action;
Med_Status_t Status;
char Name[Med_BYTES_NAME + 1];
@@ -135,11 +137,7 @@ void Med_MediaConstructor (struct Media *Media);
void Med_MediaDestructor (struct Media *Media);
void Med_ResetMedia (struct Media *Media);
-void Med_GetMediaDataFromRow (const char *Name,
- const char *TypeStr,
- const char *Title,
- const char *URL,
- struct Media *Media);
+void Med_GetMediaDataByCod (struct Media *Media);
void Med_PutMediaUploader (int NumMediaInForm,const char *ClassInput);
void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media,
@@ -148,14 +146,13 @@ void Med_GetMediaFromForm (int NumMediaInForm,struct Media *Media,
void Med_SetParamNames (struct ParamUploadMedia *ParamUploadMedia,int NumMediaInForm);
void Med_MoveMediaToDefinitiveDir (struct Media *Media);
+void Med_StoreMediaInDB (struct Media *Media);
+
void Med_ShowMedia (struct Media *Media,
const char *ClassContainer,const char *ClassMedia);
-void Med_RemoveMediaFilesFromAllRows (unsigned NumMedia,MYSQL_RES *mysql_res);
-void Med_RemoveMediaFilesFromRow (MYSQL_RES *mysql_res);
-void Med_RemoveMediaFiles (const char *Name,Med_Type_t Type);
-
-Med_Type_t Med_GetTypeFromStrInDB (const char *Str);
-const char *Med_GetStringTypeForDB (Med_Type_t Type);
+void Med_RemoveMediaFromAllRows (unsigned NumMedia,MYSQL_RES *mysql_res);
+void Med_RemoveMediaFromRow (MYSQL_RES *mysql_res);
+void Med_RemoveMedia (long MedCod);
#endif
diff --git a/swad_message.c b/swad_message.c
index 0b348aeb..13f08d7b 100644
--- a/swad_message.c
+++ b/swad_message.c
@@ -1282,25 +1282,26 @@ static long Msg_InsertNewMsg (const char *Subject,const char *Content,
long MsgCod;
/***** Check if image is received and processed *****/
+ Media->MedCod = -1L;
if (Media->Action == Med_ACTION_NEW_MEDIA && // New media
Media->Status == Med_PROCESSED) // The new media received has been processed
+ {
/* Move processed image to definitive directory */
Med_MoveMediaToDefinitiveDir (Media);
+ /* Store media in database */
+ if (Media->Status == Med_MOVED)
+ Med_StoreMediaInDB (Media); // Set Media->MedCod
+ }
+
/***** Insert message subject and content in the database *****/
MsgCod =
DB_QueryINSERTandReturnCode ("can not create message",
"INSERT INTO msg_content"
- " (Subject,Content,"
- "MediaName,MediaType,MediaTitle,MediaURL)"
+ " (Subject,Content,MedCod)"
" VALUES"
- " ('%s','%s',"
- "'%s','%s','%s','%s')",
- Subject,Content,
- Media->Name,
- Med_GetStringTypeForDB (Media->Type),
- Media->Title ? Media->Title : "",
- Media->URL ? Media->URL : "");
+ " ('%s','%s',%ld)",
+ Subject,Content,Media->MedCod);
/***** Insert message in sent messages *****/
DB_QueryINSERT ("can not create message",
@@ -1493,10 +1494,8 @@ static void Msg_MoveMsgContentToDeleted (long MsgCod)
/* Insert message content into msg_content_deleted */
DB_QueryINSERT ("can not remove the content of a message",
"INSERT IGNORE INTO msg_content_deleted"
- " (MsgCod,Subject,Content,"
- "MediaName,MediaType,MediaTitle,MediaURL)"
- " SELECT MsgCod,Subject,Content,"
- "MediaName,MediaType,MediaTitle,MediaURL"
+ " (MsgCod,Subject,Content,MedCod)"
+ " SELECT MsgCod,Subject,Content,MedCod"
" FROM msg_content WHERE MsgCod=%ld",
MsgCod);
@@ -2788,10 +2787,7 @@ static void Msg_GetMsgContent (long MsgCod,char Content[Cns_MAX_BYTES_LONG_TEXT
/***** Get content of message from database *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get the content of a message",
"SELECT Content," // row[0]
- "MediaName," // row[1]
- "MediaType," // row[2]
- "MediaTitle," // row[3]
- "MediaURL" // row[4]
+ "MedCod" // row[1]
" FROM msg_content WHERE MsgCod=%ld",
MsgCod);
@@ -2806,8 +2802,9 @@ static void Msg_GetMsgContent (long MsgCod,char Content[Cns_MAX_BYTES_LONG_TEXT
Str_Copy (Content,row[0],
Cns_MAX_BYTES_LONG_TEXT);
- /****** Get media data (row[1], row[2], row[3], row[4]) *****/
- Med_GetMediaDataFromRow (row[1],row[2],row[3],row[4],Media);
+ /***** Get media (row[1]) *****/
+ Media->MedCod = Str_ConvertStrCodToLongCod (row[1]);
+ Med_GetMediaDataByCod (Media);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
diff --git a/swad_test.c b/swad_test.c
index 56abb729..fc9801ac 100644
--- a/swad_test.c
+++ b/swad_test.c
@@ -155,6 +155,11 @@ static Tst_Status_t Tst_GetTstStatus (unsigned NumTst);
static unsigned Tst_GetNumAccessesTst (void);
static void Tst_ShowTestQuestionsWhenSeeing (MYSQL_RES *mysql_res);
static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank,double *TotalScore);
+static void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
+ struct UsrData *UsrDat,
+ struct Game *Game,
+ unsigned NumQst,long QstCod,MYSQL_ROW row,
+ double *ScoreThisQst,bool *AnswerIsNotBlank);
static void Tst_PutFormToEditQstMedia (struct Media *Media,int NumMediaInForm,
const char *ClassContainer,
const char *ClassMedia,
@@ -683,8 +688,8 @@ static bool Tst_CheckIfNextTstAllowed (void)
/***** Get date of next allowed access to test from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get last access to test",
"SELECT UNIX_TIMESTAMP(LastAccTst+INTERVAL (NumQstsLastTst*%lu) SECOND)-"
- "UNIX_TIMESTAMP(),"
- "UNIX_TIMESTAMP(LastAccTst+INTERVAL (NumQstsLastTst*%lu) SECOND)"
+ "UNIX_TIMESTAMP()," // row[0]
+ "UNIX_TIMESTAMP(LastAccTst+INTERVAL (NumQstsLastTst*%lu) SECOND)" // row[1]
" FROM crs_usr"
" WHERE CrsCod=%ld AND UsrCod=%ld",
Gbl.Test.Config.MinTimeNxtTstPerQst,
@@ -758,7 +763,8 @@ static Tst_Status_t Tst_GetTstStatus (unsigned NumTst)
/***** Get status of test from database *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get status of test",
- "SELECT Status FROM tst_status"
+ "SELECT Status" // row[0]
+ " FROM tst_status"
" WHERE SessionId='%s'"
" AND CrsCod=%ld"
" AND NumTst=%u",
@@ -795,7 +801,8 @@ static unsigned Tst_GetNumAccessesTst (void)
{
/***** Get number of hits to test from database *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get number of hits to test",
- "SELECT NumAccTst FROM crs_usr"
+ "SELECT NumAccTst" // row[0]
+ " FROM crs_usr"
" WHERE CrsCod=%ld AND UsrCod=%ld",
Gbl.CurrentCrs.Crs.CrsCod,
Gbl.Usrs.Me.UsrDat.UsrCod);
@@ -834,6 +841,18 @@ static void Tst_ShowTestQuestionsWhenSeeing (MYSQL_RES *mysql_res)
MYSQL_ROW row;
double ScoreThisQst; // Not used here
bool AnswerIsNotBlank; // Not used here
+ /*
+ row[0] QstCod
+ row[1] UNIX_TIMESTAMP(EditTime)
+ row[2] AnsType
+ row[3] Shuffle
+ row[4] Stem
+ row[5] Feedback
+ row[6] MedCod
+ row[7] NumHits
+ row[8] NumHitsNotBlank
+ row[9] Score
+ */
/***** Write rows *****/
for (NumQst = 0;
@@ -872,7 +891,8 @@ static void Tst_ShowTstTagsPresentInATestResult (long TstCod)
/***** Get all tags of questions in this test *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get tags"
" present in a test result",
- "SELECT tst_tags.TagTxt FROM"
+ "SELECT tst_tags.TagTxt" // row[0]
+ " FROM"
" (SELECT DISTINCT(tst_question_tags.TagCod)"
" FROM tst_question_tags,tst_exam_questions"
" WHERE tst_exam_questions.TstCod=%ld"
@@ -933,19 +953,16 @@ static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank
/***** Get row of the result of the query *****/
row = mysql_fetch_row (mysql_res);
/*
- row[ 0] QstCod
- row[ 1] UNIX_TIMESTAMP(EditTime)
- row[ 2] AnsType
- row[ 3] Shuffle
- row[ 4] Stem
- row[ 5] Feedback
- row[ 6] MediaName
- row[ 7] MediaType
- row[ 8] MediaTitle
- row[ 9] MediaURL
- row[10] NumHits
- row[11] NumHitsNotBlank
- row[12] Score
+ row[0] QstCod
+ row[1] UNIX_TIMESTAMP(EditTime)
+ row[2] AnsType
+ row[3] Shuffle
+ row[4] Stem
+ row[5] Feedback
+ row[6] MedCod
+ row[7] NumHits
+ row[8] NumHitsNotBlank
+ row[9] Score
*/
/***** Get the code of question (row[0]) *****/
@@ -994,27 +1011,24 @@ static void Tst_ShowTestResultAfterAssess (long TstCod,unsigned *NumQstsNotBlank
/********** Write a row of a test, with one question and its answer **********/
/*****************************************************************************/
-void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
- struct UsrData *UsrDat,
- struct Game *Game,
- unsigned NumQst,long QstCod,MYSQL_ROW row,
- double *ScoreThisQst,bool *AnswerIsNotBlank)
+static void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
+ struct UsrData *UsrDat,
+ struct Game *Game,
+ unsigned NumQst,long QstCod,MYSQL_ROW row,
+ double *ScoreThisQst,bool *AnswerIsNotBlank)
{
extern const char *Txt_TST_STR_ANSWER_TYPES[Tst_NUM_ANS_TYPES];
/*
- row[ 0] QstCod
- row[ 1] UNIX_TIMESTAMP(EditTime)
- row[ 2] AnsType
- row[ 3] Shuffle
- row[ 4] Stem
- row[ 5] Feedback
- row[ 6] MediaName
- row[ 7] MediaType
- row[ 8] MediaTitle
- row[ 9] MediaURL
- row[10] NumHits
- row[11] NumHitsNotBlank
- row[12] Score
+ row[0] QstCod
+ row[1] UNIX_TIMESTAMP(EditTime)
+ row[2] AnsType
+ row[3] Shuffle
+ row[4] Stem
+ row[5] Feedback
+ row[6] MedCod
+ row[7] NumHits
+ row[8] NumHitsNotBlank
+ row[9] Score
*/
/***** Create test question *****/
@@ -1034,16 +1048,19 @@ void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestio
"
",
Txt_TST_STR_ANSWER_TYPES[Gbl.Test.AnswerType]);
- /***** Write stem (row[4]), media data (row[6], row[7], row[8], row[9]),
- answers depending on shuffle (row[3]) and feedback (row[5]) *****/
+ /***** Write stem (row[4]) *****/
fprintf (Gbl.F.Out,"",
Gbl.RowEvenOdd);
Tst_WriteQstStem (row[4],"TEST_EXA");
- Med_GetMediaDataFromRow (row[6],row[7],row[8],row[9],&Gbl.Test.Media);
+
+ /***** Get and show media (row[6]) *****/
+ Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[6]);
+ Med_GetMediaDataByCod (&Gbl.Test.Media);
Med_ShowMedia (&Gbl.Test.Media,
"TEST_IMG_SHOW_STEM_CONTAINER",
"TEST_IMG_SHOW_STEM");
+ /***** Write answers depending on shuffle (row[3]) and feedback (row[5]) *****/
switch (ActionToDoWithQuestions)
{
case Tst_SHOW_TEST_TO_ANSWER:
@@ -1639,7 +1656,10 @@ static unsigned long Tst_GetAllTagsFromCurrentCrs (MYSQL_RES **mysql_res)
{
/***** Get available tags from database *****/
return DB_QuerySELECT (mysql_res,"can not get available tags",
- "SELECT TagCod,TagTxt,TagHidden FROM tst_tags"
+ "SELECT TagCod," // row[0]
+ "TagTxt," // row[1]
+ "TagHidden" // row[2]
+ " FROM tst_tags"
" WHERE CrsCod=%ld"
" ORDER BY TagTxt",
Gbl.CurrentCrs.Crs.CrsCod);
@@ -1677,6 +1697,11 @@ static void Tst_ShowFormSelTags (unsigned long NumRows,MYSQL_RES *mysql_res,
bool TagHidden = false;
const char *Ptr;
char TagText[Tst_MAX_BYTES_TAG + 1];
+ /*
+ row[0] TagCod
+ row[1] TagTxt
+ row[2] TagHidden
+ */
/***** Label *****/
fprintf (Gbl.F.Out," "
@@ -1785,6 +1810,11 @@ static void Tst_ShowFormEditTags (void)
NumRow++)
{
row = mysql_fetch_row (mysql_res);
+ /*
+ row[0] TagCod
+ row[1] TagTxt
+ row[2] TagHidden
+ */
if ((TagCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
Lay_ShowErrorAndExit ("Wrong code of tag.");
@@ -2126,7 +2156,9 @@ bool Tst_CheckIfCourseHaveTestsAndPluggableIsUnknown (void)
/***** Get pluggability of tests for current course from database *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get configuration of test",
- "SELECT Pluggable FROM tst_config WHERE CrsCod=%ld",
+ "SELECT Pluggable" // row[0]
+ " FROM tst_config"
+ " WHERE CrsCod=%ld",
Gbl.CurrentCrs.Crs.CrsCod);
if (NumRows == 0)
@@ -2446,19 +2478,16 @@ static unsigned long Tst_GetQuestions (MYSQL_RES **mysql_res)
/***** Select questions *****/
/* Start query */
snprintf (Query,Tst_MAX_BYTES_QUERY_TEST + 1,
- "SELECT tst_questions.QstCod," // row[ 0]
- "UNIX_TIMESTAMP(tst_questions.EditTime) AS F," // row[ 1]
- "tst_questions.AnsType," // row[ 2]
- "tst_questions.Shuffle," // row[ 3]
- "tst_questions.Stem," // row[ 4]
- "tst_questions.Feedback," // row[ 5]
- "tst_questions.MediaName," // row[ 6]
- "tst_questions.MediaType," // row[ 7]
- "tst_questions.MediaTitle," // row[ 8]
- "tst_questions.MediaURL," // row[ 9]
- "tst_questions.NumHits," // row[10]
- "tst_questions.NumHitsNotBlank," // row[11]
- "tst_questions.Score" // row[12]
+ "SELECT tst_questions.QstCod," // row[0]
+ "UNIX_TIMESTAMP(tst_questions.EditTime)," // row[1]
+ "tst_questions.AnsType," // row[2]
+ "tst_questions.Shuffle," // row[3]
+ "tst_questions.Stem," // row[4]
+ "tst_questions.Feedback," // row[5]
+ "tst_questions.MedCod," // row[6]
+ "tst_questions.NumHits," // row[7]
+ "tst_questions.NumHitsNotBlank," // row[8]
+ "tst_questions.Score" // row[9]
" FROM tst_questions");
if (!Gbl.Test.Tags.All)
Str_Concat (Query,",tst_question_tags,tst_tags",
@@ -2619,19 +2648,16 @@ static unsigned long Tst_GetQuestionsForTest (MYSQL_RES **mysql_res)
// Select only questions with tags
// DISTINCTROW is necessary to not repeat questions
snprintf (Query,Tst_MAX_BYTES_QUERY_TEST + 1,
- "SELECT DISTINCTROW tst_questions.QstCod," // row[ 0]
- "UNIX_TIMESTAMP(tst_questions.EditTime)," // row[ 1]
- "tst_questions.AnsType," // row[ 2]
- "tst_questions.Shuffle," // row[ 3]
- "tst_questions.Stem," // row[ 4]
- "tst_questions.Feedback," // row[ 5]
- "tst_questions.MediaName," // row[ 6]
- "tst_questions.MediaType," // row[ 7]
- "tst_questions.MediaTitle," // row[ 8]
- "tst_questions.MediaURL," // row[ 9]
- "tst_questions.NumHits," // row[10]
- "tst_questions.NumHitsNotBlank," // row[11]
- "tst_questions.Score" // row[12]
+ "SELECT DISTINCTROW tst_questions.QstCod," // row[0]
+ "UNIX_TIMESTAMP(tst_questions.EditTime)," // row[1]
+ "tst_questions.AnsType," // row[2]
+ "tst_questions.Shuffle," // row[3]
+ "tst_questions.Stem," // row[4]
+ "tst_questions.Feedback," // row[5]
+ "tst_questions.MedCod," // row[6]
+ "tst_questions.NumHits," // row[7]
+ "tst_questions.NumHitsNotBlank," // row[8]
+ "tst_questions.Score" // row[9]
" FROM tst_questions,tst_question_tags,tst_tags"
" WHERE tst_questions.CrsCod=%ld"
" AND tst_questions.QstCod NOT IN"
@@ -2745,19 +2771,16 @@ bool Tst_GetOneQuestionByCod (long QstCod,MYSQL_RES **mysql_res)
{
/***** Get data of a question from database *****/
return (DB_QuerySELECT (mysql_res,"can not get data of a question",
- "SELECT QstCod," // row[ 0]
- "UNIX_TIMESTAMP(EditTime)," // row[ 1]
- "AnsType," // row[ 2]
- "Shuffle," // row[ 3]
- "Stem," // row[ 4]
- "Feedback," // row[ 5]
- "MediaName," // row[ 6]
- "MediaType," // row[ 7]
- "MediaTitle," // row[ 8]
- "MediaURL," // row[ 9]
- "NumHits," // row[10]
- "NumHitsNotBlank," // row[11]
- "Score" // row[12]
+ "SELECT QstCod," // row[0]
+ "UNIX_TIMESTAMP(EditTime)," // row[1]
+ "AnsType," // row[2]
+ "Shuffle," // row[3]
+ "Stem," // row[4]
+ "Feedback," // row[5]
+ "MedCod," // row[6]
+ "NumHits," // row[7]
+ "NumHitsNotBlank," // row[8]
+ "Score" // row[9]
" FROM tst_questions"
" WHERE QstCod=%ld",
QstCod) == 1);
@@ -2859,19 +2882,16 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows,
row = mysql_fetch_row (mysql_res);
/*
- row[ 0] QstCod
- row[ 1] UNIX_TIMESTAMP(EditTime)
- row[ 2] AnsType
- row[ 3] Shuffle
- row[ 4] Stem
- row[ 5] Feedback
- row[ 6] MediaName
- row[ 7] MediaType
- row[ 8] MediaTitle
- row[ 9] MediaURL
- row[10] NumHits
- row[11] NumHitsNotBlank
- row[12] Score
+ row[0] QstCod
+ row[1] UNIX_TIMESTAMP(EditTime)
+ row[2] AnsType
+ row[3] Shuffle
+ row[4] Stem
+ row[5] Feedback
+ row[6] MedCod
+ row[7] NumHits
+ row[8] NumHitsNotBlank
+ row[9] Score
*/
/***** Create test question *****/
Tst_QstConstructor ();
@@ -2958,34 +2978,38 @@ static void Tst_ListOneOrMoreQuestionsForEdition (unsigned long NumRows,
}
fprintf (Gbl.F.Out,"");
- /* Write stem (row[4]), media data (row[6], row[7], row[8], row[9]),
- feedback (row[5]) and answers */
+ /* Write stem (row[4]) */
fprintf (Gbl.F.Out,"",
Gbl.RowEvenOdd);
Tst_WriteQstStem (row[4],"TEST_EDI");
- Med_GetMediaDataFromRow (row[6],row[7],row[8],row[9],&Gbl.Test.Media);
+
+ /***** Get and show media (row[6]) *****/
+ Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[6]);
+ Med_GetMediaDataByCod (&Gbl.Test.Media);
Med_ShowMedia (&Gbl.Test.Media,
"TEST_IMG_EDIT_LIST_STEM_CONTAINER",
"TEST_IMG_EDIT_LIST_STEM");
+
+ /* Write feedback (row[5]) and answers */
Tst_WriteQstFeedback (row[5],"TEST_EDI_LIGHT");
Tst_WriteAnswersEdit (Gbl.Test.QstCod);
fprintf (Gbl.F.Out," ");
/* Get number of hits
(number of times that the question has been answered,
- including blank answers) (row[10]) */
- if (sscanf (row[10],"%lu",&NumHitsThisQst) != 1)
+ including blank answers) (row[7]) */
+ if (sscanf (row[7],"%lu",&NumHitsThisQst) != 1)
Lay_ShowErrorAndExit ("Wrong number of hits to a question.");
/* Get number of hits not blank
(number of times that the question has been answered
- with a not blank answer) (row[11]) */
- if (sscanf (row[11],"%lu",&NumHitsNotBlankThisQst) != 1)
+ with a not blank answer) (row[8]) */
+ if (sscanf (row[8],"%lu",&NumHitsNotBlankThisQst) != 1)
Lay_ShowErrorAndExit ("Wrong number of hits not blank to a question.");
- /* Get the acumulated score of the question (row[12]) */
+ /* Get the acumulated score of the question (row[9]) */
Str_SetDecimalPointToUS (); // To get the decimal point as a dot
- if (sscanf (row[12],"%lf",&TotalScoreThisQst) != 1)
+ if (sscanf (row[9],"%lf",&TotalScoreThisQst) != 1)
Lay_ShowErrorAndExit ("Wrong score of a question.");
Str_SetDecimalPointToLocal (); // Return to local system
@@ -3113,19 +3137,16 @@ static void Tst_ListOneOrMoreQuestionsForSelection (long GamCod,
row = mysql_fetch_row (mysql_res);
/*
- row[ 0] QstCod
- row[ 1] UNIX_TIMESTAMP(EditTime)
- row[ 2] AnsType
- row[ 3] Shuffle
- row[ 4] Stem
- row[ 5] Feedback
- row[ 6] MediaName
- row[ 7] MediaType
- row[ 8] MediaTitle
- row[ 9] MediaURL
- row[10] NumHits
- row[11] NumHitsNotBlank
- row[12] Score
+ row[0] QstCod
+ row[1] UNIX_TIMESTAMP(EditTime)
+ row[2] AnsType
+ row[3] Shuffle
+ row[4] Stem
+ row[5] Feedback
+ row[6] MedCod
+ row[7] NumHits
+ row[8] NumHitsNotBlank
+ row[9] Score
*/
/***** Create test question *****/
Tst_QstConstructor ();
@@ -3193,16 +3214,22 @@ static void Tst_ListOneOrMoreQuestionsForSelection (long GamCod,
fprintf (Gbl.F.Out,"");
- /* Write stem (row[4]), media data (row[6], row[7], row[8], row[9]),
- feedback (row[5]) and answers */
+ /* Write stem (row[4]) */
fprintf (Gbl.F.Out,"",
Gbl.RowEvenOdd);
Tst_WriteQstStem (row[4],"TEST_EDI");
- Med_GetMediaDataFromRow (row[6],row[7],row[8],row[9],&Gbl.Test.Media);
+
+ /***** Get and show media (row[6]) *****/
+ Gbl.Test.Media.MedCod = Str_ConvertStrCodToLongCod (row[6]);
+ Med_GetMediaDataByCod (&Gbl.Test.Media);
Med_ShowMedia (&Gbl.Test.Media,
"TEST_IMG_EDIT_LIST_STEM_CONTAINER",
"TEST_IMG_EDIT_LIST_STEM");
+
+ /* Write feedback (row[5]) */
Tst_WriteQstFeedback (row[5],"TEST_EDI_LIGHT");
+
+ /* Write answers */
Tst_WriteAnswersEdit (Gbl.Test.QstCod);
fprintf (Gbl.F.Out," "
" ");
@@ -3255,11 +3282,8 @@ unsigned Tst_GetAnswersQst (long QstCod,MYSQL_RES **mysql_res,bool Shuffle)
"SELECT AnsInd," // row[0]
"Answer," // row[1]
"Feedback," // row[2]
- "MediaName," // row[3]
- "MediaType," // row[4]
- "MediaTitle," // row[5]
- "MediaURL," // row[6]
- "Correct" // row[7]
+ "MedCod," // row[3]
+ "Correct" // row[4]
" FROM tst_answers WHERE QstCod=%ld ORDER BY %s",
QstCod,
Shuffle ? "RAND(NOW())" :
@@ -3292,11 +3316,8 @@ static void Tst_WriteAnswersEdit (long QstCod)
row[0] AnsInd
row[1] Answer
row[2] Feedback
- row[3] MediaName
- row[4] MediaType
- row[5] MediaTitle
- row[6] MediaURL
- row[7] Correct
+ row[3] MedCod
+ row[4] Correct
*/
/***** Write the answers *****/
switch (Gbl.Test.AnswerType)
@@ -3362,15 +3383,16 @@ static void Tst_WriteAnswersEdit (long QstCod)
Feedback,LengthFeedback,false);
}
- /* Get media data (row[3], row[4], row[5], row[6]) */
- Med_GetMediaDataFromRow (row[3],row[4],row[5],row[6],
- &Gbl.Test.Answer.Options[NumOpt].Media);
+ /* Get media (row[3]) */
+ Gbl.Test.Answer.Options[NumOpt].Media.MedCod = Str_ConvertStrCodToLongCod (row[3]);
+ Med_GetMediaDataByCod (&Gbl.Test.Answer.Options[NumOpt].Media);
- /* Put an icon that indicates whether the answer is correct or wrong */
+ /* Put an icon that indicates whether the answer
+ is correct or wrong (row[4]) */
fprintf (Gbl.F.Out,""
"",
Gbl.RowEvenOdd);
- if (row[7][0] == 'Y')
+ if (row[4][0] == 'Y')
fprintf (Gbl.F.Out," ",
@@ -3467,11 +3489,8 @@ static void Tst_WriteAnswersTestResult (struct UsrData *UsrDat,
row[0] AnsInd
row[1] Answer
row[2] Feedback
- row[3] MediaName
- row[4] MediaType
- row[5] MediaTitle
- row[6] MediaURL
- row[7] Correct
+ row[3] MedCod
+ row[4] Correct
*/
/***** Write answer depending on type *****/
switch (Gbl.Test.AnswerType)
@@ -3585,11 +3604,8 @@ static void Tst_WriteTFAnsAssessTest (struct UsrData *UsrDat,
row[0] AnsInd
row[1] Answer
row[2] Feedback
- row[3] MediaName
- row[4] MediaType
- row[5] MediaTitle
- row[6] MediaURL
- row[7] Correct
+ row[3] MedCod
+ row[4] Correct
*/
/***** Check if number of rows is correct *****/
Tst_CheckIfNumberOfAnswersIsOne ();
@@ -3677,11 +3693,8 @@ static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,bool Shuffle
row[0] AnsInd
row[1] Answer
row[2] Feedback
- row[3] MediaName
- row[4] MediaType
- row[5] MediaTitle
- row[6] MediaURL
- row[7] Correct
+ row[3] MedCod
+ row[4] Correct
*/
/***** Start table *****/
@@ -3719,9 +3732,9 @@ static void Tst_WriteChoiceAnsViewTest (unsigned NumQst,long QstCod,bool Shuffle
Gbl.Test.Answer.Options[NumOpt].Text,
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
- /***** Get media data (row[3], row[4], row[5], row[6]) *****/
- Med_GetMediaDataFromRow (row[3],row[4],row[5],row[6],
- &Gbl.Test.Answer.Options[NumOpt].Media);
+ /***** Get media (row[3]) *****/
+ Gbl.Test.Answer.Options[NumOpt].Media.MedCod = Str_ConvertStrCodToLongCod (row[3]);
+ Med_GetMediaDataByCod (&Gbl.Test.Answer.Options[NumOpt].Media);
/***** Write selectors and letter of this option *****/
fprintf (Gbl.F.Out," "
@@ -3803,11 +3816,8 @@ static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat,
row[0] AnsInd
row[1] Answer
row[2] Feedback
- row[3] MediaName
- row[4] MediaType
- row[5] MediaTitle
- row[6] MediaURL
- row[7] Correct
+ row[3] MedCod
+ row[4] Correct
*/
for (NumOpt = 0;
NumOpt < Gbl.Test.Answer.NumOptions;
@@ -3842,12 +3852,12 @@ static void Tst_WriteChoiceAnsAssessTest (struct UsrData *UsrDat,
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
}
- /***** Get media data (row[3], row[4], row[5], row[6]) *****/
- Med_GetMediaDataFromRow (row[3],row[4],row[5],row[6],
- &Gbl.Test.Answer.Options[NumOpt].Media);
+ /***** Get media (row[3]) *****/
+ Gbl.Test.Answer.Options[NumOpt].Media.MedCod = Str_ConvertStrCodToLongCod (row[3]);
+ Med_GetMediaDataByCod (&Gbl.Test.Answer.Options[NumOpt].Media);
- /***** Assign correctness (row[7]) of this answer (this option) *****/
- Gbl.Test.Answer.Options[NumOpt].Correct = (row[7][0] == 'Y');
+ /***** Assign correctness (row[4]) of this answer (this option) *****/
+ Gbl.Test.Answer.Options[NumOpt].Correct = (row[4][0] == 'Y');
}
/***** Get indexes for this question from string *****/
@@ -4050,11 +4060,8 @@ static void Tst_WriteChoiceAnsViewGame (struct Game *Game,
row[0] AnsInd
row[1] Answer
row[2] Feedback
- row[3] MediaName
- row[4] MediaType
- row[5] MediaTitle
- row[6] MediaURL
- row[7] Correct
+ row[3] MedCod
+ row[4] Correct
*/
/***** Start table *****/
@@ -4092,9 +4099,9 @@ static void Tst_WriteChoiceAnsViewGame (struct Game *Game,
Gbl.Test.Answer.Options[NumOpt].Text,
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
- /***** Get media data (row[3], row[4], row[5], row[6]) *****/
- Med_GetMediaDataFromRow (row[3],row[4],row[5],row[6],
- &Gbl.Test.Answer.Options[NumOpt].Media);
+ /***** Get media (row[3]) *****/
+ Gbl.Test.Answer.Options[NumOpt].Media.MedCod = Str_ConvertStrCodToLongCod (row[3]);
+ Med_GetMediaDataByCod (&Gbl.Test.Answer.Options[NumOpt].Media);
/***** Write letter of this option *****/
fprintf (Gbl.F.Out," "
@@ -4168,11 +4175,8 @@ static void Tst_WriteTextAnsAssessTest (struct UsrData *UsrDat,
row[0] AnsInd
row[1] Answer
row[2] Feedback
- row[3] MediaName
- row[4] MediaType
- row[5] MediaTitle
- row[6] MediaURL
- row[7] Correct
+ row[3] MedCod
+ row[4] Correct
*/
/***** Get text and correctness of answers for this question from database (one row per answer) *****/
for (NumOpt = 0;
@@ -4206,8 +4210,8 @@ static void Tst_WriteTextAnsAssessTest (struct UsrData *UsrDat,
Tst_MAX_BYTES_ANSWER_OR_FEEDBACK,false);
}
- /***** Assign correctness (row[7]) of this answer (this option) *****/
- Gbl.Test.Answer.Options[NumOpt].Correct = (row[7][0] == 'Y');
+ /***** Assign correctness (row[4]) of this answer (this option) *****/
+ Gbl.Test.Answer.Options[NumOpt].Correct = (row[4][0] == 'Y');
}
/***** Header with the title of each column *****/
@@ -4362,11 +4366,8 @@ static void Tst_WriteIntAnsAssessTest (struct UsrData *UsrDat,
row[0] AnsInd
row[1] Answer
row[2] Feedback
- row[3] MediaName
- row[4] MediaType
- row[5] MediaTitle
- row[6] MediaURL
- row[7] Correct
+ row[3] MedCod
+ row[4] Correct
*/
/***** Check if number of rows is correct *****/
Tst_CheckIfNumberOfAnswersIsOne ();
@@ -4478,11 +4479,8 @@ static void Tst_WriteFloatAnsAssessTest (struct UsrData *UsrDat,
row[0] AnsInd
row[1] Answer
row[2] Feedback
- row[3] MediaName
- row[4] MediaType
- row[5] MediaTitle
- row[6] MediaURL
- row[7] Correct
+ row[3] MedCod
+ row[4] Correct
*/
/***** Check if number of rows is correct *****/
if (Gbl.Test.Answer.NumOptions != 2)
@@ -5010,7 +5008,11 @@ static void Tst_PutFormEditOneQst (char Stem[Cns_MAX_BYTES_TEXT + 1],
NumRow++)
{
row = mysql_fetch_row (mysql_res);
-
+ /*
+ row[0] TagCod
+ row[1] TagTxt
+ row[2] TagHidden
+ */
fprintf (Gbl.F.Out," image associated to stem
// NumOpt >= 0 ==> image associated to answer
@@ -5652,29 +5649,24 @@ static void Tst_GetMediaFromDB (int NumOpt,struct Media *Media)
/***** Query depending on NumOpt *****/
if (NumOpt < 0)
// Get image associated to stem
- DB_QuerySELECT (&mysql_res,"can not get image name",
- "SELECT MediaName," // row[0]
- "MediaType," // row[1]
- "MediaTitle," // row[2]
- "MediaURL" // row[3]
+ DB_QuerySELECT (&mysql_res,"can not get media",
+ "SELECT MedCod" // row[0]
" FROM tst_questions"
" WHERE QstCod=%ld AND CrsCod=%ld",
Gbl.Test.QstCod,Gbl.CurrentCrs.Crs.CrsCod);
else
// Get image associated to answer
- DB_QuerySELECT (&mysql_res,"can not get image name",
- "SELECT MediaName," // row[0]
- "MediaType," // row[1]
- "MediaTitle," // row[2]
- "MediaURL" // row[3]
+ DB_QuerySELECT (&mysql_res,"can not get media",
+ "SELECT MedCod" // row[0]
" FROM tst_answers"
" WHERE QstCod=%ld AND AnsInd=%u",
Gbl.Test.QstCod,(unsigned) NumOpt);
row = mysql_fetch_row (mysql_res);
- /***** Get media data (row[0], row[1], row[2], row[3]) *****/
- Med_GetMediaDataFromRow (row[0],row[1],row[2],row[3],Media);
+ /***** Get media (row[0]) *****/
+ Media->MedCod = Str_ConvertStrCodToLongCod (row[0]);
+ Med_GetMediaDataByCod (Media);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@@ -6152,11 +6144,18 @@ static void Tst_MoveMediaToDefinitiveDirectories (void)
and moved to the definitive directory) */
Tst_RemoveMedFileFromStemOfQst (Gbl.CurrentCrs.Crs.CrsCod,Gbl.Test.QstCod);
+ Gbl.Test.Media.MedCod = -1L;
if (Gbl.Test.Media.Action == Med_ACTION_NEW_MEDIA && // New media
Gbl.Test.Media.Status == Med_PROCESSED) // The new media received has been processed
+ {
/* Move processed image to definitive directory */
Med_MoveMediaToDefinitiveDir (&Gbl.Test.Media);
+ /* Store media in database */
+ if (Gbl.Test.Media.Status == Med_MOVED)
+ Med_StoreMediaInDB (&Gbl.Test.Media); // Set Gbl.Test.Media.MedCod
+ }
+
/****** Move images associated to answers *****/
if (Gbl.Test.AnswerType == Tst_ANS_UNIQUE_CHOICE ||
Gbl.Test.AnswerType == Tst_ANS_MULTIPLE_CHOICE)
@@ -6171,10 +6170,17 @@ static void Tst_MoveMediaToDefinitiveDirectories (void)
and moved to the definitive directory) */
Tst_RemoveMedFileFromAnsOfQst (Gbl.CurrentCrs.Crs.CrsCod,Gbl.Test.QstCod,NumOpt);
+ Gbl.Test.Answer.Options[NumOpt].Media.MedCod = -1L;
if (Gbl.Test.Answer.Options[NumOpt].Media.Action == Med_ACTION_NEW_MEDIA && // New media
Gbl.Test.Answer.Options[NumOpt].Media.Status == Med_PROCESSED) // The new media received has been processed
+ {
/* Move processed media to definitive directory */
Med_MoveMediaToDefinitiveDir (&Gbl.Test.Answer.Options[NumOpt].Media);
+
+ /* Store media in database */
+ if (Gbl.Test.Media.Status == Med_MOVED)
+ Med_StoreMediaInDB (&Gbl.Test.Answer.Options[NumOpt].Media); // Set Gbl.Test.Answer.Options[NumOpt].Media.MedCod
+ }
}
}
@@ -6506,13 +6512,11 @@ static void Tst_InsertOrUpdateQstIntoDB (void)
DB_QueryINSERTandReturnCode ("can not create question",
"INSERT INTO tst_questions"
" (CrsCod,EditTime,AnsType,Shuffle,"
- "Stem,Feedback,"
- "MediaName,MediaType,MediaTitle,MediaURL,"
+ "Stem,Feedback,MedCod,"
"NumHits,Score)"
" VALUES"
" (%ld,NOW(),'%s','%c',"
- "'%s','%s',"
- "'%s','%s','%s','%s',"
+ "'%s','%s',%ld,"
"0,0)",
Gbl.CurrentCrs.Crs.CrsCod,
Tst_StrAnswerTypesDB[Gbl.Test.AnswerType],
@@ -6520,14 +6524,7 @@ static void Tst_InsertOrUpdateQstIntoDB (void)
'N',
Gbl.Test.Stem.Text,
Gbl.Test.Feedback.Text ? Gbl.Test.Feedback.Text : "",
- Gbl.Test.Media.Name,
- Med_GetStringTypeForDB (Gbl.Test.Media.Type),
- Gbl.Test.Media.Title ? Gbl.Test.Media.Title : "",
- Gbl.Test.Media.URL ? Gbl.Test.Media.URL : "");
-
- /* Update media status */
- if (Gbl.Test.Media.Type != Med_TYPE_NONE)
- Gbl.Test.Media.Status = Med_STORED_IN_DB;
+ Gbl.Test.Media.MedCod);
}
else // It's an existing question
{
@@ -6536,24 +6533,16 @@ static void Tst_InsertOrUpdateQstIntoDB (void)
DB_QueryUPDATE ("can not update question",
"UPDATE tst_questions"
" SET EditTime=NOW(),AnsType='%s',Shuffle='%c',"
- "Stem='%s',Feedback='%s',"
- "MediaName='%s',MediaType='%s',MediaTitle='%s',MediaURL='%s'"
+ "Stem='%s',Feedback='%s',MedCod=%ld"
" WHERE QstCod=%ld AND CrsCod=%ld",
Tst_StrAnswerTypesDB[Gbl.Test.AnswerType],
Gbl.Test.Shuffle ? 'Y' :
'N',
Gbl.Test.Stem.Text,
Gbl.Test.Feedback.Text ? Gbl.Test.Feedback.Text : "",
- Gbl.Test.Media.Name,
- Med_GetStringTypeForDB (Gbl.Test.Media.Type),
- Gbl.Test.Media.Title ? Gbl.Test.Media.Title : "",
- Gbl.Test.Media.URL ? Gbl.Test.Media.URL : "",
+ Gbl.Test.Media.MedCod,
Gbl.Test.QstCod,Gbl.CurrentCrs.Crs.CrsCod);
- /* Update media status */
- if (Gbl.Test.Media.Type != Med_TYPE_NONE)
- Gbl.Test.Media.Status = Med_STORED_IN_DB;
-
/* Remove answers and tags from this test question */
Tst_RemAnsFromQst ();
Tst_RemTagsFromQst ();
@@ -6599,32 +6588,20 @@ static void Tst_InsertTagsIntoDB (void)
static void Tst_InsertAnswersIntoDB (void)
{
- char *Query = NULL;
unsigned NumOpt;
unsigned i;
- /***** Allocate space for query *****/
- if ((Query = (char *) malloc (256 +
- Tst_MAX_BYTES_ANSWER_OR_FEEDBACK * 2 +
- Med_BYTES_NAME +
- Med_MAX_BYTES_TITLE +
- Cns_MAX_BYTES_WWW)) == NULL)
- Lay_NotEnoughMemoryExit ();
-
/***** Insert answers in the answers table *****/
switch (Gbl.Test.AnswerType)
{
case Tst_ANS_INT:
DB_QueryINSERT ("can not create answer",
"INSERT INTO tst_answers"
- " (QstCod,AnsInd,Answer,Feedback,"
- "MediaName,MediaType,MediaTitle,MediaURL,Correct)"
+ " (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
" VALUES"
- " (%ld,0,%ld,'',"
- "'','%s','','','Y')",
+ " (%ld,0,%ld,'',-1,'Y')",
Gbl.Test.QstCod,
- Gbl.Test.Answer.Integer,
- Med_GetStringTypeForDB (Med_TYPE_NONE));
+ Gbl.Test.Answer.Integer);
break;
case Tst_ANS_FLOAT:
Str_SetDecimalPointToUS (); // To print the floating point as a dot
@@ -6633,27 +6610,21 @@ static void Tst_InsertAnswersIntoDB (void)
i++)
DB_QueryINSERT ("can not create answer",
"INSERT INTO tst_answers"
- " (QstCod,AnsInd,Answer,Feedback,"
- "MediaName,MediaType,MediaTitle,MediaURL,Correct)"
+ " (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
" VALUES"
- " (%ld,%u,'%lg','',"
- "'','%s','','','Y')",
+ " (%ld,%u,'%lg','',-1,'Y')",
Gbl.Test.QstCod,i,
- Gbl.Test.Answer.FloatingPoint[i],
- Med_GetStringTypeForDB (Med_TYPE_NONE));
+ Gbl.Test.Answer.FloatingPoint[i]);
Str_SetDecimalPointToLocal (); // Return to local system
break;
case Tst_ANS_TRUE_FALSE:
DB_QueryINSERT ("can not create answer",
"INSERT INTO tst_answers"
- " (QstCod,AnsInd,Answer,Feedback,"
- "MediaName,Mediatype,MediaTitle,MediaURL,Correct)"
+ " (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
" VALUES"
- " (%ld,0,'%c','',"
- "'','%s','','','Y')",
+ " (%ld,0,'%c','',-1,'Y')",
Gbl.Test.QstCod,
- Gbl.Test.Answer.TF,
- Med_GetStringTypeForDB (Med_TYPE_NONE));
+ Gbl.Test.Answer.TF);
break;
case Tst_ANS_UNIQUE_CHOICE:
case Tst_ANS_MULTIPLE_CHOICE:
@@ -6665,18 +6636,13 @@ static void Tst_InsertAnswersIntoDB (void)
{
DB_QueryINSERT ("can not create answer",
"INSERT INTO tst_answers"
- " (QstCod,AnsInd,Answer,Feedback,"
- "MediaName,MediaType,MediaTitle,MediaURL,Correct)"
+ " (QstCod,AnsInd,Answer,Feedback,MedCod,Correct)"
" VALUES"
- " (%ld,%u,'%s','%s',"
- "'%s','%s','%s','%s','%c')",
+ " (%ld,%u,'%s','%s',%ld,'%c')",
Gbl.Test.QstCod,NumOpt,
Gbl.Test.Answer.Options[NumOpt].Text,
Gbl.Test.Answer.Options[NumOpt].Feedback ? Gbl.Test.Answer.Options[NumOpt].Feedback : "",
- Gbl.Test.Answer.Options[NumOpt].Media.Name,
- Med_GetStringTypeForDB (Gbl.Test.Answer.Options[NumOpt].Media.Type),
- Gbl.Test.Answer.Options[NumOpt].Media.Title ? Gbl.Test.Answer.Options[NumOpt].Media.Title : "",
- Gbl.Test.Answer.Options[NumOpt].Media.URL ? Gbl.Test.Answer.Options[NumOpt].Media.URL : "",
+ Gbl.Test.Answer.Options[NumOpt].Media.MedCod,
Gbl.Test.Answer.Options[NumOpt].Correct ? 'Y' :
'N');
@@ -6688,9 +6654,6 @@ static void Tst_InsertAnswersIntoDB (void)
default:
break;
}
-
- /***** Free space allocated for query *****/
- free ((void *) Query);
}
/*****************************************************************************/
@@ -6745,13 +6708,12 @@ static void Tst_RemoveMedFileFromStemOfQst (long CrsCod,long QstCod)
/***** Get names of media files associated to stems of test questions from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get image",
- "SELECT MediaName," // row[0]
- "MediaType" // row[1]
+ "SELECT MedCod" // row[0]
" FROM tst_questions"
" WHERE QstCod=%ld AND CrsCod=%ld",
QstCod,CrsCod))
/***** Remove media file *****/
- Med_RemoveMediaFilesFromRow (mysql_res);
+ Med_RemoveMediaFromRow (mysql_res);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@@ -6769,15 +6731,14 @@ static void Tst_RemoveAllMedFilesFromStemOfAllQstsInCrs (long CrsCod)
/***** Get names of images associated to stems of test questions from database *****/
NumMedia =
- (unsigned) DB_QuerySELECT (&mysql_res,"can not get images",
- "SELECT MediaName," // row[0]
- "MediaType" // row[1]
+ (unsigned) DB_QuerySELECT (&mysql_res,"can not get media",
+ "SELECT MedCod" // row[0]
" FROM tst_questions"
" WHERE CrsCod=%ld",
CrsCod);
/***** Go over result removing media files *****/
- Med_RemoveMediaFilesFromAllRows (NumMedia,mysql_res);
+ Med_RemoveMediaFromAllRows (NumMedia,mysql_res);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@@ -6793,8 +6754,7 @@ static void Tst_RemoveMedFileFromAnsOfQst (long CrsCod,long QstCod,unsigned AnsI
/***** Get names of media files associated to answers of test questions from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get images",
- "SELECT tst_answers.MediaName," // row[0]
- "tst_answers.MediaType" // row[1]
+ "SELECT tst_answers.MedCod" // row[0]
" FROM tst_questions,tst_answers"
" WHERE tst_questions.CrsCod=%ld"// Extra check
" AND tst_questions.QstCod=%ld" // Extra check
@@ -6803,7 +6763,7 @@ static void Tst_RemoveMedFileFromAnsOfQst (long CrsCod,long QstCod,unsigned AnsI
" AND tst_answers.AnsInd=%u",
CrsCod,QstCod,QstCod,AnsInd))
/***** Remove media file *****/
- Med_RemoveMediaFilesFromRow (mysql_res);
+ Med_RemoveMediaFromRow (mysql_res);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@@ -6820,9 +6780,8 @@ static void Tst_RemoveAllMedFilesFromAnsOfQst (long CrsCod,long QstCod)
/***** Get names of media files associated to answers of test questions from database *****/
NumMedia =
- (unsigned) DB_QuerySELECT (&mysql_res,"can not get images",
- "SELECT tst_answers.MediaName," // row[0]
- "tst_answers.MediaType" // row[1]
+ (unsigned) DB_QuerySELECT (&mysql_res,"can not get media",
+ "SELECT tst_answers.MedCod" // row[0]
" FROM tst_questions,tst_answers"
" WHERE tst_questions.CrsCod=%ld" // Extra check
" AND tst_questions.QstCod=%ld" // Extra check
@@ -6831,7 +6790,7 @@ static void Tst_RemoveAllMedFilesFromAnsOfQst (long CrsCod,long QstCod)
CrsCod,QstCod,QstCod);
/***** Go over result removing media files *****/
- Med_RemoveMediaFilesFromAllRows (NumMedia,mysql_res);
+ Med_RemoveMediaFromAllRows (NumMedia,mysql_res);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@@ -6849,16 +6808,15 @@ static void Tst_RemoveAllMedFilesFromAnsOfAllQstsInCrs (long CrsCod)
/***** Get names of media files associated to answers of test questions from database *****/
NumMedia =
- (unsigned) DB_QuerySELECT (&mysql_res,"can not get images",
- "SELECT tst_answers.MediaName," // row[0]
- "tst_answers.MediaType" // row[1]
+ (unsigned) DB_QuerySELECT (&mysql_res,"can not get media",
+ "SELECT tst_answers.MedCod" // row[0]
" FROM tst_questions,tst_answers"
" WHERE tst_questions.CrsCod=%ld"
" AND tst_questions.QstCod=tst_answers.QstCod",
CrsCod);
/***** Go over result removing media files *****/
- Med_RemoveMediaFilesFromAllRows (NumMedia,mysql_res);
+ Med_RemoveMediaFromAllRows (NumMedia,mysql_res);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@@ -7720,9 +7678,12 @@ static void Tst_ShowTestResults (struct UsrData *UsrDat)
/***** Make database query *****/
NumExams =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get test exams of a user",
- "SELECT TstCod,AllowTeachers,"
- "UNIX_TIMESTAMP(TstTime),"
- "NumQsts,NumQstsNotBlank,Score"
+ "SELECT TstCod," // row[0]
+ "AllowTeachers," // row[1]
+ "UNIX_TIMESTAMP(TstTime)," // row[2]
+ "NumQsts," // row[3]
+ "NumQstsNotBlank," // row[4]
+ "Score" // row[5]
" FROM tst_exams"
" WHERE CrsCod=%ld AND UsrCod=%ld"
" AND TstTime>=FROM_UNIXTIME(%ld)"
@@ -8303,19 +8264,16 @@ static void Tst_ShowTestResult (time_t TstTimeUTC)
/***** Get row of the result of the query *****/
row = mysql_fetch_row (mysql_res);
/*
- row[ 0] QstCod
- row[ 1] UNIX_TIMESTAMP(EditTime)
- row[ 2] AnsType
- row[ 3] Shuffle
- row[ 4] Stem
- row[ 5] Feedback
- row[ 6] MediaName
- row[ 7] MediaType
- row[ 8] MediaTitle
- row[ 9] MediaURL
- row[10] NumHits
- row[11] NumHitsNotBlank
- row[12] Score
+ row[0] QstCod
+ row[1] UNIX_TIMESTAMP(EditTime)
+ row[2] AnsType
+ row[3] Shuffle
+ row[4] Stem
+ row[5] Feedback
+ row[6] MedCod
+ row[7] NumHits
+ row[8] NumHitsNotBlank
+ row[9] Score
*/
/***** If this question has been edited later than test time
==> don't show question ****/
@@ -8382,9 +8340,12 @@ static void Tst_GetTestResultDataByTstCod (long TstCod,time_t *TstTimeUTC,
/***** Make database query *****/
if (DB_QuerySELECT (&mysql_res,"can not get data"
" of a test result of a user",
- "SELECT UsrCod,AllowTeachers,"
- "UNIX_TIMESTAMP(TstTime),"
- "NumQsts,NumQstsNotBlank,Score"
+ "SELECT UsrCod," // row[0]
+ "AllowTeachers," // row[1]
+ "UNIX_TIMESTAMP(TstTime)," // row[2]
+ "NumQsts," // row[3]
+ "NumQstsNotBlank," // row[4]
+ "Score" // row[5]
" FROM tst_exams"
" WHERE TstCod=%ld AND CrsCod=%ld",
TstCod,
@@ -8463,7 +8424,9 @@ static void Tst_GetTestResultQuestionsFromDB (long TstCod)
Gbl.Test.NumQsts =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get questions"
" of a test result",
- "SELECT QstCod,Indexes,Answers"
+ "SELECT QstCod," // row[0]
+ "Indexes," // row[1]
+ "Answers" // row[2]
" FROM tst_exam_questions"
" WHERE TstCod=%ld ORDER BY QstInd",
TstCod);
diff --git a/swad_test.h b/swad_test.h
index 229a69bc..0becb7b6 100644
--- a/swad_test.h
+++ b/swad_test.h
@@ -143,11 +143,6 @@ void Tst_ShowFormAskTst (void);
void Tst_ShowNewTest (void);
void Tst_AssessTest (void);
-void Tst_WriteQstAndAnsTest (Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions,
- struct UsrData *UsrDat,
- struct Game *Game,
- unsigned NumQst,long QstCod,MYSQL_ROW row,
- double *ScoreThisQst,bool *AnswerIsNotBlank);
void Tst_WriteQstStem (const char *Stem,const char *ClassStem);
void Tst_WriteQstFeedback (const char *Feedback,const char *ClassFeedback);
diff --git a/swad_test_import.c b/swad_test_import.c
index 8f877712..52050be9 100644
--- a/swad_test_import.c
+++ b/swad_test_import.c
@@ -194,19 +194,16 @@ void TsI_CreateXML (unsigned long NumRows,MYSQL_RES *mysql_res)
{
row = mysql_fetch_row (mysql_res);
/*
- row[ 0] QstCod
- row[ 1] UNIX_TIMESTAMP(EditTime)
- row[ 2] AnsType
- row[ 3] Shuffle
- row[ 4] Stem
- row[ 5] Feedback
- row[ 6] MediaName
- row[ 7] MediaType
- row[ 8] MediaTitle
- row[ 9] MediaURL
- row[10] NumHits
- row[11] NumHitsNotBlank
- row[12] Score
+ row[0] QstCod
+ row[1] UNIX_TIMESTAMP(EditTime)
+ row[2] AnsType
+ row[3] Shuffle
+ row[4] Stem
+ row[5] Feedback
+ row[6] MedCod
+ row[7] NumHits
+ row[8] NumHitsNotBlank
+ row[9] Score
*/
/* row[0] holds the code of the question */
if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
@@ -313,12 +310,10 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod)
row[0] AnsInd
row[1] Answer
row[2] Feedback
- row[3] MediaName
- row[4] MediaType
- row[5] MediaTitle
- row[6] MediaURL
- row[7] Correct
+ row[3] MedCod
+ row[4] Correct
*/
+
/***** Write the answers *****/
switch (Gbl.Test.AnswerType)
{
diff --git a/swad_timeline.c b/swad_timeline.c
index 279fc244..021511bb 100644
--- a/swad_timeline.c
+++ b/swad_timeline.c
@@ -98,7 +98,7 @@ struct TL_Note
TL_NoteType_t NoteType;
long UsrCod;
long HieCod; // Hierarchy code (institution/centre/degree/course)
- long Cod; // Code of file, forum post, notice,...
+ long Cod; // Code of file, forum post, notice, timeline post...
bool Unavailable; // File, forum post, notice,... unavailable (removed)
time_t DateTimeUTC;
unsigned NumShared; // Number of times (users) this note has been shared
@@ -234,8 +234,8 @@ static void TL_UnfavComment (struct TL_Comment *SocCom);
static void TL_RequestRemovalNote (void);
static void TL_PutParamsRemoveNote (void);
static void TL_RemoveNote (void);
-static void TL_RemoveImgFileFromPost (long PstCod);
-static void TL_RemoveANoteFromDB (struct TL_Note *SocNot);
+static void TL_RemoveMediaFromPost (long PstCod);
+static void TL_RemoveNoteMediaAndDBEntries (struct TL_Note *SocNot);
static long TL_GetNotCodOfPublication (long PubCod);
static long TL_GetPubCodOfOriginalNote (long NotCod);
@@ -243,8 +243,7 @@ static long TL_GetPubCodOfOriginalNote (long NotCod);
static void TL_RequestRemovalComment (void);
static void TL_PutParamsRemoveCommment (void);
static void TL_RemoveComment (void);
-static void TL_RemoveImgFileFromComment (long PubCod);
-static void TL_RemoveACommentFromDB (struct TL_Comment *SocCom);
+static void TL_RemoveCommentMediaAndDBEntries (long PubCod);
static bool TL_CheckIfNoteIsSharedByUsr (long NotCod,long UsrCod);
static bool TL_CheckIfNoteIsFavedByUsr (long NotCod,long UsrCod);
@@ -1829,10 +1828,7 @@ static void TL_GetAndWritePost (long PstCod)
NumRows = DB_QuerySELECT (&mysql_res,"can not get the content"
" of a post",
"SELECT Content," // row[0]
- "MediaName," // row[1]
- "MediaType," // row[2]
- "MediaTitle," // row[3]
- "MediaURL" // row[4]
+ "MedCod" // row[1]
" FROM social_posts"
" WHERE PstCod=%ld",
PstCod);
@@ -1846,8 +1842,9 @@ static void TL_GetAndWritePost (long PstCod)
Str_Copy (Content,row[0],
Cns_MAX_BYTES_LONG_TEXT);
- /****** Get media data (row[1], row[2], row[3], row[4]) *****/
- Med_GetMediaDataFromRow (row[1],row[2],row[3],row[4],&Media);
+ /***** Get media (row[1]) *****/
+ Media.MedCod = Str_ConvertStrCodToLongCod (row[1]);
+ Med_GetMediaDataByCod (&Media);
}
else
Content[0] = '\0';
@@ -2477,26 +2474,28 @@ static long TL_ReceivePost (void)
Media.Status == Med_PROCESSED) // A media is attached
{
/***** Check if media is received and processed *****/
+ Media.MedCod = -1L;
if (Media.Action == Med_ACTION_NEW_MEDIA && // New media
Media.Status == Med_PROCESSED) // The new media received has been processed
+ {
/* Move processed image to definitive directory */
Med_MoveMediaToDefinitiveDir (&Media);
+ /* Store media in database */
+ if (Media.Status == Med_MOVED)
+ Med_StoreMediaInDB (&Media); // Set Media.MedCod
+ }
+
/***** Publish *****/
/* Insert post content in the database */
PstCod =
DB_QueryINSERTandReturnCode ("can not create post",
"INSERT INTO social_posts"
- " (Content,"
- "MediaName,MediaType,MediaTitle,MediaURL)"
+ " (Content,MedCod)"
" VALUES"
- " ('%s',"
- "'%s','%s','%s','%s')",
+ " ('%s',%ld)",
Content,
- Media.Name,
- Med_GetStringTypeForDB (Media.Type),
- Media.Title ? Media.Title : "",
- Media.URL ? Media.URL : "");
+ Media.MedCod);
/* Insert post in notes */
TL_StoreAndPublishNote (TL_NOTE_POST,PstCod,&SocPub);
@@ -2637,10 +2636,7 @@ static void TL_WriteCommentsInNote (const struct TL_Note *SocNot)
"UNIX_TIMESTAMP("
"social_pubs.TimePublish)," // row[3]
"social_comments.Content," // row[4]
- "social_comments.MediaName," // row[5]
- "social_comments.MediaType," // row[6]
- "social_comments.MediaTitle," // row[7]
- "social_comments.MediaURL" // row[8]
+ "social_comments.MedCod" // row[5]
" FROM social_pubs,social_comments"
" WHERE social_pubs.NotCod=%ld"
" AND social_pubs.PubType=%u"
@@ -3204,11 +3200,18 @@ static long TL_ReceiveComment (void)
Media.Status == Med_PROCESSED) // A media is attached
{
/***** Check if media is received and processed *****/
+ Media.MedCod = -1L;
if (Media.Action == Med_ACTION_NEW_MEDIA && // New media
Media.Status == Med_PROCESSED) // The new media received has been processed
+ {
/* Move processed image to definitive directory */
Med_MoveMediaToDefinitiveDir (&Media);
+ /* Store media in database */
+ if (Media.Status == Med_MOVED)
+ Med_StoreMediaInDB (&Media); // Set Media.MedCod
+ }
+
/***** Publish *****/
/* Insert into publications */
SocPub.NotCod = SocNot.NotCod;
@@ -3219,17 +3222,12 @@ static long TL_ReceiveComment (void)
/* Insert comment content in the database */
DB_QueryINSERT ("can not store comment content",
"INSERT INTO social_comments"
- " (PubCod,Content,"
- "MediaName,MediaType,MediaTitle,MediaURL)"
+ " (PubCod,Content,MedCod)"
" VALUES"
- " (%ld,'%s',"
- "'%s','%s','%s','%s')",
+ " (%ld,'%s',%ld)",
SocPub.PubCod,
Content,
- Media.Name,
- Med_GetStringTypeForDB (Media.Type),
- Media.Title ? Media.Title : "",
- Media.URL ? Media.URL : "");
+ Media.MedCod);
/***** Store notifications about the new comment *****/
Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_TIMELINE_COMMENT,SocPub.PubCod);
@@ -3856,12 +3854,11 @@ static void TL_RemoveNote (void)
ItsMe = Usr_ItsMe (SocNot.UsrCod);
if (ItsMe) // I am the author of this note
{
- if (SocNot.NoteType == TL_NOTE_POST)
- /***** Remove image file associated to post *****/
- TL_RemoveImgFileFromPost (SocNot.Cod);
-
/***** Delete note from database *****/
- TL_RemoveANoteFromDB (&SocNot);
+ TL_RemoveNoteMediaAndDBEntries (&SocNot);
+
+ /***** Reset note *****/
+ TL_ResetNote (&SocNot);
/***** Message of success *****/
Ale_ShowAlert (Ale_SUCCESS,Txt_TIMELINE_Post_removed);
@@ -3875,19 +3872,18 @@ static void TL_RemoveNote (void)
/***************** Remove one file associated to a post **********************/
/*****************************************************************************/
-static void TL_RemoveImgFileFromPost (long PstCod)
+static void TL_RemoveMediaFromPost (long PstCod)
{
MYSQL_RES *mysql_res;
- /***** Get name of image associated to a post from database *****/
+ /***** Get name of media associated to a post from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get image",
- "SELECT MediaName," // row[0]
- "MediaType" // row[1]
+ "SELECT MedCod" // row[0]
" FROM social_posts"
" WHERE PstCod=%ld",
PstCod))
/***** Remove media file *****/
- Med_RemoveMediaFilesFromRow (mysql_res);
+ Med_RemoveMediaFromRow (mysql_res);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@@ -3897,7 +3893,7 @@ static void TL_RemoveImgFileFromPost (long PstCod)
/*********************** Remove a note from database *************************/
/*****************************************************************************/
-static void TL_RemoveANoteFromDB (struct TL_Note *SocNot)
+static void TL_RemoveNoteMediaAndDBEntries (struct TL_Note *SocNot)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
@@ -3905,18 +3901,7 @@ static void TL_RemoveANoteFromDB (struct TL_Note *SocNot)
unsigned long NumComments;
unsigned long NumCom;
- /***** Mark possible notifications on the publications
- of this note as removed *****/
- /* Mark notifications of the original note as removed */
- PubCod = TL_GetPubCodOfOriginalNote (SocNot->NotCod);
- if (PubCod > 0)
- {
- Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_COMMENT,PubCod);
- Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_FAV ,PubCod);
- Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_SHARE ,PubCod);
- Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_MENTION,PubCod);
- }
-
+ /***** Remove comments associated to this note *****/
/* Get comments of this note */
NumComments = DB_QuerySELECT (&mysql_res,"can not get comments",
"SELECT PubCod"
@@ -3934,43 +3919,50 @@ static void TL_RemoveANoteFromDB (struct TL_Note *SocNot)
row = mysql_fetch_row (mysql_res);
PubCod = Str_ConvertStrCodToLongCod (row[0]);
- /* Mark notifications as removed */
- if (PubCod > 0)
- {
- Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_COMMENT,PubCod);
- Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_FAV ,PubCod);
- Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_MENTION,PubCod);
- }
+ /* Remove media associated to comment
+ and delete comment from database */
+ TL_RemoveCommentMediaAndDBEntries (PubCod);
}
/* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
- /***** Remove favs *****/
- /* Remove favs for all comments in this note */
- DB_QueryDELETE ("can not remove favs for note",
- "DELETE FROM social_comments_fav"
- " USING social_pubs,social_comments_fav"
- " WHERE social_pubs.NotCod=%ld"
- " AND social_pubs.PubType=%u"
- " AND social_pubs.PubCod=social_comments_fav.PubCod",
- SocNot->NotCod,(unsigned) TL_PUB_COMMENT_TO_NOTE);
+ /***** Remove media associated to post *****/
+ if (SocNot->NoteType == TL_NOTE_POST)
+ {
+ TL_RemoveMediaFromPost (SocNot->Cod);
+ MYSQL_RES *mysql_res;
- /* Remove favs for this note */
+ /* Get name of media associated to a post from database */
+ if (DB_QuerySELECT (&mysql_res,"can not get image",
+ "SELECT MedCod" // row[0]
+ " FROM social_posts"
+ " WHERE PstCod=%ld",
+ SocNot->Cod))
+ /* Remove media */
+ Med_RemoveMediaFromRow (mysql_res);
+
+ /* Free structure that stores the query result */
+ DB_FreeMySQLResult (&mysql_res);
+ }
+
+ /***** Mark possible notifications on the publications
+ of this note as removed *****/
+ /* Mark notifications of the original note as removed */
+ PubCod = TL_GetPubCodOfOriginalNote (SocNot->NotCod);
+ if (PubCod > 0)
+ {
+ Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_FAV ,PubCod);
+ Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_SHARE ,PubCod);
+ Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_MENTION,PubCod);
+ }
+
+ /***** Remove favs for this note *****/
DB_QueryDELETE ("can not remove favs for note",
"DELETE FROM social_notes_fav"
" WHERE NotCod=%ld",
SocNot->NotCod);
- /***** Remove content of the comments of this note *****/
- DB_QueryDELETE ("can not remove comments",
- "DELETE FROM social_comments"
- " USING social_pubs,social_comments"
- " WHERE social_pubs.NotCod=%ld"
- " AND social_pubs.PubType=%u"
- " AND social_pubs.PubCod=social_comments.PubCod",
- SocNot->NotCod,(unsigned) TL_PUB_COMMENT_TO_NOTE);
-
/***** Remove all the publications of this note *****/
DB_QueryDELETE ("can not remove a publication",
"DELETE FROM social_pubs"
@@ -3991,9 +3983,6 @@ static void TL_RemoveANoteFromDB (struct TL_Note *SocNot)
"DELETE FROM social_posts"
" WHERE PstCod=%ld",
SocNot->Cod);
-
- /***** Reset note *****/
- TL_ResetNote (SocNot);
}
/*****************************************************************************/
@@ -4198,11 +4187,12 @@ static void TL_RemoveComment (void)
ItsMe = Usr_ItsMe (SocCom.UsrCod);
if (ItsMe) // I am the author of this comment
{
- /***** Remove image file associated to post *****/
- TL_RemoveImgFileFromComment (SocCom.PubCod);
+ /***** Remove media associated to comment
+ and delete comment from database *****/
+ TL_RemoveCommentMediaAndDBEntries (SocCom.PubCod);
- /***** Delete comment from database *****/
- TL_RemoveACommentFromDB (&SocCom);
+ /***** Reset fields of comment *****/
+ TL_ResetComment (&SocCom);
/***** Message of success *****/
Ale_ShowAlert (Ale_SUCCESS,Txt_Comment_removed);
@@ -4216,49 +4206,42 @@ static void TL_RemoveComment (void)
}
/*****************************************************************************/
-/**************** Remove one file associated to a comment ********************/
+/*************** Remove comment media and database entries *******************/
/*****************************************************************************/
-static void TL_RemoveImgFileFromComment (long PubCod)
+static void TL_RemoveCommentMediaAndDBEntries (long PubCod)
{
MYSQL_RES *mysql_res;
- /***** Get name of media associated to a post from database *****/
+ /***** Remove media associated to comment *****/
+ /* Get name of media associated to a comment from database */
if (DB_QuerySELECT (&mysql_res,"can not get media",
- "SELECT MediaName," // row[0]
- "MediaType" // row[1]
+ "SELECT MedCod" // row[0]
" FROM social_comments"
" WHERE PubCod=%ld",
PubCod))
- /***** Remove media file *****/
- Med_RemoveMediaFilesFromRow (mysql_res);
+ /* Remove media */
+ Med_RemoveMediaFromRow (mysql_res);
- /***** Free structure that stores the query result *****/
+ /* Free structure that stores the query result */
DB_FreeMySQLResult (&mysql_res);
- }
-/*****************************************************************************/
-/********************* Remove a comment from database ************************/
-/*****************************************************************************/
-
-static void TL_RemoveACommentFromDB (struct TL_Comment *SocCom)
- {
/***** Mark possible notifications on this comment as removed *****/
- Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_COMMENT,SocCom->PubCod);
- Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_FAV ,SocCom->PubCod);
- Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_MENTION,SocCom->PubCod);
+ Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_COMMENT,PubCod);
+ Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_FAV ,PubCod);
+ Ntf_MarkNotifAsRemoved (Ntf_EVENT_TIMELINE_MENTION,PubCod);
/***** Remove favs for this comment *****/
DB_QueryDELETE ("can not remove favs for comment",
"DELETE FROM social_comments_fav"
" WHERE PubCod=%ld",
- SocCom->PubCod);
+ PubCod);
/***** Remove content of this comment *****/
DB_QueryDELETE ("can not remove a comment",
"DELETE FROM social_comments"
" WHERE PubCod=%ld",
- SocCom->PubCod);
+ PubCod);
/***** Remove this comment *****/
DB_QueryDELETE ("can not remove a comment",
@@ -4266,12 +4249,9 @@ static void TL_RemoveACommentFromDB (struct TL_Comment *SocCom)
" WHERE PubCod=%ld"
" AND PublisherCod=%ld" // Extra check: I am the author
" AND PubType=%u", // Extra check: it's a comment
- SocCom->PubCod,
+ PubCod,
Gbl.Usrs.Me.UsrDat.UsrCod,
(unsigned) TL_PUB_COMMENT_TO_NOTE);
-
- /***** Reset comment *****/
- TL_ResetComment (SocCom);
}
/*****************************************************************************/
@@ -4693,10 +4673,7 @@ static void TL_GetDataOfCommByCod (struct TL_Comment *SocCom)
"social_pubs.NotCod," // row[2]
"UNIX_TIMESTAMP(social_pubs.TimePublish)," // row[3]
"social_comments.Content," // row[4]
- "social_comments.MediaName," // row[5]
- "social_comments.MediaType," // row[6]
- "social_comments.MediaTitle," // row[7]
- "social_comments.MediaURL" // row[8]
+ "social_comments.MedCod" // row[5]
" FROM social_pubs,social_comments"
" WHERE social_pubs.PubCod=%ld"
" AND social_pubs.PubType=%u"
@@ -4826,10 +4803,7 @@ static void TL_GetDataOfCommentFromRow (MYSQL_ROW row,struct TL_Comment *SocCom)
row[2]: NotCod
row[3]: TimePublish
row[4]: Content
- row[5]: MediaName
- row[6]: MediaType
- row[7]: MediaTitle
- row[8]: MediaURL
+ row[5]: MedCod
*/
/***** Get code of comment (row[0]) *****/
SocCom->PubCod = Str_ConvertStrCodToLongCod (row[0]);
@@ -4850,8 +4824,9 @@ static void TL_GetDataOfCommentFromRow (MYSQL_ROW row,struct TL_Comment *SocCom)
/***** Get number of times this comment has been favourited *****/
TL_GetNumTimesACommHasBeenFav (SocCom);
- /****** Get media data (row[5], row[6], row[7], row[8]) *****/
- Med_GetMediaDataFromRow (row[5],row[6],row[7],row[8],&SocCom->Media);
+ /***** Get media (row[5]) *****/
+ SocCom->Media.MedCod = Str_ConvertStrCodToLongCod (row[5]);
+ Med_GetMediaDataByCod (&SocCom->Media);
}
/*****************************************************************************/
diff --git a/swad_web_service.c b/swad_web_service.c
index ad18f837..a8c470cd 100644
--- a/swad_web_service.c
+++ b/swad_web_service.c
@@ -3446,13 +3446,10 @@ static int Svc_SendMessageToUsr (long OriginalMsgCod,
NewMsgCod =
DB_QueryINSERTandReturnCode ("can not create message",
"INSERT INTO msg_content"
- " (Subject,Content,"
- "MediaName,MediaType,MediaTitle,MediaURL)"
+ " (Subject,Content,MedCod)"
" VALUES"
- " ('%s','%s',"
- "'','%s','','')",
- Subject,Content,
- Med_GetStringTypeForDB (Med_TYPE_NONE));
+ " ('%s','%s',-1)",
+ Subject,Content);
/* Insert message in sent messages */
DB_QueryINSERT ("can not create message",