Version 20.81: May 22, 2021 New module swad_country_database for database queries related to countries.

This commit is contained in:
acanas 2021-05-22 12:34:10 +02:00
parent 34fb16932c
commit c1a0a2832b
14 changed files with 1264 additions and 1076 deletions

View File

@ -36,7 +36,8 @@ OBJS = swad_account.o swad_account_database.o swad_action.o swad_agenda.o \
swad_center_config.o swad_chat.o swad_chat_database.o swad_config.o \ swad_center_config.o swad_chat.o swad_chat_database.o swad_config.o \
swad_connected.o swad_connected_database.o swad_cookie.o \ swad_connected.o swad_connected_database.o swad_cookie.o \
swad_cookie_database.o swad_country.o swad_country_config.o \ swad_cookie_database.o swad_country.o swad_country_config.o \
swad_course.o swad_course_config.o swad_cryptography.o \ swad_country_database.o swad_course.o swad_course_config.o \
swad_cryptography.o \
swad_database.o swad_date.o swad_degree.o swad_degree_config.o \ swad_database.o swad_date.o swad_degree.o swad_degree_config.o \
swad_degree_type.o swad_department.o swad_duplicate.o \ swad_degree_type.o swad_department.o swad_duplicate.o \
swad_enrolment.o swad_error.o swad_exam.o swad_exam_log.o \ swad_enrolment.o swad_error.o swad_exam.o swad_exam_log.o \

View File

@ -67,7 +67,7 @@ struct Ctr_Center
long PlcCod; // Place code long PlcCod; // Place code
Ctr_Status_t Status; // Center status Ctr_Status_t Status; // Center status
long RequesterUsrCod; // User code of the person who requested the creation of this center long RequesterUsrCod; // User code of the person who requested the creation of this center
struct Coordinates Coord; // Geographical coordinates struct Map_Coordinates Coord; // Geographical coordinates
char ShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1]; char ShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1];
char FullName[Cns_HIERARCHY_MAX_BYTES_FULL_NAME + 1]; char FullName[Cns_HIERARCHY_MAX_BYTES_FULL_NAME + 1];
char WWW[Cns_MAX_BYTES_WWW + 1]; char WWW[Cns_MAX_BYTES_WWW + 1];

View File

@ -602,14 +602,15 @@ 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 20.80 (2021-05-20)" #define Log_PLATFORM_VERSION "SWAD 20.81 (2021-05-22)"
#define CSS_FILE "swad20.45.css" #define CSS_FILE "swad20.45.css"
#define JS_FILE "swad20.69.1.js" #define JS_FILE "swad20.69.1.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 20.80: May 20, 2021 New module swad_cookie_database for database queries related to cookies. (? lines) Version 20.81: May 22, 2021 New module swad_country_database for database queries related to countries. (311632 lines)
Version 20.80: May 20, 2021 New module swad_cookie_database for database queries related to cookies. (311497 lines)
Version 20.79: May 20, 2021 New module swad_connected_database for database queries related to connected users. (311415 lines) Version 20.79: May 20, 2021 New module swad_connected_database for database queries related to connected users. (311415 lines)
Version 20.78.2: May 20, 2021 Code formatting in games and matches. (311326 lines) Version 20.78.2: May 20, 2021 Code formatting in games and matches. (311326 lines)
Version 20.78.1: May 20, 2021 Fixed bug in matches. Reported by Jesús Garrido Alcázar. (311317 lines) Version 20.78.1: May 20, 2021 Fixed bug in matches. Reported by Jesús Garrido Alcázar. (311317 lines)

View File

