Version 18.63

This commit is contained in:
Antonio Cañas Vargas 2019-03-02 21:49:11 +01:00
parent 2f5773f810
commit 97610ac7b7
20 changed files with 763 additions and 1540 deletions

View File

@ -40,11 +40,10 @@ OBJS = swad_account.o swad_action.o swad_agenda.o swad_alert.o \
swad_forum.o \
swad_game.o swad_global.o swad_group.o \
swad_help.o swad_hierarchy.o swad_holiday.o \
swad_icon.o swad_ID.o swad_image.o swad_indicator.o swad_info.o \
swad_institution.o \
swad_icon.o swad_ID.o swad_indicator.o swad_info.o swad_institution.o \
swad_language.o swad_layout.o swad_link.o swad_logo.o \
swad_mail.o swad_main.o swad_mark.o swad_menu.o swad_message.o \
swad_MFU.o \
swad_mail.o swad_main.o swad_mark.o swad_media.o swad_menu.o \
swad_message.o swad_MFU.o \
swad_network.o swad_nickname.o swad_notice.o swad_notification.o \
swad_pagination.o swad_parameter.o swad_password.o swad_photo.o \
swad_place.o swad_plugin.o swad_preference.o swad_privacy.o \

View File

@ -2676,28 +2676,28 @@ a:hover img.CENTRE_PHOTO_SHOW
opacity:0.3;
}
/****************************** Image uploading ******************************/
.IMG_UPLOAD_CONTAINER
/*********************** Media (image/video) uploading ***********************/
.MED_UPL_CON /* Upload container */
{
vertical-align:top;
margin-bottom:10px;
}
.IMG_UPLOAD_BUTTON
.MED_UPL_BUT /* Upload button _*/
{
cursor:pointer;
}
.IMG_UPLOAD_ICO
.MED_UPL_ICO /* Upload icon */
{
width:16px;
height:16px;
margin:0 5px;
vertical-align:middle;
}
.IMG_UPLOAD_FILE
.MED_UPL_FIL /* Upload file */
{
display:none;
}
.IMG_UPLOAD_FILENAME
.MED_UPL_NAM /* Upload filename */
{
color:#808080;
font-size:12pt;

View File

@ -1052,10 +1052,10 @@ function enableDisableImgAns (elem, isDisabled) {
var Tst_MAX_OPTIONS_PER_QUESTION = 10;
for (var i = 0; i < Tst_MAX_OPTIONS_PER_QUESTION; i++)
if (elem.name == ('ImgAct' + i) ||
elem.name == ('ImgFil' + i) ||
elem.name == ('ImgTit' + i) ||
elem.name == ('ImgURL' + i))
if (elem.name == ('MedAct' + i) ||
elem.name == ('MedFil' + i) ||
elem.name == ('MedTit' + i) ||
elem.name == ('MedURL' + i))
elem.disabled = isDisabled;
}
@ -1079,7 +1079,7 @@ function disableDetailedClicks () {
/************************** Upload images in a form **************************/
/*****************************************************************************/
function imageUploadOnSelectFile (inputFile,id) {
function mediaUploadOnSelectFile (inputFile,id) {
document.getElementById(id + '_fil').innerHTML = inputFile.value; // Display image filename
document.getElementById(id + '_tit_url').style.display = ''; // Show hidden fields
}

View File

@ -2381,13 +2381,13 @@ void Ctr_ReceivePhoto (void)
/* Create private directory for images if it does not exist */
snprintf (PathImgPriv,sizeof (PathImgPriv),
"%s/%s",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG);
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA);
Fil_CreateDirIfNotExists (PathImgPriv);
/* Create temporary private directory for images if it does not exist */
snprintf (PathImgPriv,sizeof (PathImgPriv),
"%s/%s/%s",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG,Cfg_FOLDER_IMG_TMP);
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA,Cfg_FOLDER_IMG_TMP);
Fil_CreateDirIfNotExists (PathImgPriv);
/* Get filename extension */
@ -2407,7 +2407,7 @@ void Ctr_ReceivePhoto (void)
/* End the reception of image in a temporary file */
snprintf (FileNameImgTmp,sizeof (FileNameImgTmp),
"%s/%s/%s/%s.%s",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG,Cfg_FOLDER_IMG_TMP,
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_MEDIA,Cfg_FOLDER_IMG_TMP,
Gbl.UniqueNameEncrypted,PtrExtension);
if (!Fil_EndReceptionOfFile (FileNameImgTmp,Param))
{
@ -2476,11 +2476,11 @@ void Ctr_ReceivePhoto (void)
void Ctr_ChangeCtrPhotoAttribution (void)
{
char NewPhotoAttribution[Img_MAX_BYTES_ATTRIBUTION + 1];
char NewPhotoAttribution[Med_MAX_BYTES_ATTRIBUTION + 1];
/***** Get parameters from form *****/
/* Get the new photo attribution for the centre */
Par_GetParToText ("Attribution",NewPhotoAttribution,Img_MAX_BYTES_ATTRIBUTION);
Par_GetParToText ("Attribution",NewPhotoAttribution,Med_MAX_BYTES_ATTRIBUTION);
/***** Update the table changing old attribution by new attribution *****/
DB_QueryUPDATE ("can not update the photo attribution"

View File

@ -430,10 +430,48 @@ En OpenSWAD:
ps2pdf source.ps destination.pdf
*/
#define Log_PLATFORM_VERSION "SWAD 18.62 (2019-02-27)"
#define Log_PLATFORM_VERSION "SWAD 18.63 (2019-03-02)"
#define CSS_FILE "swad18.61.css"
#define JS_FILE "swad18.62.js"
/*
Version 18.63: Mar 02, 2019 Allowing animated GIFs. Not finished. (238125 lines)
Rename the following directory:
sudo mv /var/www/swad/img /var/www/swad/med
28 changes necessary in database:
ALTER TABLE forum_post CHANGE COLUMN ImageName MediaName VARCHAR(43) NOT NULL DEFAULT '';
ALTER TABLE games CHANGE COLUMN ImageName MediaName VARCHAR(43) NOT NULL DEFAULT '';
ALTER TABLE msg_content CHANGE COLUMN ImageName MediaName VARCHAR(43) NOT NULL DEFAULT '';
ALTER TABLE msg_content_deleted CHANGE COLUMN ImageName MediaName VARCHAR(43) NOT NULL DEFAULT '';
ALTER TABLE social_comments CHANGE COLUMN ImageName MediaName VARCHAR(43) NOT NULL DEFAULT '';
ALTER TABLE social_posts CHANGE COLUMN ImageName MediaName VARCHAR(43) NOT NULL DEFAULT '';
ALTER TABLE tst_answers CHANGE COLUMN ImageName MediaName VARCHAR(43) NOT NULL DEFAULT '';
ALTER TABLE tst_questions CHANGE COLUMN ImageName MediaName VARCHAR(43) NOT NULL DEFAULT '';
ALTER TABLE forum_post ADD COLUMN MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg' AFTER MediaName;
ALTER TABLE msg_content ADD COLUMN MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg' AFTER MediaName;
ALTER TABLE msg_content_deleted ADD COLUMN MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg' AFTER MediaName;
ALTER TABLE social_comments ADD COLUMN MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg' AFTER MediaName;
ALTER TABLE social_posts ADD COLUMN MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg' AFTER MediaName;
ALTER TABLE tst_answers ADD COLUMN MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg' AFTER MediaName;
ALTER TABLE tst_questions ADD COLUMN MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg' AFTER MediaName;
ALTER TABLE forum_post CHANGE COLUMN ImageTitle MediaTitle VARCHAR(2047) NOT NULL DEFAULT '';
ALTER TABLE msg_content CHANGE COLUMN ImageTitle MediaTitle VARCHAR(2047) NOT NULL DEFAULT '';
ALTER TABLE msg_content_deleted CHANGE COLUMN ImageTitle MediaTitle VARCHAR(2047) NOT NULL DEFAULT '';
ALTER TABLE social_comments CHANGE COLUMN ImageTitle MediaTitle VARCHAR(2047) NOT NULL DEFAULT '';
ALTER TABLE social_posts CHANGE COLUMN ImageTitle MediaTitle VARCHAR(2047) NOT NULL DEFAULT '';
ALTER TABLE tst_answers CHANGE COLUMN ImageTitle MediaTitle VARCHAR(2047) NOT NULL DEFAULT '';
ALTER TABLE tst_questions CHANGE COLUMN ImageTitle MediaTitle VARCHAR(2047) NOT NULL DEFAULT '';
ALTER TABLE forum_post CHANGE COLUMN ImageURL MediaURL VARCHAR(255) NOT NULL DEFAULT '';
ALTER TABLE msg_content CHANGE COLUMN ImageURL MediaURL VARCHAR(255) NOT NULL DEFAULT '';
ALTER TABLE msg_content_deleted CHANGE COLUMN ImageURL MediaURL VARCHAR(255) NOT NULL DEFAULT '';
ALTER TABLE social_comments CHANGE COLUMN ImageURL MediaURL VARCHAR(255) NOT NULL DEFAULT '';
ALTER TABLE social_posts CHANGE COLUMN ImageURL MediaURL VARCHAR(255) NOT NULL DEFAULT '';
ALTER TABLE tst_answers CHANGE COLUMN ImageURL MediaURL VARCHAR(255) NOT NULL DEFAULT '';
ALTER TABLE tst_questions CHANGE COLUMN ImageURL MediaURL VARCHAR(255) NOT NULL DEFAULT '';
Version 18.62: Feb 27, 2019 By default show only the last comments in a social publishing. (237901 lines)
Version 18.61: Feb 27, 2019 Hide/show comments in a social publishing. (237855 lines)
Version 18.60.5: Feb 26, 2019 Changes in CSS for responsive design in timeline. (237788 lines)

View File

@ -363,8 +363,8 @@
/* Folder for compression of assignments and works into a zip files, inside private swad directory */
#define Cfg_FOLDER_ZIP "zip" // Created automatically the first time it is accessed
/* Folders for images inside public and private swad directories */
#define Cfg_FOLDER_IMG "img" // Created automatically the first time it is accessed
/* Folders for images/videos inside public and private swad directories */
#define Cfg_FOLDER_MEDIA "med" // Created automatically the first time it is accessed
/* Folders for temporary users' photos inside photos directories */
#define Cfg_FOLDER_IMG_TMP "tmp" // Created automatically the first time it is accessed

View File

@ -1940,11 +1940,11 @@ void Cty_ChangeCtyWWW (void)
void Cty_ChangeCtyMapAttribution (void)
{
char NewMapAttribution[Img_MAX_BYTES_ATTRIBUTION + 1];
char NewMapAttribution[Med_MAX_BYTES_ATTRIBUTION + 1];
/***** Get parameters from form *****/
/* Get the new map attribution for the country */
Par_GetParToText ("Attribution",NewMapAttribution,Img_MAX_BYTES_ATTRIBUTION);
Par_GetParToText ("Attribution",NewMapAttribution,Med_MAX_BYTES_ATTRIBUTION);
/***** Update the table changing old attribution by new attribution *****/
DB_QueryUPDATE ("can not update the map attribution of a country",

View File

@ -442,7 +442,7 @@ mysql> DESCRIBE centres;
"ShortName VARCHAR(511) COLLATE latin1_spanish_ci NOT NULL," // Hie_MAX_BYTES_SHRT_NAME
"FullName VARCHAR(2047) COLLATE latin1_spanish_ci NOT NULL," // Hie_MAX_BYTES_FULL_NAME
"WWW VARCHAR(255) NOT NULL," // Cns_MAX_BYTES_WWW
"PhotoAttribution TEXT NOT NULL," // Img_MAX_BYTES_ATTRIBUTION
"PhotoAttribution TEXT NOT NULL," // Med_MAX_BYTES_ATTRIBUTION
"UNIQUE INDEX(CtrCod),"
"INDEX(InsCod),"
"INDEX(PlcCod),"
@ -588,7 +588,7 @@ mysql> DESCRIBE countries;
DB_CreateTable ("CREATE TABLE IF NOT EXISTS countries ("
"CtyCod INT NOT NULL,"
"Alpha2 CHAR(2) NOT NULL,"
"MapAttribution TEXT NOT NULL," // Img_MAX_BYTES_ATTRIBUTION
"MapAttribution TEXT NOT NULL," // Med_MAX_BYTES_ATTRIBUTION
"Name_ca VARCHAR(767) NOT NULL," // Cty_MAX_BYTES_NAME
"Name_de VARCHAR(767) NOT NULL," // Cty_MAX_BYTES_NAME
"Name_en VARCHAR(767) NOT NULL," // Cty_MAX_BYTES_NAME
@ -1207,22 +1207,23 @@ mysql> DESCRIBE forum_disabled_post;
/***** Table forum_post *****/
/*
mysql> DESCRIBE forum_post;
+------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+----------------+
| PstCod | int(11) | NO | PRI | NULL | auto_increment |
| ThrCod | int(11) | NO | MUL | NULL | |
| UsrCod | int(11) | NO | MUL | NULL | |
| CreatTime | datetime | NO | MUL | NULL | |
| ModifTime | datetime | NO | MUL | NULL | |
| NumNotif | int(11) | NO | | 0 | |
| Subject | text | NO | | NULL | |
| Content | longtext | NO | | NULL | |
| ImageName | varchar(43) | NO | | NULL | |
| ImageTitle | varchar(2047) | NO | | NULL | |
| ImageURL | varchar(255) | NO | | NULL | |
+------------+---------------+------+-----+---------+----------------+
11 rows in set (0,00 sec)
+------------+-------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+---------+----------------+
| PstCod | int(11) | NO | PRI | NULL | auto_increment |
| ThrCod | int(11) | NO | MUL | NULL | |
| UsrCod | int(11) | NO | MUL | NULL | |
| CreatTime | datetime | NO | MUL | NULL | |
| ModifTime | datetime | NO | MUL | NULL | |
| NumNotif | int(11) | NO | | 0 | |
| Subject | text | NO | | NULL | |
| Content | longtext | NO | | NULL | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('jpg','gif') | NO | | jpg | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
+------------+-------------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS forum_post ("
"PstCod INT NOT NULL AUTO_INCREMENT,"
@ -1231,11 +1232,12 @@ mysql> DESCRIBE forum_post;
"CreatTime DATETIME NOT NULL,"
"ModifTime DATETIME NOT NULL,"
"NumNotif INT NOT NULL DEFAULT 0,"
"Subject TEXT NOT NULL," // Cns_MAX_BYTES_SUBJECT
"Content LONGTEXT NOT NULL," // Cns_MAX_BYTES_LONG_TEXT
"ImageName VARCHAR(43) NOT NULL," // Img_BYTES_NAME
"ImageTitle VARCHAR(2047) NOT NULL," // Img_MAX_BYTES_TITLE
"ImageURL VARCHAR(255) NOT NULL," // Cns_MAX_BYTES_WWW
"Subject TEXT NOT NULL," // Cns_MAX_BYTES_SUBJECT
"Content LONGTEXT NOT NULL," // Cns_MAX_BYTES_LONG_TEXT
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"UNIQUE INDEX(PstCod),"
"INDEX(ThrCod),"
"INDEX(UsrCod),"
@ -1731,50 +1733,54 @@ mysql> DESCRIBE msg_banned;
/***** Table msg_content *****/
/*
mysql> DESCRIBE msg_content;
+------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+----------------+
| MsgCod | int(11) | NO | PRI | NULL | auto_increment |
| Subject | text | NO | MUL | NULL | |
| Content | longtext | NO | | NULL | |
| ImageName | varchar(43) | NO | | | |
| ImageTitle | varchar(2047) | NO | | | |
| ImageURL | varchar(255) | NO | | | |
+------------+---------------+------+-----+---------+----------------+
6 rows in set (0,00 sec)
+------------+-------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+---------+----------------+
| MsgCod | int(11) | NO | PRI | NULL | auto_increment |
| Subject | text | NO | MUL | NULL | |
| Content | longtext | NO | | NULL | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('jpg','gif') | NO | | jpg | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
+------------+-------------------+------+-----+---------+----------------+
7 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,"
"ImageName VARCHAR(43) NOT NULL DEFAULT ''," // Img_BYTES_NAME
"ImageTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Img_MAX_BYTES_TITLE
"ImageURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg',"
"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;");
/***** Table msg_content_deleted *****/
/*
mysql> DESCRIBE msg_content_deleted;
+------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| MsgCod | int(11) | NO | PRI | NULL | |
| Subject | text | NO | MUL | NULL | |
| Content | longtext | NO | | NULL | |
| ImageName | varchar(43) | NO | | | |
| ImageTitle | varchar(2047) | NO | | | |
| ImageURL | varchar(255) | NO | | | |
+------------+---------------+------+-----+---------+-------+
6 rows in set (0,00 sec)
+------------+-------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+---------+-------+
| MsgCod | int(11) | NO | PRI | NULL | |
| Subject | text | NO | MUL | NULL | |
| Content | longtext | NO | | NULL | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('jpg','gif') | NO | | jpg | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
+------------+-------------------+------+-----+---------+-------+
7 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,"
"ImageName VARCHAR(43) NOT NULL DEFAULT ''," // Img_BYTES_NAME
"ImageTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Img_MAX_BYTES_TITLE
"ImageURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg',"
"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;");
@ -2170,23 +2176,25 @@ mysql> DESCRIBE sessions;
/***** Table social_comments *****/
/*
mysql> DESCRIBE social_comments;
+------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| PubCod | bigint(20) | NO | PRI | NULL | |
| Content | longtext | NO | MUL | NULL | |
| ImageName | varchar(43) | NO | | NULL | |
| ImageTitle | varchar(2047) | NO | | NULL | |
| ImageURL | varchar(255) | NO | | NULL | |
+------------+---------------+------+-----+---------+-------+
5 rows in set (0,00 sec)
+------------+-------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+---------+-------+
| PubCod | bigint(20) | NO | PRI | NULL | |
| Content | longtext | NO | MUL | NULL | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('jpg','gif') | NO | | jpg | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
+------------+-------------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS social_comments ("
"PubCod BIGINT NOT NULL,"
"Content LONGTEXT NOT NULL,"
"ImageName VARCHAR(43) NOT NULL," // Img_BYTES_NAME
"ImageTitle VARCHAR(2047) NOT NULL," // Img_MAX_BYTES_TITLE
"ImageURL VARCHAR(255) NOT NULL," // Cns_MAX_BYTES_WWW
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg',"
"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;");
@ -2266,23 +2274,25 @@ mysql> DESCRIBE social_notes_fav;
/***** Table social_posts *****/
/*
mysql> DESCRIBE social_posts;
+------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+----------------+
| PstCod | int(11) | NO | PRI | NULL | auto_increment |
| Content | longtext | NO | MUL | NULL | |
| ImageName | varchar(43) | NO | | NULL | |
| ImageTitle | varchar(2047) | NO | | NULL | |
| ImageURL | varchar(255) | NO | | NULL | |
+------------+---------------+------+-----+---------+----------------+
5 rows in set (0,00 sec)
+------------+-------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+---------+----------------+
| PstCod | int(11) | NO | PRI | NULL | auto_increment |
| Content | longtext | NO | MUL | NULL | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('jpg','gif') | NO | | jpg | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
+------------+-------------------+------+-----+---------+----------------+
6 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,"
"ImageName VARCHAR(43) NOT NULL," // Img_BYTES_NAME
"ImageTitle VARCHAR(2047) NOT NULL," // Img_MAX_BYTES_TITLE
"ImageURL VARCHAR(255) NOT NULL," // Cns_MAX_BYTES_WWW
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg',"
"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;");
@ -2537,28 +2547,30 @@ mysql> DESCRIBE timetable_tut;
/***** Table tst_answers *****/
/*
mysql> DESCRIBE tst_answers;
+------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| QstCod | int(11) | NO | MUL | NULL | |
| AnsInd | tinyint(4) | NO | | NULL | |
| Answer | text | NO | | NULL | |
| Feedback | text | NO | | NULL | |
| ImageName | varchar(43) | NO | | NULL | |
| ImageTitle | varchar(2047) | NO | | NULL | |
| ImageURL | varchar(255) | NO | | NULL | |
| Correct | enum('N','Y') | NO | | NULL | |
+------------+---------------+------+-----+---------+-------+
8 rows in set (0,00 sec)
+------------+-------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+---------+-------+
| QstCod | int(11) | NO | MUL | NULL | |
| AnsInd | tinyint(4) | NO | | NULL | |
| Answer | text | NO | | NULL | |
| Feedback | text | NO | | NULL | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('jpg','gif') | NO | | jpg | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
| Correct | enum('N','Y') | NO | | NULL | |
+------------+-------------------+------+-----+---------+-------+
9 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
"ImageName VARCHAR(43) NOT NULL," // Img_BYTES_NAME
"ImageTitle VARCHAR(2047) NOT NULL," // Img_MAX_BYTES_TITLE
"ImageURL VARCHAR(255) NOT NULL," // Cns_MAX_BYTES_WWW
"Answer TEXT NOT NULL," // Tst_MAX_BYTES_ANSWER_OR_FEEDBACK
"Feedback TEXT NOT NULL," // Tst_MAX_BYTES_ANSWER_OR_FEEDBACK
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg',"
"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))");
@ -2672,14 +2684,15 @@ mysql> DESCRIBE tst_questions;
| Shuffle | enum('N','Y') | NO | | NULL | |
| Stem | text | NO | | NULL | |
| Feedback | text | NO | | NULL | |
| ImageName | varchar(43) | NO | | NULL | |
| ImageTitle | varchar(2047) | NO | | NULL | |
| ImageURL | varchar(255) | NO | | NULL | |
| MediaName | varchar(43) | NO | | | |
| MediaType | enum('jpg','gif') | NO | | jpg | |
| MediaTitle | varchar(2047) | NO | | | |
| MediaURL | varchar(255) | NO | | | |
| NumHits | int(11) | NO | | 0 | |
| NumHitsNotBlank | int(11) | NO | | 0 | |
| Score | double | NO | | 0 | |
+-----------------+---------------------------------------------------------------------------+------+-----+---------+----------------+
13 rows in set (0,00 sec)
14 rows in set (0.00 sec)
*/
DB_CreateTable ("CREATE TABLE IF NOT EXISTS tst_questions ("
"QstCod INT NOT NULL AUTO_INCREMENT,"
@ -2687,11 +2700,12 @@ mysql> DESCRIBE tst_questions;
"EditTime DATETIME NOT NULL,"
"AnsType ENUM ('int','float','true_false','unique_choice','multiple_choice','text') NOT NULL,"
"Shuffle ENUM('N','Y') NOT NULL,"
"Stem TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
"Feedback TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
"ImageName VARCHAR(43) NOT NULL," // Img_BYTES_NAME
"ImageTitle VARCHAR(2047) NOT NULL," // Img_MAX_BYTES_TITLE
"ImageURL VARCHAR(255) NOT NULL," // Cns_MAX_BYTES_WWW
"Stem TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
"Feedback TEXT NOT NULL," // Cns_MAX_BYTES_TEXT
"MediaName VARCHAR(43) NOT NULL DEFAULT ''," // Med_BYTES_NAME
"MediaType ENUM('jpg','gif') NOT NULL DEFAULT 'jpg',"
"MediaTitle VARCHAR(2047) NOT NULL DEFAULT ''," // Med_MAX_BYTES_TITLE
"MediaURL VARCHAR(255) NOT NULL DEFAULT ''," // Cns_MAX_BYTES_WWW
"NumHits INT NOT NULL DEFAULT 0,"
"NumHitsNotBlank INT NOT NULL DEFAULT 0,"
"Score DOUBLE PRECISION NOT NULL DEFAULT 0,"

View File

@ -273,7 +273,6 @@ struct Param *Fil_StartReceptionOfFile (const char *ParamFile,
bool Fil_EndReceptionOfFile (char *FileNameDataTmp,struct Param *Param)
{
extern const char *Txt_UPLOAD_FILE_File_too_large_maximum_X_MiB_NO_HTML;
FILE *FileDataTmp;
unsigned char Bytes[NUM_BYTES_PER_CHUNK];
size_t RemainingBytesToCopy;

View File

@ -282,8 +282,8 @@ static void For_InsertPstIntoBannedPstTable (long PstCod);
static long For_InsertForumPst (long ThrCod,long UsrCod,
const char *Subject,const char *Content,
struct Image *Image);
static bool For_RemoveForumPst (long PstCod,struct Image *Image);
struct Media *Media);
static bool For_RemoveForumPst (long PstCod,struct Media *Media);
static unsigned For_NumPstsInThrWithPstCod (long PstCod,long *ThrCod);
static long For_InsertForumThread (long FirstPstCod);
@ -313,7 +313,7 @@ static void For_ShowAForumPost (unsigned PstNum,long PstCod,
static void For_GetPstData (long PstCod,long *UsrCod,time_t *CreatTimeUTC,
char Subject[Cns_MAX_BYTES_SUBJECT + 1],
char Content[Cns_MAX_BYTES_LONG_TEXT + 1],
struct Image *Image);
struct Media *Media);
static void For_WriteNumberOfPosts (long UsrCod);
static void For_PutParamForumSet (For_ForumSet_t ForumSet);
@ -496,30 +496,30 @@ static void For_InsertPstIntoBannedPstTable (long PstCod)
static long For_InsertForumPst (long ThrCod,long UsrCod,
const char *Subject,const char *Content,
struct Image *Image)
struct Media *Media)
{
long PstCod;
/***** Check if image is received and processed *****/
if (Image->Action == Img_ACTION_NEW_IMAGE && // Upload new image
Image->Status == Img_FILE_PROCESSED) // The new image received has been processed
if (Media->Action == Med_ACTION_NEW_MEDIA && // Upload new image
Media->Status == Med_FILE_PROCESSED) // The new image received has been processed
/* Move processed image to definitive directory */
Img_MoveImageToDefinitiveDirectory (Image);
Med_MoveMediaToDefinitiveDirectory (Media);
/***** 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,ImageName,ImageTitle,ImageURL)"
"Subject,Content,MediaName,MediaTitle,MediaURL)"
" VALUES"
" (%ld,%ld,NOW(),NOW(),0,"
"'%s','%s','%s','%s','%s')",
ThrCod,UsrCod,
Subject,Content,
Image->Name,
Image->Title ? Image->Title : "",
Image->URL ? Image->URL : "");
Media->Name,
Media->Title ? Media->Title : "",
Media->URL ? Media->URL : "");
return PstCod;
}
@ -529,13 +529,13 @@ static long For_InsertForumPst (long ThrCod,long UsrCod,
/*****************************************************************************/
// Return true if the post thread is deleted
static bool For_RemoveForumPst (long PstCod,struct Image *Image)
static bool For_RemoveForumPst (long PstCod,struct Media *Media)
{
long ThrCod;
bool ThreadDeleted = false;
/***** Remove image file attached to forum post *****/
Img_RemoveImageFile (Image->Name);
/***** Remove media file attached to forum post *****/
Med_RemoveMediaFile (Media->Name,Media->Type);
/***** If the post is the only one in its thread, delete that thread *****/
if (For_NumPstsInThrWithPstCod (PstCod,&ThrCod) < 2)
@ -1157,7 +1157,7 @@ static void For_ShowAForumPost (unsigned PstNum,long PstCod,
char OriginalContent[Cns_MAX_BYTES_LONG_TEXT + 1];
char Subject[Cns_MAX_BYTES_SUBJECT + 1];
char Content[Cns_MAX_BYTES_LONG_TEXT + 1];
struct Image Image;
struct Media Media;
bool Enabled;
bool ItsMe;
@ -1165,14 +1165,14 @@ static void For_ShowAForumPost (unsigned PstNum,long PstCod,
Usr_UsrDataConstructor (&UsrDat);
/***** Initialize image *****/
Img_ImageConstructor (&Image);
Med_MediaConstructor (&Media);
/***** Check if post is enabled *****/
Enabled = For_GetIfPstIsEnabled (PstCod);
/***** Get data of post *****/
For_GetPstData (PstCod,&UsrDat.UsrCod,&CreatTimeUTC,
Subject,OriginalContent,&Image);
Subject,OriginalContent,&Media);
if (Enabled)
/* Return this subject as last subject */
@ -1308,7 +1308,7 @@ static void For_ShowAForumPost (unsigned PstNum,long PstCod,
Msg_WriteMsgContent (Content,Cns_MAX_BYTES_LONG_TEXT,true,false);
/***** Show image *****/
Img_ShowImage (&Image,"FOR_IMG_CONTAINER","FOR_IMG");
Med_ShowMedia (&Media,"FOR_IMG_CONTAINER","FOR_IMG");
}
else
fprintf (Gbl.F.Out,"%s",Txt_This_post_has_been_banned_probably_for_not_satisfy_the_rules_of_the_forums);
@ -1316,7 +1316,7 @@ static void For_ShowAForumPost (unsigned PstNum,long PstCod,
"</tr>");
/***** Free image *****/
Img_ImageDestructor (&Image);
Med_MediaDestructor (&Media);
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
@ -1329,7 +1329,7 @@ static void For_ShowAForumPost (unsigned PstNum,long PstCod,
static void For_GetPstData (long PstCod,long *UsrCod,time_t *CreatTimeUTC,
char Subject[Cns_MAX_BYTES_SUBJECT + 1],
char Content[Cns_MAX_BYTES_LONG_TEXT + 1],
struct Image *Image)
struct Media *Media)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
@ -1337,8 +1337,14 @@ static void For_GetPstData (long PstCod,long *UsrCod,time_t *CreatTimeUTC,
/***** Get data of a post from database *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get data of a post",
"SELECT UsrCod,UNIX_TIMESTAMP(CreatTime),"
"Subject,Content,ImageName,ImageTitle,ImageURL"
"SELECT UsrCod," // row[0]
"UNIX_TIMESTAMP(CreatTime)," // row[1]
"Subject," // row[2]
"Content," // row[3]
"MediaName," // row[4]
"MediaType," // row[5]
"MediaTitle," // row[6]
"MediaURL" // row[7]
" FROM forum_post WHERE PstCod=%ld",
PstCod);
@ -1363,8 +1369,9 @@ static void For_GetPstData (long PstCod,long *UsrCod,time_t *CreatTimeUTC,
Str_Copy (Content,row[3],
Cns_MAX_BYTES_LONG_TEXT);
/****** Get image name (row[4]), title (row[5]) and URL (row[6]) *****/
Img_GetImageNameTitleAndURLFromRow (row[4],row[5],row[6],Image);
/****** Get media name (row[4]), type (row[5]),
title (row[6]) and URL (row[7]) *****/
Med_GetMediaNameTitleAndURLFromRow (row[4],row[5],row[6],row[7],Media);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@ -3999,7 +4006,7 @@ static void For_WriteFormForumPst (bool IsReply,const char *Subject)
Lay_HelpPlainEditor ();
/***** Attached image (optional) *****/
Img_PutImageUploader (-1,"FOR_IMG_TIT_URL");
Med_PutMediaUploader (-1,"FOR_IMG_TIT_URL");
/***** Send button *****/
Btn_PutCreateButton (Txt_Send);
@ -4023,7 +4030,7 @@ void For_ReceiveForumPost (void)
unsigned NumUsrsToBeNotifiedByEMail;
struct SocialPublishing SocPub;
char Content[Cns_MAX_BYTES_LONG_TEXT + 1];
struct Image Image;
struct Media Media;
/***** Get parameters related to forum *****/
For_GetParamsForum ();
@ -4045,13 +4052,13 @@ void For_ReceiveForumPost (void)
Str_TO_RIGOROUS_HTML,false);
/***** Initialize image *****/
Img_ImageConstructor (&Image);
Med_MediaConstructor (&Media);
/***** Get attached image (action, file and title) *****/
Image.Width = For_IMAGE_SAVED_MAX_WIDTH;
Image.Height = For_IMAGE_SAVED_MAX_HEIGHT;
Image.Quality = For_IMAGE_SAVED_QUALITY;
Img_GetImageFromForm (-1,&Image,NULL);
Media.Width = For_IMAGE_SAVED_MAX_WIDTH;
Media.Height = For_IMAGE_SAVED_MAX_HEIGHT;
Media.Quality = For_IMAGE_SAVED_QUALITY;
Med_GetMediaFromForm (-1,&Media,NULL);
/***** Create a new message *****/
if (IsReply) // This post is a reply to another posts in the thread
@ -4060,7 +4067,7 @@ void For_ReceiveForumPost (void)
/***** Create last message of the thread *****/
PstCod = For_InsertForumPst (Gbl.Forum.ForumSelected.ThrCod,Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Msg.Subject,Content,&Image);
Gbl.Msg.Subject,Content,&Media);
/***** Modify last message of the thread *****/
For_UpdateThrLastPst (Gbl.Forum.ForumSelected.ThrCod,PstCod);
@ -4072,14 +4079,14 @@ void For_ReceiveForumPost (void)
/***** Create first (and last) message of the thread *****/
PstCod = For_InsertForumPst (Gbl.Forum.ForumSelected.ThrCod,Gbl.Usrs.Me.UsrDat.UsrCod,
Gbl.Msg.Subject,Content,&Image);
Gbl.Msg.Subject,Content,&Media);
/***** Update first and last posts of new thread *****/
For_UpdateThrFirstAndLastPst (Gbl.Forum.ForumSelected.ThrCod,PstCod,PstCod);
}
/***** Free image *****/
Img_ImageDestructor (&Image);
Med_MediaDestructor (&Media);
/***** Increment number of forum posts in my user's figures *****/
Prf_IncrementNumForPstUsr (Gbl.Usrs.Me.UsrDat.UsrCod);
@ -4148,7 +4155,7 @@ void For_RemovePost (void)
time_t CreatTimeUTC; // Creation time of a message
char Subject[Cns_MAX_BYTES_SUBJECT + 1];
char OriginalContent[Cns_MAX_BYTES_LONG_TEXT + 1];
struct Image Image;
struct Media Media;
bool ItsMe;
bool ThreadDeleted = false;
@ -4156,11 +4163,11 @@ void For_RemovePost (void)
For_GetParamsForum ();
/***** Initialize image *****/
Img_ImageConstructor (&Image);
Med_MediaConstructor (&Media);
/***** Get forum post data *****/
For_GetPstData (Gbl.Forum.ForumSelected.PstCod,&UsrDat.UsrCod,&CreatTimeUTC,
Subject,OriginalContent,&Image);
Subject,OriginalContent,&Media);
/***** Check if I can remove the post *****/
/* Check if the message really exists, if it has not been removed */
@ -4177,10 +4184,10 @@ 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,&Image);
ThreadDeleted = For_RemoveForumPst (Gbl.Forum.ForumSelected.PstCod,&Media);
/***** Free image *****/
Img_ImageDestructor (&Image);
Med_MediaDestructor (&Media);
/***** Mark possible notifications as removed *****/
Ntf_MarkNotifAsRemoved (Ntf_EVENT_FORUM_POST_COURSE,Gbl.Forum.ForumSelected.PstCod);

View File

@ -2729,23 +2729,15 @@ static void Gam_ListGameQuestions (struct Game *Game)
ActionToDoWithQuestions = Tst_SHOW_GAME_RESULT;
/***** Get data of questions from database *****/
/*
row[0] QstCod
row[1] AnsType
row[2] Stem
row[3] Feedback
row[4] ImageName
row[5] ImageTitle
row[6] ImageURL
*/
NumQsts = (unsigned) DB_QuerySELECT (&mysql_res,"can not get data of a question",
"SELECT tst_questions.QstCod,"
"tst_questions.AnsType,"
"tst_questions.Stem,"
"tst_questions.Feedback,"
"tst_questions.ImageName,"
"tst_questions.ImageTitle,"
"tst_questions.ImageURL"
"SELECT tst_questions.QstCod," // row[0]
"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]
" FROM gam_questions,tst_questions"
" WHERE gam_questions.GamCod=%ld"
" AND gam_questions.QstCod=tst_questions.QstCod"
@ -2850,9 +2842,10 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game,
row[1] AnsType
row[2] Stem
row[3] Feedback
row[4] ImageName
row[5] ImageTitle
row[6] ImageURL
row[4] MediaName
row[5] MediaType
row[6] MediaTitle
row[7] MediaURL
*/
/***** Create test question *****/
Tst_QstConstructor ();
@ -2930,13 +2923,14 @@ static void Gam_ListOneOrMoreQuestionsForEdition (struct Game *Game,
Tst_GetAndWriteTagsQst (Gbl.Test.QstCod);
fprintf (Gbl.F.Out,"</td>");
/* Write the stem (row[2]), the image (row[4], row[5], row[6]),
/* Write the stem (row[2]), the image (row[4], row[5], row[6], row[7]),
the feedback (row[3]) and the answers */
fprintf (Gbl.F.Out,"<td class=\"LEFT_TOP COLOR%u\">",
Gbl.RowEvenOdd);
Tst_WriteQstStem (row[2],"TEST_EDI");
Img_GetImageNameTitleAndURLFromRow (row[4],row[5],row[6],&Gbl.Test.Image);
Img_ShowImage (&Gbl.Test.Image,
Med_GetMediaNameTitleAndURLFromRow (row[4],row[5],row[6],row[7],
&Gbl.Test.Media);
Med_ShowMedia (&Gbl.Test.Media,
"TEST_IMG_EDIT_LIST_STEM_CONTAINER",
"TEST_IMG_EDIT_LIST_STEM");
Tst_WriteQstFeedback (row[3],"TEST_EDI_LIGHT");
@ -3534,22 +3528,14 @@ static void Gam_PlayGameShowQuestionAndAnswers (bool ShowAnswers)
QstInd = Gam_GetParamQstInd ();
/***** Get data of question from database *****/
/*
row[0] AnsType
row[1] QstCod
row[2] Stem
row[3] ImageName
row[4] ImageTitle
row[5] ImageURL
*/
if (!DB_QuerySELECT (&mysql_res,"can not get data of a question",
"SELECT "
"tst_questions.QstCod,"
"tst_questions.AnsType,"
"tst_questions.Stem,"
"tst_questions.ImageName,"
"tst_questions.ImageTitle,"
"tst_questions.ImageURL"
"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]
" FROM gam_questions,tst_questions"
" WHERE gam_questions.GamCod=%ld"
" AND gam_questions.QstInd=%u"
@ -3568,10 +3554,11 @@ static void Gam_PlayGameShowQuestionAndAnswers (bool ShowAnswers)
fprintf (Gbl.F.Out,"<div class=\"GAM_PLAY_QST_CONTAINER\">");
/* Write the stem (row[2]) and the image (row[3], row[4], row[5]) */
/* Write the stem (row[2]) and the image (row[3], row[4], row[5], row[6]) */
Tst_WriteQstStem (row[2],"GAM_PLAY_QST");
Img_GetImageNameTitleAndURLFromRow (row[3],row[4],row[5],&Gbl.Test.Image);
Img_ShowImage (&Gbl.Test.Image,
Med_GetMediaNameTitleAndURLFromRow (row[3],row[4],row[5],row[6],
&Gbl.Test.Media);
Med_ShowMedia (&Gbl.Test.Media,
"TEST_IMG_EDIT_LIST_STEM_CONTAINER",
"TEST_IMG_EDIT_LIST_STEM");

View File

@ -54,7 +54,6 @@
#include "swad_forum.h"
#include "swad_game.h"
#include "swad_holiday.h"
#include "swad_image.h"
#include "swad_icon.h"
#include "swad_indicator.h"
#include "swad_institution.h"
@ -62,8 +61,9 @@
#include "swad_link.h"
#include "swad_mail.h"
#include "swad_mark.h"
#include "swad_message.h"
#include "swad_media.h"
#include "swad_menu.h"
#include "swad_message.h"
#include "swad_parameter.h"
#include "swad_password.h"
#include "swad_photo.h"
@ -702,7 +702,7 @@ struct Globals
char *Text;
size_t Length;
} Stem, Feedback;
struct Image Image;
struct Media Media;
bool Shuffle;
struct
{
@ -713,7 +713,7 @@ struct Globals
bool Correct;
char *Text;
char *Feedback;
struct Image Image;
struct Media Media;
} Options[Tst_MAX_OPTIONS_PER_QUESTION];
long Integer;
double FloatingPoint[2];

View File

@ -1,673 +0,0 @@
// swad_image.c: processing of image uploaded in a form
/*
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2019 Antonio Cañas Vargas
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General 3 License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/*********************************** Headers *********************************/
/*****************************************************************************/
#include <linux/limits.h> // For PATH_MAX
#include <stdbool.h> // For boolean type
#include <stdlib.h> // For exit, system, malloc, free, etc
#include <string.h> // For string functions
#include <sys/wait.h> // For the macro WEXITSTATUS
#include <unistd.h> // For unlink
#include "swad_config.h"
#include "swad_global.h"
#include "swad_file.h"
#include "swad_file_browser.h"
#include "swad_form.h"
#include "swad_image.h"
/*****************************************************************************/
/****************************** Public constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Internal constants ****************************/
/*****************************************************************************/
/*****************************************************************************/
/****************************** Internal types *******************************/
/*****************************************************************************/
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/************************* Internal global variables *************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Internal prototypes ***************************/
/*****************************************************************************/
static Img_Action_t Img_GetImageActionFromForm (const char *ParamAction);
static void Img_GetAndProcessImageFileFromForm (struct Image *Image,
const char *ParamFile);
static int Img_ProcessImage (struct Image *Image,
const char *FileNameImgOriginal,
const char *FileNameImgProcessed);
/*****************************************************************************/
/*************************** Reset image fields ******************************/
/*****************************************************************************/
// Every struct Image must be initialized with this function Img_ImageConstructor after it is declared
// Every call to Img_ImageConstructor must have a call to Img_ImageDestructor
void Img_ImageConstructor (struct Image *Image)
{
Img_ResetImageExceptTitleAndURL (Image);
Image->Title = NULL;
Image->URL = NULL;
}
/*****************************************************************************/
/***************** Reset image fields except title and URL *******************/
/*****************************************************************************/
void Img_ResetImageExceptTitleAndURL (struct Image *Image)
{
Image->Action = Img_ACTION_NO_IMAGE;
Image->Status = Img_FILE_NONE;
Image->Name[0] = '\0';
}
/*****************************************************************************/
/******************************** Free image *********************************/
/*****************************************************************************/
// Every call to Img_ImageConstructor must have a call to Img_ImageDestructor
void Img_ImageDestructor (struct Image *Image)
{
Img_FreeImageTitle (Image);
Img_FreeImageURL (Image);
}
/*****************************************************************************/
/****************************** Free image title *****************************/
/*****************************************************************************/
void Img_FreeImageTitle (struct Image *Image)
{
// Image->Title must be initialized to NULL after declaration
if (Image->Title)
{
free ((void *) Image->Title);
Image->Title = NULL;
}
}
/*****************************************************************************/
/******************************* Free image URL ******************************/
/*****************************************************************************/
void Img_FreeImageURL (struct Image *Image)
{
// Image->URL must be initialized to NULL after declaration
if (Image->URL)
{
free ((void *) Image->URL);
Image->URL = NULL;
}
}
/*****************************************************************************/
/**** Get image name, title and URL from a query result and copy to struct ***/
/*****************************************************************************/
void Img_GetImageNameTitleAndURLFromRow (const char *Name,
const char *Title,
const char *URL,
struct Image *Image)
{
size_t Length;
/***** Copy image name to struct *****/
Str_Copy (Image->Name,Name,
Img_BYTES_NAME);
/***** Set status of image file *****/
Image->Status = Image->Name[0] ? Img_NAME_STORED_IN_DB :
Img_FILE_NONE;
/***** Copy image title to struct *****/
// Image->Title can be empty or filled with previous value
// If filled ==> free it
Img_FreeImageTitle (Image);
if (Title[0])
{
/* Get and limit length of the title */
Length = strlen (Title);
if (Length > Img_MAX_BYTES_TITLE)
Length = Img_MAX_BYTES_TITLE;
if ((Image->Title = (char *) malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for image title.");
Str_Copy (Image->Title,Title,
Length);
}
/***** Copy image URL to struct *****/
// Image->URL can be empty or filled with previous value
// If filled ==> free it
Img_FreeImageURL (Image);
if (URL[0])
{
/* Get and limit length of the URL */
Length = strlen (URL);
if (Length > Img_MAX_BYTES_TITLE)
Length = Img_MAX_BYTES_TITLE;
if ((Image->URL = (char *) malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for image URL.");
Str_Copy (Image->URL,URL,
Length);
}
}
/*****************************************************************************/
/************ Draw input fields to upload an image inside a form *************/
/*****************************************************************************/
void Img_PutImageUploader (int NumImgInForm,const char *ClassImgTitURL)
{
extern const char *Txt_Image;
extern const char *Txt_optional;
extern const char *Txt_Image_title_attribution;
extern const char *Txt_Link;
struct ParamUploadImg ParamUploadImg;
char Id[Frm_MAX_BYTES_ID + 1];
/***** Set names of parameters depending on number of image in form *****/
Img_SetParamNames (&ParamUploadImg,NumImgInForm);
/***** Create unique id for this image uploader *****/
Frm_SetUniqueId (Id);
/***** Start container *****/
fprintf (Gbl.F.Out,"<div class=\"IMG_UPLOAD_CONTAINER\">");
/***** Action to perform on image *****/
Par_PutHiddenParamUnsigned (ParamUploadImg.Action,(unsigned) Img_ACTION_NEW_IMAGE);
/***** Image file *****/
fprintf (Gbl.F.Out,"<label class=\"IMG_UPLOAD_BUTTON\">"
"<img src=\"%s/camera.svg\""
" alt=\"%s\" title=\"%s (%s)\""
" class=\"IMG_UPLOAD_ICO\" />"
"<input type=\"file\" name=\"%s\" accept=\"image/*\""
" class=\"IMG_UPLOAD_FILE\""
" onchange=\"imageUploadOnSelectFile (this,'%s');\" />"
"<span id=\"%s_fil\" class=\"IMG_UPLOAD_FILENAME\" />"
"</span>"
"</label>",
Gbl.Prefs.URLIcons,
Txt_Image,Txt_Image,Txt_optional,
ParamUploadImg.File,
Id,Id);
/***** Image title/attribution and URL *****/
fprintf (Gbl.F.Out,"<div id=\"%s_tit_url\" style=\"display:none;\">",
Id);
fprintf (Gbl.F.Out,"<input type=\"text\" name=\"%s\""
" placeholder=\"%s (%s)\""
" class=\"%s\" maxlength=\"%u\" value=\"\" />",
ParamUploadImg.Title,
Txt_Image_title_attribution,Txt_optional,
ClassImgTitURL,Img_MAX_CHARS_TITLE);
fprintf (Gbl.F.Out,"<br />"
"<input type=\"url\" name=\"%s\""
" placeholder=\"%s (%s)\""
" class=\"%s\" maxlength=\"%u\" value=\"\" />",
ParamUploadImg.URL,
Txt_Link,Txt_optional,
ClassImgTitURL,Cns_MAX_CHARS_WWW);
fprintf (Gbl.F.Out,"</div>");
/***** End container *****/
fprintf (Gbl.F.Out,"</div>");
}
/*****************************************************************************/
/***************************** Get image from form ***************************/
/*****************************************************************************/
// If NumImgInForm < 0, params have no suffix
// If NumImgInForm >= 0, the number is a suffix of the params
void Img_GetImageFromForm (int NumImgInForm,struct Image *Image,
void (*GetImageFromDB) (int NumImgInForm,struct Image *Image))
{
struct ParamUploadImg ParamUploadImg;
char Title[Img_MAX_BYTES_TITLE + 1];
char URL[Cns_MAX_BYTES_WWW + 1];
size_t Length;
/***** Set names of parameters depending on number of image in form *****/
Img_SetParamNames (&ParamUploadImg,NumImgInForm);
/***** First, get action and initialize image
(except title, that will be get after the image file) *****/
Image->Action = Img_GetImageActionFromForm (ParamUploadImg.Action);
Image->Status = Img_FILE_NONE;
Image->Name[0] = '\0';
/***** Secondly, get the image name and the file *****/
switch (Image->Action)
{
case Img_ACTION_NEW_IMAGE: // Upload new image
/***** Get new image (if present ==> process and create temporary file) *****/
Img_GetAndProcessImageFileFromForm (Image,ParamUploadImg.File);
switch (Image->Status)
{
case Img_FILE_NONE: // No new image received
Image->Action = Img_ACTION_NO_IMAGE;
Image->Name[0] = '\0';
break;
case Img_FILE_RECEIVED: // New image received, but not processed
Image->Status = Img_FILE_NONE;
Image->Name[0] = '\0';
break;
default:
break;
}
break;
case Img_ACTION_KEEP_IMAGE: // Keep current image unchanged
/***** Get image name *****/
if (GetImageFromDB != NULL)
GetImageFromDB (NumImgInForm,Image);
break;
case Img_ACTION_CHANGE_IMAGE: // Replace old image by new image
/***** Get new image (if present ==> process and create temporary file) *****/
Img_GetAndProcessImageFileFromForm (Image,ParamUploadImg.File);
if (Image->Status != Img_FILE_PROCESSED && // No new image received-processed successfully
GetImageFromDB != NULL)
/* Get image name */
GetImageFromDB (NumImgInForm,Image);
break;
case Img_ACTION_NO_IMAGE: // Do not use image (remove current image if exists)
break;
}
/***** Third, get image title from form *****/
Par_GetParToText (ParamUploadImg.Title,Title,Img_MAX_BYTES_TITLE);
/* If the title coming from the form is empty, keep current image title unchanged
If not empty, copy it to current image title */
if ((Length = strlen (Title)) > 0)
{
/* Overwrite current title (empty or coming from database)
with the title coming from the form */
Img_FreeImageTitle (Image);
if ((Image->Title = (char *) malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for image title.");
Str_Copy (Image->Title,Title,
Length);
}
/***** By last, get image URL from form *****/
Par_GetParToText (ParamUploadImg.URL,URL,Cns_MAX_BYTES_WWW);
/* If the URL coming from the form is empty, keep current image URL unchanged
If not empty, copy it to current image URL */
if ((Length = strlen (URL)) > 0)
{
/* Overwrite current URL (empty or coming from database)
with the URL coming from the form */
Img_FreeImageURL (Image);
if ((Image->URL = (char *) malloc (Length + 1)) == NULL)
Lay_ShowErrorAndExit ("Error allocating memory for image URL.");
Str_Copy (Image->URL,URL,
Length);
}
}
/*****************************************************************************/
/********* Set parameters names depending on number of image in form *********/
/*****************************************************************************/
// If NumImgInForm < 0, params have no suffix
// If NumImgInForm >= 0, the number is a suffix of the params
void Img_SetParamNames (struct ParamUploadImg *ParamUploadImg,int NumImgInForm)
{
if (NumImgInForm < 0) // One unique image in form ==> no suffix needed
{
Str_Copy (ParamUploadImg->Action,"ImgAct",
Img_MAX_BYTES_PARAM_UPLOAD_IMG);
Str_Copy (ParamUploadImg->File ,"ImgFil",
Img_MAX_BYTES_PARAM_UPLOAD_IMG);
Str_Copy (ParamUploadImg->Title ,"ImgTit",
Img_MAX_BYTES_PARAM_UPLOAD_IMG);
Str_Copy (ParamUploadImg->URL ,"ImgURL",
Img_MAX_BYTES_PARAM_UPLOAD_IMG);
}
else // Several images in form ==> add suffix
{
snprintf (ParamUploadImg->Action,sizeof (ParamUploadImg->Action),
"ImgAct%u",
NumImgInForm);
snprintf (ParamUploadImg->File ,sizeof (ParamUploadImg->File),
"ImgFil%u",
NumImgInForm);
snprintf (ParamUploadImg->Title ,sizeof (ParamUploadImg->Title),
"ImgTit%u",
NumImgInForm);
snprintf (ParamUploadImg->URL ,sizeof (ParamUploadImg->URL),
"ImgURL%u",
NumImgInForm);
}
}
/*****************************************************************************/
/************************* Get image action from form ************************/
/*****************************************************************************/
static Img_Action_t Img_GetImageActionFromForm (const char *ParamAction)
{
/***** Get parameter with the action to perform on image *****/
return (Img_Action_t)
Par_GetParToUnsignedLong (ParamAction,
0,
Img_NUM_ACTIONS - 1,
(unsigned long) Img_ACTION_DEFAULT);
}
/*****************************************************************************/
/**************************** Get image from form ****************************/
/*****************************************************************************/
static void Img_GetAndProcessImageFileFromForm (struct Image *Image,
const char *ParamFile)
{
extern const char *Txt_The_image_could_not_be_processed_successfully;
struct Param *Param;
char FileNameImgSrc[PATH_MAX + 1];
char *PtrExtension;
size_t LengthExtension;
char MIMEType[Brw_MAX_BYTES_MIME_TYPE + 1];
char PathImgPriv[PATH_MAX + 1];
char FileNameImgOrig[PATH_MAX + 1]; // Full name of original uploaded file
char FileNameImgTmp[PATH_MAX + 1]; // Full name of temporary processed file
bool WrongType = false;
/***** Set image file status *****/
Image->Status = Img_FILE_NONE;
/***** Get filename and MIME type *****/
Param = Fil_StartReceptionOfFile (ParamFile,FileNameImgSrc,MIMEType);
if (!FileNameImgSrc[0]) // No file present
return;
/* Get filename extension */
if ((PtrExtension = strrchr (FileNameImgSrc,(int) '.')) == NULL)
return;
// PtrExtension now points to last '.' in file
PtrExtension++;
// PtrExtension now points to first char in extension
LengthExtension = strlen (PtrExtension);
if (LengthExtension < Fil_MIN_BYTES_FILE_EXTENSION ||
LengthExtension > Fil_MAX_BYTES_FILE_EXTENSION)
return;
/* Check if the file type is image/ or application/octet-stream */
if (strncmp (MIMEType,"image/",strlen ("image/")))
if (strcmp (MIMEType,"application/octet-stream"))
if (strcmp (MIMEType,"application/octetstream"))
if (strcmp (MIMEType,"application/octet"))
WrongType = true;
if (WrongType)
return;
/***** Assign a unique name for the image *****/
Cry_CreateUniqueNameEncrypted (Image->Name);
/***** Create private directories if not exist *****/
/* Create private directory for images if it does not exist */
snprintf (PathImgPriv,sizeof (PathImgPriv),
"%s/%s",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG);
Fil_CreateDirIfNotExists (PathImgPriv);
/* Create temporary private directory for images if it does not exist */
snprintf (PathImgPriv,sizeof (PathImgPriv),
"%s/%s/%s",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG,Cfg_FOLDER_IMG_TMP);
Fil_CreateDirIfNotExists (PathImgPriv);
/***** Remove old temporary private files *****/
Fil_RemoveOldTmpFiles (PathImgPriv,Cfg_TIME_TO_DELETE_IMAGES_TMP_FILES,false);
/***** End the reception of original not processed image
(it may be very big) into a temporary file *****/
Image->Status = Img_FILE_NONE;
snprintf (FileNameImgOrig,sizeof (FileNameImgOrig),
"%s/%s/%s/%s_original.%s",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG,Cfg_FOLDER_IMG_TMP,
Image->Name,PtrExtension);
if (Fil_EndReceptionOfFile (FileNameImgOrig,Param)) // Success
{
Image->Status = Img_FILE_RECEIVED;
/***** Convert original image to temporary JPEG processed file
by calling to program that makes the conversion *****/
snprintf (FileNameImgTmp,sizeof (FileNameImgTmp),
"%s/%s/%s/%s.jpg",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG,Cfg_FOLDER_IMG_TMP,
Image->Name);
if (Img_ProcessImage (Image,FileNameImgOrig,FileNameImgTmp) == 0) // Return 0 on success
/* Success */
Image->Status = Img_FILE_PROCESSED;
else // Error processing image
{
/* Error ==> remove temporary destination image file */
if (Fil_CheckIfPathExists (FileNameImgTmp))
unlink (FileNameImgTmp);
/* Show error alert */
Ale_ShowAlert (Ale_ERROR,Txt_The_image_could_not_be_processed_successfully);
}
/***** Remove temporary original file *****/
unlink (FileNameImgOrig);
}
}
/*****************************************************************************/
/************ Process original image generating processed image **************/
/*****************************************************************************/
// Return 0 on success
// Return != 0 on error
static int Img_ProcessImage (struct Image *Image,
const char *FileNameImgOriginal,
const char *FileNameImgProcessed)
{
char Command[1024 + PATH_MAX * 2];
int ReturnCode;
// char ErrorMsg[256];
snprintf (Command,sizeof (Command),
"convert %s -resize '%ux%u>' -quality %u %s",
FileNameImgOriginal,
Image->Width,
Image->Height,
Image->Quality,
FileNameImgProcessed);
ReturnCode = system (Command);
if (ReturnCode == -1)
Lay_ShowErrorAndExit ("Error when running command to process image.");
ReturnCode = WEXITSTATUS(ReturnCode);
return ReturnCode;
}
/*****************************************************************************/
/**** Move temporary processed image file to definitive private directory ****/
/*****************************************************************************/
void Img_MoveImageToDefinitiveDirectory (struct Image *Image)
{
char PathImgPriv[PATH_MAX + 1];
char FileNameImgTmp[PATH_MAX + 1]; // Full name of temporary processed file
char FileNameImg[PATH_MAX + 1]; // Full name of definitive processed file
/***** Create subdirectory if it does not exist *****/
snprintf (PathImgPriv,sizeof (PathImgPriv),
"%s/%s/%c%c",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG,
Image->Name[0],
Image->Name[1]);
Fil_CreateDirIfNotExists (PathImgPriv);
/***** Temporary processed file *****/
snprintf (FileNameImgTmp,sizeof (FileNameImgTmp),
"%s/%s/%s/%s.jpg",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG,Cfg_FOLDER_IMG_TMP,
Image->Name);
/***** Definitive processed file *****/
snprintf (FileNameImg,sizeof (FileNameImg),
"%s/%s/%c%c/%s.jpg",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG,
Image->Name[0],
Image->Name[1],
Image->Name);
/***** Move file *****/
if (rename (FileNameImgTmp,FileNameImg)) // Fail
Ale_ShowAlert (Ale_ERROR,"Can not move file.");
else // Success
Image->Status = Img_FILE_MOVED;
}
/*****************************************************************************/
/****** Show a user uploaded image (in a test question, timeline, etc.) ******/
/*****************************************************************************/
void Img_ShowImage (struct Image *Image,
const char *ClassContainer,const char *ClassImg)
{
extern const char *Txt_Image_not_found;
char FileNameImgPriv[PATH_MAX + 1];
char FullPathImgPriv[PATH_MAX + 1];
char URL[PATH_MAX + 1];
bool PutLink;
/***** If no image to show ==> nothing to do *****/
if (!Image->Name)
return;
if (!Image->Name[0])
return;
if (Image->Status != Img_NAME_STORED_IN_DB)
return;
/***** Create a temporary public directory used to show the image *****/
Brw_CreateDirDownloadTmp ();
/***** Build private path to image *****/
snprintf (FileNameImgPriv,sizeof (FileNameImgPriv),
"%s.jpg",
Image->Name);
snprintf (FullPathImgPriv,sizeof (FullPathImgPriv),
"%s/%s/%c%c/%s",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG,
Image->Name[0],
Image->Name[1],
FileNameImgPriv);
/***** Check if private image file exists *****/
if (Fil_CheckIfPathExists (FullPathImgPriv))
{
/***** Create symbolic link from temporary public directory to private file
in order to gain access to it for showing/downloading *****/
Brw_CreateTmpPublicLinkToPrivateFile (FullPathImgPriv,FileNameImgPriv);
/***** Create URL pointing to symbolic link *****/
snprintf (URL,sizeof (URL),
"%s/%s/%s/%s",
Cfg_URL_SWAD_PUBLIC,Cfg_FOLDER_FILE_BROWSER_TMP,
Gbl.FileBrowser.TmpPubDir,
FileNameImgPriv);
/***** Show image *****/
/* Check if optional link is present */
PutLink = false;
if (Image->URL)
if (Image->URL[0])
PutLink = true;
/* Start image container */
fprintf (Gbl.F.Out,"<div class=\"%s\">",ClassContainer);
/* Start optional link to external URL */
if (PutLink)
fprintf (Gbl.F.Out,"<a href=\"%s\" target=\"_blank\">",Image->URL);
/* Image */
fprintf (Gbl.F.Out,"<img src=\"%s\" class=\"%s\" alt=\"\"",URL,ClassImg);
if (Image->Title)
if (Image->Title[0])
fprintf (Gbl.F.Out," title=\"%s\"",Image->Title);
fprintf (Gbl.F.Out," lazyload=\"on\" />"); // Lazy load of the image
/* End optional link to external URL */
if (PutLink)
fprintf (Gbl.F.Out,"</a>");
/* End image container */
fprintf (Gbl.F.Out,"</div>");
}
else
Ale_ShowAlert (Ale_WARNING,Txt_Image_not_found);
}
/*****************************************************************************/
/** Remove private file with an image, given the image name (without .jpg) ***/
/*****************************************************************************/
void Img_RemoveImageFile (const char *ImageName)
{
char FullPathImgPriv[PATH_MAX + 1];
if (ImageName[0])
{
/***** Build path to private file *****/
snprintf (FullPathImgPriv,sizeof (FullPathImgPriv),
"%s/%s/%c%c/%s.jpg",
Cfg_PATH_SWAD_PRIVATE,Cfg_FOLDER_IMG,
ImageName[0],
ImageName[1],
ImageName);
/***** Remove private file *****/
unlink (FullPathImgPriv);
// Public links are removed automatically after a period
}
}

View File

@ -1,142 +0,0 @@
// swad_image.h: processing of image uploaded in a form
#ifndef _SWAD_IMG
#define _SWAD_IMG
/*
SWAD (Shared Workspace At a Distance in Spanish),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2019 Antonio Cañas Vargas
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Public constants ******************************/
/*****************************************************************************/
#define Img_BYTES_NAME Cry_BYTES_ENCRYPTED_STR_SHA256_BASE64
#define Img_MAX_CHARS_TITLE (128 - 1) // 127
#define Img_MAX_BYTES_TITLE ((Img_MAX_CHARS_TITLE + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 2047
#define Img_MAX_CHARS_ATTRIBUTION (256 - 1) // 255
#define Img_MAX_BYTES_ATTRIBUTION ((Img_MAX_CHARS_ATTRIBUTION + 1) * Str_MAX_BYTES_PER_CHAR - 1) // 4095
/*****************************************************************************/
/******************************* Public types ********************************/
/*****************************************************************************/
/***** Action to perform when editing a form with an image *****/
#define Img_NUM_ACTIONS 4
typedef enum
{
Img_ACTION_NEW_IMAGE, // Upload new image
Img_ACTION_KEEP_IMAGE, // Keep current image unchanged
Img_ACTION_CHANGE_IMAGE, // Change existing image by a new image
Img_ACTION_NO_IMAGE, // Do not use image (remove current image if exists)
} Img_Action_t;
#define Img_ACTION_DEFAULT Img_ACTION_NO_IMAGE
/***** Status of an image file *****/
/*
No image Original file Temporary Definitive Name of the image
uploaded uploaded by user processed image processed image stored in database
--------- --------------------------- ------------------ ------------------ ---------------------
Img_NONE Img_FILE_RECEIVED Img_FILE_PROCESSED Img_FILE_MOVED Img_NAME_STORED_IN_DB
--------- --------------------------- ------------------ ------------------ ---------------------
-> upload-file -> -> process-file -> b -> move-file -> -> insert-name ->
--------- --------------------------- ------------------ ------------------ ---------------------
file.ext / / / xx-unique-name
| | |
var var var
| | |
www www www
| | |
swad swad swad
| | |
img img img
| | |
tmp tmp xx (2 first chars)
| | |
xx-unique-name_original.ext xx-unique-name.jpg xx-unique-name.jpg
xx-unique-name: a unique name encrypted starting by two random chars xx
*/
typedef enum
{
Img_FILE_NONE,
Img_FILE_RECEIVED,
Img_FILE_PROCESSED,
Img_FILE_MOVED,
Img_NAME_STORED_IN_DB,
} Img_FileStatus_t;
/***** Struct used to get images from forms *****/
struct Image
{
Img_Action_t Action;
Img_FileStatus_t Status;
char Name[Img_BYTES_NAME + 1];
char *Title; // Title/attribution (it must be initialized to NULL
// in order to not trying to free it when no memory allocated)
char *URL; // URL, i.e. link to original big photo or video
// (it must be initialized to NULL
// in order to not trying to free it when no memory allocated)
unsigned Width;
unsigned Height;
unsigned Quality;
};
/***** Parameters used in a form to upload an image *****/
#define Img_MAX_BYTES_PARAM_UPLOAD_IMG (16 - 1)
struct ParamUploadImg
{
char Action[Img_MAX_BYTES_PARAM_UPLOAD_IMG + 1];
char File [Img_MAX_BYTES_PARAM_UPLOAD_IMG + 1];
char Title [Img_MAX_BYTES_PARAM_UPLOAD_IMG + 1];
char URL [Img_MAX_BYTES_PARAM_UPLOAD_IMG + 1];
};
/*****************************************************************************/
/***************************** Public prototypes *****************************/
/*****************************************************************************/
void Img_ImageConstructor (struct Image *Image);
void Img_ResetImageExceptTitleAndURL (struct Image *Image);
void Img_ImageDestructor (struct Image *Image);
void Img_FreeImageTitle (struct Image *Image);
void Img_FreeImageURL (struct Image *Image);
void Img_GetImageNameTitleAndURLFromRow (const char *Name,
const char *Title,
const char *URL,
struct Image *Image);
void Img_PutImageUploader (int NumImgInForm,const char *ClassImgTitURL);
void Img_GetImageFromForm (int NumImgInForm,struct Image *Image,
void (*GetImageFromDB) (int NumImgInForm,struct Image *Image));
void Img_SetParamNames (struct ParamUploadImg *ParamUploadImg,int NumImgInForm);
void Img_MoveImageToDefinitiveDirectory (struct Image *Image);
void Img_ShowImage (struct Image *Image,
const char *ClassContainer,const char *ClassImg);
void Img_RemoveImageFile (const char *ImageName);
#endif

View File

@ -121,7 +121,7 @@ static void Msg_ContractSentMsg (long MsgCod);
static void Msg_ContractReceivedMsg (long MsgCod);
static long Msg_InsertNewMsg (const char *Subject,const char *Content,
struct Image *Image);
struct Media *Media);
static unsigned long Msg_DelSomeRecOrSntMsgsUsr (Msg_TypeOfMessages_t TypeOfMessages,long UsrCod,
long FilterCrsCod,const char *FilterFromToSubquery);
@ -139,7 +139,7 @@ static void Msg_GetMsgSntData (long MsgCod,long *CrsCod,long *UsrCod,
char Subject[Cns_MAX_BYTES_SUBJECT + 1],
bool *Deleted);
static void Msg_GetMsgContent (long MsgCod,char Content[Cns_MAX_BYTES_LONG_TEXT + 1],
struct Image *Image);
struct Media *Media);
static void Msg_WriteSentOrReceivedMsgSubject (long MsgCod,const char *Subject,bool Open,bool Expanded);
static void Msg_WriteFormToReply (long MsgCod,long CrsCod,
@ -325,7 +325,7 @@ static void Msg_PutFormMsgUsrs (char Content[Cns_MAX_BYTES_LONG_TEXT + 1])
Lay_HelpPlainEditor ();
/***** Attached image (optional) *****/
Img_PutImageUploader (-1,"MSG_IMG_TIT_URL");
Med_PutMediaUploader (-1,"MSG_IMG_TIT_URL");
/***** Send button *****/
Btn_PutCreateButton (Txt_Send_message);
@ -669,7 +669,7 @@ void Msg_RecMsgFromUsr (void)
bool CreateNotif;
bool NotifyByEmail;
char Content[Cns_MAX_BYTES_LONG_TEXT + 1];
struct Image Image;
struct Media Media;
bool Error = false;
/***** Get data from form *****/
@ -727,13 +727,13 @@ void Msg_RecMsgFromUsr (void)
Usr_UsrDataConstructor (&UsrDstData);
/***** Initialize image *****/
Img_ImageConstructor (&Image);
Med_MediaConstructor (&Media);
/***** Get attached image (action, file and title) *****/
Image.Width = Msg_IMAGE_SAVED_MAX_WIDTH;
Image.Height = Msg_IMAGE_SAVED_MAX_HEIGHT;
Image.Quality = Msg_IMAGE_SAVED_QUALITY;
Img_GetImageFromForm (-1,&Image,NULL);
Media.Width = Msg_IMAGE_SAVED_MAX_WIDTH;
Media.Height = Msg_IMAGE_SAVED_MAX_HEIGHT;
Media.Quality = Msg_IMAGE_SAVED_QUALITY;
Med_GetMediaFromForm (-1,&Media,NULL);
/***** Loop over the list Gbl.Usrs.Select[Rol_UNK], that holds the list of the
recipients, creating a received message for each recipient *****/
@ -761,7 +761,7 @@ void Msg_RecMsgFromUsr (void)
if (!MsgAlreadyInserted)
{
// The message is inserted only once in the table of messages sent
NewMsgCod = Msg_InsertNewMsg (Gbl.Msg.Subject,Content,&Image);
NewMsgCod = Msg_InsertNewMsg (Gbl.Msg.Subject,Content,&Media);
MsgAlreadyInserted = true;
}
@ -806,7 +806,7 @@ void Msg_RecMsgFromUsr (void)
}
/***** Free image *****/
Img_ImageDestructor (&Image);
Med_MediaDestructor (&Media);
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDstData);
@ -1277,27 +1277,28 @@ void Msg_SetReceivedMsgAsOpen (long MsgCod,long UsrCod)
// Return the code of the new inserted message
static long Msg_InsertNewMsg (const char *Subject,const char *Content,
struct Image *Image)
struct Media *Media)
{
long MsgCod;
/***** Check if image is received and processed *****/
if (Image->Action == Img_ACTION_NEW_IMAGE && // Upload new image
Image->Status == Img_FILE_PROCESSED) // The new image received has been processed
if (Media->Action == Med_ACTION_NEW_MEDIA && // Upload new image
Media->Status == Med_FILE_PROCESSED) // The new image received has been processed
/* Move processed image to definitive directory */
Img_MoveImageToDefinitiveDirectory (Image);
Med_MoveMediaToDefinitiveDirectory (Media);
/***** Insert message subject and content in the database *****/
MsgCod =
DB_QueryINSERTandReturnCode ("can not create message",
"INSERT INTO msg_content"
" (Subject,Content,ImageName,ImageTitle,ImageURL)"
" (Subject,Content,MediaName,MediaType,MediaTitle,MediaURL)"
" VALUES"
" ('%s','%s','%s','%s','%s')",
" ('%s','%s','%s','%s','%s','%s')",
Subject,Content,
Image->Name,
Image->Title ? Image->Title : "",
Image->URL ? Image->URL : "");
Media->Name,
Med_GetStringTypeForDB (Media->Type),
Media->Title ? Media->Title : "",
Media->URL ? Media->URL : "");
/***** Insert message in sent messages *****/
DB_QueryINSERT ("can not create message",
@ -1490,8 +1491,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,ImageName,ImageTitle,ImageURL)"
" SELECT MsgCod,Subject,Content,ImageName,ImageTitle,ImageURL"
" (MsgCod,Subject,Content,MediaName,MediaType,MediaTitle,MediaURL)"
" SELECT MsgCod,Subject,Content,MediaName,MediaType,MediaTitle,MediaURL"
" FROM msg_content WHERE MsgCod=%ld",
MsgCod);
@ -2774,7 +2775,7 @@ void Msg_GetMsgSubject (long MsgCod,char Subject[Cns_MAX_BYTES_SUBJECT + 1])
/*****************************************************************************/
static void Msg_GetMsgContent (long MsgCod,char Content[Cns_MAX_BYTES_LONG_TEXT + 1],
struct Image *Image)
struct Media *Media)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
@ -2782,7 +2783,11 @@ 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,ImageName,ImageTitle,ImageURL"
"SELECT Content," // row[0]
"MediaName," // row[1]
"MediaType," // row[2]
"MediaTitle," // row[3]
"MediaURL" // row[4]
" FROM msg_content WHERE MsgCod=%ld",
MsgCod);
@ -2797,8 +2802,8 @@ static void Msg_GetMsgContent (long MsgCod,char Content[Cns_MAX_BYTES_LONG_TEXT
Str_Copy (Content,row[0],
Cns_MAX_BYTES_LONG_TEXT);
/****** Get image name (row[1]), title (row[2]) and URL (row[3]) *****/
Img_GetImageNameTitleAndURLFromRow (row[1],row[2],row[3],Image);
/****** Get image name (row[1]), type (row[2]), title (row[3]) and URL (row[4]) *****/
Med_GetMediaNameTitleAndURLFromRow (row[1],row[2],row[3],row[4],Media);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@ -2897,7 +2902,7 @@ static void Msg_ShowASentOrReceivedMessage (long MsgNum,long MsgCod)
long CrsCod;
char Subject[Cns_MAX_BYTES_SUBJECT + 1];
char Content[Cns_MAX_BYTES_LONG_TEXT + 1];
struct Image Image;
struct Media Media;
bool Deleted;
bool Open = true;
bool Replied = false; // Initialized to avoid warning
@ -3030,21 +3035,21 @@ static void Msg_ShowASentOrReceivedMessage (long MsgNum,long MsgCod)
Txt_MSG_Content);
/***** Initialize image *****/
Img_ImageConstructor (&Image);
Med_MediaConstructor (&Media);
/***** Get message content and optional image *****/
Msg_GetMsgContent (MsgCod,Content,&Image);
Msg_GetMsgContent (MsgCod,Content,&Media);
/***** Show content and image *****/
fprintf (Gbl.F.Out,"<td colspan=\"2\" class=\"MSG_TXT LEFT_TOP\">");
if (Content[0])
Msg_WriteMsgContent (Content,Cns_MAX_BYTES_LONG_TEXT,true,false);
Img_ShowImage (&Image,"MSG_IMG_CONTAINER","MSG_IMG");
Med_ShowMedia (&Media,"MSG_IMG_CONTAINER","MSG_IMG");
fprintf (Gbl.F.Out,"</td>"
"</tr>");
/***** Free image *****/
Img_ImageDestructor (&Image);
Med_MediaDestructor (&Media);
}
/***** Free memory used for user's data *****/

View File

@ -40,8 +40,8 @@
#include "swad_follow.h"
#include "swad_form.h"
#include "swad_global.h"
#include "swad_image.h"
#include "swad_layout.h"
#include "swad_media.h"
#include "swad_notice.h"
#include "swad_notification.h"
#include "swad_parameter.h"
@ -113,7 +113,7 @@ struct SocialComment
time_t DateTimeUTC;
unsigned NumFavs; // Number of times (users) this comment has been favourited
char Content[Cns_MAX_BYTES_LONG_TEXT + 1];
struct Image Image;
struct Media Media;
};
/*****************************************************************************/
@ -523,7 +523,6 @@ void Soc_MarkMyNotifAsSeen (void)
/*****************************************************************************/
/************************ Build query to get timeline ************************/
/*****************************************************************************/
// Query must have space for at least 1024 chars
#define Soc_MAX_BYTES_SUBQUERY_ALREADY_EXISTS (256 - 1)
@ -1809,15 +1808,19 @@ static void Soc_GetAndWriteSocialPost (long PstCod)
MYSQL_ROW row;
unsigned long NumRows;
char Content[Cns_MAX_BYTES_LONG_TEXT + 1];
struct Image Image;
struct Media Media;
/***** Initialize image *****/
Img_ImageConstructor (&Image);
Med_MediaConstructor (&Media);
/***** Get social post from database *****/
NumRows = DB_QuerySELECT (&mysql_res,"can not get the content"
" of a social post",
"SELECT Content,ImageName,ImageTitle,ImageURL"
"SELECT Content," // row[0]
"MediaName," // row[1]
"MediaType," // row[2]
"MediaTitle," // row[3]
"MediaURL" // row[4]
" FROM social_posts WHERE PstCod=%ld",
PstCod);
@ -1830,8 +1833,8 @@ static void Soc_GetAndWriteSocialPost (long PstCod)
Str_Copy (Content,row[0],
Cns_MAX_BYTES_LONG_TEXT);
/****** Get image name (row[1]), title (row[2]) and URL (row[3]) *****/
Img_GetImageNameTitleAndURLFromRow (row[1],row[2],row[3],&Image);
/****** Get image name (row[1]), type (row[2]), title (row[3]) and URL (row[4]) *****/
Med_GetMediaNameTitleAndURLFromRow (row[1],row[2],row[3],row[4],&Media);
}
else
Content[0] = '\0';
@ -1848,11 +1851,11 @@ static void Soc_GetAndWriteSocialPost (long PstCod)
}
/***** Show image *****/
Img_ShowImage (&Image,"TL_POST_IMG_CONTAINER TL_RIGHT_WIDTH",
Med_ShowMedia (&Media,"TL_POST_IMG_CONTAINER TL_RIGHT_WIDTH",
"TL_POST_IMG TL_RIGHT_WIDTH");
/***** Free image *****/
Img_ImageDestructor (&Image);
Med_MediaDestructor (&Media);
}
/*****************************************************************************/
@ -2381,7 +2384,7 @@ static void Soc_PutTextarea (const char *Placeholder,
Lay_HelpPlainEditor ();
/***** Attached image (optional) *****/
Img_PutImageUploader (-1,ClassImgTit);
Med_PutMediaUploader (-1,ClassImgTit);
/***** Submit button *****/
fprintf (Gbl.F.Out,"<button type=\"submit\""
@ -2436,7 +2439,7 @@ void Soc_ReceiveSocialPostUsr (void)
static long Soc_ReceiveSocialPost (void)
{
char Content[Cns_MAX_BYTES_LONG_TEXT + 1];
struct Image Image;
struct Media Media;
long PstCod;
struct SocialPublishing SocPub;
@ -2445,37 +2448,38 @@ static long Soc_ReceiveSocialPost (void)
Str_TO_RIGOROUS_HTML,true);
/***** Initialize image *****/
Img_ImageConstructor (&Image);
Med_MediaConstructor (&Media);
/***** Get attached image (action, file and title) *****/
Image.Width = Soc_IMAGE_SAVED_MAX_WIDTH;
Image.Height = Soc_IMAGE_SAVED_MAX_HEIGHT;
Image.Quality = Soc_IMAGE_SAVED_QUALITY;
Img_GetImageFromForm (-1,&Image,NULL);
Media.Width = Soc_IMAGE_SAVED_MAX_WIDTH;
Media.Height = Soc_IMAGE_SAVED_MAX_HEIGHT;
Media.Quality = Soc_IMAGE_SAVED_QUALITY;
Med_GetMediaFromForm (-1,&Media,NULL);
if (Content[0] || // Text not empty
Image.Name[0]) // An image is attached
Media.Name[0]) // An image is attached
{
/***** Check if image is received and processed *****/
if (Image.Action == Img_ACTION_NEW_IMAGE && // Upload new image
Image.Status == Img_FILE_PROCESSED) // The new image received has been processed
if (Media.Action == Med_ACTION_NEW_MEDIA && // Upload new image
Media.Status == Med_FILE_PROCESSED) // The new image received has been processed
/* Move processed image to definitive directory */
Img_MoveImageToDefinitiveDirectory (&Image);
Med_MoveMediaToDefinitiveDirectory (&Media);
/***** Publish *****/
/* Insert post content in the database */
PstCod =
DB_QueryINSERTandReturnCode ("can not create post",
"INSERT INTO social_posts"
" (Content,ImageName,ImageTitle,ImageURL)"
" (Content,MediaName,MediaType,MediaTitle,MediaURL)"
" VALUES"
" ('%s','%s','%s','%s')",
" ('%s','%s','%s','%s','%s')",
Content,
Image.Name,
(Image.Name[0] && // Save image title only if image attached
Image.Title) ? Image.Title : "",
(Image.Name[0] && // Save image URL only if image attached
Image.URL ) ? Image.URL : "");
Media.Name,
Med_GetStringTypeForDB (Media.Type),
(Media.Name[0] && // Save image title only if image attached
Media.Title) ? Media.Title : "",
(Media.Name[0] && // Save image URL only if image attached
Media.URL ) ? Media.URL : "");
/* Insert post in social notes */
Soc_StoreAndPublishSocialNote (Soc_NOTE_SOCIAL_POST,PstCod,&SocPub);
@ -2487,7 +2491,7 @@ static long Soc_ReceiveSocialPost (void)
SocPub.NotCod = -1L;
/***** Free image *****/
Img_ImageDestructor (&Image);
Med_MediaDestructor (&Media);
return SocPub.NotCod;
}
@ -2616,9 +2620,10 @@ static void Soc_WriteCommentsInSocialNote (const struct SocialNote *SocNot)
"UNIX_TIMESTAMP("
"social_pubs.TimePublish)," // row[3]
"social_comments.Content," // row[4]
"social_comments.ImageName," // row[5]
"social_comments.ImageTitle," // row[6]
"social_comments.ImageURL" // row[7]
"social_comments.MediaName," // row[5]
"social_comments.MediaType," // row[6]
"social_comments.MediaTitle," // row[7]
"social_comments.MediaURL" // row[8]
" FROM social_pubs,social_comments"
" WHERE social_pubs.NotCod=%ld"
" AND social_pubs.PubType=%u"
@ -2687,7 +2692,7 @@ static void Soc_WriteOneSocialCommentInList (MYSQL_RES *mysql_res)
struct SocialComment SocCom;
/***** Initialize image *****/
Img_ImageConstructor (&SocCom.Image);
Med_MediaConstructor (&SocCom.Media);
/***** Get data of social comment *****/
row = mysql_fetch_row (mysql_res);
@ -2699,7 +2704,7 @@ static void Soc_WriteOneSocialCommentInList (MYSQL_RES *mysql_res)
false);
/***** Free image *****/
Img_ImageDestructor (&SocCom.Image);
Med_MediaDestructor (&SocCom.Media);
}
/*****************************************************************************/
@ -2711,7 +2716,7 @@ static void Soc_PutIconToToggleComments (const char *UniqueId,
{
extern const char *The_ClassFormInBox[The_NUM_THEMES];
/***** Link to toggle on/off some fields of project *****/
/***** Link to toggle on/off some divs *****/
fprintf (Gbl.F.Out,"<a href=\"\" title=\"%s\" class=\"%s\""
" onclick=\"toggleComments('%s');"
"return false;\" />",
@ -2804,7 +2809,7 @@ static void Soc_WriteSocialComment (struct SocialComment *SocCom,
fprintf (Gbl.F.Out,"</div>");
/* Show image */
Img_ShowImage (&SocCom->Image,"TL_COMMENT_IMG_CONTAINER TL_COMMENT_WIDTH",
Med_ShowMedia (&SocCom->Media,"TL_COMMENT_IMG_CONTAINER TL_COMMENT_WIDTH",
"TL_COMMENT_IMG TL_COMMENT_WIDTH");
/* Put icon to mark this social comment as favourite */
@ -3154,7 +3159,7 @@ static long Soc_ReceiveComment (void)
{
extern const char *Txt_The_original_post_no_longer_exists;
char Content[Cns_MAX_BYTES_LONG_TEXT + 1];
struct Image Image;
struct Media Media;
struct SocialNote SocNot;
struct SocialPublishing SocPub;
@ -3169,22 +3174,22 @@ static long Soc_ReceiveComment (void)
Str_TO_RIGOROUS_HTML,true);
/***** Initialize image *****/
Img_ImageConstructor (&Image);
Med_MediaConstructor (&Media);
/***** Get attached image (action, file and title) *****/
Image.Width = Soc_IMAGE_SAVED_MAX_WIDTH;
Image.Height = Soc_IMAGE_SAVED_MAX_HEIGHT;
Image.Quality = Soc_IMAGE_SAVED_QUALITY;
Img_GetImageFromForm (-1,&Image,NULL);
Media.Width = Soc_IMAGE_SAVED_MAX_WIDTH;
Media.Height = Soc_IMAGE_SAVED_MAX_HEIGHT;
Media.Quality = Soc_IMAGE_SAVED_QUALITY;
Med_GetMediaFromForm (-1,&Media,NULL);
if (Content[0] || // Text not empty
Image.Name[0]) // An image is attached
Media.Name[0]) // An image is attached
{
/***** Check if image is received and processed *****/
if (Image.Action == Img_ACTION_NEW_IMAGE && // Upload new image
Image.Status == Img_FILE_PROCESSED) // The new image received has been processed
if (Media.Action == Med_ACTION_NEW_MEDIA && // Upload new image
Media.Status == Med_FILE_PROCESSED) // The new image received has been processed
/* Move processed image to definitive directory */
Img_MoveImageToDefinitiveDirectory (&Image);
Med_MoveMediaToDefinitiveDirectory (&Media);
/***** Publish *****/
/* Insert into publishings */
@ -3196,16 +3201,17 @@ static long Soc_ReceiveComment (void)
/* Insert comment content in the database */
DB_QueryINSERT ("can not store comment content",
"INSERT INTO social_comments"
" (PubCod,Content,ImageName,ImageTitle,ImageURL)"
" (PubCod,Content,MediaName,MediaType,MediaTitle,MediaURL)"
" VALUES"
" (%ld,'%s','%s','%s','%s')",
" (%ld,'%s','%s','%s','%s','%s')",
SocPub.PubCod,
Content,
Image.Name,
(Image.Name[0] && // Save image title only if image attached
Image.Title) ? Image.Title : "",
(Image.Name[0] && // Save image URL only if image attached
Image.URL ) ? Image.URL : "");
Media.Name,
Med_GetStringTypeForDB (Media.Type),
(Media.Name[0] && // Save image title only if image attached
Media.Title) ? Media.Title : "",
(Media.Name[0] && // Save image URL only if image attached
Media.URL ) ? Media.URL : "");
/***** Store notifications about the new comment *****/
Ntf_StoreNotifyEventsToAllUsrs (Ntf_EVENT_TIMELINE_COMMENT,SocPub.PubCod);
@ -3220,7 +3226,7 @@ static long Soc_ReceiveComment (void)
}
/***** Free image *****/
Img_ImageDestructor (&Image);
Med_MediaDestructor (&Media);
}
else
Ale_ShowAlert (Ale_WARNING,Txt_The_original_post_no_longer_exists);
@ -3411,7 +3417,7 @@ static void Soc_FavSocialComment (struct SocialComment *SocCom)
bool ItsMe;
/***** Initialize image *****/
Img_ImageConstructor (&SocCom->Image);
Med_MediaConstructor (&SocCom->Media);
/***** Get data of social comment *****/
SocCom->PubCod = Soc_GetParamPubCod ();
@ -3443,7 +3449,7 @@ static void Soc_FavSocialComment (struct SocialComment *SocCom)
}
/***** Free image *****/
Img_ImageDestructor (&SocCom->Image);
Med_MediaDestructor (&SocCom->Media);
}
/*****************************************************************************/
@ -3665,7 +3671,7 @@ static void Soc_UnfavSocialComment (struct SocialComment *SocCom)
bool ItsMe;
/***** Initialize image *****/
Img_ImageConstructor (&SocCom->Image);
Med_MediaConstructor (&SocCom->Media);
/***** Get data of social comment *****/
SocCom->PubCod = Soc_GetParamPubCod ();
@ -3695,7 +3701,7 @@ static void Soc_UnfavSocialComment (struct SocialComment *SocCom)
}
/***** Free image *****/
Img_ImageDestructor (&SocCom->Image);
Med_MediaDestructor (&SocCom->Media);
}
/*****************************************************************************/
@ -3859,19 +3865,16 @@ static void Soc_RemoveSocialNote (void)
static void Soc_RemoveImgFileFromSocialPost (long PstCod)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
/***** Get name of image associated to a social post from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get image",
"SELECT ImageName FROM social_posts WHERE PstCod=%ld",
"SELECT MediaName," // row[0]
"MediaType" // row[1]
" FROM social_posts"
" WHERE PstCod=%ld",
PstCod))
{
/***** Get image name (row[0]) *****/
row = mysql_fetch_row (mysql_res);
/***** Remove image file *****/
Img_RemoveImageFile (row[0]);
}
/***** Remove media file *****/
Med_RemoveMediaFileFromRow (mysql_res);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@ -4072,7 +4075,7 @@ static void Soc_RequestRemovalSocialComment (void)
bool ItsMe;
/***** Initialize image *****/
Img_ImageConstructor (&SocCom.Image);
Med_MediaConstructor (&SocCom.Media);
/***** Get data of social comment *****/
SocCom.PubCod = Soc_GetParamPubCod ();
@ -4108,7 +4111,7 @@ static void Soc_RequestRemovalSocialComment (void)
Ale_ShowAlert (Ale_WARNING,Txt_The_comment_no_longer_exists);
/***** Free image *****/
Img_ImageDestructor (&SocCom.Image);
Med_MediaDestructor (&SocCom.Media);
}
/*****************************************************************************/
@ -4166,7 +4169,7 @@ static void Soc_RemoveSocialComment (void)
bool ItsMe;
/***** Initialize image *****/
Img_ImageConstructor (&SocCom.Image);
Med_MediaConstructor (&SocCom.Media);
/***** Get data of social comment *****/
SocCom.PubCod = Soc_GetParamPubCod ();
@ -4191,7 +4194,7 @@ static void Soc_RemoveSocialComment (void)
Ale_ShowAlert (Ale_WARNING,Txt_The_comment_no_longer_exists);
/***** Free image *****/
Img_ImageDestructor (&SocCom.Image);
Med_MediaDestructor (&SocCom.Media);
}
/*****************************************************************************/
@ -4201,20 +4204,16 @@ static void Soc_RemoveSocialComment (void)
static void Soc_RemoveImgFileFromSocialComment (long PubCod)
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
/***** Get name of image associated to a social post from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get image",
"SELECT ImageName FROM social_comments"
/***** Get name of media associated to a social post from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get media",
"SELECT MediaName," // row[0]
"MediaType" // row[1]
" FROM social_comments"
" WHERE PubCod=%ld",
PubCod))
{
/***** Get image name (row[0]) *****/
row = mysql_fetch_row (mysql_res);
/***** Remove image file *****/
Img_RemoveImageFile (row[0]);
}
/***** Remove media file *****/
Med_RemoveMediaFileFromRow (mysql_res);
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
@ -4670,9 +4669,10 @@ static void Soc_GetDataOfSocialComByCod (struct SocialComment *SocCom)
"social_pubs.NotCod," // row[2]
"UNIX_TIMESTAMP(social_pubs.TimePublish)," // row[3]
"social_comments.Content," // row[4]
"social_comments.ImageName," // row[5]
"social_comments.ImageTitle," // row[6]
"social_comments.ImageURL" // row[7]
"social_comments.MediaName," // row[5]
"social_comments.MediaType," // row[6]
"social_comments.MediaTitle," // row[7]
"social_comments.MediaURL" // row[8]
" FROM social_pubs,social_comments"
" WHERE social_pubs.PubCod=%ld"
" AND social_pubs.PubType=%u"
@ -4802,9 +4802,10 @@ static void Soc_GetDataOfSocialCommentFromRow (MYSQL_ROW row,struct SocialCommen
row[2]: NotCod
row[3]: TimePublish
row[4]: Content
row[5]: ImageName
row[6]: ImageTitle
row[7]: ImageURL
row[5]: MediaName
row[6]: MediaType
row[7]: MediaTitle
row[8]: MediaURL
*/
/***** Get code of social comment (row[0]) *****/
SocCom->PubCod = Str_ConvertStrCodToLongCod (row[0]);
@ -4825,8 +4826,9 @@ static void Soc_GetDataOfSocialCommentFromRow (MYSQL_ROW row,struct SocialCommen
/***** Get number of times this comment has been favourited *****/
Soc_GetNumTimesACommHasBeenFav (SocCom);
/****** Get image name (row[5]), title (row[6]) and URL (row[7]) *****/
Img_GetImageNameTitleAndURLFromRow (row[5],row[6],row[7],&SocCom->Image);
/****** Get image name (row[5]), type (row[6]), title (row[7]) and URL (row[8]) *****/
Med_GetMediaNameTitleAndURLFromRow (row[5],row[6],row[7],row[8],
&SocCom->Media);
}
/*****************************************************************************/

View File

@ -50,7 +50,7 @@ typedef enum
Soc_USRS_FOLLOWED = 1,
Soc_USRS_ALL = 2,
} Soc_WhichUsrs_t; // Which users I want to see: only users I follow or all users
#define Soc_DEFAULT_WHICH_USRS Soc_USRS_ALL
#define Soc_DEFAULT_WHICH_USRS Soc_USRS_FOLLOWED
#define Soc_NUM_PUB_TYPES 4
// If the numbers assigned to each event type change,

