// swad_nickname.c: Users' nicknames
/*
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 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 .
*/
/*****************************************************************************/
/********************************* Headers ***********************************/
/*****************************************************************************/
#include // For string functions
#include "swad_account.h"
#include "swad_box.h"
#include "swad_database.h"
#include "swad_form.h"
#include "swad_global.h"
#include "swad_HTML.h"
#include "swad_parameter.h"
#include "swad_QR.h"
#include "swad_user.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/******************************* Private types *******************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
const char *Nck_NICKNAME_SECTION_ID = "nickname_section";
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
static void Nck_ShowFormChangeUsrNickname (const struct UsrData *UsrDat,bool ItsMe,
bool IMustFillNickname);
static void Nck_RemoveNicknameFromDB (long UsrCod,const char *Nickname);
static void Nck_UpdateUsrNick (struct UsrData *UsrDat);
/*****************************************************************************/
/********* Check whether a nickname (with initial arroba) if valid ***********/
/*****************************************************************************/
bool Nck_CheckIfNickWithArrobaIsValid (const char *NicknameWithArroba)
{
char NicknameWithoutArroba[Nck_MAX_BYTES_NICKNAME_FROM_FORM + 1];
unsigned Length;
const char *Ptr;
/***** A nickname must start by '@' *****/
if (NicknameWithArroba[0] != '@') // It's not a nickname
return false;
/***** Make a copy of nickname *****/
Str_Copy (NicknameWithoutArroba,NicknameWithArroba,
Nck_MAX_BYTES_NICKNAME_FROM_FORM);
Str_RemoveLeadingArrobas (NicknameWithoutArroba);
Length = strlen (NicknameWithoutArroba);
/***** A nick (without arroba) must have a number of characters
Nck_MIN_BYTES_NICKNAME_WITHOUT_ARROBA <= Length <= Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA *****/
if (Length < Nck_MIN_BYTES_NICKNAME_WITHOUT_ARROBA ||
Length > Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA)
return false;
/***** A nick can have digits, letters and '_' *****/
for (Ptr = NicknameWithoutArroba;
*Ptr;
Ptr++)
if (!((*Ptr >= 'a' && *Ptr <= 'z') ||
(*Ptr >= 'A' && *Ptr <= 'Z') ||
(*Ptr >= '0' && *Ptr <= '9') ||
(*Ptr == '_')))
return false;
return true;
}
/*****************************************************************************/
/************* Get nickname of a user from his/her user's code ***************/
/*****************************************************************************/
bool Nck_GetNicknameFromUsrCod (long UsrCod,
char Nickname[Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA + 1])
{
MYSQL_RES *mysql_res;
MYSQL_ROW row;
bool Found;
/***** Get current (last updated) user's nickname from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get nickname",
"SELECT Nickname FROM usr_nicknames"
" WHERE UsrCod=%ld ORDER BY CreatTime DESC LIMIT 1",
UsrCod))
{
/* Get nickname */
row = mysql_fetch_row (mysql_res);
Str_Copy (Nickname,row[0],
Nck_MAX_BYTES_NICKNAME_WITHOUT_ARROBA);
Found = true;
}
else
{
Nickname[0] = '\0';
Found = false;
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
return Found;
}
/*****************************************************************************/
/************** Get user's code of a user from his/her nickname **************/
/*****************************************************************************/
// Nickname may have leading '@'
// Returns true if nickname found in database
long Nck_GetUsrCodFromNickname (const char *Nickname)
{
char NicknameWithoutArroba[Nck_MAX_BYTES_NICKNAME_FROM_FORM + 1];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
long UsrCod = -1L;
if (Nickname)
if (Nickname[0])
{
/***** Make a copy without possible starting arrobas *****/
Str_Copy (NicknameWithoutArroba,Nickname,
Nck_MAX_BYTES_NICKNAME_FROM_FORM);
Str_RemoveLeadingArrobas (NicknameWithoutArroba);
/***** Get user's code from database *****/
/* Check if user code from table usr_nicknames is also in table usr_data */
if (DB_QuerySELECT (&mysql_res,"can not get user's code",
"SELECT usr_nicknames.UsrCod"
" FROM usr_nicknames,usr_data"
" WHERE usr_nicknames.Nickname='%s'"
" AND usr_nicknames.UsrCod=usr_data.UsrCod",
NicknameWithoutArroba))
{
/* Get row */
row = mysql_fetch_row (mysql_res);
/* Get user's code */
UsrCod = Str_ConvertStrCodToLongCod (row[0]);
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
}
return UsrCod;
}
/*****************************************************************************/
/*********************** Show form to change my nickname *********************/
/*****************************************************************************/
void Nck_ShowFormChangeMyNickname (bool IMustFillNickname)
{
Nck_ShowFormChangeUsrNickname (&Gbl.Usrs.Me.UsrDat,
true, // ItsMe
IMustFillNickname);
}
/*****************************************************************************/
/*********************** Show form to change my nickname *********************/
/*****************************************************************************/
void Nck_ShowFormChangeOtherUsrNickname (void)
{
Nck_ShowFormChangeUsrNickname (&Gbl.Usrs.Other.UsrDat,
false, // ItsMe
false); // IMustFillNickname
}
/*****************************************************************************/
/*********************** Show form to change my nickname *********************/
/*****************************************************************************/
static void Nck_ShowFormChangeUsrNickname (const struct UsrData *UsrDat,bool ItsMe,
bool IMustFillNickname)
{
extern const char *Hlp_PROFILE_Account;
extern const char *The_ClassFormInBox[The_NUM_THEMES];
extern const char *Txt_Nickname;
extern const char *Txt_Before_going_to_any_other_option_you_must_fill_your_nickname;
extern const char *Txt_Current_nickname;
extern const char *Txt_Other_nicknames;
extern const char *Txt_Use_this_nickname;
extern const char *Txt_New_nickname;
extern const char *Txt_Change_nickname;
extern const char *Txt_Save_changes;
MYSQL_RES *mysql_res;
MYSQL_ROW row;
char StrRecordWidth[10 + 1];
unsigned NumNicks;
unsigned NumNick;
Act_Action_t NextAction;
/***** Start section *****/
HTM_SECTION_Begin (Nck_NICKNAME_SECTION_ID);
/***** Get my nicknames *****/
NumNicks =
(unsigned) DB_QuerySELECT (&mysql_res,"can not get nicknames of a user",
"SELECT Nickname FROM usr_nicknames"
" WHERE UsrCod=%ld"
" ORDER BY CreatTime DESC",
UsrDat->UsrCod);
/***** Begin box *****/
snprintf (StrRecordWidth,sizeof (StrRecordWidth),
"%upx",
Rec_RECORD_WIDTH);
Box_BoxBegin (StrRecordWidth,Txt_Nickname,Acc_PutLinkToRemoveMyAccount,
Hlp_PROFILE_Account,Box_NOT_CLOSABLE);
/***** Show possible alerts *****/
Ale_ShowAlerts (Nck_NICKNAME_SECTION_ID);
/***** Help message *****/
if (IMustFillNickname)
Ale_ShowAlert (Ale_WARNING,Txt_Before_going_to_any_other_option_you_must_fill_your_nickname);
/***** Begin table *****/
HTM_TABLE_BeginWidePadding (2);
/***** List nicknames *****/
for (NumNick = 1;
NumNick <= NumNicks;
NumNick++)
{
/* Get nickname */
row = mysql_fetch_row (mysql_res);
HTM_TR_Begin (NULL);
if (NumNick == 1)
{
/* The first nickname is the current one */
HTM_TD_Begin ("class=\"REC_C1_BOT RT\"");
fprintf (Gbl.F.Out,"