mirror of https://github.com/acanas/swad-core.git
Version 15.234
This commit is contained in:
parent
9ebfc85f69
commit
f104cf00de
|
@ -410,9 +410,11 @@ int swad__getTests (char *wsKey,int courseCode,long beginTime,
|
||||||
int swad__getTrivialQuestion (char *wsKey,char *degrees,float lowerScore,float upperScore,
|
int swad__getTrivialQuestion (char *wsKey,char *degrees,float lowerScore,float upperScore,
|
||||||
struct swad__getTrivialQuestionOutput *getTrivialQuestionOut);
|
struct swad__getTrivialQuestionOutput *getTrivialQuestionOut);
|
||||||
|
|
||||||
/* List of users of a course / group */
|
/* List of users */
|
||||||
int swad__getUsers (char *wsKey,int courseCode,int groupCode,int userRole,
|
int swad__getUsers (char *wsKey,int courseCode,char *groups,int userRole,
|
||||||
struct swad__getUsersOutput *getUsersOut);
|
struct swad__getUsersOutput *getUsersOut);
|
||||||
|
int swad__findUsers (char *wsKey,int courseCode,char *filter,int userRole,
|
||||||
|
struct swad__getUsersOutput *getUsersOut);
|
||||||
|
|
||||||
/* Control of attendance */
|
/* Control of attendance */
|
||||||
int swad__getAttendanceEvents (char *wsKey,int courseCode,
|
int swad__getAttendanceEvents (char *wsKey,int courseCode,
|
||||||
|
|
|
@ -70,7 +70,6 @@ typedef enum
|
||||||
|
|
||||||
static bool ID_CheckIfUsrIDIsValidUsingMinDigits (const char *UsrID,unsigned MinDigits);
|
static bool ID_CheckIfUsrIDIsValidUsingMinDigits (const char *UsrID,unsigned MinDigits);
|
||||||
|
|
||||||
static bool ID_ICanSeeAnotherUsrID (struct UsrData *UsrDat);
|
|
||||||
static void ID_PutButtonToReqConfirmID (struct UsrData *UsrDat,unsigned NumID);
|
static void ID_PutButtonToReqConfirmID (struct UsrData *UsrDat,unsigned NumID);
|
||||||
static void ID_PutButtonToConfirmID (struct UsrData *UsrDat,unsigned NumID);
|
static void ID_PutButtonToConfirmID (struct UsrData *UsrDat,unsigned NumID);
|
||||||
|
|
||||||
|
@ -405,7 +404,7 @@ void ID_WriteUsrIDs (struct UsrData *UsrDat)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
// This function should not be called when UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod
|
// This function should not be called when UsrDat->UsrCod == Gbl.Usrs.Me.UsrDat.UsrCod
|
||||||
|
|
||||||
static bool ID_ICanSeeAnotherUsrID (struct UsrData *UsrDat)
|
bool ID_ICanSeeAnotherUsrID (struct UsrData *UsrDat)
|
||||||
{
|
{
|
||||||
/***** Check if I have permission to see another user's IDs *****/
|
/***** Check if I have permission to see another user's IDs *****/
|
||||||
switch (Gbl.Usrs.Me.LoggedRole)
|
switch (Gbl.Usrs.Me.LoggedRole)
|
||||||
|
|
|
@ -65,6 +65,7 @@ bool ID_CheckIfUsrIDIsValid (const char *UsrID);
|
||||||
bool ID_CheckIfUsrIDSeemsAValidID (const char *UsrID);
|
bool ID_CheckIfUsrIDSeemsAValidID (const char *UsrID);
|
||||||
|
|
||||||
void ID_WriteUsrIDs (struct UsrData *UsrDat);
|
void ID_WriteUsrIDs (struct UsrData *UsrDat);
|
||||||
|
bool ID_ICanSeeAnotherUsrID (struct UsrData *UsrDat);
|
||||||
|
|
||||||
void ID_PutLinkToChangeUsrIDs (void);
|
void ID_PutLinkToChangeUsrIDs (void);
|
||||||
void ID_ShowFormOthIDs (void);
|
void ID_ShowFormOthIDs (void);
|
||||||
|
|
|
@ -121,6 +121,11 @@
|
||||||
// TODO: Messages in msg_content_deleted older than a certain time should be deleted to ensure the protection of personal data
|
// TODO: Messages in msg_content_deleted older than a certain time should be deleted to ensure the protection of personal data
|
||||||
// TODO: FIX BUG: A teacher uploads a document in course documents zone, then he/she unregister from course, then he/she search for his/her documents, a document is shown in results but he/she can not view it
|
// TODO: FIX BUG: A teacher uploads a document in course documents zone, then he/she unregister from course, then he/she search for his/her documents, a document is shown in results but he/she can not view it
|
||||||
// TODO: Add Stack Exchange to webs/networks
|
// TODO: Add Stack Exchange to webs/networks
|
||||||
|
// TODO: Optimize slow query searching messages received
|
||||||
|
// TODO: FIX BUG: Searching messages received gives unordered list
|
||||||
|
|
||||||
|
// TODO: Add file size to summary in notifications of new files.
|
||||||
|
// TODO: Put Raúl Hinojosa (iSWAD developer) in a row of marks file of EC (B,C) and publish file
|
||||||
|
|
||||||
// TODO: Modify WS function getUsers changing: userRole to indicate all users, and a new parameter filter (search string (name, @nickname, mail)) to restring number of users
|
// TODO: Modify WS function getUsers changing: userRole to indicate all users, and a new parameter filter (search string (name, @nickname, mail)) to restring number of users
|
||||||
// TODO: Add a new WS function to count the nunmber of users to return in call to function getUsers
|
// TODO: Add a new WS function to count the nunmber of users to return in call to function getUsers
|
||||||
|
@ -129,13 +134,14 @@
|
||||||
/****************************** Public constants *****************************/
|
/****************************** Public constants *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define Log_PLATFORM_VERSION "SWAD 15.233.4 (2016-06-27)"
|
#define Log_PLATFORM_VERSION "SWAD 15.234 (2016-06-29)"
|
||||||
#define CSS_FILE "swad15.229.css"
|
#define CSS_FILE "swad15.229.css"
|
||||||
#define JS_FILE "swad15.226.js"
|
#define JS_FILE "swad15.226.js"
|
||||||
|
|
||||||
// Number of lines (includes comments but not blank lines) has been got with the following command:
|
// Number of lines (includes comments but not blank lines) has been got with the following command:
|
||||||
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1
|
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h sql/swad*.sql | tail -1
|
||||||
/*
|
/*
|
||||||
|
Version 15.234: Jun 29, 2015 New web service functions getUsers and findUsers. (203169 lines)
|
||||||
Version 15.233.4: Jun 27, 2015 Changes in links in list of notifications. (203065 lines)
|
Version 15.233.4: Jun 27, 2015 Changes in links in list of notifications. (203065 lines)
|
||||||
Version 15.233.3: Jun 27, 2015 Fixed bug in list of admins. (203074 lines)
|
Version 15.233.3: Jun 27, 2015 Fixed bug in list of admins. (203074 lines)
|
||||||
Version 15.233.2: Jun 27, 2015 Code refactoring in search of users. (203072 lines)
|
Version 15.233.2: Jun 27, 2015 Code refactoring in search of users. (203072 lines)
|
||||||
|
|
164
swad_search.c
164
swad_search.c
|
@ -41,11 +41,8 @@
|
||||||
/***************************** Internal constants ****************************/
|
/***************************** Internal constants ****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define Sch_MAX_WORDS_IN_SEARCH 10
|
|
||||||
#define Sch_MAX_LENGTH_SEARCH_WORD 255
|
|
||||||
#define Sch_MIN_LENGTH_LONGEST_WORD 3
|
#define Sch_MIN_LENGTH_LONGEST_WORD 3
|
||||||
#define Sch_MIN_LENGTH_TOTAL 7 // "A An Ann" is not valid; "A An Ann Anna" is valid
|
#define Sch_MIN_LENGTH_TOTAL 7 // "A An Ann" is not valid; "A An Ann Anna" is valid
|
||||||
#define Sch_MAX_LENGTH_SEARCH_QUERY (10*Sch_MAX_LENGTH_STRING_TO_FIND)
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/****************************** Internal types *******************************/
|
/****************************** Internal types *******************************/
|
||||||
|
@ -77,8 +74,6 @@ static unsigned Sch_SearchUsrsInDB (Rol_Role_t Role);
|
||||||
static unsigned Sch_SearchOpenDocumentsInDB (const char *RangeQuery);
|
static unsigned Sch_SearchOpenDocumentsInDB (const char *RangeQuery);
|
||||||
static unsigned Sch_SearchDocumentsInMyCoursesInDB (const char *RangeQuery);
|
static unsigned Sch_SearchDocumentsInMyCoursesInDB (const char *RangeQuery);
|
||||||
static unsigned Sch_SearchMyDocumentsInDB (const char *RangeQuery);
|
static unsigned Sch_SearchMyDocumentsInDB (const char *RangeQuery);
|
||||||
static bool Sch_BuildSearchQuery (char *SearchQuery,const char *FieldName,
|
|
||||||
const char *CharSet,const char *Collate);
|
|
||||||
|
|
||||||
static void Sch_SaveLastSearchIntoSession (void);
|
static void Sch_SaveLastSearchIntoSession (void);
|
||||||
|
|
||||||
|
@ -793,25 +788,29 @@ static unsigned Sch_SearchCoursesInDB (const char *RangeQuery)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************************* Search teachers in database ***********************/
|
/*************************** Search users in database ************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
// Returns number of teachers found
|
// Returns number of users found
|
||||||
|
|
||||||
static unsigned Sch_SearchUsrsInDB (Rol_Role_t Role)
|
static unsigned Sch_SearchUsrsInDB (Rol_Role_t Role)
|
||||||
{
|
{
|
||||||
|
extern const char *Txt_The_search_text_must_be_longer;
|
||||||
|
static bool WarningMessageWritten = false;
|
||||||
char SearchQuery[Sch_MAX_LENGTH_SEARCH_QUERY+1];
|
char SearchQuery[Sch_MAX_LENGTH_SEARCH_QUERY+1];
|
||||||
|
|
||||||
/***** Check user's permission *****/
|
/***** Split user string into words *****/
|
||||||
if (Sch_CheckIfIHavePermissionToSearch ( Role == Rol_UNKNOWN ? Sch_SEARCH_USERS :
|
if (Sch_BuildSearchQuery (SearchQuery,
|
||||||
(Role == Rol_TEACHER ? Sch_SEARCH_TEACHERS :
|
"CONCAT_WS(' ',FirstName,Surname1,Surname2)",
|
||||||
(Role == Rol_STUDENT ? Sch_SEARCH_STUDENTS :
|
NULL,NULL))
|
||||||
Sch_SEARCH_GUESTS))))
|
/***** Query database and list users found *****/
|
||||||
/***** Split user string into words *****/
|
return Usr_ListUsrsFound (Role,SearchQuery);
|
||||||
if (Sch_BuildSearchQuery (SearchQuery,
|
else
|
||||||
"CONCAT_WS(' ',usr_data.FirstName,usr_data.Surname1,usr_data.Surname2)",
|
// Too short
|
||||||
NULL,NULL))
|
if (!WarningMessageWritten) // To avoid repetitions
|
||||||
/***** Query database and list users found *****/
|
{
|
||||||
return Usr_ListUsrsFound (Role,SearchQuery);
|
Lay_ShowAlert (Lay_WARNING,Txt_The_search_text_must_be_longer);
|
||||||
|
WarningMessageWritten = true;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1215,11 +1214,9 @@ static unsigned Sch_SearchMyDocumentsInDB (const char *RangeQuery)
|
||||||
// Returns true if a valid search query is built
|
// Returns true if a valid search query is built
|
||||||
// Returns false when no valid search query
|
// Returns false when no valid search query
|
||||||
|
|
||||||
static bool Sch_BuildSearchQuery (char *SearchQuery,const char *FieldName,
|
bool Sch_BuildSearchQuery (char *SearchQuery,const char *FieldName,
|
||||||
const char *CharSet,const char *Collate)
|
const char *CharSet,const char *Collate)
|
||||||
{
|
{
|
||||||
extern const char *Txt_The_search_text_must_be_longer;
|
|
||||||
static bool WarningMessageWritten = false;
|
|
||||||
const char *Ptr;
|
const char *Ptr;
|
||||||
unsigned NumWords;
|
unsigned NumWords;
|
||||||
unsigned NumWord;
|
unsigned NumWord;
|
||||||
|
@ -1229,74 +1226,71 @@ static bool Sch_BuildSearchQuery (char *SearchQuery,const char *FieldName,
|
||||||
char SearchWords[Sch_MAX_WORDS_IN_SEARCH][Sch_MAX_LENGTH_SEARCH_WORD+1];
|
char SearchWords[Sch_MAX_WORDS_IN_SEARCH][Sch_MAX_LENGTH_SEARCH_WORD+1];
|
||||||
bool SearchWordIsValid = true;
|
bool SearchWordIsValid = true;
|
||||||
|
|
||||||
SearchQuery[0] = '\0';
|
if (Gbl.Search.Str[0])
|
||||||
Ptr = Gbl.Search.Str;
|
|
||||||
for (NumWords = 0;
|
|
||||||
NumWords < Sch_MAX_WORDS_IN_SEARCH && *Ptr;
|
|
||||||
NumWords++)
|
|
||||||
{
|
{
|
||||||
/* Get next word */
|
SearchQuery[0] = '\0';
|
||||||
Str_GetNextStringUntilSpace (&Ptr,SearchWords[NumWords],Sch_MAX_LENGTH_SEARCH_WORD);
|
Ptr = Gbl.Search.Str;
|
||||||
|
for (NumWords = 0;
|
||||||
/* Is this word valid? */
|
NumWords < Sch_MAX_WORDS_IN_SEARCH && *Ptr;
|
||||||
switch (Gbl.Search.WhatToSearch)
|
NumWords++)
|
||||||
{
|
|
||||||
case Sch_SEARCH_OPEN_DOCUMENTS:
|
|
||||||
case Sch_SEARCH_DOCUM_IN_MY_COURSES:
|
|
||||||
case Sch_SEARCH_MY_DOCUMENTS:
|
|
||||||
SearchWordIsValid = Str_ConvertFilFolLnkNameToValid (SearchWords[NumWords]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SearchWordIsValid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if this word is repeated (case insensitive) */
|
|
||||||
for (NumWord = 0;
|
|
||||||
SearchWordIsValid && NumWord < NumWords;
|
|
||||||
NumWord++)
|
|
||||||
if (!strcasecmp (SearchWords[NumWord],SearchWords[NumWords]))
|
|
||||||
SearchWordIsValid = false;
|
|
||||||
|
|
||||||
/* Concatenate word to search string */
|
|
||||||
if (SearchWordIsValid)
|
|
||||||
{
|
{
|
||||||
LengthWord = strlen (SearchWords[NumWords]);
|
/* Get next word */
|
||||||
LengthTotal += LengthWord;
|
Str_GetNextStringUntilSpace (&Ptr,SearchWords[NumWords],Sch_MAX_LENGTH_SEARCH_WORD);
|
||||||
if (LengthWord > MaxLengthWord)
|
|
||||||
MaxLengthWord = LengthWord;
|
|
||||||
if (strlen (SearchQuery) + LengthWord + 512 > Sch_MAX_LENGTH_SEARCH_QUERY) // Prevent string overflow
|
|
||||||
break;
|
|
||||||
if (NumWords)
|
|
||||||
strcat (SearchQuery," AND ");
|
|
||||||
strcat (SearchQuery,FieldName);
|
|
||||||
strcat (SearchQuery," LIKE ");
|
|
||||||
if (CharSet)
|
|
||||||
if (CharSet[0])
|
|
||||||
strcat (SearchQuery,CharSet);
|
|
||||||
strcat (SearchQuery,"'%");
|
|
||||||
strcat (SearchQuery,SearchWords[NumWords]);
|
|
||||||
strcat (SearchQuery,"%'");
|
|
||||||
if (Collate)
|
|
||||||
if (Collate[0])
|
|
||||||
strcat (SearchQuery,Collate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***** If search string valid? *****/
|
/* Is this word valid? */
|
||||||
if (LengthTotal < Sch_MIN_LENGTH_TOTAL ||
|
switch (Gbl.Search.WhatToSearch)
|
||||||
MaxLengthWord < Sch_MIN_LENGTH_LONGEST_WORD)
|
{
|
||||||
{
|
case Sch_SEARCH_OPEN_DOCUMENTS:
|
||||||
// Too short
|
case Sch_SEARCH_DOCUM_IN_MY_COURSES:
|
||||||
if (!WarningMessageWritten) // To avoid repetitions
|
case Sch_SEARCH_MY_DOCUMENTS:
|
||||||
{
|
SearchWordIsValid = Str_ConvertFilFolLnkNameToValid (SearchWords[NumWords]);
|
||||||
Lay_ShowAlert (Lay_WARNING,Txt_The_search_text_must_be_longer);
|
break;
|
||||||
WarningMessageWritten = true;
|
default:
|
||||||
|
SearchWordIsValid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this word is repeated (case insensitive) */
|
||||||
|
for (NumWord = 0;
|
||||||
|
SearchWordIsValid && NumWord < NumWords;
|
||||||
|
NumWord++)
|
||||||
|
if (!strcasecmp (SearchWords[NumWord],SearchWords[NumWords]))
|
||||||
|
SearchWordIsValid = false;
|
||||||
|
|
||||||
|
/* Concatenate word to search string */
|
||||||
|
if (SearchWordIsValid)
|
||||||
|
{
|
||||||
|
LengthWord = strlen (SearchWords[NumWords]);
|
||||||
|
LengthTotal += LengthWord;
|
||||||
|
if (LengthWord > MaxLengthWord)
|
||||||
|
MaxLengthWord = LengthWord;
|
||||||
|
if (strlen (SearchQuery) + LengthWord + 512 > Sch_MAX_LENGTH_SEARCH_QUERY) // Prevent string overflow
|
||||||
|
break;
|
||||||
|
if (NumWords)
|
||||||
|
strcat (SearchQuery," AND ");
|
||||||
|
strcat (SearchQuery,FieldName);
|
||||||
|
strcat (SearchQuery," LIKE ");
|
||||||
|
if (CharSet)
|
||||||
|
if (CharSet[0])
|
||||||
|
strcat (SearchQuery,CharSet);
|
||||||
|
strcat (SearchQuery,"'%");
|
||||||
|
strcat (SearchQuery,SearchWords[NumWords]);
|
||||||
|
strcat (SearchQuery,"%'");
|
||||||
|
if (Collate)
|
||||||
|
if (Collate[0])
|
||||||
|
strcat (SearchQuery,Collate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
/***** If search string valid? *****/
|
||||||
else
|
if (LengthTotal < Sch_MIN_LENGTH_TOTAL ||
|
||||||
|
MaxLengthWord < Sch_MIN_LENGTH_LONGEST_WORD)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -31,7 +31,10 @@
|
||||||
/****************************** Public constants *****************************/
|
/****************************** Public constants *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define Sch_MAX_LENGTH_STRING_TO_FIND 255
|
#define Sch_MAX_LENGTH_STRING_TO_FIND 255
|
||||||
|
#define Sch_MAX_WORDS_IN_SEARCH 10
|
||||||
|
#define Sch_MAX_LENGTH_SEARCH_WORD 255
|
||||||
|
#define Sch_MAX_LENGTH_SEARCH_QUERY (Sch_MAX_WORDS_IN_SEARCH*Sch_MAX_LENGTH_SEARCH_WORD)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************************** Public types *******************************/
|
/******************************** Public types *******************************/
|
||||||
|
@ -78,4 +81,7 @@ void Sch_CtrSearch (void);
|
||||||
void Sch_DegSearch (void);
|
void Sch_DegSearch (void);
|
||||||
void Sch_CrsSearch (void);
|
void Sch_CrsSearch (void);
|
||||||
|
|
||||||
|
bool Sch_BuildSearchQuery (char *SearchQuery,const char *FieldName,
|
||||||
|
const char *CharSet,const char *Collate);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
21
swad_user.c
21
swad_user.c
|
@ -142,9 +142,6 @@ static void Usr_WriteUsrData (const char *BgColor,
|
||||||
bool NonBreak,bool Accepted);
|
bool NonBreak,bool Accepted);
|
||||||
|
|
||||||
static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role,char *Query);
|
static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role,char *Query);
|
||||||
static void Usr_SearchListUsrs (Rol_Role_t Role);
|
|
||||||
static void Usr_CreateTmpTableAndSearchCandidateUsrs (const char *UsrQuery);
|
|
||||||
static void Usr_DropTmpTableWithCandidateUsrs (void);
|
|
||||||
|
|
||||||
static void Usr_GetAdmsLst (Sco_Scope_t Scope);
|
static void Usr_GetAdmsLst (Sco_Scope_t Scope);
|
||||||
static void Usr_GetGstsLst (Sco_Scope_t Scope);
|
static void Usr_GetGstsLst (Sco_Scope_t Scope);
|
||||||
|
@ -3802,7 +3799,7 @@ void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope)
|
||||||
/********* Search list of users with a given role in current scope ***********/
|
/********* Search list of users with a given role in current scope ***********/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Usr_SearchListUsrs (Rol_Role_t Role)
|
void Usr_SearchListUsrs (Rol_Role_t Role)
|
||||||
{
|
{
|
||||||
char Query[4*1024];
|
char Query[4*1024];
|
||||||
const char *OrderQuery = "candidate_users.UsrCod=usr_data.UsrCod"
|
const char *OrderQuery = "candidate_users.UsrCod=usr_data.UsrCod"
|
||||||
|
@ -4011,7 +4008,7 @@ static void Usr_SearchListUsrs (Rol_Role_t Role)
|
||||||
/*************** Create temporary table with candidate users *****************/
|
/*************** Create temporary table with candidate users *****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Usr_CreateTmpTableAndSearchCandidateUsrs (const char *UsrQuery)
|
void Usr_CreateTmpTableAndSearchCandidateUsrs (const char *SearchQuery)
|
||||||
{
|
{
|
||||||
char Query[16*1024];
|
char Query[16*1024];
|
||||||
|
|
||||||
|
@ -4024,7 +4021,7 @@ static void Usr_CreateTmpTableAndSearchCandidateUsrs (const char *UsrQuery)
|
||||||
sprintf (Query,"CREATE TEMPORARY TABLE candidate_users"
|
sprintf (Query,"CREATE TEMPORARY TABLE candidate_users"
|
||||||
" (UsrCod INT NOT NULL,UNIQUE INDEX(UsrCod)) ENGINE=MEMORY"
|
" (UsrCod INT NOT NULL,UNIQUE INDEX(UsrCod)) ENGINE=MEMORY"
|
||||||
" SELECT UsrCod FROM usr_data WHERE %s",
|
" SELECT UsrCod FROM usr_data WHERE %s",
|
||||||
UsrQuery);
|
SearchQuery);
|
||||||
if (mysql_query (&Gbl.mysql,Query))
|
if (mysql_query (&Gbl.mysql,Query))
|
||||||
DB_ExitOnMySQLError ("can not create temporary table");
|
DB_ExitOnMySQLError ("can not create temporary table");
|
||||||
}
|
}
|
||||||
|
@ -4033,7 +4030,7 @@ static void Usr_CreateTmpTableAndSearchCandidateUsrs (const char *UsrQuery)
|
||||||
/***************** Drop temporary table with candidate users *****************/
|
/***************** Drop temporary table with candidate users *****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Usr_DropTmpTableWithCandidateUsrs (void)
|
void Usr_DropTmpTableWithCandidateUsrs (void)
|
||||||
{
|
{
|
||||||
char Query[128];
|
char Query[128];
|
||||||
|
|
||||||
|
@ -5802,24 +5799,24 @@ void Usr_ListAllDataTchs (void)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
// Returns number of users found
|
// Returns number of users found
|
||||||
|
|
||||||
unsigned Usr_ListUsrsFound (Rol_Role_t Role,const char *UsrQuery)
|
unsigned Usr_ListUsrsFound (Rol_Role_t Role,const char *SearchQuery)
|
||||||
{
|
{
|
||||||
extern const char *Txt_user[Usr_NUM_SEXS];
|
extern const char *Txt_user[Usr_NUM_SEXS];
|
||||||
extern const char *Txt_users[Usr_NUM_SEXS];
|
extern const char *Txt_users[Usr_NUM_SEXS];
|
||||||
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
extern const char *Txt_ROLES_PLURAL_Abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
||||||
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
extern const char *Txt_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
||||||
extern const char *Txt_ROLES_PLURAL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
extern const char *Txt_ROLES_PLURAL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
|
||||||
Usr_Sex_t Sex;
|
unsigned NumUsrs;
|
||||||
unsigned NumUsr;
|
unsigned NumUsr;
|
||||||
struct UsrData UsrDat;
|
struct UsrData UsrDat;
|
||||||
unsigned NumUsrs;
|
Usr_Sex_t Sex;
|
||||||
|
|
||||||
/***** Initialize field names *****/
|
/***** Initialize field names *****/
|
||||||
Usr_SetUsrDatMainFieldNames ();
|
Usr_SetUsrDatMainFieldNames ();
|
||||||
|
|
||||||
/***** Create temporary table with candidate users *****/
|
/***** Create temporary table with candidate users *****/
|
||||||
// Search is faster (aproximately x2) using temporary tables
|
// Search is faster (aproximately x2) using temporary tables
|
||||||
Usr_CreateTmpTableAndSearchCandidateUsrs (UsrQuery);
|
Usr_CreateTmpTableAndSearchCandidateUsrs (SearchQuery);
|
||||||
|
|
||||||
/***** Search for users *****/
|
/***** Search for users *****/
|
||||||
Usr_SearchListUsrs (Role);
|
Usr_SearchListUsrs (Role);
|
||||||
|
@ -5884,7 +5881,7 @@ unsigned Usr_ListUsrsFound (Rol_Role_t Role,const char *UsrQuery)
|
||||||
/***** Free memory for teachers list *****/
|
/***** Free memory for teachers list *****/
|
||||||
Usr_FreeUsrsList (Role);
|
Usr_FreeUsrsList (Role);
|
||||||
|
|
||||||
/***** Drop temporary tables *****/
|
/***** Drop temporary table with candidate users *****/
|
||||||
Usr_DropTmpTableWithCandidateUsrs ();
|
Usr_DropTmpTableWithCandidateUsrs ();
|
||||||
|
|
||||||
return NumUsrs;
|
return NumUsrs;
|
||||||
|
|
|
@ -305,6 +305,10 @@ unsigned Usr_GetNumberOfTeachersInCentre (long CtrCod);
|
||||||
|
|
||||||
void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope);
|
void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope);
|
||||||
|
|
||||||
|
void Usr_SearchListUsrs (Rol_Role_t Role);
|
||||||
|
void Usr_CreateTmpTableAndSearchCandidateUsrs (const char *UsrQuery);
|
||||||
|
void Usr_DropTmpTableWithCandidateUsrs (void);
|
||||||
|
|
||||||
void Usr_GetUnorderedStdsCodesInDeg (long DegCod);
|
void Usr_GetUnorderedStdsCodesInDeg (long DegCod);
|
||||||
void Usr_FreeUsrsList (Rol_Role_t Role);
|
void Usr_FreeUsrsList (Rol_Role_t Role);
|
||||||
bool Usr_GetIfShowBigList (unsigned NumUsrs);
|
bool Usr_GetIfShowBigList (unsigned NumUsrs);
|
||||||
|
@ -332,7 +336,7 @@ void Usr_ListAllDataGsts (void);
|
||||||
void Usr_ListAllDataStds (void);
|
void Usr_ListAllDataStds (void);
|
||||||
void Usr_ListUsrsForSelection (Rol_Role_t Role);
|
void Usr_ListUsrsForSelection (Rol_Role_t Role);
|
||||||
void Usr_ListAllDataTchs (void);
|
void Usr_ListAllDataTchs (void);
|
||||||
unsigned Usr_ListUsrsFound (Rol_Role_t Role,const char *UsrQuery);
|
unsigned Usr_ListUsrsFound (Rol_Role_t Role,const char *SearchQuery);
|
||||||
void Usr_ListDataAdms (void);
|
void Usr_ListDataAdms (void);
|
||||||
|
|
||||||
void Usr_GetAndUpdatePrefsAboutUsrList (void);
|
void Usr_GetAndUpdatePrefsAboutUsrList (void);
|
||||||
|
|
|
@ -109,6 +109,7 @@ cp -f /home/acanas/swad/swad/swad /var/www/cgi-bin/
|
||||||
#include "swad_notice.h"
|
#include "swad_notice.h"
|
||||||
#include "swad_notification.h"
|
#include "swad_notification.h"
|
||||||
#include "swad_password.h"
|
#include "swad_password.h"
|
||||||
|
#include "swad_search.h"
|
||||||
#include "swad_user.h"
|
#include "swad_user.h"
|
||||||
#include "swad_web_service.h"
|
#include "swad_web_service.h"
|
||||||
|
|
||||||
|
@ -179,13 +180,15 @@ static int Svc_CheckParamsNewAccount (char *NewNicknameWithArroba, // Input
|
||||||
char *NewPlainPassword, // Input
|
char *NewPlainPassword, // Input
|
||||||
char *NewEncryptedPassword); // Output
|
char *NewEncryptedPassword); // Output
|
||||||
|
|
||||||
|
static void Svc_CopyListUsers (Rol_Role_t Role,struct swad__getUsersOutput *getUsersOut);
|
||||||
static void Svc_CopyUsrData (struct swad__user *Usr,struct UsrData *UsrDat,bool UsrIDIsVisible);
|
static void Svc_CopyUsrData (struct swad__user *Usr,struct UsrData *UsrDat,bool UsrIDIsVisible);
|
||||||
|
|
||||||
static void Svc_GetListGrpsInAttendanceEvent (long AttCod,char **ListGroups);
|
static void Svc_GetListGrpsInAttendanceEventFromDB (long AttCod,char **ListGroups);
|
||||||
|
static void Svc_GetLstGrpsSel (const char *Groups);
|
||||||
|
|
||||||
static int Svc_GetMyLanguage (void);
|
static int Svc_GetMyLanguage (void);
|
||||||
|
|
||||||
static int Svc_sendMessageToUsr (long OriginalMsgCod,long SenderUsrCod,long ReplyUsrCod,long RecipientUsrCod,bool NotifyByEmail,const char *Subject,const char *Content);
|
static int Svc_SendMessageToUsr (long OriginalMsgCod,long SenderUsrCod,long ReplyUsrCod,long RecipientUsrCod,bool NotifyByEmail,const char *Subject,const char *Content);
|
||||||
|
|
||||||
static int Svc_GetTstConfig (long CrsCod);
|
static int Svc_GetTstConfig (long CrsCod);
|
||||||
static int Svc_GetNumTestQuestionsInCrs (long CrsCod);
|
static int Svc_GetNumTestQuestionsInCrs (long CrsCod);
|
||||||
|
@ -1340,25 +1343,20 @@ int swad__getCourseInfo (struct soap *soap,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********************** Return students in a course **************************/
|
/************* Get users in a course (and optionally in groups) **************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
// If groupCode <= 0 ==> get users from the whole course
|
|
||||||
|
|
||||||
int swad__getUsers (struct soap *soap,
|
int swad__getUsers (struct soap *soap,
|
||||||
char *wsKey,int courseCode,int groupCode,int userRole, // input
|
char *wsKey,int courseCode,char *groups,int userRole, // input
|
||||||
struct swad__getUsersOutput *getUsersOut) // output
|
struct swad__getUsersOutput *getUsersOut) // output
|
||||||
{
|
{
|
||||||
int ReturnCode;
|
int ReturnCode;
|
||||||
char Query[512];
|
Rol_Role_t Role;
|
||||||
MYSQL_RES *mysql_res;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
unsigned NumRow,NumRows;
|
|
||||||
bool UsrIDIsVisible;
|
|
||||||
|
|
||||||
Gbl.soap = soap;
|
Gbl.soap = soap;
|
||||||
Gbl.WebService.Function = Svc_getUsers;
|
Gbl.WebService.Function = Svc_getUsers;
|
||||||
Gbl.CurrentCrs.Crs.CrsCod = (long) courseCode;
|
Gbl.CurrentCrs.Crs.CrsCod = (courseCode > 0) ? (long) courseCode :
|
||||||
Gbl.CurrentCrs.Grps.GrpCod = (long) groupCode;
|
-1L;
|
||||||
|
|
||||||
/***** Check web service key *****/
|
/***** Check web service key *****/
|
||||||
if ((ReturnCode = Svc_CheckWSKey (wsKey)) != SOAP_OK)
|
if ((ReturnCode = Svc_CheckWSKey (wsKey)) != SOAP_OK)
|
||||||
|
@ -1368,8 +1366,8 @@ int swad__getUsers (struct soap *soap,
|
||||||
"Bad web service key",
|
"Bad web service key",
|
||||||
"Web service key does not exist in database");
|
"Web service key does not exist in database");
|
||||||
|
|
||||||
/***** Check course and group codes *****/
|
/***** Check course *****/
|
||||||
if ((ReturnCode = Svc_CheckCourseAndGroupCodes (Gbl.CurrentCrs.Crs.CrsCod,Gbl.CurrentCrs.Grps.GrpCod)) != SOAP_OK)
|
if ((ReturnCode = Svc_CheckCourseAndGroupCodes (Gbl.CurrentCrs.Crs.CrsCod,-1L)) != SOAP_OK)
|
||||||
return ReturnCode;
|
return ReturnCode;
|
||||||
|
|
||||||
/***** Get some of my data *****/
|
/***** Get some of my data *****/
|
||||||
|
@ -1382,78 +1380,194 @@ int swad__getUsers (struct soap *soap,
|
||||||
if (Gbl.Usrs.Me.UsrDat.RoleInCurrentCrsDB != Rol_STUDENT &&
|
if (Gbl.Usrs.Me.UsrDat.RoleInCurrentCrsDB != Rol_STUDENT &&
|
||||||
Gbl.Usrs.Me.UsrDat.RoleInCurrentCrsDB != Rol_TEACHER)
|
Gbl.Usrs.Me.UsrDat.RoleInCurrentCrsDB != Rol_TEACHER)
|
||||||
return soap_receiver_fault (Gbl.soap,
|
return soap_receiver_fault (Gbl.soap,
|
||||||
"Request forbidden",
|
"Request forbidden",
|
||||||
"Requester must belong to course");
|
"Requester must belong to course");
|
||||||
|
|
||||||
/***** Get degree of current course *****/
|
/***** Get degree of current course *****/
|
||||||
if ((ReturnCode = Svc_GetCurrentDegCodFromCurrentCrsCod ()) != SOAP_OK)
|
if ((ReturnCode = Svc_GetCurrentDegCodFromCurrentCrsCod ()) != SOAP_OK) // TODO: Is this necessary?
|
||||||
return ReturnCode;
|
return ReturnCode;
|
||||||
|
|
||||||
/***** Check requested users' type *****/
|
/***** Check requested users' role *****/
|
||||||
if (userRole != 2 && // student
|
if (userRole < 2 || // Students
|
||||||
userRole != 3) // teacher
|
userRole > 3) // Teachers
|
||||||
{
|
|
||||||
sprintf (Gbl.Message,"Only students (user's type = %u) or teachers (user's type = %u) are allowed",
|
|
||||||
(unsigned) 2, // student
|
|
||||||
(unsigned) 3); // teacher
|
|
||||||
return soap_sender_fault (Gbl.soap,
|
return soap_sender_fault (Gbl.soap,
|
||||||
"Bad requested users' type",
|
"Bad requested users' type",
|
||||||
Gbl.Message);
|
"User roles allowed are 2 (students) or 3 (teachers)");
|
||||||
}
|
Role = (Rol_Role_t) userRole;
|
||||||
|
|
||||||
/***** Query users beloging to course or group from database *****/
|
/***** Create a list of groups selected *****/
|
||||||
if (groupCode <= 0) // Users belonging to the whole course
|
Svc_GetLstGrpsSel (groups);
|
||||||
sprintf (Query,"SELECT usr_data.UsrCod"
|
if (Gbl.CurrentCrs.Grps.LstGrpsSel.NumGrps)
|
||||||
" FROM crs_usr,usr_data"
|
/***** Get list of groups types and groups in current course *****/
|
||||||
" WHERE crs_usr.CrsCod='%ld' AND crs_usr.UsrCod=usr_data.UsrCod AND crs_usr.Role='%d'"
|
Grp_GetListGrpTypesInThisCrs (Grp_ONLY_GROUP_TYPES_WITH_GROUPS);
|
||||||
" ORDER BY usr_data.Surname1,usr_data.Surname2,usr_data.FirstName,usr_data.UsrCod",
|
|
||||||
(long) courseCode,
|
|
||||||
userRole == 2 ? (unsigned) Rol_STUDENT :
|
|
||||||
(unsigned) Rol_TEACHER);
|
|
||||||
else // Users belonging to the group
|
|
||||||
sprintf (Query,"SELECT usr_data.UsrCod"
|
|
||||||
" FROM crs_grp_usr,crs_usr,usr_data"
|
|
||||||
" WHERE crs_grp_usr.GrpCod='%ld' AND crs_grp_usr.UsrCod=crs_usr.UsrCod AND crs_grp_usr.UsrCod=usr_data.UsrCod AND crs_usr.Role='%d'"
|
|
||||||
" ORDER BY usr_data.Surname1,usr_data.Surname2,usr_data.FirstName,usr_data.UsrCod",
|
|
||||||
(long) groupCode,
|
|
||||||
userRole == 2 ? (unsigned) Rol_STUDENT :
|
|
||||||
(unsigned) Rol_TEACHER);
|
|
||||||
NumRows = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get users");
|
|
||||||
|
|
||||||
getUsersOut->numUsers = (int) NumRows;
|
/***** Get list of users *****/
|
||||||
getUsersOut->usersArray.__size = (int) NumRows;
|
Usr_GetListUsrs (Role,Sco_SCOPE_CRS);
|
||||||
|
Svc_CopyListUsers (Role,getUsersOut);
|
||||||
|
Usr_FreeUsrsList (Role);
|
||||||
|
|
||||||
if (NumRows == 0)
|
if (Gbl.CurrentCrs.Grps.LstGrpsSel.NumGrps)
|
||||||
getUsersOut->usersArray.__ptr = NULL;
|
|
||||||
else // Users found
|
|
||||||
{
|
{
|
||||||
getUsersOut->usersArray.__ptr = soap_malloc (Gbl.soap,(getUsersOut->usersArray.__size) * sizeof (*(getUsersOut->usersArray.__ptr)));
|
/***** Free list of groups types and groups in current course *****/
|
||||||
|
Grp_FreeListGrpTypesAndGrps ();
|
||||||
|
|
||||||
/***** Users' IDs are visible? *****/
|
/***** Free memory for list of selected groups *****/
|
||||||
UsrIDIsVisible = (Gbl.Usrs.Me.UsrDat.RoleInCurrentCrsDB == Rol_STUDENT &&
|
Grp_FreeListCodSelectedGrps ();
|
||||||
userRole == 2); // get students in the course
|
|
||||||
for (NumRow = 0;
|
|
||||||
NumRow < NumRows;
|
|
||||||
NumRow++)
|
|
||||||
{
|
|
||||||
/* Get next user */
|
|
||||||
row = mysql_fetch_row (mysql_res);
|
|
||||||
|
|
||||||
/* Get user's code (row[0]) */
|
|
||||||
if ((Gbl.Usrs.Other.UsrDat.UsrCod = (long) Str_ConvertStrCodToLongCod (row[0])) > 0)
|
|
||||||
/* Get user's data */
|
|
||||||
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&Gbl.Usrs.Other.UsrDat))
|
|
||||||
/* Copy user's data into output structure */
|
|
||||||
Svc_CopyUsrData (&(getUsersOut->usersArray.__ptr[NumRow]),&Gbl.Usrs.Other.UsrDat,UsrIDIsVisible);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Free structure that stores the query result *****/
|
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
|
||||||
|
|
||||||
return SOAP_OK;
|
return SOAP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int swad__findUsers (struct soap *soap,
|
||||||
|
char *wsKey,int courseCode,char *filter,int userRole, // input
|
||||||
|
struct swad__getUsersOutput *getUsersOut) // output
|
||||||
|
{
|
||||||
|
int ReturnCode;
|
||||||
|
char SearchQuery[Sch_MAX_LENGTH_SEARCH_QUERY+1];
|
||||||
|
Rol_Role_t Role;
|
||||||
|
bool FilterTooShort = false;
|
||||||
|
|
||||||
|
Gbl.soap = soap;
|
||||||
|
Gbl.WebService.Function = Svc_getUsers;
|
||||||
|
Gbl.CurrentCrs.Crs.CrsCod = (courseCode > 0) ? (long) courseCode :
|
||||||
|
-1L;
|
||||||
|
|
||||||
|
/***** Check web service key *****/
|
||||||
|
if ((ReturnCode = Svc_CheckWSKey (wsKey)) != SOAP_OK)
|
||||||
|
return ReturnCode;
|
||||||
|
if (Gbl.Usrs.Me.UsrDat.UsrCod < 0) // Web service key does not exist in database
|
||||||
|
return soap_receiver_fault (Gbl.soap,
|
||||||
|
"Bad web service key",
|
||||||
|
"Web service key does not exist in database");
|
||||||
|
|
||||||
|
if (Gbl.CurrentCrs.Crs.CrsCod > 0)
|
||||||
|
/***** Check course *****/
|
||||||
|
if ((ReturnCode = Svc_CheckCourseAndGroupCodes (Gbl.CurrentCrs.Crs.CrsCod,-1L)) != SOAP_OK)
|
||||||
|
return ReturnCode;
|
||||||
|
|
||||||
|
/***** Get some of my data *****/
|
||||||
|
if ((ReturnCode = Svc_GetSomeUsrDataFromUsrCod (&Gbl.Usrs.Me.UsrDat,Gbl.CurrentCrs.Crs.CrsCod)) != SOAP_OK)
|
||||||
|
return ReturnCode;
|
||||||
|
Gbl.Usrs.Me.Logged = true;
|
||||||
|
Gbl.Usrs.Me.LoggedRole = Gbl.Usrs.Me.UsrDat.RoleInCurrentCrsDB;
|
||||||
|
|
||||||
|
if (Gbl.CurrentCrs.Crs.CrsCod > 0)
|
||||||
|
/***** Check if I am a student or teacher in the course *****/
|
||||||
|
if (Gbl.Usrs.Me.UsrDat.RoleInCurrentCrsDB != Rol_STUDENT &&
|
||||||
|
Gbl.Usrs.Me.UsrDat.RoleInCurrentCrsDB != Rol_TEACHER)
|
||||||
|
return soap_receiver_fault (Gbl.soap,
|
||||||
|
"Request forbidden",
|
||||||
|
"Requester must belong to course");
|
||||||
|
|
||||||
|
if (Gbl.CurrentCrs.Crs.CrsCod > 0)
|
||||||
|
{
|
||||||
|
/***** Get degree of current course *****/
|
||||||
|
if ((ReturnCode = Svc_GetCurrentDegCodFromCurrentCrsCod ()) != SOAP_OK) // TODO: Is this necessary?
|
||||||
|
return ReturnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Check requested users' role *****/
|
||||||
|
if (userRole < 0 ||
|
||||||
|
userRole > 3)
|
||||||
|
return soap_sender_fault (Gbl.soap,
|
||||||
|
"Bad requested users' type",
|
||||||
|
"User roles allowed are 0 (all),1 (guests), 2 (students) or 3 (teachers)");
|
||||||
|
Role = (Rol_Role_t) userRole;
|
||||||
|
|
||||||
|
/***** Query users beloging to course or group from database *****/
|
||||||
|
strncpy (Gbl.Search.Str,filter,Sch_MAX_LENGTH_STRING_TO_FIND);
|
||||||
|
Gbl.Search.Str[Sch_MAX_LENGTH_STRING_TO_FIND] = '\0';
|
||||||
|
|
||||||
|
if (Gbl.Search.Str[0]) // Search some users
|
||||||
|
{
|
||||||
|
Gbl.Scope.Current = (Gbl.CurrentCrs.Crs.CrsCod > 0) ? Sco_SCOPE_CRS :
|
||||||
|
Sco_SCOPE_SYS;
|
||||||
|
if (Sch_BuildSearchQuery (SearchQuery,
|
||||||
|
"CONCAT_WS(' ',FirstName,Surname1,Surname2)",
|
||||||
|
NULL,NULL))
|
||||||
|
{
|
||||||
|
/***** Create temporary table with candidate users *****/
|
||||||
|
// Search is faster (aproximately x2) using temporary tables
|
||||||
|
Usr_CreateTmpTableAndSearchCandidateUsrs (SearchQuery);
|
||||||
|
|
||||||
|
/***** Search for users *****/
|
||||||
|
Usr_SearchListUsrs (Role);
|
||||||
|
Svc_CopyListUsers (Role,getUsersOut);
|
||||||
|
Usr_FreeUsrsList (Role);
|
||||||
|
|
||||||
|
/***** Drop temporary table with candidate users *****/
|
||||||
|
Usr_DropTmpTableWithCandidateUsrs ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FilterTooShort = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FilterTooShort = true;
|
||||||
|
|
||||||
|
/***** Return error in filter? *****/
|
||||||
|
if (FilterTooShort)
|
||||||
|
{
|
||||||
|
getUsersOut->numUsers = -1; // < 0 ==> filter too short
|
||||||
|
getUsersOut->usersArray.__size = 0;
|
||||||
|
getUsersOut->usersArray.__ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SOAP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/***************************** Copy users from list **************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void Svc_CopyListUsers (Rol_Role_t Role,struct swad__getUsersOutput *getUsersOut)
|
||||||
|
{
|
||||||
|
unsigned NumUsrs;
|
||||||
|
unsigned NumUsr;
|
||||||
|
struct UsrData UsrDat;
|
||||||
|
bool ICanSeeUsrID;
|
||||||
|
|
||||||
|
/***** Initialize result *****/
|
||||||
|
getUsersOut->numUsers = 0;
|
||||||
|
getUsersOut->usersArray.__size = 0;
|
||||||
|
getUsersOut->usersArray.__ptr = NULL;
|
||||||
|
|
||||||
|
NumUsrs = Gbl.Usrs.LstUsrs[Role].NumUsrs;
|
||||||
|
if (NumUsrs)
|
||||||
|
{
|
||||||
|
getUsersOut->numUsers = (int) NumUsrs;
|
||||||
|
getUsersOut->usersArray.__size = (int) NumUsrs;
|
||||||
|
getUsersOut->usersArray.__ptr = soap_malloc (Gbl.soap,(getUsersOut->usersArray.__size) * sizeof (*(getUsersOut->usersArray.__ptr)));
|
||||||
|
|
||||||
|
/***** Initialize structure with user's data *****/
|
||||||
|
Usr_UsrDataConstructor (&UsrDat);
|
||||||
|
|
||||||
|
/***** List data of users *****/
|
||||||
|
for (NumUsr = 0;
|
||||||
|
NumUsr < NumUsrs;
|
||||||
|
NumUsr++)
|
||||||
|
{
|
||||||
|
UsrDat.UsrCod = Gbl.Usrs.LstUsrs[Role].Lst[NumUsr].UsrCod;
|
||||||
|
|
||||||
|
/* Get user's data */
|
||||||
|
if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat)) // If user's data exist...
|
||||||
|
{
|
||||||
|
UsrDat.Accepted = Gbl.Usrs.LstUsrs[Role].Lst[NumUsr].Accepted;
|
||||||
|
|
||||||
|
if (Gbl.Usrs.Me.UsrDat.UsrCod == UsrDat.UsrCod) // It's me
|
||||||
|
ICanSeeUsrID = true;
|
||||||
|
else // A user distinct than me
|
||||||
|
ICanSeeUsrID = ID_ICanSeeAnotherUsrID (&UsrDat);
|
||||||
|
|
||||||
|
/* Copy user's data into output structure */
|
||||||
|
Svc_CopyUsrData (&(getUsersOut->usersArray.__ptr[NumUsr]),&UsrDat,ICanSeeUsrID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Free memory used for user's data *****/
|
||||||
|
Usr_UsrDataDestructor (&UsrDat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********************** Return group types in a course ***********************/
|
/********************** Return group types in a course ***********************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -2026,7 +2140,7 @@ int swad__getAttendanceEvents (struct soap *soap,
|
||||||
row[6]);
|
row[6]);
|
||||||
|
|
||||||
/* Get list of groups for this attendance event */
|
/* Get list of groups for this attendance event */
|
||||||
Svc_GetListGrpsInAttendanceEvent (AttCod,&(getAttendanceEventsOut->eventsArray.__ptr[NumAttEvent].groups));
|
Svc_GetListGrpsInAttendanceEventFromDB (AttCod,&(getAttendanceEventsOut->eventsArray.__ptr[NumAttEvent].groups));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2040,7 +2154,7 @@ int swad__getAttendanceEvents (struct soap *soap,
|
||||||
/**************** Get lists of groups of an attendance event *****************/
|
/**************** Get lists of groups of an attendance event *****************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Svc_GetListGrpsInAttendanceEvent (long AttCod,char **ListGroups)
|
static void Svc_GetListGrpsInAttendanceEventFromDB (long AttCod,char **ListGroups)
|
||||||
{
|
{
|
||||||
char Query[128];
|
char Query[128];
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
|
@ -2093,9 +2207,6 @@ int swad__sendAttendanceEvent (struct soap *soap,
|
||||||
int ReturnCode;
|
int ReturnCode;
|
||||||
struct AttendanceEvent Att;
|
struct AttendanceEvent Att;
|
||||||
bool ItsANewAttEvent;
|
bool ItsANewAttEvent;
|
||||||
const char *Ptr;
|
|
||||||
char LongStr[1+10+1];
|
|
||||||
unsigned NumGrp;
|
|
||||||
|
|
||||||
Gbl.soap = soap;
|
Gbl.soap = soap;
|
||||||
Gbl.WebService.Function = Svc_sendAttendanceEvent;
|
Gbl.WebService.Function = Svc_sendAttendanceEvent;
|
||||||
|
@ -2168,8 +2279,35 @@ int swad__sendAttendanceEvent (struct soap *soap,
|
||||||
strncpy (Att.Title,title,Att_MAX_LENGTH_ATTENDANCE_EVENT_TITLE);
|
strncpy (Att.Title,title,Att_MAX_LENGTH_ATTENDANCE_EVENT_TITLE);
|
||||||
Att.Title[Att_MAX_LENGTH_ATTENDANCE_EVENT_TITLE] = '\0';
|
Att.Title[Att_MAX_LENGTH_ATTENDANCE_EVENT_TITLE] = '\0';
|
||||||
|
|
||||||
|
/* Create a list of groups selected */
|
||||||
|
Svc_GetLstGrpsSel (groups);
|
||||||
|
|
||||||
|
/***** Create or update attendance event *****/
|
||||||
|
if (ItsANewAttEvent)
|
||||||
|
Att_CreateAttEvent (&Att,text); // Add new attendance event to database
|
||||||
|
else
|
||||||
|
Att_UpdateAttEvent (&Att,text); // Modify existing attendance event
|
||||||
|
|
||||||
|
/***** Free memory for list of selected groups *****/
|
||||||
|
Grp_FreeListCodSelectedGrps ();
|
||||||
|
|
||||||
|
sendAttendanceEventOut->attendanceEventCode = Att.AttCod;
|
||||||
|
|
||||||
|
return SOAP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/********************** Create a list of groups selected *********************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void Svc_GetLstGrpsSel (const char *Groups)
|
||||||
|
{
|
||||||
|
const char *Ptr;
|
||||||
|
char LongStr[1+10+1];
|
||||||
|
unsigned NumGrp;
|
||||||
|
|
||||||
/***** Count number of groups *****/
|
/***** Count number of groups *****/
|
||||||
for (Ptr = groups, NumGrp = 0;
|
for (Ptr = Groups, NumGrp = 0;
|
||||||
*Ptr;
|
*Ptr;
|
||||||
NumGrp++)
|
NumGrp++)
|
||||||
Str_GetNextStringUntilComma (&Ptr,LongStr,1+10);
|
Str_GetNextStringUntilComma (&Ptr,LongStr,1+10);
|
||||||
|
@ -2184,7 +2322,7 @@ int swad__sendAttendanceEvent (struct soap *soap,
|
||||||
if ((Gbl.CurrentCrs.Grps.LstGrpsSel.GrpCod = (long *) calloc (Gbl.CurrentCrs.Grps.LstGrpsSel.NumGrps,sizeof (long))) == NULL)
|
if ((Gbl.CurrentCrs.Grps.LstGrpsSel.GrpCod = (long *) calloc (Gbl.CurrentCrs.Grps.LstGrpsSel.NumGrps,sizeof (long))) == NULL)
|
||||||
Lay_ShowErrorAndExit ("Not enough memory to store the codes of the selected groups.");
|
Lay_ShowErrorAndExit ("Not enough memory to store the codes of the selected groups.");
|
||||||
|
|
||||||
for (Ptr = groups, NumGrp = 0;
|
for (Ptr = Groups, NumGrp = 0;
|
||||||
*Ptr;
|
*Ptr;
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -2195,19 +2333,6 @@ int swad__sendAttendanceEvent (struct soap *soap,
|
||||||
}
|
}
|
||||||
Gbl.CurrentCrs.Grps.LstGrpsSel.NumGrps = NumGrp; // Update number of groups
|
Gbl.CurrentCrs.Grps.LstGrpsSel.NumGrps = NumGrp; // Update number of groups
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Create or update attendance event *****/
|
|
||||||
if (ItsANewAttEvent)
|
|
||||||
Att_CreateAttEvent (&Att,text); // Add new attendance event to database
|
|
||||||
else
|
|
||||||
Att_UpdateAttEvent (&Att,text); // Modify existing attendance event
|
|
||||||
|
|
||||||
/***** Free memory for list of selected groups *****/
|
|
||||||
Grp_FreeListCodSelectedGrps ();
|
|
||||||
|
|
||||||
sendAttendanceEventOut->attendanceEventCode = Att.AttCod;
|
|
||||||
|
|
||||||
return SOAP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -2991,7 +3116,7 @@ int swad__sendMessage (struct soap *soap,
|
||||||
(Gbl.Usrs.Other.UsrDat.Prefs.EmailNtfEvents & (1 << Ntf_EVENT_MESSAGE)));
|
(Gbl.Usrs.Other.UsrDat.Prefs.EmailNtfEvents & (1 << Ntf_EVENT_MESSAGE)));
|
||||||
|
|
||||||
/* Send message to this user */
|
/* Send message to this user */
|
||||||
if ((ReturnCode = Svc_sendMessageToUsr ((long) messageCode,Gbl.Usrs.Me.UsrDat.UsrCod,ReplyUsrCod,Gbl.Usrs.Other.UsrDat.UsrCod,NotifyByEmail,subject,body)) != SOAP_OK)
|
if ((ReturnCode = Svc_SendMessageToUsr ((long) messageCode,Gbl.Usrs.Me.UsrDat.UsrCod,ReplyUsrCod,Gbl.Usrs.Other.UsrDat.UsrCod,NotifyByEmail,subject,body)) != SOAP_OK)
|
||||||
{
|
{
|
||||||
DB_FreeMySQLResult (&mysql_res);
|
DB_FreeMySQLResult (&mysql_res);
|
||||||
return ReturnCode;
|
return ReturnCode;
|
||||||
|
@ -3013,7 +3138,7 @@ int swad__sendMessage (struct soap *soap,
|
||||||
/************************* Send a message to one user ************************/
|
/************************* Send a message to one user ************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static int Svc_sendMessageToUsr (long OriginalMsgCod,long SenderUsrCod,long ReplyUsrCod,long RecipientUsrCod,bool NotifyByEmail,const char *Subject,const char *Content)
|
static int Svc_SendMessageToUsr (long OriginalMsgCod,long SenderUsrCod,long ReplyUsrCod,long RecipientUsrCod,bool NotifyByEmail,const char *Subject,const char *Content)
|
||||||
{
|
{
|
||||||
static bool MsgAlreadyInserted = false;
|
static bool MsgAlreadyInserted = false;
|
||||||
static long NewMsgCod;
|
static long NewMsgCod;
|
||||||
|
|
Loading…
Reference in New Issue