File diff suppressed because it is too large Load Diff

View File

@ -200,12 +200,13 @@ void TsI_CreateXML (unsigned long NumRows,MYSQL_RES *mysql_res)
row[ 3] Shuffle
row[ 4] Stem
row[ 5] Feedback
row[ 6] ImageName
row[ 7] ImageTitle
row[ 8] ImageURL
row[ 9] NumHits
row[10] NumHitsNotBlank
row[11] Score
row[ 6] MediaName
row[ 7] MediaType
row[ 8] MediaTitle
row[ 9] MediaURL
row[10] NumHits
row[11] NumHitsNotBlank
row[12] Score
*/
/* row[0] holds the code of the question */
if ((QstCod = Str_ConvertStrCodToLongCod (row[0])) < 0)
@ -309,13 +310,14 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod)
Gbl.Test.Answer.NumOptions = Tst_GetAnswersQst (QstCod,&mysql_res,false); // Result: AnsInd,Answer,Correct
/*
row[ 0] AnsInd
row[ 1] Answer
row[ 2] Feedback
row[ 3] ImageName
row[ 4] ImageTitle
row[ 5] ImageURL
row[ 6] Correct
row[0] AnsInd
row[1] Answer
row[2] Feedback
row[3] MediaName
row[4] MediaType
row[5] MediaTitle
row[6] MediaURL
row[7] Correct
*/
/***** Write the answers *****/
switch (Gbl.Test.AnswerType)
@ -365,7 +367,7 @@ static void TsI_WriteAnswersOfAQstXML (long QstCod)
fprintf (Gbl.Test.XML.FileXML,"<option");
if (Gbl.Test.AnswerType != Tst_ANS_TEXT)
fprintf (Gbl.Test.XML.FileXML," correct=\"%s\"",
(row[6][0] == 'Y') ? "yes" :
(row[7][0] == 'Y') ? "yes" :
"no");
fprintf (Gbl.Test.XML.FileXML,">%s"
"<text>%s</text>%s",

View File

@ -3446,9 +3446,11 @@ static int Svc_SendMessageToUsr (long OriginalMsgCod,
NewMsgCod =
DB_QueryINSERTandReturnCode ("can not create message",
"INSERT INTO msg_content"
" (Subject,Content,ImageName,ImageTitle,ImageURL)"
" (Subject,Content,"
"MediaName,MediaType,MediaTitle,MediaURL)"
" VALUES"
" ('%s','%s','','','')",
" ('%s','%s',"
"'','','','')",
Subject,Content);
/* Insert message in sent messages */