@ -33,6 +33,7 @@
#include <string.h> // For string functions #include <string.h> // For string functions
#include "swad_country_config.h" #include "swad_country_config.h"
#include "swad_country_database.h"
#include "swad_database.h" #include "swad_database.h"
#include "swad_error.h" #include "swad_error.h"
#include "swad_figure.h" #include "swad_figure.h"
@ -84,9 +85,9 @@ static void Cty_ListCountriesForEdition (void);
static void Cty_PutParamOtherCtyCod (void *CtyCod); static void Cty_PutParamOtherCtyCod (void *CtyCod);
static long Cty_GetParamOtherCtyCod (void); static long Cty_GetParamOtherCtyCod (void);
static bool Cty_CheckIfNumericCountryCodeExists (long CtyCod); static bool Cty_DB_CheckIfNumericCountryCodeExists (long CtyCod);
static bool Cty_CheckIfAlpha2CountryCodeExists (const char Alpha2[2 + 1]); static bool Cty_DB_CheckIfAlpha2CountryCodeExists (const char Alpha2[2 + 1]);
static bool Cty_CheckIfCountryNameExists (Lan_Language_t Language,const char *Name,long CtyCod); static bool Cty_DB_CheckIfCountryNameExists (Lan_Language_t Language,const char *Name,long CtyCod);
static void Cty_UpdateCtyNameDB (long CtyCod,const char *FieldName,const char *NewCtyName); static void Cty_UpdateCtyNameDB (long CtyCod,const char *FieldName,const char *NewCtyName);
static void Cty_ShowAlertAndButtonToGoToCty (void); static void Cty_ShowAlertAndButtonToGoToCty (void);
@ -108,7 +109,6 @@ static void Cty_FormToGoToMap (struct Cty_Countr *Cty);
void Cty_SeeCtyWithPendingInss (void) void Cty_SeeCtyWithPendingInss (void)
{ {
extern const char *Hlp_SYSTEM_Pending; extern const char *Hlp_SYSTEM_Pending;
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
extern const char *Txt_Countries_with_pending_institutions; extern const char *Txt_Countries_with_pending_institutions;
extern const char *Txt_Country; extern const char *Txt_Country;
extern const char *Txt_Institutions_ABBREVIATION; extern const char *Txt_Institutions_ABBREVIATION;
@ -120,30 +120,17 @@ void Cty_SeeCtyWithPendingInss (void)
struct Cty_Countr Cty; struct Cty_Countr Cty;
const char *BgColor; const char *BgColor;
/***** Get countries with pending institutions *****/ /***** Trivial check: only system admins can see countries with pending institutions *****/
switch (Gbl.Usrs.Me.Role.Logged) switch (Gbl.Usrs.Me.Role.Logged)
{ {
case Rol_SYS_ADM: case Rol_SYS_ADM:
NumCtys = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get countries"
" with pending institutions",
"SELECT ins_instits.CtyCod," // row[0]
"COUNT(*)" // row[1]
" FROM ins_instits,"
"cty_countrs"
" WHERE (ins_instits.Status & %u)<>0"
" AND ins_instits.CtyCod=cty_countrs.CtyCod"
" GROUP BY ins_instits.CtyCod"
" ORDER BY cty_countrs.Name_%s",
(unsigned) Ins_STATUS_BIT_PENDING,
Lan_STR_LANG_ID[Gbl.Prefs.Language]);
break; break;
default: // Forbidden for other users default: // Forbidden for other users
return; return;
} }
/***** Get countries *****/ /***** Get countries with pending institutions *****/
if (NumCtys) if ((NumCtys = Cty_DB_GetListOfCountriesWithPendingInss (&mysql_res)))
{ {
/***** Begin box and table *****/ /***** Begin box and table *****/
Box_BoxTableBegin (NULL,Txt_Countries_with_pending_institutions, Box_BoxTableBegin (NULL,Txt_Countries_with_pending_institutions,
@ -152,16 +139,14 @@ void Cty_SeeCtyWithPendingInss (void)
/***** Write heading *****/ /***** Write heading *****/
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
HTM_TH (1,1,"LM",Txt_Country); HTM_TH (1,1,"LM",Txt_Country);
HTM_TH (1,1,"RM",Txt_Institutions_ABBREVIATION); HTM_TH (1,1,"RM",Txt_Institutions_ABBREVIATION);
HTM_TR_End (); HTM_TR_End ();
/***** List the countries *****/ /***** List the countries *****/
for (NumCty = 0; for (NumCty = 0;
NumCty < NumCtys; NumCty < NumCtys;
NumCty++) NumCty++, Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd)
{ {
/* Get next country */ /* Get next country */
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
@ -174,6 +159,7 @@ void Cty_SeeCtyWithPendingInss (void)
/* Get data of country */ /* Get data of country */
Cty_GetDataOfCountryByCod (&Cty); Cty_GetDataOfCountryByCod (&Cty);
/* Begin row for this country */
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
/* Country map */ /* Country map */
@ -189,8 +175,8 @@ void Cty_SeeCtyWithPendingInss (void)
HTM_Txt (row[1]); HTM_Txt (row[1]);
HTM_TD_End (); HTM_TD_End ();
/* End row for this country */
HTM_TR_End (); HTM_TR_End ();
Gbl.RowEvenOdd = 1 - Gbl.RowEvenOdd;
} }
/***** End table and box *****/ /***** End table and box *****/
@ -525,6 +511,8 @@ void Cty_DrawCountryMapAndNameWithLink (struct Cty_Countr *Cty,Act_Action_t Acti
/***** Begin form *****/ /***** Begin form *****/
Frm_BeginFormGoTo (Action); Frm_BeginFormGoTo (Action);
Cty_PutParamCtyCod (Cty->CtyCod); Cty_PutParamCtyCod (Cty->CtyCod);
/***** Begin container *****/
HTM_DIV_Begin ("class=\"%s\"",ClassContainer); HTM_DIV_Begin ("class=\"%s\"",ClassContainer);
/***** Link to action *****/ /***** Link to action *****/
@ -543,8 +531,10 @@ void Cty_DrawCountryMapAndNameWithLink (struct Cty_Countr *Cty,Act_Action_t Acti
/***** End link *****/ /***** End link *****/
HTM_BUTTON_End (); HTM_BUTTON_End ();
/***** End form *****/ /***** End container *****/
HTM_DIV_End (); HTM_DIV_End ();
/***** End form *****/
Frm_EndForm (); Frm_EndForm ();
/***** Map *****/ /***** Map *****/
@ -751,24 +741,18 @@ static void Cty_PutIconToViewCountries (void)
void Cty_GetBasicListOfCountries (void) void Cty_GetBasicListOfCountries (void)
{ {
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
unsigned NumCty; unsigned NumCty;
struct Cty_Countr *Cty; struct Cty_Countr *Cty;
Lan_Language_t Lan; Lan_Language_t Lan;
/***** Trivial check: if list is already got, nothing to do *****/
if (Gbl.Hierarchy.Ctys.Num)
return;
/***** Get countries from database *****/ /***** Get countries from database *****/
Gbl.Hierarchy.Ctys.Num = (unsigned) if ((Gbl.Hierarchy.Ctys.Num = Cty_DB_GetBasicListOfCountries (&mysql_res))) // Countries found...
DB_QuerySELECT (&mysql_res,"can not get countries",
"SELECT CtyCod," // row[0]
"Alpha2," // row[1]
"Name_%s" // row[2]
" FROM cty_countrs"
" ORDER BY Name_%s",
Lan_STR_LANG_ID[Gbl.Prefs.Language],
Lan_STR_LANG_ID[Gbl.Prefs.Language]);
if (Gbl.Hierarchy.Ctys.Num) // Countries found...
{ {
/***** Create list with countries *****/ /***** Create list with countries *****/
if ((Gbl.Hierarchy.Ctys.Lst = calloc ((size_t) Gbl.Hierarchy.Ctys.Num, if ((Gbl.Hierarchy.Ctys.Lst = calloc ((size_t) Gbl.Hierarchy.Ctys.Num,
@ -789,9 +773,7 @@ void Cty_GetBasicListOfCountries (void)
if ((Cty->CtyCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) if ((Cty->CtyCod = Str_ConvertStrCodToLongCod (row[0])) <= 0)
Err_WrongCountrExit (); Err_WrongCountrExit ();
/* Get Alpha-2 country code (row[1]) */ /* Reset names and webs */
Str_Copy (Cty->Alpha2,row[1],sizeof (Cty->Alpha2) - 1);
for (Lan = (Lan_Language_t) 1; for (Lan = (Lan_Language_t) 1;
Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES; Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES;
Lan++) Lan++)
@ -801,7 +783,7 @@ void Cty_GetBasicListOfCountries (void)
} }
/* Get the name of the country in current language */ /* Get the name of the country in current language */
Str_Copy (Cty->Name[Gbl.Prefs.Language],row[2], Str_Copy (Cty->Name[Gbl.Prefs.Language],row[1],
sizeof (Cty->Name[Gbl.Prefs.Language]) - 1); sizeof (Cty->Name[Gbl.Prefs.Language]) - 1);
/* Reset number of users who claim to belong to country */ /* Reset number of users who claim to belong to country */
@ -822,79 +804,18 @@ void Cty_GetBasicListOfCountries (void)
void Cty_GetFullListOfCountries (void) void Cty_GetFullListOfCountries (void)
{ {
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
char StrField[32];
char SubQueryNam1[Cty_MAX_BYTES_SUBQUERY_CTYS + 1];
char SubQueryNam2[Cty_MAX_BYTES_SUBQUERY_CTYS + 1];
char SubQueryWWW1[Cty_MAX_BYTES_SUBQUERY_CTYS + 1];
char SubQueryWWW2[Cty_MAX_BYTES_SUBQUERY_CTYS + 1];
char *OrderBySubQuery = NULL;
static const char *OrderBySubQueryFmt[Cty_NUM_ORDERS] =
{
[Cty_ORDER_BY_COUNTRY ] = "Name_%s",
[Cty_ORDER_BY_NUM_USRS] = "NumUsrs DESC,Name_%s",
};
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
MYSQL_ROW row; MYSQL_ROW row;
unsigned NumCty; unsigned NumCty;
struct Cty_Countr *Cty; struct Cty_Countr *Cty;
Lan_Language_t Lan; Lan_Language_t Lan;
/***** Trivial check: if list is already got, nothing to do *****/
if (Gbl.Hierarchy.Ctys.Num)
return;
/***** Get countries from database *****/ /***** Get countries from database *****/
SubQueryNam1[0] = '\0'; if ((Gbl.Hierarchy.Ctys.Num = Cty_DB_GetFullListOfCountries (&mysql_res))) // Countries found...
SubQueryNam2[0] = '\0';
SubQueryWWW1[0] = '\0';
SubQueryWWW2[0] = '\0';
for (Lan = (Lan_Language_t) 1;
Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES;
Lan++)
{
snprintf (StrField,sizeof (StrField),"cty_countrs.Name_%s,",Lan_STR_LANG_ID[Lan]);
Str_Concat (SubQueryNam1,StrField,sizeof (SubQueryNam1) - 1);
snprintf (StrField,sizeof (StrField),"Name_%s,",Lan_STR_LANG_ID[Lan]);
Str_Concat (SubQueryNam2,StrField,sizeof (SubQueryNam2) - 1);
snprintf (StrField,sizeof (StrField),"cty_countrs.WWW_%s,",Lan_STR_LANG_ID[Lan]);
Str_Concat (SubQueryWWW1,StrField,sizeof (SubQueryWWW1) - 1);
snprintf (StrField,sizeof (StrField),"WWW_%s,",Lan_STR_LANG_ID[Lan]);
Str_Concat (SubQueryWWW2,StrField,sizeof (SubQueryWWW2) - 1);
}
/* Build order subquery */
if (asprintf (&OrderBySubQuery,OrderBySubQueryFmt[Gbl.Hierarchy.Ctys.SelectedOrder],
Lan_STR_LANG_ID[Gbl.Prefs.Language]) < 0)
Err_NotEnoughMemoryExit ();
/* Query database */
Gbl.Hierarchy.Ctys.Num = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get countries",
"(SELECT cty_countrs.CtyCod," // row[0]
"cty_countrs.Alpha2," // row[1]
"%s" // row[...]
"%s" // row[...]
"COUNT(*) AS NumUsrs" // row[...]
" FROM cty_countrs,"
"usr_data"
" WHERE cty_countrs.CtyCod=usr_data.CtyCod"
" GROUP BY cty_countrs.CtyCod)"
" UNION "
"(SELECT CtyCod," // row[0]
"Alpha2," // row[1]
"%s" // row[...]
"%s" // row[...]
"0 AS NumUsrs" // row[...]
" FROM cty_countrs"
" WHERE CtyCod NOT IN"
" (SELECT DISTINCT CtyCod"
" FROM usr_data))"
" ORDER BY %s",
SubQueryNam1,SubQueryWWW1,
SubQueryNam2,SubQueryWWW2,OrderBySubQuery);
/* Free memory for subquery */
free (OrderBySubQuery);
if (Gbl.Hierarchy.Ctys.Num) // Countries found...
{ {
/***** Create list with countries *****/ /***** Create list with countries *****/
if ((Gbl.Hierarchy.Ctys.Lst = calloc ((size_t) Gbl.Hierarchy.Ctys.Num, if ((Gbl.Hierarchy.Ctys.Lst = calloc ((size_t) Gbl.Hierarchy.Ctys.Num,
@ -948,54 +869,37 @@ void Cty_GetFullListOfCountries (void)
void Cty_WriteSelectorOfCountry (void) void Cty_WriteSelectorOfCountry (void)
{ {
extern const char *Txt_Country; extern const char *Txt_Country;
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
MYSQL_RES *mysql_res;
MYSQL_ROW row;
unsigned NumCtys;
unsigned NumCty; unsigned NumCty;
long CtyCod;
/***** Get list of countries *****/
Cty_GetBasicListOfCountries ();
/***** Begin form *****/ /***** Begin form *****/
Frm_BeginFormGoTo (ActSeeIns); Frm_BeginFormGoTo (ActSeeIns);
/* Begin selector of country */
HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE, HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE,
"id=\"cty\" name=\"cty\" class=\"HIE_SEL\""); "id=\"cty\" name=\"cty\" class=\"HIE_SEL\"");
/* Initial disabled option */
HTM_OPTION (HTM_Type_STRING,"",Gbl.Hierarchy.Cty.CtyCod < 0,true, HTM_OPTION (HTM_Type_STRING,"",Gbl.Hierarchy.Cty.CtyCod < 0,true,
"[%s]",Txt_Country); "[%s]",Txt_Country);
/***** Get countries from database *****/ /* List countries */
NumCtys = (unsigned)
DB_QuerySELECT (&mysql_res,"can not get countries",
"SELECT DISTINCT CtyCod," // row[0]
"Name_%s" // row[1]
" FROM cty_countrs"
" ORDER BY Name_%s",
Lan_STR_LANG_ID[Gbl.Prefs.Language],
Lan_STR_LANG_ID[Gbl.Prefs.Language]);
/***** List countries *****/
for (NumCty = 0; for (NumCty = 0;
NumCty < NumCtys; NumCty < Gbl.Hierarchy.Ctys.Num;
NumCty++) NumCty++)
{ HTM_OPTION (HTM_Type_LONG,&Gbl.Hierarchy.Ctys.Lst[NumCty].CtyCod,
/* Get next country */ Gbl.Hierarchy.Ctys.Lst[NumCty].CtyCod == Gbl.Hierarchy.Cty.CtyCod,false,
row = mysql_fetch_row (mysql_res); "%s",Gbl.Hierarchy.Ctys.Lst[NumCty].Name[Gbl.Prefs.Language]);
/* Get country code (row[0]) */ /* End selector of country */
if ((CtyCod = Str_ConvertStrCodToLongCod (row[0])) <= 0) HTM_SELECT_End ();
Err_WrongCountrExit ();
/* Write option */
HTM_OPTION (HTM_Type_LONG,&CtyCod,
CtyCod == Gbl.Hierarchy.Cty.CtyCod,false,
"%s",row[1]);
}
/***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res);
/***** End form *****/ /***** End form *****/
HTM_SELECT_End ();
Frm_EndForm (); Frm_EndForm ();
// Do not free list of countries here, because it can be reused
} }
/*****************************************************************************/ /*****************************************************************************/
@ -1412,7 +1316,7 @@ void Cty_RenameCountry (void)
if (strcmp (Cty_EditingCty->Name[Language],NewCtyName)) // Different names if (strcmp (Cty_EditingCty->Name[Language],NewCtyName)) // Different names
{ {
/***** If country was in database... *****/ /***** If country was in database... *****/
if (Cty_CheckIfCountryNameExists (Language,NewCtyName,Cty_EditingCty->CtyCod)) if (Cty_DB_CheckIfCountryNameExists (Language,NewCtyName,Cty_EditingCty->CtyCod))
Ale_CreateAlert (Ale_WARNING,NULL, Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_country_X_already_exists, Txt_The_country_X_already_exists,
NewCtyName); NewCtyName);
@ -1446,7 +1350,7 @@ void Cty_RenameCountry (void)
/******************* Check if a numeric country code exists ******************/ /******************* Check if a numeric country code exists ******************/
/*****************************************************************************/ /*****************************************************************************/
static bool Cty_CheckIfNumericCountryCodeExists (long CtyCod) static bool Cty_DB_CheckIfNumericCountryCodeExists (long CtyCod)
{ {
/***** Get number of countries with a name from database *****/ /***** Get number of countries with a name from database *****/
return (DB_QueryCOUNT ("can not check if the numeric code" return (DB_QueryCOUNT ("can not check if the numeric code"
@ -1461,7 +1365,7 @@ static bool Cty_CheckIfNumericCountryCodeExists (long CtyCod)
/*************** Check if an alphabetic country code exists ******************/ /*************** Check if an alphabetic country code exists ******************/
/*****************************************************************************/ /*****************************************************************************/
static bool Cty_CheckIfAlpha2CountryCodeExists (const char Alpha2[2 + 1]) static bool Cty_DB_CheckIfAlpha2CountryCodeExists (const char Alpha2[2 + 1])
{ {
/***** Get number of countries with a name from database *****/ /***** Get number of countries with a name from database *****/
return (DB_QueryCOUNT ("can not check if the alphabetic code" return (DB_QueryCOUNT ("can not check if the alphabetic code"
@ -1476,7 +1380,7 @@ static bool Cty_CheckIfAlpha2CountryCodeExists (const char Alpha2[2 + 1])
/******************** Check if the name of country exists ********************/ /******************** Check if the name of country exists ********************/
/*****************************************************************************/ /*****************************************************************************/
static bool Cty_CheckIfCountryNameExists (Lan_Language_t Language,const char *Name,long CtyCod) static bool Cty_DB_CheckIfCountryNameExists (Lan_Language_t Language,const char *Name,long CtyCod)
{ {
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
@ -1752,7 +1656,7 @@ void Cty_ReceiveFormNewCountry (void)
Txt_You_must_specify_the_numerical_code_of_the_new_country); Txt_You_must_specify_the_numerical_code_of_the_new_country);
CreateCountry = false; CreateCountry = false;
} }
else if (Cty_CheckIfNumericCountryCodeExists (Cty_EditingCty->CtyCod)) else if (Cty_DB_CheckIfNumericCountryCodeExists (Cty_EditingCty->CtyCod))
{ {
Ale_CreateAlert (Ale_WARNING,NULL, Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_numerical_code_X_already_exists, Txt_The_numerical_code_X_already_exists,
@ -1777,7 +1681,7 @@ void Cty_ReceiveFormNewCountry (void)
} }
if (CreateCountry) if (CreateCountry)
{ {
if (Cty_CheckIfAlpha2CountryCodeExists (Cty_EditingCty->Alpha2)) if (Cty_DB_CheckIfAlpha2CountryCodeExists (Cty_EditingCty->Alpha2))
{ {
Ale_CreateAlert (Ale_WARNING,NULL, Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_alphabetical_code_X_already_exists, Txt_The_alphabetical_code_X_already_exists,
@ -1797,7 +1701,7 @@ void Cty_ReceiveFormNewCountry (void)
if (Cty_EditingCty->Name[Lan][0]) // If there's a country name if (Cty_EditingCty->Name[Lan][0]) // If there's a country name
{ {
/***** If name of country was in database... *****/ /***** If name of country was in database... *****/
if (Cty_CheckIfCountryNameExists (Lan,Cty_EditingCty->Name[Lan],-1L)) if (Cty_DB_CheckIfCountryNameExists (Lan,Cty_EditingCty->Name[Lan],-1L))
{ {
Ale_CreateAlert (Ale_WARNING,NULL, Ale_CreateAlert (Ale_WARNING,NULL,
Txt_The_country_X_already_exists, Txt_The_country_X_already_exists,

View File

@ -32,6 +32,8 @@
#include <stdlib.h> // For free #include <stdlib.h> // For free
#include <string.h> // For string functions #include <string.h> // For string functions
#include "swad_country_config.h"
#include "swad_country_database.h"
#include "swad_database.h" #include "swad_database.h"
#include "swad_error.h" #include "swad_error.h"
#include "swad_figure_cache.h" #include "swad_figure_cache.h"
@ -67,7 +69,6 @@ extern struct Globals Gbl;
static void CtyCfg_Configuration (bool PrintView); static void CtyCfg_Configuration (bool PrintView);
static void CtyCfg_PutIconToPrint (__attribute__((unused)) void *Args); static void CtyCfg_PutIconToPrint (__attribute__((unused)) void *Args);
static void CtyCfg_Title (bool PutLink); static void CtyCfg_Title (bool PutLink);
static void CtyCfg_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom);
static void CtyCfg_Map (void); static void CtyCfg_Map (void);
static void CtyCfg_MapImage (bool PrintView,bool PutLink); static void CtyCfg_MapImage (bool PrintView,bool PutLink);
static void CtyCfg_Platform (bool PrintView); static void CtyCfg_Platform (bool PrintView);
@ -138,31 +139,31 @@ static void CtyCfg_Configuration (bool PrintView)
/**************************** Left part ***********************************/ /**************************** Left part ***********************************/
HTM_DIV_Begin ("class=\"HIE_CFG_LEFT HIE_CFG_WIDTH\""); HTM_DIV_Begin ("class=\"HIE_CFG_LEFT HIE_CFG_WIDTH\"");
/***** Begin table *****/ /* Begin table */
HTM_TABLE_BeginWidePadding (2); HTM_TABLE_BeginWidePadding (2);
/***** Platform *****/ /* Platform */
CtyCfg_Platform (PrintView); CtyCfg_Platform (PrintView);
/***** Country name (an link to WWW if exists) *****/ /* Country name (an link to WWW if exists) */
CtyCfg_Name (PutLink); CtyCfg_Name (PutLink);
/***** Shortcut to the country *****/ /* Shortcut to the country */
CtyCfg_Shortcut (PrintView); CtyCfg_Shortcut (PrintView);
NumCtrsWithMap = Ctr_GetCachedNumCtrsWithMapInCty (Gbl.Hierarchy.Cty.CtyCod); NumCtrsWithMap = Ctr_GetCachedNumCtrsWithMapInCty (Gbl.Hierarchy.Cty.CtyCod);
if (PrintView) if (PrintView)
/***** QR code with link to the country *****/ /* QR code with link to the country */
CtyCfg_QR (); CtyCfg_QR ();
else else
{ {
NumCtrs = Ctr_GetCachedNumCtrsInCty (Gbl.Hierarchy.Cty.CtyCod); NumCtrs = Ctr_GetCachedNumCtrsInCty (Gbl.Hierarchy.Cty.CtyCod);
/***** Number of users who claim to belong to this country, /* Number of users who claim to belong to this country,
number of institutions, number of institutions,
number of centers, number of centers,
number of degrees, number of degrees,
number of courses *****/ number of courses */
CtyCfg_NumUsrs (); CtyCfg_NumUsrs ();
CtyCfg_NumInss (); CtyCfg_NumInss ();
HieCfg_NumCtrs (NumCtrs, HieCfg_NumCtrs (NumCtrs,
@ -171,35 +172,37 @@ static void CtyCfg_Configuration (bool PrintView)
CtyCfg_NumDegs (); CtyCfg_NumDegs ();
CtyCfg_NumCrss (); CtyCfg_NumCrss ();
/***** Number of users in courses of this country *****/ /* Number of users in courses of this country */
HieCfg_NumUsrsInCrss (Hie_Lvl_CTY,Gbl.Hierarchy.Cty.CtyCod,Rol_TCH); HieCfg_NumUsrsInCrss (Hie_Lvl_CTY,Gbl.Hierarchy.Cty.CtyCod,Rol_TCH);
HieCfg_NumUsrsInCrss (Hie_Lvl_CTY,Gbl.Hierarchy.Cty.CtyCod,Rol_NET); HieCfg_NumUsrsInCrss (Hie_Lvl_CTY,Gbl.Hierarchy.Cty.CtyCod,Rol_NET);
HieCfg_NumUsrsInCrss (Hie_Lvl_CTY,Gbl.Hierarchy.Cty.CtyCod,Rol_STD); HieCfg_NumUsrsInCrss (Hie_Lvl_CTY,Gbl.Hierarchy.Cty.CtyCod,Rol_STD);
HieCfg_NumUsrsInCrss (Hie_Lvl_CTY,Gbl.Hierarchy.Cty.CtyCod,Rol_UNK); HieCfg_NumUsrsInCrss (Hie_Lvl_CTY,Gbl.Hierarchy.Cty.CtyCod,Rol_UNK);
} }
/***** End table *****/ /* End table */
HTM_TABLE_End (); HTM_TABLE_End ();
/***** End of left part *****/ /* End of left part */
HTM_DIV_End (); HTM_DIV_End ();
/**************************** Right part **********************************/ /**************************** Right part **********************************/
/***** Check country map *****/ /* Check country map */
MapImageExists = Cty_CheckIfCountryPhotoExists (&Gbl.Hierarchy.Cty); MapImageExists = Cty_CheckIfCountryPhotoExists (&Gbl.Hierarchy.Cty);
if (NumCtrsWithMap || MapImageExists) if (NumCtrsWithMap || MapImageExists)
{ {
/* Begin container */
HTM_DIV_Begin ("class=\"HIE_CFG_RIGHT HIE_CFG_WIDTH\""); HTM_DIV_Begin ("class=\"HIE_CFG_RIGHT HIE_CFG_WIDTH\"");
/***** Country map *****/ /* Country map */
if (NumCtrsWithMap) if (NumCtrsWithMap)
CtyCfg_Map (); CtyCfg_Map ();
/***** Country map image *****/ /* Country map image */
if (MapImageExists) if (MapImageExists)
CtyCfg_MapImage (PrintView,PutLink); CtyCfg_MapImage (PrintView,PutLink);
/* End container */
HTM_DIV_End (); HTM_DIV_End ();
} }
@ -223,46 +226,27 @@ static void CtyCfg_PutIconToPrint (__attribute__((unused)) void *Args)
static void CtyCfg_Title (bool PutLink) static void CtyCfg_Title (bool PutLink)
{ {
/***** Begin container *****/
HTM_DIV_Begin ("class=\"FRAME_TITLE FRAME_TITLE_BIG\""); HTM_DIV_Begin ("class=\"FRAME_TITLE FRAME_TITLE_BIG\"");
/* Begin link */
if (PutLink) if (PutLink)
HTM_A_Begin ("href=\"%s\" target=\"_blank\"" HTM_A_Begin ("href=\"%s\" target=\"_blank\""
" class=\"FRAME_TITLE_BIG\" title=\"%s\"", " class=\"FRAME_TITLE_BIG\" title=\"%s\"",
Gbl.Hierarchy.Cty.WWW[Gbl.Prefs.Language], Gbl.Hierarchy.Cty.WWW[Gbl.Prefs.Language],
Gbl.Hierarchy.Cty.Name[Gbl.Prefs.Language]); Gbl.Hierarchy.Cty.Name[Gbl.Prefs.Language]);
/* Country name */
HTM_Txt (Gbl.Hierarchy.Cty.Name[Gbl.Prefs.Language]); HTM_Txt (Gbl.Hierarchy.Cty.Name[Gbl.Prefs.Language]);
/* End link */
if (PutLink) if (PutLink)
HTM_A_End (); HTM_A_End ();
/***** End container *****/
HTM_DIV_End (); HTM_DIV_End ();
} }
/*****************************************************************************/
/********* Get average coordinates of centers in current institution *********/
/*****************************************************************************/
static void CtyCfg_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom)
{
char *Query;
/***** Get average coordinates of centers of current country
with both coordinates set
(coordinates 0, 0 means not set ==> don't show map) *****/
if (asprintf (&Query,
"SELECT AVG(ctr_centers.Latitude)," // row[0]
"AVG(ctr_centers.Longitude)," // row[1]
"GREATEST(MAX(ctr_centers.Latitude)-MIN(ctr_centers.Latitude),"
"MAX(ctr_centers.Longitude)-MIN(ctr_centers.Longitude))" // row[2]
" FROM ins_instits,"
"ctr_centers"
" WHERE ins_instits.CtyCod=%ld"
" AND ins_instits.InsCod=ctr_centers.InsCod"
" AND ctr_centers.Latitude<>0"
" AND ctr_centers.Longitude<>0",
Gbl.Hierarchy.Cty.CtyCod) < 0)
Err_NotEnoughMemoryExit ();
Map_GetCoordAndZoom (Coord,Zoom,Query);
free (Query);
}
/*****************************************************************************/ /*****************************************************************************/
/****************************** Draw country map *****************************/ /****************************** Draw country map *****************************/
/*****************************************************************************/ /*****************************************************************************/
@ -272,7 +256,7 @@ static void CtyCfg_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom)
static void CtyCfg_Map (void) static void CtyCfg_Map (void)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
struct Coordinates CtyAvgCoord; struct Map_Coordinates CtyAvgCoord;
unsigned Zoom; unsigned Zoom;
unsigned NumCtrs; unsigned NumCtrs;
unsigned NumCtr; unsigned NumCtr;
@ -293,23 +277,14 @@ static void CtyCfg_Map (void)
HTM_SCRIPT_Begin (NULL,NULL); HTM_SCRIPT_Begin (NULL,NULL);
/* Let's create a map with pretty Mapbox Streets tiles */ /* Let's create a map with pretty Mapbox Streets tiles */
CtyCfg_GetCoordAndZoom (&CtyAvgCoord,&Zoom); Cty_DB_GetCoordAndZoom (&CtyAvgCoord,&Zoom);
Map_CreateMap (CtyCfg_MAP_CONTAINER_ID,&CtyAvgCoord,Zoom); Map_CreateMap (CtyCfg_MAP_CONTAINER_ID,&CtyAvgCoord,Zoom);
/* Add Mapbox Streets tile layer to our map */ /* Add Mapbox Streets tile layer to our map */
Map_AddTileLayer (); Map_AddTileLayer ();
/* Get centers with coordinates */ /* Get centers which have coordinates in the current country */
NumCtrs = (unsigned) NumCtrs = Cty_DB_GetCtrsWithCoordsInCurrentCty (&mysql_res);
DB_QuerySELECT (&mysql_res,"can not get centers with coordinates",
"SELECT ctr_centers.CtrCod" // row[0]
" FROM ins_instits,"
"ctr_centers"
" WHERE ins_instits.CtyCod=%ld"
" AND ins_instits.InsCod=ctr_centers.InsCod"
" AND ctr_centers.Latitude<>0"
" AND ctr_centers.Longitude<>0",
Gbl.Hierarchy.Cty.CtyCod);
/* Add a marker and a popup for each center */ /* Add a marker and a popup for each center */
for (NumCtr = 0; for (NumCtr = 0;
@ -578,12 +553,8 @@ static void CtyCfg_GetMapAttr (long CtyCod,char **MapAttribution)
/***** Free possible former map attribution *****/ /***** Free possible former map attribution *****/
CtyCfg_FreeMapAttr (MapAttribution); CtyCfg_FreeMapAttr (MapAttribution);
/***** Get photo attribution from database *****/ /***** Get map attribution from database *****/
if (DB_QuerySELECT (&mysql_res,"can not get photo attribution", if (Cty_DB_GetMapAttr (&mysql_res,CtyCod))
"SELECT MapAttribution" // row[0]
" FROM cty_countrs"
" WHERE CtyCod=%ld",
CtyCod))
{ {
/* Get row */ /* Get row */
row = mysql_fetch_row (mysql_res); row = mysql_fetch_row (mysql_res);
@ -628,13 +599,8 @@ void CtyCfg_ChangeCtyMapAttr (void)
/* Get the new map attribution for the country */ /* Get the new map attribution for the country */
Par_GetParToText ("Attribution",NewMapAttribution,Med_MAX_BYTES_ATTRIBUTION); Par_GetParToText ("Attribution",NewMapAttribution,Med_MAX_BYTES_ATTRIBUTION);
/***** Update the table changing old attribution by new attribution *****/ /***** Change old attribution by new attribution in database *****/
DB_QueryUPDATE ("can not update the map attribution of a country", Cty_DB_UpdateCtyMapAttr (NewMapAttribution);
"UPDATE cty_countrs"
" SET MapAttribution='%s'"
" WHERE CtyCod='%03ld'",
NewMapAttribution,
Gbl.Hierarchy.Cty.CtyCod);
/***** Show the country information again *****/ /***** Show the country information again *****/
CtyCfg_ShowConfiguration (); CtyCfg_ShowConfiguration ();

257
swad_country_database.c Normal file
View File

@ -0,0 +1,257 @@
// swad_country_database.h: countries operations with database
/*
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-2021 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 ***********************************/
/*****************************************************************************/
#define _GNU_SOURCE // For asprintf
// #include <stdbool.h> // For boolean type
// #include <stddef.h> // For NULL
#include <stdio.h> // For asprintf
// #include <stdlib.h> // For free
// #include <string.h> // For string functions
#include "swad_country_database.h"
#include "swad_database.h"
#include "swad_error.h"
#include "swad_global.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/***************************** Private constants *****************************/
/*****************************************************************************/
/*****************************************************************************/
/******************************* Private types *******************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private variables *****************************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Private prototypes ****************************/
/*****************************************************************************/
/*****************************************************************************/
/********** Get basic list of countries ordered by name of country ***********/
/*****************************************************************************/
unsigned Cty_DB_GetBasicListOfCountries (MYSQL_RES **mysql_res)
{
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get countries",
"SELECT CtyCod," // row[0]
"Name_%s" // row[1]
" FROM cty_countrs"
" ORDER BY Name_%s",
Lan_STR_LANG_ID[Gbl.Prefs.Language],
Lan_STR_LANG_ID[Gbl.Prefs.Language]);
}
/*****************************************************************************/
/******************* Get countries with pending institutions *****************/
/*****************************************************************************/
unsigned Cty_DB_GetListOfCountriesWithPendingInss (MYSQL_RES **mysql_res)
{
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get countries"
" with pending institutions",
"SELECT ins_instits.CtyCod," // row[0]
"COUNT(*)" // row[1]
" FROM ins_instits,"
"cty_countrs"
" WHERE (ins_instits.Status & %u)<>0"
" AND ins_instits.CtyCod=cty_countrs.CtyCod"
" GROUP BY ins_instits.CtyCod"
" ORDER BY cty_countrs.Name_%s",
(unsigned) Ins_STATUS_BIT_PENDING,
Lan_STR_LANG_ID[Gbl.Prefs.Language]);
}
/*****************************************************************************/
/********** Get full list of countries with names in all languages ***********/
/********** and number of users who claim to belong to them ***********/
/*****************************************************************************/
#define Cty_MAX_BYTES_SUBQUERY_CTYS ((1 + Lan_NUM_LANGUAGES) * 32)
unsigned Cty_DB_GetFullListOfCountries (MYSQL_RES **mysql_res)
{
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
char StrField[32];
char SubQueryNam1[Cty_MAX_BYTES_SUBQUERY_CTYS + 1];
char SubQueryNam2[Cty_MAX_BYTES_SUBQUERY_CTYS + 1];
char SubQueryWWW1[Cty_MAX_BYTES_SUBQUERY_CTYS + 1];
char SubQueryWWW2[Cty_MAX_BYTES_SUBQUERY_CTYS + 1];
char *OrderBySubQuery = NULL;
static const char *OrderBySubQueryFmt[Cty_NUM_ORDERS] =
{
[Cty_ORDER_BY_COUNTRY ] = "Name_%s",
[Cty_ORDER_BY_NUM_USRS] = "NumUsrs DESC,Name_%s",
};
unsigned NumCtys;
Lan_Language_t Lan;
/***** Get countries from database *****/
SubQueryNam1[0] = '\0';
SubQueryNam2[0] = '\0';
SubQueryWWW1[0] = '\0';
SubQueryWWW2[0] = '\0';
for (Lan = (Lan_Language_t) 1;
Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES;
Lan++)
{
snprintf (StrField,sizeof (StrField),"cty_countrs.Name_%s,",Lan_STR_LANG_ID[Lan]);
Str_Concat (SubQueryNam1,StrField,sizeof (SubQueryNam1) - 1);
snprintf (StrField,sizeof (StrField),"Name_%s,",Lan_STR_LANG_ID[Lan]);
Str_Concat (SubQueryNam2,StrField,sizeof (SubQueryNam2) - 1);
snprintf (StrField,sizeof (StrField),"cty_countrs.WWW_%s,",Lan_STR_LANG_ID[Lan]);
Str_Concat (SubQueryWWW1,StrField,sizeof (SubQueryWWW1) - 1);
snprintf (StrField,sizeof (StrField),"WWW_%s,",Lan_STR_LANG_ID[Lan]);
Str_Concat (SubQueryWWW2,StrField,sizeof (SubQueryWWW2) - 1);
}
/* Build order subquery */
if (asprintf (&OrderBySubQuery,OrderBySubQueryFmt[Gbl.Hierarchy.Ctys.SelectedOrder],
Lan_STR_LANG_ID[Gbl.Prefs.Language]) < 0)
Err_NotEnoughMemoryExit ();
/* Query database */
NumCtys = (unsigned)
DB_QuerySELECT (mysql_res,"can not get countries",
"(SELECT cty_countrs.CtyCod," // row[0]
"cty_countrs.Alpha2," // row[1]
"%s" // row[...]
"%s" // row[...]
"COUNT(*) AS NumUsrs" // row[...]
" FROM cty_countrs,"
"usr_data"
" WHERE cty_countrs.CtyCod=usr_data.CtyCod"
" GROUP BY cty_countrs.CtyCod)"
" UNION "
"(SELECT CtyCod," // row[0]
"Alpha2," // row[1]
"%s" // row[...]
"%s" // row[...]
"0 AS NumUsrs" // row[...]
" FROM cty_countrs"
" WHERE CtyCod NOT IN"
" (SELECT DISTINCT CtyCod"
" FROM usr_data))"
" ORDER BY %s",
SubQueryNam1,SubQueryWWW1,
SubQueryNam2,SubQueryWWW2,OrderBySubQuery);
/* Free memory for subquery */
free (OrderBySubQuery);
return NumCtys;
}
/*****************************************************************************/
/*********** Get average coordinates of centers in current country ***********/
/*****************************************************************************/
void Cty_DB_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom)
{
char *Query;
/***** Get average coordinates of centers of current country
with both coordinates set
(coordinates 0, 0 means not set ==> don't show map) *****/
if (asprintf (&Query,
"SELECT AVG(ctr_centers.Latitude)," // row[0]
"AVG(ctr_centers.Longitude)," // row[1]
"GREATEST(MAX(ctr_centers.Latitude)-MIN(ctr_centers.Latitude),"
"MAX(ctr_centers.Longitude)-MIN(ctr_centers.Longitude))" // row[2]
" FROM ins_instits,"
"ctr_centers"
" WHERE ins_instits.CtyCod=%ld"
" AND ins_instits.InsCod=ctr_centers.InsCod"
" AND ctr_centers.Latitude<>0"
" AND ctr_centers.Longitude<>0",
Gbl.Hierarchy.Cty.CtyCod) < 0)
Err_NotEnoughMemoryExit ();
Map_GetCoordAndZoom (Coord,Zoom,Query);
free (Query);
}
/*****************************************************************************/
/*********** Get centres which have coordinates in current country ***********/
/*****************************************************************************/
unsigned Cty_DB_GetCtrsWithCoordsInCurrentCty (MYSQL_RES **mysql_res)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get centers with coordinates",
"SELECT ctr_centers.CtrCod"
" FROM ins_instits,"
"ctr_centers"
" WHERE ins_instits.CtyCod=%ld"
" AND ins_instits.InsCod=ctr_centers.InsCod"
" AND ctr_centers.Latitude<>0"
" AND ctr_centers.Longitude<>0",
Gbl.Hierarchy.Cty.CtyCod);
}
/*****************************************************************************/
/******************** Get map attribution from database **********************/
/*****************************************************************************/
unsigned Cty_DB_GetMapAttr (MYSQL_RES **mysql_res,long CtyCod)
{
return (unsigned)
DB_QuerySELECT (mysql_res,"can not get map attribution",
"SELECT MapAttribution" // row[0]
" FROM cty_countrs"
" WHERE CtyCod=%ld",
CtyCod);
}
/*****************************************************************************/
/*********** Update the attribution of the map of current country ************/
/*****************************************************************************/
void Cty_DB_UpdateCtyMapAttr (const char NewMapAttribution[Med_MAX_BYTES_ATTRIBUTION + 1])
{
DB_QueryUPDATE ("can not update the map attribution",
"UPDATE cty_countrs"
" SET MapAttribution='%s'"
" WHERE CtyCod='%03ld'",
NewMapAttribution,
Gbl.Hierarchy.Cty.CtyCod);
}

52
swad_country_database.h Normal file
View File

@ -0,0 +1,52 @@
// swad_country_database.h: countries operations with database
#ifndef _SWAD_CTY_DB
#define _SWAD_CTY_DB
/*
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-2021 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 ***********************************/
/*****************************************************************************/
#include <mysql/mysql.h> // To access MySQL databases
#include "swad_map.h"
#include "swad_media.h"
/*****************************************************************************/
/************************** Public types and constants ***********************/
/*****************************************************************************/
/*****************************************************************************/
/***************************** Public prototypes *****************************/
/*****************************************************************************/
unsigned Cty_DB_GetBasicListOfCountries (MYSQL_RES **mysql_res);
unsigned Cty_DB_GetListOfCountriesWithPendingInss (MYSQL_RES **mysql_res);
unsigned Cty_DB_GetFullListOfCountries (MYSQL_RES **mysql_res);
void Cty_DB_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom);
unsigned Cty_DB_GetCtrsWithCoordsInCurrentCty (MYSQL_RES **mysql_res);
unsigned Cty_DB_GetMapAttr (MYSQL_RES **mysql_res,long CtyCod);
void Cty_DB_UpdateCtyMapAttr (const char NewMapAttribution[Med_MAX_BYTES_ATTRIBUTION + 1]);
#endif

View File

@ -70,7 +70,7 @@ extern struct Globals Gbl;
static void InsCfg_Configuration (bool PrintView); static void InsCfg_Configuration (bool PrintView);
static void InsCfg_PutIconsToPrintAndUpload (__attribute__((unused)) void *Args); static void InsCfg_PutIconsToPrintAndUpload (__attribute__((unused)) void *Args);
static void InsCfg_Title (bool PutLink); static void InsCfg_Title (bool PutLink);
static void InsCfg_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom); static void InsCfg_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom);
static void InsCfg_Map (void); static void InsCfg_Map (void);
static void InsCfg_Country (bool PrintView,bool PutForm); static void InsCfg_Country (bool PrintView,bool PutForm);
static void InsCfg_FullName (bool PutForm); static void InsCfg_FullName (bool PutForm);
@ -248,7 +248,7 @@ static void InsCfg_Title (bool PutLink)
/********* Get average coordinates of centers in current institution *********/ /********* Get average coordinates of centers in current institution *********/
/*****************************************************************************/ /*****************************************************************************/
static void InsCfg_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom) static void InsCfg_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom)
{ {
char *Query; char *Query;
@ -279,7 +279,7 @@ static void InsCfg_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom)
static void InsCfg_Map (void) static void InsCfg_Map (void)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
struct Coordinates InsAvgCoord; struct Map_Coordinates InsAvgCoord;
unsigned Zoom; unsigned Zoom;
unsigned NumCtrs; unsigned NumCtrs;
unsigned NumCtr; unsigned NumCtr;
@ -349,6 +349,9 @@ static void InsCfg_Country (bool PrintView,bool PutForm)
extern const char *Txt_Country; extern const char *Txt_Country;
unsigned NumCty; unsigned NumCty;
/***** Get list of countries *****/
Cty_GetBasicListOfCountries ();
/***** Country *****/ /***** Country *****/
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
@ -361,9 +364,6 @@ static void InsCfg_Country (bool PrintView,bool PutForm)
HTM_TD_Begin ("class=\"DAT LB\""); HTM_TD_Begin ("class=\"DAT LB\"");
if (PutForm) if (PutForm)
{ {
/* Get list of countries */
Cty_GetBasicListOfCountries ();
/* Put form to select country */ /* Put form to select country */
Frm_BeginForm (ActChgInsCtyCfg); Frm_BeginForm (ActChgInsCtyCfg);
HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE, HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE,
@ -377,9 +377,6 @@ static void InsCfg_Country (bool PrintView,bool PutForm)
"%s",Gbl.Hierarchy.Ctys.Lst[NumCty].Name[Gbl.Prefs.Language]); "%s",Gbl.Hierarchy.Ctys.Lst[NumCty].Name[Gbl.Prefs.Language]);
HTM_SELECT_End (); HTM_SELECT_End ();
Frm_EndForm (); Frm_EndForm ();
/* Free list of countries */
Cty_FreeListCountries ();
} }
else // I can not move institution to another country else // I can not move institution to another country
{ {
@ -403,6 +400,8 @@ static void InsCfg_Country (bool PrintView,bool PutForm)
HTM_TD_End (); HTM_TD_End ();
HTM_TR_End (); HTM_TR_End ();
// Do not free list of countries here, because it can be reused
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -89,7 +89,7 @@ void Map_LeafletScript (void)
/*****************************************************************************/ /*****************************************************************************/
void Map_CreateMap (const char *ContainerId, void Map_CreateMap (const char *ContainerId,
const struct Coordinates *Coord,unsigned Zoom) const struct Map_Coordinates *Coord,unsigned Zoom)
{ {
/* Let's create a map with pretty Mapbox Streets tiles */ /* Let's create a map with pretty Mapbox Streets tiles */
Str_SetDecimalPointToUS (); // To write the decimal point as a dot Str_SetDecimalPointToUS (); // To write the decimal point as a dot
@ -136,7 +136,7 @@ void Map_AddTileLayer (void)
/************************** Add a marker to our map **************************/ /************************** Add a marker to our map **************************/
/*****************************************************************************/ /*****************************************************************************/
void Map_AddMarker (const struct Coordinates *Coord) void Map_AddMarker (const struct Map_Coordinates *Coord)
{ {
Str_SetDecimalPointToUS (); // To write the decimal point as a dot Str_SetDecimalPointToUS (); // To write the decimal point as a dot
HTM_TxtF ("\t" HTM_TxtF ("\t"
@ -167,7 +167,7 @@ void Map_AddPopup (const char *Title,const char *Subtitle,bool Open)
/********* Get average coordinates of centers in current institution *********/ /********* Get average coordinates of centers in current institution *********/
/*****************************************************************************/ /*****************************************************************************/
void Map_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom, void Map_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom,
const char *Query) const char *Query)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;

View File

@ -27,11 +27,13 @@
/********************************* Headers ***********************************/ /********************************* Headers ***********************************/
/*****************************************************************************/ /*****************************************************************************/
#include <stdbool.h> // For boolean type
/*****************************************************************************/ /*****************************************************************************/
/************************** Public types and constants ***********************/ /************************** Public types and constants ***********************/
/*****************************************************************************/ /*****************************************************************************/
struct Coordinates struct Map_Coordinates
{ {
double Latitude; double Latitude;
double Longitude; double Longitude;
@ -45,11 +47,11 @@ struct Coordinates
void Map_LeafletCSS (void); void Map_LeafletCSS (void);
void Map_LeafletScript (void); void Map_LeafletScript (void);
void Map_CreateMap (const char *ContainerId, void Map_CreateMap (const char *ContainerId,
const struct Coordinates *Coord,unsigned Zoom); const struct Map_Coordinates *Coord,unsigned Zoom);
void Map_AddTileLayer (void); void Map_AddTileLayer (void);
void Map_AddMarker (const struct Coordinates *Coord); void Map_AddMarker (const struct Map_Coordinates *Coord);
void Map_AddPopup (const char *Title,const char *Subtitle,bool Open); void Map_AddPopup (const char *Title,const char *Subtitle,bool Open);
void Map_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom, void Map_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom,
const char *Query); const char *Query);
double Map_GetLatitudeFromStr (char *Str); double Map_GetLatitudeFromStr (char *Str);
double Map_GetLongitudeFromStr (char *Str); double Map_GetLongitudeFromStr (char *Str);

View File

@ -30,6 +30,7 @@
#include <mysql/mysql.h> // To access MySQL databases #include <mysql/mysql.h> // To access MySQL databases
#include "swad_cryptography.h" #include "swad_cryptography.h"
#include "swad_string.h"
/*****************************************************************************/ /*****************************************************************************/
/***************************** Public constants ******************************/ /***************************** Public constants ******************************/

View File

@ -3278,7 +3278,6 @@ static void Rec_ShowCountry (struct UsrData *UsrDat,bool PutForm)
unsigned NumCty; unsigned NumCty;
/***** If list of countries is empty, try to get it *****/ /***** If list of countries is empty, try to get it *****/
if (!Gbl.Hierarchy.Ctys.Num)
Cty_GetBasicListOfCountries (); Cty_GetBasicListOfCountries ();
/***** Selector of country *****/ /***** Selector of country *****/
@ -3313,6 +3312,8 @@ static void Rec_ShowCountry (struct UsrData *UsrDat,bool PutForm)
HTM_TD_End (); HTM_TD_End ();
HTM_TR_End (); HTM_TR_End ();
// Do not free here list of countries, because it can be reused
} }
/*****************************************************************************/ /*****************************************************************************/
@ -3816,11 +3817,13 @@ void Rec_ShowMySharedRecordAndMore (void)
HTM_DIV_Begin ("class=\"REC_USR\""); HTM_DIV_Begin ("class=\"REC_USR\"");
/***** Left part *****/ /***** Left part *****/
/* Begin container for left part */
HTM_DIV_Begin ("class=\"REC_LEFT\""); HTM_DIV_Begin ("class=\"REC_LEFT\"");
/* My shared record card */ /* My shared record card */
Rec_ShowSharedUsrRecord (Rec_SHA_MY_RECORD_FORM,&Gbl.Usrs.Me.UsrDat,NULL); Rec_ShowSharedUsrRecord (Rec_SHA_MY_RECORD_FORM,&Gbl.Usrs.Me.UsrDat,NULL);
/* End container for left part */
HTM_DIV_End (); HTM_DIV_End ();
/***** Right part *****/ /***** Right part *****/
@ -3865,6 +3868,9 @@ static void Rec_ShowFormMyInsCtrDpt (bool IAmATeacher)
unsigned NumCtr; unsigned NumCtr;
char StrRecordWidth[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; char StrRecordWidth[Cns_MAX_DECIMAL_DIGITS_UINT + 1];
/***** Get list of countries *****/
Cty_GetBasicListOfCountries ();
/***** Begin section *****/ /***** Begin section *****/
HTM_SECTION_Begin (Rec_MY_INS_CTR_DPT_ID); HTM_SECTION_Begin (Rec_MY_INS_CTR_DPT_ID);
@ -3887,10 +3893,6 @@ static void Rec_ShowFormMyInsCtrDpt (bool IAmATeacher)
/* Data */ /* Data */
HTM_TD_Begin ("class=\"REC_C2_BOT LM\""); HTM_TD_Begin ("class=\"REC_C2_BOT LM\"");
/* If list of countries is empty, try to get it */
if (!Gbl.Hierarchy.Ctys.Num)
Cty_GetBasicListOfCountries ();
/* Begin form to select the country of my institution */ /* Begin form to select the country of my institution */
Frm_StartFormAnchor (ActChgCtyMyIns,Rec_MY_INS_CTR_DPT_ID); Frm_StartFormAnchor (ActChgCtyMyIns,Rec_MY_INS_CTR_DPT_ID);
HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE, HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE,
@ -3907,6 +3909,7 @@ static void Rec_ShowFormMyInsCtrDpt (bool IAmATeacher)
"%s",Gbl.Hierarchy.Ctys.Lst[NumCty].Name[Gbl.Prefs.Language]); "%s",Gbl.Hierarchy.Ctys.Lst[NumCty].Name[Gbl.Prefs.Language]);
HTM_SELECT_End (); HTM_SELECT_End ();
Frm_EndForm (); Frm_EndForm ();
HTM_TD_End (); HTM_TD_End ();
HTM_TR_End (); HTM_TR_End ();
@ -4053,6 +4056,8 @@ static void Rec_ShowFormMyInsCtrDpt (bool IAmATeacher)
/***** End section *****/ /***** End section *****/
HTM_SECTION_End (); HTM_SECTION_End ();
// Do not free list of countries here, because it can be reused
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -68,7 +68,7 @@
static void SysCfg_Configuration (bool PrintView); static void SysCfg_Configuration (bool PrintView);
static void SysCfg_PutIconToPrint (__attribute__((unused)) void *Args); static void SysCfg_PutIconToPrint (__attribute__((unused)) void *Args);
static void SysCfg_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom); static void SysCfg_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom);
static void SysCfg_Map (void); static void SysCfg_Map (void);
static void SysCfg_Platform (void); static void SysCfg_Platform (void);
static void SysCfg_Shortcut (bool PrintView); static void SysCfg_Shortcut (bool PrintView);
@ -197,7 +197,7 @@ static void SysCfg_PutIconToPrint (__attribute__((unused)) void *Args)
/********* Get average coordinates of centers in current institution *********/ /********* Get average coordinates of centers in current institution *********/
/*****************************************************************************/ /*****************************************************************************/
static void SysCfg_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom) static void SysCfg_GetCoordAndZoom (struct Map_Coordinates *Coord,unsigned *Zoom)
{ {
char *Query; char *Query;
@ -225,7 +225,7 @@ static void SysCfg_GetCoordAndZoom (struct Coordinates *Coord,unsigned *Zoom)
static void SysCfg_Map (void) static void SysCfg_Map (void)
{ {
MYSQL_RES *mysql_res; MYSQL_RES *mysql_res;
struct Coordinates CtyAvgCoord; struct Map_Coordinates CtyAvgCoord;
unsigned Zoom; unsigned Zoom;
unsigned NumCtrs; unsigned NumCtrs;
unsigned NumCtr; unsigned NumCtr;