mirror of https://github.com/acanas/swad-core.git
Version 21.62: Nov 24, 2021 Code refactoring in photos.
This commit is contained in:
parent
401c38181b
commit
b81c85b6ac
|
@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par
|
||||||
|
|
||||||
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
|
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
|
||||||
*/
|
*/
|
||||||
#define Log_PLATFORM_VERSION "SWAD 21.61 (2021-11-24)"
|
#define Log_PLATFORM_VERSION "SWAD 21.62 (2021-11-24)"
|
||||||
#define CSS_FILE "swad21.59.css"
|
#define CSS_FILE "swad21.59.css"
|
||||||
#define JS_FILE "swad21.59.js"
|
#define JS_FILE "swad21.59.js"
|
||||||
/*
|
/*
|
||||||
TODO: Rename CENTRE to CENTER in help wiki.
|
TODO: Rename CENTRE to CENTER in help wiki.
|
||||||
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
|
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
|
||||||
|
|
||||||
|
Version 21.62: Nov 24, 2021 Code refactoring in photos. (319415 lines)
|
||||||
Version 21.61: Nov 24, 2021 User's photo is shown near a mention. (319454 lines)
|
Version 21.61: Nov 24, 2021 User's photo is shown near a mention. (319454 lines)
|
||||||
Version 21.60.1: Nov 24, 2021 Code optimization in insertion of links in a string. (319233 lines)
|
Version 21.60.1: Nov 24, 2021 Code optimization in insertion of links in a string. (319233 lines)
|
||||||
Version 21.60: Nov 24, 2021 Code refactoring inserting links in a string. (319208 lines)
|
Version 21.60: Nov 24, 2021 Code refactoring inserting links in a string. (319208 lines)
|
||||||
|
|
|
@ -90,10 +90,7 @@ bool Nck_CheckIfNickWithArrIsValid (const char *NickWithArr)
|
||||||
for (Ptr = CopyOfNick; // Leading arrobas already removed
|
for (Ptr = CopyOfNick; // Leading arrobas already removed
|
||||||
*Ptr;
|
*Ptr;
|
||||||
Ptr++)
|
Ptr++)
|
||||||
if (!((*Ptr >= 'a' && *Ptr <= 'z') ||
|
if (!Str_ChIsAlphaNum (*Ptr))
|
||||||
(*Ptr >= 'A' && *Ptr <= 'Z') ||
|
|
||||||
(*Ptr >= '0' && *Ptr <= '9') ||
|
|
||||||
(*Ptr == '_')))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
300
swad_photo.c
300
swad_photo.c
|
@ -1034,12 +1034,13 @@ bool Pho_CheckIfPrivPhotoExists (long UsrCod,char PathPrivRelPhoto[PATH_MAX + 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*************************** Show a user's photo *****************************/
|
/********************* Build HTML code for user's photo **********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
|
void Pho_BuildHTMLUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
|
||||||
const char *ClassPhoto,Pho_Zoom_t Zoom,
|
const char *ClassPhoto,Pho_Zoom_t Zoom,
|
||||||
bool FormUnique)
|
char **ImgStr,
|
||||||
|
char **CaptionStr)
|
||||||
{
|
{
|
||||||
extern const char *Rol_Icons[Rol_NUM_ROLES];
|
extern const char *Rol_Icons[Rol_NUM_ROLES];
|
||||||
extern const char *Txt_Following;
|
extern const char *Txt_Following;
|
||||||
|
@ -1051,99 +1052,144 @@ void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
|
||||||
bool BrowserTabIs1stTab = (BrowserTab == Act_BRW_1ST_TAB ||
|
bool BrowserTabIs1stTab = (BrowserTab == Act_BRW_1ST_TAB ||
|
||||||
BrowserTab == Act_AJAX_NORMAL ||
|
BrowserTab == Act_AJAX_NORMAL ||
|
||||||
BrowserTab == Act_AJAX_RFRESH);
|
BrowserTab == Act_AJAX_RFRESH);
|
||||||
bool PutLinkToPublicProfile = !Gbl.Form.Inside && // Only if not inside another form
|
|
||||||
BrowserTabIs1stTab; // Only in main browser tab (or AJAX)
|
|
||||||
bool PutZoomCode = (Zoom == Pho_ZOOM) && // Make zoom
|
bool PutZoomCode = (Zoom == Pho_ZOOM) && // Make zoom
|
||||||
BrowserTabIs1stTab; // Only in main browser tab (or AJAX)
|
BrowserTabIs1stTab; // Only in main browser tab (or AJAX)
|
||||||
char IdCaption[Frm_MAX_BYTES_ID + 1];
|
char IdCaption[Frm_MAX_BYTES_ID + 1];
|
||||||
|
char CtyName[Cns_HIERARCHY_MAX_BYTES_FULL_NAME + 1];
|
||||||
|
struct Ins_Instit Ins;
|
||||||
char MainDegreeShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1];
|
char MainDegreeShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1];
|
||||||
Rol_Role_t MaxRole; // Maximum user's role in his/her main degree
|
Rol_Role_t MaxRole; // Maximum user's role in his/her main degree
|
||||||
|
struct
|
||||||
/***** Begin form to go to public profile *****/
|
|
||||||
if (PutLinkToPublicProfile)
|
|
||||||
{
|
{
|
||||||
if (FormUnique)
|
char *Name;
|
||||||
Frm_BeginFormUnique (ActSeeOthPubPrf);
|
char *Nick;
|
||||||
else
|
char *InsCty;
|
||||||
Frm_BeginForm (ActSeeOthPubPrf);
|
char *MainDeg;
|
||||||
Usr_PutParamUsrCodEncrypted (UsrDat->EnUsrCod);
|
char *Follow;
|
||||||
|
} Caption;
|
||||||
HTM_BUTTON_SUBMIT_Begin (NULL,"BT_LINK",NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** Hidden div to pass user's name to Javascript *****/
|
/***** Hidden div to pass user's name to Javascript *****/
|
||||||
if (PutZoomCode)
|
if (PutZoomCode)
|
||||||
{
|
{
|
||||||
|
/* First name and surnames */
|
||||||
|
if (asprintf (&Caption.Name,"<div class=\"ZOOM_TXT_LINE DAT_N_BOLD\">" // Limited width
|
||||||
|
"%s<br />"
|
||||||
|
"%s%s%s"
|
||||||
|
"</div>",
|
||||||
|
UsrDat->FrstName,
|
||||||
|
UsrDat->Surname1,
|
||||||
|
UsrDat->Surname2[0] ? " " :
|
||||||
|
"",
|
||||||
|
UsrDat->Surname2[0] ? UsrDat->Surname2 :
|
||||||
|
"") < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
|
/* Nickname */
|
||||||
|
if (UsrDat->Nickname[0])
|
||||||
|
{
|
||||||
|
if (asprintf (&Caption.Nick,"<div class=\"ZOOM_TXT_LINE DAT_SMALL_N\">"
|
||||||
|
"@%s"
|
||||||
|
"</div>",
|
||||||
|
UsrDat->Nickname) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
|
else if (asprintf (&Caption.Nick,"%s","") < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
|
/* Institution full name and institution country */
|
||||||
|
if (UsrDat->InsCod > 0)
|
||||||
|
{
|
||||||
|
/* Get institution short name and country name */
|
||||||
|
Ins.InsCod = UsrDat->InsCod;
|
||||||
|
Ins_GetShrtNameAndCtyOfInstitution (&Ins,CtyName);
|
||||||
|
|
||||||
|
/* Write institution short name and country name */
|
||||||
|
if (asprintf (&Caption.InsCty,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
|
||||||
|
"%s (%s)"
|
||||||
|
"</div>",
|
||||||
|
Ins.ShrtName,CtyName) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
|
else if (UsrDat->CtyCod > 0)
|
||||||
|
{
|
||||||
|
/* Get country name */
|
||||||
|
Cty_GetCountryName (UsrDat->CtyCod,Gbl.Prefs.Language,CtyName);
|
||||||
|
|
||||||
|
/* Write country name */
|
||||||
|
if (asprintf (&Caption.InsCty,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
|
||||||
|
"%s"
|
||||||
|
"</div>",
|
||||||
|
CtyName) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
|
else if (asprintf (&Caption.InsCty,"%s","") < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
|
/* Main degree (in which the user has more courses) short name */
|
||||||
|
Deg_GetUsrMainDeg (UsrDat->UsrCod,MainDegreeShrtName,&MaxRole);
|
||||||
|
if (MainDegreeShrtName[0])
|
||||||
|
{
|
||||||
|
if (asprintf (&Caption.MainDeg,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
|
||||||
|
"<div class=\"ZOOM_DEG\" style=\"background-image:url('%s/%s');\">"
|
||||||
|
"%s"
|
||||||
|
"</div>"
|
||||||
|
"</div>",
|
||||||
|
Cfg_URL_ICON_PUBLIC,Rol_Icons[MaxRole],
|
||||||
|
MainDegreeShrtName) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
|
else if (asprintf (&Caption.MainDeg,"%s","") < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
|
/* Following and followers */
|
||||||
|
if (UsrDat->Nickname[0]) // Get social data only if nickname is retrieved (in some actions)
|
||||||
|
{
|
||||||
|
Fol_GetNumFollow (UsrDat->UsrCod,&NumFollowing,&NumFollowers);
|
||||||
|
if (asprintf (&Caption.Follow,"<div class=\"ZOOM_TXT_LINE\">"
|
||||||
|
"<span class=\"DAT_N_BOLD\">"
|
||||||
|
"%u"
|
||||||
|
"</span>"
|
||||||
|
"<span class=\"DAT_SMALL\">"
|
||||||
|
" %s "
|
||||||
|
"</span>"
|
||||||
|
"<span class=\"DAT_N_BOLD\">"
|
||||||
|
"%u"
|
||||||
|
"</span>"
|
||||||
|
"<span class=\"DAT_SMALL\">"
|
||||||
|
" %s"
|
||||||
|
"</span>"
|
||||||
|
"</div>",
|
||||||
|
NumFollowing,
|
||||||
|
Txt_Following,
|
||||||
|
NumFollowers,
|
||||||
|
Txt_Followers) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
|
else if (asprintf (&Caption.Follow,"%s","") < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
|
/* Hidden div */
|
||||||
Frm_SetUniqueId (IdCaption);
|
Frm_SetUniqueId (IdCaption);
|
||||||
HTM_DIV_Begin ("id=\"%s\" class=\"NOT_SHOWN\"",IdCaption);
|
if (asprintf (CaptionStr,"<div id=\"%s\" class=\"NOT_SHOWN\">"
|
||||||
|
"%s%s%s%s%s"
|
||||||
/* First name and surnames */
|
"</div>",
|
||||||
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE DAT_N_BOLD\""); // Limited width
|
IdCaption,
|
||||||
Usr_WriteFirstNameBRSurnames (UsrDat);
|
Caption.Name,
|
||||||
HTM_DIV_End ();
|
Caption.Nick,
|
||||||
|
Caption.InsCty,
|
||||||
/* Nickname */
|
Caption.MainDeg,
|
||||||
if (UsrDat->Nickname[0])
|
Caption.Follow) < 0)
|
||||||
{
|
Err_NotEnoughMemoryExit ();
|
||||||
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE DAT_SMALL_N\"");
|
free (Caption.Follow);
|
||||||
HTM_TxtF ("@%s",UsrDat->Nickname);
|
free (Caption.MainDeg);
|
||||||
HTM_DIV_End ();
|
free (Caption.InsCty);
|
||||||
}
|
free (Caption.Nick);
|
||||||
|
free (Caption.Name);
|
||||||
/* Institution full name and institution country */
|
}
|
||||||
if (UsrDat->InsCod > 0)
|
else
|
||||||
{
|
{
|
||||||
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE DAT_SMALL\"");
|
if (asprintf (CaptionStr,"%s","") < 0)
|
||||||
Ins_WriteInstitutionNameAndCty (UsrDat->InsCod);
|
Err_NotEnoughMemoryExit ();
|
||||||
HTM_DIV_End ();
|
|
||||||
}
|
|
||||||
/* User's country */
|
|
||||||
else if (UsrDat->CtyCod > 0)
|
|
||||||
{
|
|
||||||
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE DAT_SMALL\"");
|
|
||||||
Cty_WriteCountryName (UsrDat->CtyCod,
|
|
||||||
NULL); // Don't put link to country
|
|
||||||
HTM_DIV_End ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main degree (in which the user has more courses) short name */
|
|
||||||
Deg_GetUsrMainDeg (UsrDat->UsrCod,MainDegreeShrtName,&MaxRole);
|
|
||||||
if (MainDegreeShrtName[0])
|
|
||||||
{
|
|
||||||
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE DAT_SMALL\"");
|
|
||||||
HTM_DIV_Begin ("class=\"ZOOM_DEG\" style=\"background-image:url('%s/%s');\"",
|
|
||||||
Cfg_URL_ICON_PUBLIC,Rol_Icons[MaxRole]);
|
|
||||||
HTM_Txt (MainDegreeShrtName);
|
|
||||||
HTM_DIV_End ();
|
|
||||||
HTM_DIV_End ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Following and followers */
|
|
||||||
if (UsrDat->Nickname[0]) // Get social data only if nickname is retrieved (in some actions)
|
|
||||||
{
|
|
||||||
Fol_GetNumFollow (UsrDat->UsrCod,&NumFollowing,&NumFollowers);
|
|
||||||
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE\"");
|
|
||||||
|
|
||||||
HTM_SPAN_Begin ("class=\"DAT_N_BOLD\"");
|
|
||||||
HTM_Unsigned (NumFollowing);
|
|
||||||
HTM_SPAN_End ();
|
|
||||||
|
|
||||||
HTM_SPAN_Begin ("class=\"DAT_SMALL\"");
|
|
||||||
HTM_TxtF (" %s ",Txt_Following);
|
|
||||||
HTM_SPAN_End ();
|
|
||||||
|
|
||||||
HTM_SPAN_Begin ("class=\"DAT_N_BOLD\"");
|
|
||||||
HTM_Unsigned (NumFollowers);
|
|
||||||
HTM_SPAN_End ();
|
|
||||||
|
|
||||||
HTM_SPAN_Begin ("class=\"DAT_SMALL\"");
|
|
||||||
HTM_TxtF (" %s",Txt_Followers);
|
|
||||||
HTM_SPAN_End ();
|
|
||||||
|
|
||||||
HTM_DIV_End ();
|
|
||||||
}
|
|
||||||
|
|
||||||
HTM_DIV_End ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Image zoom *****/
|
/***** Image zoom *****/
|
||||||
|
@ -1154,33 +1200,85 @@ void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
|
||||||
if (PutZoomCode)
|
if (PutZoomCode)
|
||||||
{
|
{
|
||||||
if (PhotoExists)
|
if (PhotoExists)
|
||||||
HTM_IMG (PhotoURL,NULL,UsrDat->FullName,
|
{
|
||||||
"class=\"%s\""
|
if (asprintf (ImgStr,"<img src=\"%s\" alt=\"\" title=\"%s\" class=\"%s\""
|
||||||
" onmouseover=\"zoom(this,'%s','%s');\""
|
" onmouseover=\"zoom(this,'%s','%s');\""
|
||||||
" onmouseout=\"noZoom();\"",
|
" onmouseout=\"noZoom();\""
|
||||||
ClassPhoto,PhotoURL,IdCaption);
|
" />",
|
||||||
|
PhotoURL,UsrDat->FullName,ClassPhoto,
|
||||||
|
PhotoURL,IdCaption) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
HTM_IMG (Cfg_URL_ICON_PUBLIC,"usr_bl.jpg",UsrDat->FullName,
|
{
|
||||||
"class=\"%s\""
|
if (asprintf (ImgStr,"<img src=\"%s/usr_bl.jpg\" alt=\"\" title=\"%s\" class=\"%s\""
|
||||||
" onmouseover=\"zoom(this,'%s/usr_bl.jpg','%s');\""
|
" onmouseover=\"zoom(this,'%s/usr_bl.jpg','%s');\""
|
||||||
" onmouseout=\"noZoom();\"",
|
" onmouseout=\"noZoom();\""
|
||||||
ClassPhoto,Cfg_URL_ICON_PUBLIC,IdCaption);
|
" />",
|
||||||
|
Cfg_URL_ICON_PUBLIC,UsrDat->FullName,ClassPhoto,
|
||||||
|
Cfg_URL_ICON_PUBLIC,IdCaption) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (PhotoExists)
|
if (PhotoExists)
|
||||||
HTM_IMG (PhotoURL,NULL,UsrDat->FullName,
|
{
|
||||||
"class=\"%s\"",ClassPhoto);
|
if (asprintf (ImgStr,"<img src=\"%s\" alt=\"\" title=\"%s\" class=\"%s\" />",
|
||||||
|
PhotoURL,UsrDat->FullName,ClassPhoto) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
HTM_IMG (Cfg_URL_ICON_PUBLIC,"usr_bl.jpg",UsrDat->FullName,
|
{
|
||||||
"class=\"%s\"",ClassPhoto);
|
if (asprintf (ImgStr,"<img src=\"%s/usr_bl.jpg\" alt=\"\" title=\"%s\" class=\"%s\" />",
|
||||||
|
Cfg_URL_ICON_PUBLIC,UsrDat->FullName,ClassPhoto) < 0)
|
||||||
|
Err_NotEnoughMemoryExit ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/*************************** Show a user's photo *****************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
|
||||||
|
const char *ClassPhoto,Pho_Zoom_t Zoom,
|
||||||
|
bool FormUnique)
|
||||||
|
{
|
||||||
|
Act_BrowserTab_t BrowserTab = Act_GetBrowserTab (Gbl.Action.Act);
|
||||||
|
bool BrowserTabIs1stTab = (BrowserTab == Act_BRW_1ST_TAB ||
|
||||||
|
BrowserTab == Act_AJAX_NORMAL ||
|
||||||
|
BrowserTab == Act_AJAX_RFRESH);
|
||||||
|
bool PutLinkToPublicProfile = !Gbl.Form.Inside && // Only if not inside another form
|
||||||
|
BrowserTabIs1stTab; // Only in main browser tab (or AJAX)
|
||||||
|
char *CaptionStr;
|
||||||
|
char *ImgStr;
|
||||||
|
|
||||||
|
/***** Begin form to go to public profile *****/
|
||||||
|
if (PutLinkToPublicProfile)
|
||||||
|
{
|
||||||
|
if (FormUnique)
|
||||||
|
Frm_BeginFormUnique (ActSeeOthPubPrf);
|
||||||
|
else
|
||||||
|
Frm_BeginForm (ActSeeOthPubPrf);
|
||||||
|
Usr_PutParamUsrCodEncrypted (UsrDat->EnUsrCod);
|
||||||
|
HTM_BUTTON_SUBMIT_Begin (NULL,"BT_LINK",NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Hidden div to pass user's name to Javascript *****/
|
||||||
|
Pho_BuildHTMLUsrPhoto (UsrDat,PhotoURL,
|
||||||
|
ClassPhoto,Zoom,
|
||||||
|
&CaptionStr,
|
||||||
|
&ImgStr);
|
||||||
|
HTM_Txt (CaptionStr);
|
||||||
|
HTM_Txt (ImgStr);
|
||||||
|
free (ImgStr);
|
||||||
|
free (CaptionStr);
|
||||||
|
|
||||||
/***** End form to go to public profile *****/
|
/***** End form to go to public profile *****/
|
||||||
if (PutLinkToPublicProfile)
|
if (PutLinkToPublicProfile)
|
||||||
{
|
{
|
||||||
HTM_BUTTON_End ();
|
HTM_BUTTON_End ();
|
||||||
|
|
||||||
Frm_EndForm ();
|
Frm_EndForm ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,10 @@ bool Pho_ShowingUsrPhotoIsAllowed (struct UsrData *UsrDat,
|
||||||
char PhotoURL[PATH_MAX + 1]);
|
char PhotoURL[PATH_MAX + 1]);
|
||||||
bool Pho_BuildLinkToPhoto (const struct UsrData *UsrDat,char PhotoURL[PATH_MAX + 1]);
|
bool Pho_BuildLinkToPhoto (const struct UsrData *UsrDat,char PhotoURL[PATH_MAX + 1]);
|
||||||
bool Pho_CheckIfPrivPhotoExists (long UsrCod,char PathPrivRelPhoto[PATH_MAX + 1]);
|
bool Pho_CheckIfPrivPhotoExists (long UsrCod,char PathPrivRelPhoto[PATH_MAX + 1]);
|
||||||
|
void Pho_BuildHTMLUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
|
||||||
|
const char *ClassPhoto,Pho_Zoom_t Zoom,
|
||||||
|
char **ImgStr,
|
||||||
|
char **CaptionStr);
|
||||||
void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
|
void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
|
||||||
const char *ClassPhoto,Pho_Zoom_t Zoom,
|
const char *ClassPhoto,Pho_Zoom_t Zoom,
|
||||||
bool FormUnique);
|
bool FormUnique);
|
||||||
|
|
509
swad_string.c
509
swad_string.c
|
@ -35,15 +35,13 @@
|
||||||
#include <string.h> // For string functions
|
#include <string.h> // For string functions
|
||||||
|
|
||||||
#include "swad_error.h"
|
#include "swad_error.h"
|
||||||
#include "swad_follow.h" // TODO: Remove?
|
|
||||||
#include "swad_form.h"
|
#include "swad_form.h"
|
||||||
#include "swad_global.h"
|
#include "swad_global.h"
|
||||||
#include "swad_ID.h"
|
#include "swad_ID.h"
|
||||||
#include "swad_institution.h" // TODO: Remove?
|
|
||||||
#include "swad_nickname_database.h"
|
#include "swad_nickname_database.h"
|
||||||
#include "swad_notification_database.h"
|
#include "swad_notification_database.h"
|
||||||
#include "swad_parameter.h"
|
#include "swad_parameter.h"
|
||||||
#include "swad_photo.h" // TODO: Remove?
|
#include "swad_photo.h"
|
||||||
#include "swad_string.h"
|
#include "swad_string.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -93,18 +91,14 @@ static void Str_CreateFirstLink (struct Str_Link **Link,
|
||||||
static void Str_CreateNextLink (struct Str_Link **Link,
|
static void Str_CreateNextLink (struct Str_Link **Link,
|
||||||
struct Str_Link **LastLink);
|
struct Str_Link **LastLink);
|
||||||
static void Str_FreeLinks (struct Str_Link *LastLink);
|
static void Str_FreeLinks (struct Str_Link *LastLink);
|
||||||
static Str_LinkType_t Str_CheckURL (char **PtrSrc,
|
static Str_LinkType_t Str_CheckURL (char **PtrSrc,char PrevCh,
|
||||||
struct Str_Link **Link,
|
struct Str_Link **Link,
|
||||||
struct Str_Link **LastLink,
|
struct Str_Link **LastLink,
|
||||||
size_t MaxCharsURLOnScreen);
|
size_t MaxCharsURLOnScreen);
|
||||||
static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
|
static Str_LinkType_t Str_CheckNickname (char **PtrSrc,char PrevCh,
|
||||||
struct Str_Link **Link,
|
struct Str_Link **Link,
|
||||||
struct Str_Link **LastLink);
|
struct Str_Link **LastLink);
|
||||||
static void Str_CopySubstring (const struct Str_Substring *PtrSrc,char **PtrDst);
|
static void Str_CopySubstring (const struct Str_Substring *PtrSrc,char **PtrDst);
|
||||||
static void Str_GetUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
|
|
||||||
const char *ClassPhoto,
|
|
||||||
char **CaptionStr,
|
|
||||||
char **ImgStr);
|
|
||||||
|
|
||||||
static unsigned Str_GetNextASCIICharFromStr (const char *Ptr,unsigned char *Ch);
|
static unsigned Str_GetNextASCIICharFromStr (const char *Ptr,unsigned char *Ch);
|
||||||
|
|
||||||
|
@ -193,6 +187,7 @@ static const struct Str_Substring NickAnchor3 =
|
||||||
void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScreen)
|
void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScreen)
|
||||||
{
|
{
|
||||||
size_t TxtLength;
|
size_t TxtLength;
|
||||||
|
char PrevCh = '\0';
|
||||||
char *PtrSrc;
|
char *PtrSrc;
|
||||||
char *PtrDst;
|
char *PtrDst;
|
||||||
struct Str_Link *Link;
|
struct Str_Link *Link;
|
||||||
|
@ -212,14 +207,17 @@ void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre
|
||||||
for (PtrSrc = Txt;
|
for (PtrSrc = Txt;
|
||||||
*PtrSrc;)
|
*PtrSrc;)
|
||||||
/* Check if the next char is the start of a URL */
|
/* Check if the next char is the start of a URL */
|
||||||
if ((Link->Type = Str_CheckURL (&PtrSrc,
|
if ((Link->Type = Str_CheckURL (&PtrSrc,PrevCh,
|
||||||
&Link,&LastLink,
|
&Link,&LastLink,
|
||||||
MaxCharsURLOnScreen)) == Str_LINK_UNKNOWN)
|
MaxCharsURLOnScreen)) == Str_LINK_UNKNOWN)
|
||||||
/* Check if the next char is the start of a nickname */
|
/* Check if the next char is the start of a nickname */
|
||||||
if ((Link->Type = Str_CheckNickname (&PtrSrc,
|
if ((Link->Type = Str_CheckNickname (&PtrSrc,PrevCh,
|
||||||
&Link,&LastLink)) == Str_LINK_UNKNOWN)
|
&Link,&LastLink)) == Str_LINK_UNKNOWN)
|
||||||
|
{
|
||||||
/* The next char is not the start of a URL or a nickname */
|
/* The next char is not the start of a URL or a nickname */
|
||||||
|
PrevCh = *PtrSrc;
|
||||||
PtrSrc++;
|
PtrSrc++;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/***** If there are one or more links (URLs or nicknames) in text *****/
|
/***** If there are one or more links (URLs or nicknames) in text *****/
|
||||||
|
@ -373,7 +371,7 @@ static void Str_FreeLinks (struct Str_Link *LastLink)
|
||||||
|
|
||||||
/**************************** Check if a URL found ***************************/
|
/**************************** Check if a URL found ***************************/
|
||||||
|
|
||||||
static Str_LinkType_t Str_CheckURL (char **PtrSrc,
|
static Str_LinkType_t Str_CheckURL (char **PtrSrc,char PrevCh,
|
||||||
struct Str_Link **Link,
|
struct Str_Link **Link,
|
||||||
struct Str_Link **LastLink,
|
struct Str_Link **LastLink,
|
||||||
size_t MaxCharsURLOnScreen)
|
size_t MaxCharsURLOnScreen)
|
||||||
|
@ -387,91 +385,94 @@ static Str_LinkType_t Str_CheckURL (char **PtrSrc,
|
||||||
|
|
||||||
/***** Check if the next char is the start of a URL *****/
|
/***** Check if the next char is the start of a URL *****/
|
||||||
if (tolower ((int) *(*PtrSrc)) == (int) 'h')
|
if (tolower ((int) *(*PtrSrc)) == (int) 'h')
|
||||||
{
|
if (!Str_ChIsAlphaNum (PrevCh))
|
||||||
(*Link)->URLorNick.Str = (*PtrSrc);
|
|
||||||
if (tolower ((int) *++(*PtrSrc)) == (int) 't') // ht...
|
|
||||||
{
|
{
|
||||||
if (tolower ((int) *++(*PtrSrc)) == (int) 't') // htt...
|
(*Link)->URLorNick.Str = (*PtrSrc);
|
||||||
|
if (tolower ((int) *++(*PtrSrc)) == (int) 't') // ht...
|
||||||
{
|
{
|
||||||
if (tolower ((int) *++(*PtrSrc)) == (int) 'p') // http...
|
if (tolower ((int) *++(*PtrSrc)) == (int) 't') // htt...
|
||||||
{
|
{
|
||||||
(*PtrSrc)++;
|
if (tolower ((int) *++(*PtrSrc)) == (int) 'p') // http...
|
||||||
if (*(*PtrSrc) == ':') // http:...
|
|
||||||
{
|
{
|
||||||
if (*++(*PtrSrc) == '/') // http:/...
|
(*PtrSrc)++;
|
||||||
if (*++(*PtrSrc) == '/') // http://...
|
if (*(*PtrSrc) == ':') // http:...
|
||||||
Type = Str_LINK_URL;
|
|
||||||
}
|
|
||||||
else if (tolower ((int) *(*PtrSrc)) == (int) 's') // https...
|
|
||||||
{
|
|
||||||
if (*++(*PtrSrc) == ':') // https:...
|
|
||||||
{
|
{
|
||||||
if (*++(*PtrSrc) == '/') // https:/...
|
if (*++(*PtrSrc) == '/') // http:/...
|
||||||
if (*++(*PtrSrc) == '/') // https://...
|
if (*++(*PtrSrc) == '/') // http://...
|
||||||
Type = Str_LINK_URL;
|
Type = Str_LINK_URL;
|
||||||
}
|
}
|
||||||
|
else if (tolower ((int) *(*PtrSrc)) == (int) 's') // https...
|
||||||
|
{
|
||||||
|
if (*++(*PtrSrc) == ':') // https:...
|
||||||
|
{
|
||||||
|
if (*++(*PtrSrc) == '/') // https:/...
|
||||||
|
if (*++(*PtrSrc) == '/') // https://...
|
||||||
|
Type = Str_LINK_URL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (Type == Str_LINK_URL)
|
||||||
if (Type == Str_LINK_URL)
|
|
||||||
{
|
|
||||||
/***** Find URL end *****/
|
|
||||||
(*PtrSrc)++; // Points to first character after http:// or https://
|
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
NumChars1 = Str_GetNextASCIICharFromStr ((*PtrSrc),&Ch);
|
/***** Find URL end *****/
|
||||||
(*PtrSrc) += NumChars1;
|
(*PtrSrc)++; // Points to first character after http:// or https://
|
||||||
if (Ch <= 32 || Ch == '<' || Ch == '"')
|
for (;;)
|
||||||
{
|
{
|
||||||
PtrEnd = (*PtrSrc) - NumChars1 - 1;
|
NumChars1 = Str_GetNextASCIICharFromStr ((*PtrSrc),&Ch);
|
||||||
break;
|
(*PtrSrc) += NumChars1;
|
||||||
}
|
if (Ch <= 32 || Ch == '<' || Ch == '"')
|
||||||
else if (Ch == ',' || Ch == '.' || Ch == ';' || Ch == ':' ||
|
|
||||||
Ch == ')' || Ch == ']' || Ch == '}')
|
|
||||||
{
|
|
||||||
NumChars2 = Str_GetNextASCIICharFromStr ((*PtrSrc),&Ch);
|
|
||||||
(*PtrSrc) += NumChars2;
|
|
||||||
if (Ch <= 32 || Ch == '<' || Ch == '"')
|
|
||||||
{
|
{
|
||||||
PtrEnd = (*PtrSrc) - NumChars2 - NumChars1 - 1;
|
PtrEnd = (*PtrSrc) - NumChars1 - 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (Ch == ',' || Ch == '.' || Ch == ';' || Ch == ':' ||
|
||||||
|
Ch == ')' || Ch == ']' || Ch == '}')
|
||||||
|
{
|
||||||
|
NumChars2 = Str_GetNextASCIICharFromStr ((*PtrSrc),&Ch);
|
||||||
|
(*PtrSrc) += NumChars2;
|
||||||
|
if (Ch <= 32 || Ch == '<' || Ch == '"')
|
||||||
|
{
|
||||||
|
PtrEnd = (*PtrSrc) - NumChars2 - NumChars1 - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/***** Compute number of bytes added until here *****/
|
/***** Compute number of bytes added until here *****/
|
||||||
(*Link)->AddedLengthUntilHere = (*Link)->Prev ? (*Link)->Prev->AddedLengthUntilHere : 0;
|
(*Link)->AddedLengthUntilHere = (*Link)->Prev ? (*Link)->Prev->AddedLengthUntilHere :
|
||||||
(*Link)->URLorNick.Len = (size_t) (PtrEnd + 1 - (*Link)->URLorNick.Str);
|
0;
|
||||||
if ((*Link)->URLorNick.Len <= MaxCharsURLOnScreen)
|
(*Link)->URLorNick.Len = (size_t) (PtrEnd + 1 - (*Link)->URLorNick.Str);
|
||||||
(*Link)->AddedLengthUntilHere += URL_ANCHOR_TOTAL_LENGTH +
|
if ((*Link)->URLorNick.Len <= MaxCharsURLOnScreen)
|
||||||
(*Link)->URLorNick.Len;
|
(*Link)->AddedLengthUntilHere += URL_ANCHOR_TOTAL_LENGTH +
|
||||||
else // If URL is too long to be displayed ==> short it
|
(*Link)->URLorNick.Len;
|
||||||
{
|
else // If URL is too long to be displayed ==> short it
|
||||||
if ((Limited = malloc ((*Link)->URLorNick.Len + 1)) == NULL)
|
{
|
||||||
Err_NotEnoughMemoryExit ();
|
if ((Limited = malloc ((*Link)->URLorNick.Len + 1)) == NULL)
|
||||||
strncpy (Limited,(*Link)->URLorNick.Str,(*Link)->URLorNick.Len);
|
Err_NotEnoughMemoryExit ();
|
||||||
Limited[(*Link)->URLorNick.Len] = '\0';
|
strncpy (Limited,(*Link)->URLorNick.Str,(*Link)->URLorNick.Len);
|
||||||
(*Link)->AddedLengthUntilHere += URL_ANCHOR_TOTAL_LENGTH +
|
Limited[(*Link)->URLorNick.Len] = '\0';
|
||||||
Str_LimitLengthHTMLStr (Limited,MaxCharsURLOnScreen);
|
(*Link)->AddedLengthUntilHere += URL_ANCHOR_TOTAL_LENGTH +
|
||||||
free (Limited);
|
Str_LimitLengthHTMLStr (Limited,MaxCharsURLOnScreen);
|
||||||
}
|
free (Limited);
|
||||||
|
}
|
||||||
|
|
||||||
/***** Create next link *****/
|
/***** Create next link *****/
|
||||||
Str_CreateNextLink (Link,LastLink);
|
Str_CreateNextLink (Link,LastLink);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return Type;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************* Check if a nickname found *************************/
|
/************************* Check if a nickname found *************************/
|
||||||
|
|
||||||
static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
|
static Str_LinkType_t Str_CheckNickname (char **PtrSrc,char PrevCh,
|
||||||
struct Str_Link **Link,
|
struct Str_Link **Link,
|
||||||
struct Str_Link **LastLink)
|
struct Str_Link **LastLink)
|
||||||
{
|
{
|
||||||
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
|
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
|
||||||
|
char Ch;
|
||||||
size_t Length;
|
size_t Length;
|
||||||
char ParamsStr[Frm_MAX_BYTES_PARAMS_STR];
|
char ParamsStr[Frm_MAX_BYTES_PARAMS_STR];
|
||||||
struct UsrData UsrDat;
|
struct UsrData UsrDat;
|
||||||
|
@ -480,119 +481,125 @@ static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
|
||||||
char *CaptionStr;
|
char *CaptionStr;
|
||||||
char *ImgStr;
|
char *ImgStr;
|
||||||
char NickWithoutArr[Nck_MAX_BYTES_NICK_WITHOUT_ARROBA + 1];
|
char NickWithoutArr[Nck_MAX_BYTES_NICK_WITHOUT_ARROBA + 1];
|
||||||
|
bool NickSeemsValid;
|
||||||
Str_LinkType_t Type = Str_LINK_UNKNOWN;
|
Str_LinkType_t Type = Str_LINK_UNKNOWN;
|
||||||
|
|
||||||
/***** Check if the next char is the start of a nickname *****/
|
/***** Check if the next char is the start of a nickname *****/
|
||||||
if ((int) *(*PtrSrc) == (int) '@')
|
Ch = *(*PtrSrc);
|
||||||
{
|
if (Ch == '@') // Current is @
|
||||||
(*Link)->URLorNick.Str = (*PtrSrc);
|
if (!Str_ChIsAlphaNum (PrevCh)) // Previous is not alphanumeric
|
||||||
|
if (Str_ChIsAlphaNum (*((*PtrSrc) + 1))) // Next is alphanumeric
|
||||||
|
{
|
||||||
|
(*Link)->URLorNick.Str = (*PtrSrc);
|
||||||
|
|
||||||
/***** Find nickname end *****/
|
/***** Find nickname end *****/
|
||||||
(*PtrSrc)++; // Points to first character after @
|
(*PtrSrc)++; // Points to first character after @
|
||||||
|
|
||||||
/***** A nick can have digits, letters and '_' *****/
|
/***** A nick can have digits, letters and '_' *****/
|
||||||
for (;
|
for (;
|
||||||
*(*PtrSrc);
|
*(*PtrSrc);
|
||||||
(*PtrSrc)++)
|
(*PtrSrc)++)
|
||||||
if (!((*(*PtrSrc) >= 'a' && *(*PtrSrc) <= 'z') ||
|
{
|
||||||
(*(*PtrSrc) >= 'A' && *(*PtrSrc) <= 'Z') ||
|
Ch = *(*PtrSrc);
|
||||||
(*(*PtrSrc) >= '0' && *(*PtrSrc) <= '9') ||
|
if (!Str_ChIsAlphaNum (Ch))
|
||||||
(*(*PtrSrc) == '_')))
|
break;
|
||||||
break;
|
}
|
||||||
|
|
||||||
/***** Calculate length of this nickname *****/
|
/***** Calculate length of this nickname *****/
|
||||||
(*Link)->URLorNick.Len = (size_t) ((*PtrSrc) - (*Link)->URLorNick.Str);
|
(*Link)->URLorNick.Len = (size_t) ((*PtrSrc) - (*Link)->URLorNick.Str);
|
||||||
|
|
||||||
/***** A nick (without arroba) must have a number of characters
|
/***** A nick (without arroba) must have a number of characters
|
||||||
Nck_MIN_CHARS_NICK_WITHOUT_ARROBA <= Length <= Nck_MAX_CHARS_NICK_WITHOUT_ARROBA *****/
|
Nck_MIN_CHARS_NICK_WITHOUT_ARROBA <= Length <= Nck_MAX_CHARS_NICK_WITHOUT_ARROBA *****/
|
||||||
Length = (*Link)->URLorNick.Len - 1; // Do not count the initial @
|
Length = (*Link)->URLorNick.Len - 1; // Do not count the initial @
|
||||||
if (Length >= Nck_MIN_CHARS_NICK_WITHOUT_ARROBA &&
|
NickSeemsValid = Length >= Nck_MIN_CHARS_NICK_WITHOUT_ARROBA &&
|
||||||
Length <= Nck_MAX_CHARS_NICK_WITHOUT_ARROBA)
|
Length <= Nck_MAX_CHARS_NICK_WITHOUT_ARROBA;
|
||||||
{
|
|
||||||
strncpy (NickWithoutArr,(*Link)->URLorNick.Str + 1,Length);
|
|
||||||
NickWithoutArr[Length] = '\0';
|
|
||||||
Type = Str_LINK_NICK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Type == Str_LINK_NICK)
|
if (NickSeemsValid)
|
||||||
{
|
{
|
||||||
/***** Get user's code using nickname *****/
|
/***** Get user's code using nickname *****/
|
||||||
Usr_UsrDataConstructor (&UsrDat);
|
Usr_UsrDataConstructor (&UsrDat);
|
||||||
UsrDat.UsrCod = Nck_DB_GetUsrCodFromNickname (NickWithoutArr);
|
strncpy (NickWithoutArr,(*Link)->URLorNick.Str + 1,Length);
|
||||||
if (UsrDat.UsrCod > 0)
|
NickWithoutArr[Length] = '\0';
|
||||||
Usr_GetUsrDataFromUsrCod (&UsrDat,
|
if ((UsrDat.UsrCod = Nck_DB_GetUsrCodFromNickname (NickWithoutArr)) > 0)
|
||||||
Usr_DONT_GET_PREFS,
|
{
|
||||||
Usr_DONT_GET_ROLE_IN_CURRENT_CRS);
|
Type = Str_LINK_NICK;
|
||||||
|
Usr_GetUsrDataFromUsrCod (&UsrDat,
|
||||||
|
Usr_DONT_GET_PREFS,
|
||||||
|
Usr_DONT_GET_ROLE_IN_CURRENT_CRS);
|
||||||
|
}
|
||||||
|
|
||||||
/***** Reset anchors (checked on freeing) *****/
|
if (Type == Str_LINK_NICK)
|
||||||
(*Link)->Nick.Anchor1.Str =
|
{
|
||||||
(*Link)->Nick.Anchor2.Str =
|
/***** Reset anchors (checked on freeing) *****/
|
||||||
(*Link)->Nick.Anchor3.Str = NULL;
|
(*Link)->Nick.Anchor1.Str =
|
||||||
|
(*Link)->Nick.Anchor2.Str =
|
||||||
|
(*Link)->Nick.Anchor3.Str = NULL;
|
||||||
|
|
||||||
/***** Create id for this form *****/
|
/***** Create id for this form *****/
|
||||||
Gbl.Form.Num++;
|
Gbl.Form.Num++;
|
||||||
if (Gbl.Usrs.Me.Logged)
|
if (Gbl.Usrs.Me.Logged)
|
||||||
snprintf (Gbl.Form.UniqueId,sizeof (Gbl.Form.UniqueId),
|
snprintf (Gbl.Form.UniqueId,sizeof (Gbl.Form.UniqueId),
|
||||||
"form_%s_%d",Gbl.UniqueNameEncrypted,Gbl.Form.Num);
|
"form_%s_%d",Gbl.UniqueNameEncrypted,Gbl.Form.Num);
|
||||||
else
|
else
|
||||||
snprintf (Gbl.Form.Id,sizeof (Gbl.Form.Id),
|
snprintf (Gbl.Form.Id,sizeof (Gbl.Form.Id),
|
||||||
"form_%d",Gbl.Form.Num);
|
"form_%d",Gbl.Form.Num);
|
||||||
|
|
||||||
/***** Store first part of anchor *****/
|
/***** Store first part of anchor *****/
|
||||||
Frm_SetParamsForm (ParamsStr,ActSeeOthPubPrf,true);
|
Frm_SetParamsForm (ParamsStr,ActSeeOthPubPrf,true);
|
||||||
if (asprintf (&(*Link)->Nick.Anchor1.Str,
|
if (asprintf (&(*Link)->Nick.Anchor1.Str,
|
||||||
"<form method=\"post\" action=\"%s/%s\" id=\"%s\">"
|
"<form method=\"post\" action=\"%s/%s\" id=\"%s\">"
|
||||||
"%s" // Parameters
|
"%s" // Parameters
|
||||||
"<input type=\"hidden\" name=\"usr\" value=\"",
|
"<input type=\"hidden\" name=\"usr\" value=\"",
|
||||||
Cfg_URL_SWAD_CGI,
|
Cfg_URL_SWAD_CGI,
|
||||||
Lan_STR_LANG_ID[Gbl.Prefs.Language],
|
Lan_STR_LANG_ID[Gbl.Prefs.Language],
|
||||||
Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId :
|
Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId :
|
||||||
Gbl.Form.Id,
|
Gbl.Form.Id,
|
||||||
ParamsStr) < 0)
|
ParamsStr) < 0)
|
||||||
Err_NotEnoughMemoryExit ();
|
Err_NotEnoughMemoryExit ();
|
||||||
(*Link)->Nick.Anchor1.Len = strlen ((*Link)->Nick.Anchor1.Str);
|
(*Link)->Nick.Anchor1.Len = strlen ((*Link)->Nick.Anchor1.Str);
|
||||||
|
|
||||||
/***** Store second part of anchor *****/
|
/***** Store second part of anchor *****/
|
||||||
if (asprintf (&(*Link)->Nick.Anchor2.Str,
|
if (asprintf (&(*Link)->Nick.Anchor2.Str,
|
||||||
"\">"
|
"\">"
|
||||||
"<a href=\"\""
|
"<a href=\"\""
|
||||||
" onclick=\"document.getElementById('%s').submit();return false;\">",
|
" onclick=\"document.getElementById('%s').submit();return false;\">",
|
||||||
Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId :
|
Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId :
|
||||||
Gbl.Form.Id) < 0)
|
Gbl.Form.Id) < 0)
|
||||||
Err_NotEnoughMemoryExit ();
|
Err_NotEnoughMemoryExit ();
|
||||||
(*Link)->Nick.Anchor2.Len = strlen ((*Link)->Nick.Anchor2.Str);
|
(*Link)->Nick.Anchor2.Len = strlen ((*Link)->Nick.Anchor2.Str);
|
||||||
|
|
||||||
/***** Store third part of anchor *****/
|
/***** Store third part of anchor *****/
|
||||||
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (&UsrDat,PhotoURL);
|
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (&UsrDat,PhotoURL);
|
||||||
Str_GetUsrPhoto (&UsrDat,ShowPhoto ? PhotoURL :
|
Pho_BuildHTMLUsrPhoto (&UsrDat,ShowPhoto ? PhotoURL :
|
||||||
NULL,
|
NULL,
|
||||||
"PHOTO15x20",
|
"PHOTO15x20",Pho_ZOOM,
|
||||||
&CaptionStr,
|
&CaptionStr,
|
||||||
&ImgStr);
|
&ImgStr);
|
||||||
if (asprintf (&(*Link)->Nick.Anchor3.Str,
|
if (asprintf (&(*Link)->Nick.Anchor3.Str,
|
||||||
"</a></form>"
|
"</a></form>%s%s",
|
||||||
"%s%s",
|
CaptionStr,
|
||||||
CaptionStr,
|
ImgStr) < 0)
|
||||||
ImgStr) < 0)
|
Err_NotEnoughMemoryExit ();
|
||||||
Err_NotEnoughMemoryExit ();
|
free (ImgStr);
|
||||||
free (ImgStr);
|
free (CaptionStr);
|
||||||
free (CaptionStr);
|
(*Link)->Nick.Anchor3.Len = strlen ((*Link)->Nick.Anchor3.Str);
|
||||||
(*Link)->Nick.Anchor3.Len = strlen ((*Link)->Nick.Anchor3.Str);
|
|
||||||
|
|
||||||
/***** Free memory used for user's data *****/
|
/***** Free memory used for user's data *****/
|
||||||
Usr_UsrDataDestructor (&UsrDat);
|
Usr_UsrDataDestructor (&UsrDat);
|
||||||
|
|
||||||
/***** Compute number of bytes added until here *****/
|
/***** Compute number of bytes added until here *****/
|
||||||
(*Link)->AddedLengthUntilHere = (*Link)->Prev ? (*Link)->Prev->AddedLengthUntilHere : 0;
|
(*Link)->AddedLengthUntilHere = (*Link)->Prev ? (*Link)->Prev->AddedLengthUntilHere :
|
||||||
(*Link)->AddedLengthUntilHere += (*Link)->Nick.Anchor1.Len +
|
0;
|
||||||
(*Link)->URLorNick.Len +
|
(*Link)->AddedLengthUntilHere += (*Link)->Nick.Anchor1.Len +
|
||||||
(*Link)->Nick.Anchor2.Len +
|
(*Link)->URLorNick.Len +
|
||||||
(*Link)->Nick.Anchor3.Len;
|
(*Link)->Nick.Anchor2.Len +
|
||||||
|
(*Link)->Nick.Anchor3.Len;
|
||||||
|
|
||||||
/***** Create next link *****/
|
/***** Create next link *****/
|
||||||
Str_CreateNextLink (Link,LastLink);
|
Str_CreateNextLink (Link,LastLink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Type;
|
return Type;
|
||||||
}
|
}
|
||||||
|
@ -638,175 +645,15 @@ static void Str_CopySubstring (const struct Str_Substring *Src,char **Dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*************************** Show a user's photo *****************************/
|
/*********** Check if a character is in set { a-z, A-Z, 0-9, _ } *************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Str_GetUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
|
bool Str_ChIsAlphaNum (char Ch)
|
||||||
const char *ClassPhoto,
|
|
||||||
char **CaptionStr,
|
|
||||||
char **ImgStr)
|
|
||||||
{
|
{
|
||||||
extern const char *Rol_Icons[Rol_NUM_ROLES];
|
return ((Ch >= 'a' && Ch <= 'z') ||
|
||||||
extern const char *Txt_Following;
|
(Ch >= 'A' && Ch <= 'Z') ||
|
||||||
extern const char *Txt_Followers;
|
(Ch >= '0' && Ch <= '9') ||
|
||||||
unsigned NumFollowing;
|
(Ch == '_'));
|
||||||
unsigned NumFollowers;
|
|
||||||
bool PhotoExists;
|
|
||||||
char IdCaption[Frm_MAX_BYTES_ID + 1];
|
|
||||||
char CtyName[Cns_HIERARCHY_MAX_BYTES_FULL_NAME + 1];
|
|
||||||
struct Ins_Instit Ins;
|
|
||||||
char MainDegreeShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1];
|
|
||||||
Rol_Role_t MaxRole; // Maximum user's role in his/her main degree
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
char *Name;
|
|
||||||
char *Nick;
|
|
||||||
char *InsCty;
|
|
||||||
char *MainDeg;
|
|
||||||
char *Follow;
|
|
||||||
} Caption;
|
|
||||||
|
|
||||||
/***** First name and surnames *****/
|
|
||||||
if (asprintf (&Caption.Name,"<div class=\"ZOOM_TXT_LINE DAT_N_BOLD\">" // Limited width
|
|
||||||
"%s<br />"
|
|
||||||
"%s%s%s"
|
|
||||||
"</div>",
|
|
||||||
UsrDat->FrstName,
|
|
||||||
UsrDat->Surname1,
|
|
||||||
UsrDat->Surname2[0] ? " " :
|
|
||||||
"",
|
|
||||||
UsrDat->Surname2[0] ? UsrDat->Surname2 :
|
|
||||||
"") < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
|
|
||||||
/***** Nickname *****/
|
|
||||||
if (UsrDat->Nickname[0])
|
|
||||||
{
|
|
||||||
if (asprintf (&Caption.Nick,"<div class=\"ZOOM_TXT_LINE DAT_SMALL_N\">"
|
|
||||||
"@%s"
|
|
||||||
"</div>",
|
|
||||||
UsrDat->Nickname) < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
}
|
|
||||||
else if (asprintf (&Caption.Nick,"%s","") < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
|
|
||||||
/***** Institution full name and institution country *****/
|
|
||||||
if (UsrDat->InsCod > 0)
|
|
||||||
{
|
|
||||||
/***** Get institution short name and country name *****/
|
|
||||||
Ins.InsCod = UsrDat->InsCod;
|
|
||||||
Ins_GetShrtNameAndCtyOfInstitution (&Ins,CtyName);
|
|
||||||
|
|
||||||
/***** Write institution short name and country name *****/
|
|
||||||
if (asprintf (&Caption.InsCty,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
|
|
||||||
"%s (%s)"
|
|
||||||
"</div>",
|
|
||||||
Ins.ShrtName,CtyName) < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
}
|
|
||||||
else if (UsrDat->CtyCod > 0)
|
|
||||||
{
|
|
||||||
/***** Get country name *****/
|
|
||||||
Cty_GetCountryName (UsrDat->CtyCod,Gbl.Prefs.Language,CtyName);
|
|
||||||
|
|
||||||
/***** Write country name *****/
|
|
||||||
if (asprintf (&Caption.InsCty,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
|
|
||||||
"%s"
|
|
||||||
"</div>",
|
|
||||||
CtyName) < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
}
|
|
||||||
else if (asprintf (&Caption.InsCty,"%s","") < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
|
|
||||||
/***** Main degree (in which the user has more courses) short name *****/
|
|
||||||
Deg_GetUsrMainDeg (UsrDat->UsrCod,MainDegreeShrtName,&MaxRole);
|
|
||||||
if (MainDegreeShrtName[0])
|
|
||||||
{
|
|
||||||
if (asprintf (&Caption.MainDeg,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
|
|
||||||
"<div class=\"ZOOM_DEG\" style=\"background-image:url('%s/%s');\">"
|
|
||||||
"%s"
|
|
||||||
"</div>"
|
|
||||||
"</div>",
|
|
||||||
Cfg_URL_ICON_PUBLIC,Rol_Icons[MaxRole],
|
|
||||||
MainDegreeShrtName) < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
}
|
|
||||||
else if (asprintf (&Caption.MainDeg,"%s","") < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
|
|
||||||
/***** Following and followers *****/
|
|
||||||
if (UsrDat->Nickname[0]) // Get social data only if nickname is retrieved (in some actions)
|
|
||||||
{
|
|
||||||
Fol_GetNumFollow (UsrDat->UsrCod,&NumFollowing,&NumFollowers);
|
|
||||||
if (asprintf (&Caption.Follow,"<div class=\"ZOOM_TXT_LINE\">"
|
|
||||||
"<span class=\"DAT_N_BOLD\">"
|
|
||||||
"%u"
|
|
||||||
"</span>"
|
|
||||||
"<span class=\"DAT_SMALL\">"
|
|
||||||
" %s "
|
|
||||||
"</span>"
|
|
||||||
"<span class=\"DAT_N_BOLD\">"
|
|
||||||
"%u"
|
|
||||||
"</span>"
|
|
||||||
"<span class=\"DAT_SMALL\">"
|
|
||||||
" %s"
|
|
||||||
"</span>"
|
|
||||||
"</div>",
|
|
||||||
NumFollowing,
|
|
||||||
Txt_Following,
|
|
||||||
NumFollowers,
|
|
||||||
Txt_Followers) < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
}
|
|
||||||
else if (asprintf (&Caption.Follow,"%s","") < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
|
|
||||||
/***** Hidden div *****/
|
|
||||||
Frm_SetUniqueId (IdCaption);
|
|
||||||
if (asprintf (CaptionStr,"<div id=\"%s\" class=\"NOT_SHOWN\">"
|
|
||||||
"%s%s%s%s%s"
|
|
||||||
"</div>",
|
|
||||||
IdCaption,
|
|
||||||
Caption.Name,
|
|
||||||
Caption.Nick,
|
|
||||||
Caption.InsCty,
|
|
||||||
Caption.MainDeg,
|
|
||||||
Caption.Follow) < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
free (Caption.Follow);
|
|
||||||
free (Caption.MainDeg);
|
|
||||||
free (Caption.InsCty);
|
|
||||||
free (Caption.Nick);
|
|
||||||
free (Caption.Name);
|
|
||||||
|
|
||||||
/***** Image zoom *****/
|
|
||||||
PhotoExists = false;
|
|
||||||
if (PhotoURL)
|
|
||||||
if (PhotoURL[0])
|
|
||||||
PhotoExists = true;
|
|
||||||
|
|
||||||
if (PhotoExists)
|
|
||||||
{
|
|
||||||
if (asprintf (ImgStr,"<img src=\"%s\" alt=\"%s\" title=\"%s\" class=\"%s\""
|
|
||||||
" onmouseover=\"zoom(this,'%s','%s');\""
|
|
||||||
" onmouseout=\"noZoom();\""
|
|
||||||
" />",
|
|
||||||
PhotoURL,UsrDat->FullName,UsrDat->FullName,ClassPhoto,
|
|
||||||
PhotoURL,IdCaption) < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (asprintf (ImgStr,"<img src=\"%s/usr_bl.jpg\" alt=\"%s\" title=\"%s\" class=\"%s\""
|
|
||||||
" onmouseover=\"zoom(this,'%s/usr_bl.jpg','%s');\""
|
|
||||||
" onmouseout=\"noZoom();\""
|
|
||||||
" />",
|
|
||||||
Cfg_URL_ICON_PUBLIC,UsrDat->FullName,UsrDat->FullName,ClassPhoto,
|
|
||||||
Cfg_URL_ICON_PUBLIC,IdCaption) < 0)
|
|
||||||
Err_NotEnoughMemoryExit ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -83,6 +83,9 @@ typedef enum
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScreen);
|
void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScreen);
|
||||||
|
|
||||||
|
bool Str_ChIsAlphaNum (char Ch);
|
||||||
|
|
||||||
size_t Str_LimitLengthHTMLStr (char *Str,size_t MaxCharsOnScreen);
|
size_t Str_LimitLengthHTMLStr (char *Str,size_t MaxCharsOnScreen);
|
||||||
|
|
||||||
void Str_AnalyzeTxtAndStoreNotifyEventToMentionedUsrs (long PubCod,const char *Txt);
|
void Str_AnalyzeTxtAndStoreNotifyEventToMentionedUsrs (long PubCod,const char *Txt);
|
||||||
|
|
Loading…
Reference in New Issue