mirror of
https://github.com/acanas/swad-core.git
synced 2024-06-03 07:15:26 +02:00
Version 16.16
This commit is contained in:
parent
784a984d20
commit
157c4912ea
|
@ -11643,3 +11643,8 @@ SELECT SQL_NO_CACHE YEAR(CONVERT_TZ(ClickTime,@@session.time_zone,'Europe/Berlin
|
||||||
CREATE TABLE IF NOT EXISTS usr_report (RepCod INT NOT NULL AUTO_INCREMENT,UsrCod INT NOT NULL,ReportTimeUTC DATETIME NOT NULL,UniqueDirL CHAR(2) NOT NULL,UniqueDirR CHAR(41) NOT NULL,Filename VARCHAR(255) NOT NULL,Permalink VARCHAR(255) NOT NULL,UNIQUE INDEX(RepCod),INDEX(UsrCod));
|
CREATE TABLE IF NOT EXISTS usr_report (RepCod INT NOT NULL AUTO_INCREMENT,UsrCod INT NOT NULL,ReportTimeUTC DATETIME NOT NULL,UniqueDirL CHAR(2) NOT NULL,UniqueDirR CHAR(41) NOT NULL,Filename VARCHAR(255) NOT NULL,Permalink VARCHAR(255) NOT NULL,UNIQUE INDEX(RepCod),INDEX(UsrCod));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SELECT CrsCod,COUNT(*) AS N FROM crs_usr LEFT JOIN log_full ON (crs_usr.CrsCod=log_full.CrsCod AND crs_usr.UsrCod=log_full.UsrCod AND crs_usr.Role=log_full.Role) WHERE UsrCod='7' AND Role='3' GROUP BY CrsCod ORDER BY N DESC;
|
||||||
|
|
|
@ -146,13 +146,16 @@
|
||||||
/****************************** Public constants *****************************/
|
/****************************** Public constants *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define Log_PLATFORM_VERSION "SWAD 16.15.6 (2016-10-06)"
|
#define Log_PLATFORM_VERSION "SWAD 16.16 (2016-10-07)"
|
||||||
#define CSS_FILE "swad15.229.css"
|
#define CSS_FILE "swad15.229.css"
|
||||||
#define JS_FILE "swad15.238.1.js"
|
#define JS_FILE "swad15.238.1.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 16.16: Oct 07, 2016 Order current courses in user's usage report by number of clicks.
|
||||||
|
Do not write number of users in historic courses.
|
||||||
|
Clicks without course selected are shown apart. (206085 lines)
|
||||||
Version 16.15.6: Oct 06, 2016 Message in user's usage reports. (206027 lines)
|
Version 16.15.6: Oct 06, 2016 Message in user's usage reports. (206027 lines)
|
||||||
Version 16.15.5: Oct 06, 2016 Fix bug removing user's usage reports. (206023 lines)
|
Version 16.15.5: Oct 06, 2016 Fix bug removing user's usage reports. (206023 lines)
|
||||||
Version 16.15.4: Oct 06, 2016 When a user is removed, all his/her user's usage reports are removed. (206022 lines)
|
Version 16.15.4: Oct 06, 2016 When a user is removed, all his/her user's usage reports are removed. (206022 lines)
|
||||||
|
|
121
swad_report.c
121
swad_report.c
|
@ -116,18 +116,22 @@ static void Rep_WriteSectionHistoricCourses (const struct UsrFigures *UsrFigures
|
||||||
unsigned long MaxHitsPerYear);
|
unsigned long MaxHitsPerYear);
|
||||||
|
|
||||||
static unsigned long Rep_GetMaxHitsPerYear (time_t FirstClickTimeUTC);
|
static unsigned long Rep_GetMaxHitsPerYear (time_t FirstClickTimeUTC);
|
||||||
static void Rep_GetAndWriteCurrentCrssOfAUsr (const struct UsrData *UsrDat,Rol_Role_t Role,
|
static void Rep_GetAndWriteMyCurrentCrss (Rol_Role_t Role,
|
||||||
time_t FirstClickTimeUTC,
|
time_t FirstClickTimeUTC,
|
||||||
const struct tm *tm_FirstClickTime,
|
const struct tm *tm_FirstClickTime,
|
||||||
unsigned long MaxHitsPerYear);
|
unsigned long MaxHitsPerYear);
|
||||||
static void Rep_GetAndWriteHistoricCrssOfAUsr (const struct UsrData *UsrDat,Rol_Role_t Role,
|
static void Rep_GetAndWriteMyHistoricClicsWithoutCrs (time_t FirstClickTimeUTC,
|
||||||
|
const struct tm *tm_FirstClickTime,
|
||||||
|
unsigned long MaxHitsPerYear);
|
||||||
|
static void Rep_GetAndWriteMyHistoricCrss (Rol_Role_t Role,
|
||||||
time_t FirstClickTimeUTC,
|
time_t FirstClickTimeUTC,
|
||||||
const struct tm *tm_FirstClickTime,
|
const struct tm *tm_FirstClickTime,
|
||||||
unsigned long MaxHitsPerYear);
|
unsigned long MaxHitsPerYear);
|
||||||
static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
|
static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
|
||||||
time_t FirstClickTimeUTC,
|
time_t FirstClickTimeUTC,
|
||||||
const struct tm *tm_FirstClickTime,
|
const struct tm *tm_FirstClickTime,
|
||||||
unsigned long MaxHitsPerYear);
|
unsigned long MaxHitsPerYear,
|
||||||
|
bool WriteNumUsrs);
|
||||||
|
|
||||||
static void Rep_ShowMyHitsPerYear (bool AnyCourse,long CrsCod,Rol_Role_t Role,
|
static void Rep_ShowMyHitsPerYear (bool AnyCourse,long CrsCod,Rol_Role_t Role,
|
||||||
time_t FirstClickTimeUTC,
|
time_t FirstClickTimeUTC,
|
||||||
|
@ -789,9 +793,9 @@ static void Rep_WriteSectionCurrentCourses (const struct UsrFigures *UsrFigures,
|
||||||
Role <= Rol_TEACHER;
|
Role <= Rol_TEACHER;
|
||||||
Role++)
|
Role++)
|
||||||
/* List my courses with this role */
|
/* List my courses with this role */
|
||||||
Rep_GetAndWriteCurrentCrssOfAUsr (&Gbl.Usrs.Me.UsrDat,Role,
|
Rep_GetAndWriteMyCurrentCrss (Role,
|
||||||
UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
|
UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
|
||||||
MaxHitsPerYear);
|
MaxHitsPerYear);
|
||||||
|
|
||||||
/***** End of section *****/
|
/***** End of section *****/
|
||||||
fprintf (Gbl.F.Rep,"</ul>"
|
fprintf (Gbl.F.Rep,"</ul>"
|
||||||
|
@ -819,12 +823,16 @@ static void Rep_WriteSectionHistoricCourses (const struct UsrFigures *UsrFigures
|
||||||
Rep_MIN_CLICKS_CRS);
|
Rep_MIN_CLICKS_CRS);
|
||||||
fprintf (Gbl.F.Rep,"<ul>");
|
fprintf (Gbl.F.Rep,"<ul>");
|
||||||
|
|
||||||
/***** Number of courses in which the user clicked as student/teacher *****/
|
/********* Historic clicks of a user without course selected ***********/
|
||||||
|
Rep_GetAndWriteMyHistoricClicsWithoutCrs (UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
|
||||||
|
MaxHitsPerYear);
|
||||||
|
|
||||||
|
/***** Historic courses in which the user clicked as student/teacher *****/
|
||||||
for (Role = Rol_STUDENT;
|
for (Role = Rol_STUDENT;
|
||||||
Role <= Rol_TEACHER;
|
Role <= Rol_TEACHER;
|
||||||
Role++)
|
Role++)
|
||||||
/* List my courses with this role */
|
/* List my courses with this role */
|
||||||
Rep_GetAndWriteHistoricCrssOfAUsr (&Gbl.Usrs.Me.UsrDat,Role,
|
Rep_GetAndWriteMyHistoricCrss (Role,
|
||||||
UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
|
UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
|
||||||
MaxHitsPerYear);
|
MaxHitsPerYear);
|
||||||
|
|
||||||
|
@ -871,13 +879,13 @@ static unsigned long Rep_GetMaxHitsPerYear (time_t FirstClickTimeUTC)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************************** Write courses of a user **************************/
|
/************************* Write my current courses **************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Rep_GetAndWriteCurrentCrssOfAUsr (const struct UsrData *UsrDat,Rol_Role_t Role,
|
static void Rep_GetAndWriteMyCurrentCrss (Rol_Role_t Role,
|
||||||
time_t FirstClickTimeUTC,
|
time_t FirstClickTimeUTC,
|
||||||
const struct tm *tm_FirstClickTime,
|
const struct tm *tm_FirstClickTime,
|
||||||
unsigned long MaxHitsPerYear)
|
unsigned long MaxHitsPerYear)
|
||||||
{
|
{
|
||||||
extern const char *Txt_USER_in_COURSE;
|
extern const char *Txt_USER_in_COURSE;
|
||||||
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];
|
||||||
|
@ -892,7 +900,7 @@ static void Rep_GetAndWriteCurrentCrssOfAUsr (const struct UsrData *UsrDat,Rol_R
|
||||||
unsigned NumCrs;
|
unsigned NumCrs;
|
||||||
long CrsCod;
|
long CrsCod;
|
||||||
|
|
||||||
NumCrss = Usr_GetNumCrssOfUsrWithARole (UsrDat->UsrCod,Role);
|
NumCrss = Usr_GetNumCrssOfUsrWithARole (Gbl.Usrs.Me.UsrDat.UsrCod,Role);
|
||||||
sprintf (Gbl.Title,Txt_USER_in_COURSE,Txt_ROLES_SINGUL_Abc[Role][Gbl.Usrs.Me.UsrDat.Sex]);
|
sprintf (Gbl.Title,Txt_USER_in_COURSE,Txt_ROLES_SINGUL_Abc[Role][Gbl.Usrs.Me.UsrDat.Sex]);
|
||||||
fprintf (Gbl.F.Rep,"<li>%s %u %s",
|
fprintf (Gbl.F.Rep,"<li>%s %u %s",
|
||||||
Gbl.Title,
|
Gbl.Title,
|
||||||
|
@ -908,14 +916,16 @@ static void Rep_GetAndWriteCurrentCrssOfAUsr (const struct UsrData *UsrDat,Rol_R
|
||||||
Txt_students_ABBREVIATION);
|
Txt_students_ABBREVIATION);
|
||||||
|
|
||||||
/***** Get courses of a user from database *****/
|
/***** Get courses of a user from database *****/
|
||||||
sprintf (Query,"SELECT courses.CrsCod,degrees.FullName,courses.Year,courses.FullName"
|
sprintf (Query,"SELECT crs_usr.CrsCod,log_full.CrsCod,COUNT(*) AS N"
|
||||||
" FROM crs_usr,courses,degrees"
|
" FROM crs_usr LEFT JOIN log_full ON"
|
||||||
" WHERE crs_usr.UsrCod='%ld'"
|
" (crs_usr.CrsCod=log_full.CrsCod"
|
||||||
" AND crs_usr.Role='%u'"
|
" AND crs_usr.UsrCod=log_full.UsrCod"
|
||||||
" AND crs_usr.CrsCod=courses.CrsCod"
|
" AND crs_usr.Role=log_full.Role)"
|
||||||
" AND courses.DegCod=degrees.DegCod"
|
" WHERE crs_usr.UsrCod='%ld'"
|
||||||
" ORDER BY degrees.FullName,courses.Year,courses.FullName",
|
" AND crs_usr.Role='%u'"
|
||||||
UsrDat->UsrCod,(unsigned) Role);
|
" GROUP BY crs_usr.CrsCod"
|
||||||
|
" ORDER BY N DESC,log_full.CrsCod DESC",
|
||||||
|
Gbl.Usrs.Me.UsrDat.UsrCod,(unsigned) Role);
|
||||||
|
|
||||||
/***** List the courses (one row per course) *****/
|
/***** List the courses (one row per course) *****/
|
||||||
if ((NumCrss = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get courses of a user")))
|
if ((NumCrss = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get courses of a user")))
|
||||||
|
@ -937,7 +947,8 @@ static void Rep_GetAndWriteCurrentCrssOfAUsr (const struct UsrData *UsrDat,Rol_R
|
||||||
/* Write data of this course */
|
/* Write data of this course */
|
||||||
Rep_WriteRowCrsData (CrsCod,Role,
|
Rep_WriteRowCrsData (CrsCod,Role,
|
||||||
FirstClickTimeUTC,tm_FirstClickTime,
|
FirstClickTimeUTC,tm_FirstClickTime,
|
||||||
MaxHitsPerYear);
|
MaxHitsPerYear,
|
||||||
|
true); // Write number of users in course
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End table */
|
/* End table */
|
||||||
|
@ -952,13 +963,40 @@ static void Rep_GetAndWriteCurrentCrssOfAUsr (const struct UsrData *UsrDat,Rol_R
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/************************** Write courses of a user **************************/
|
/************* Write my historic clicks without course selected **************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Rep_GetAndWriteHistoricCrssOfAUsr (const struct UsrData *UsrDat,Rol_Role_t Role,
|
static void Rep_GetAndWriteMyHistoricClicsWithoutCrs (time_t FirstClickTimeUTC,
|
||||||
time_t FirstClickTimeUTC,
|
const struct tm *tm_FirstClickTime,
|
||||||
const struct tm *tm_FirstClickTime,
|
unsigned long MaxHitsPerYear)
|
||||||
unsigned long MaxHitsPerYear)
|
{
|
||||||
|
extern const char *Txt_Hits_without_course_selected;
|
||||||
|
|
||||||
|
/***** Heading row *****/
|
||||||
|
fprintf (Gbl.F.Rep,"<li>%s:"
|
||||||
|
"<ol>",
|
||||||
|
Txt_Hits_without_course_selected);
|
||||||
|
|
||||||
|
/***** Historic clicks *****/
|
||||||
|
Rep_WriteRowCrsData (-1L,
|
||||||
|
Rol_UNKNOWN, // Role does not matter
|
||||||
|
FirstClickTimeUTC,tm_FirstClickTime,
|
||||||
|
MaxHitsPerYear,
|
||||||
|
false); // Do not write number of users in course
|
||||||
|
|
||||||
|
/***** End of list *****/
|
||||||
|
fprintf (Gbl.F.Rep,"</ol>"
|
||||||
|
"</li>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/********************** Write historic courses of a user *********************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void Rep_GetAndWriteMyHistoricCrss (Rol_Role_t Role,
|
||||||
|
time_t FirstClickTimeUTC,
|
||||||
|
const struct tm *tm_FirstClickTime,
|
||||||
|
unsigned long MaxHitsPerYear)
|
||||||
{
|
{
|
||||||
extern const char *Txt_Hits_as_a_USER;
|
extern const char *Txt_Hits_as_a_USER;
|
||||||
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];
|
||||||
|
@ -969,14 +1007,14 @@ static void Rep_GetAndWriteHistoricCrssOfAUsr (const struct UsrData *UsrDat,Rol_
|
||||||
unsigned NumCrs;
|
unsigned NumCrs;
|
||||||
long CrsCod;
|
long CrsCod;
|
||||||
|
|
||||||
/***** Get courses of a user from database *****/
|
/***** Get historic courses of a user from log *****/
|
||||||
sprintf (Query,"SELECT CrsCod,COUNT(*) AS N"
|
sprintf (Query,"SELECT CrsCod,COUNT(*) AS N"
|
||||||
" FROM log_full"
|
" FROM log_full"
|
||||||
" WHERE UsrCod='%ld' AND Role='%u'"
|
" WHERE UsrCod='%ld' AND Role='%u' AND CrsCod>'0'"
|
||||||
" GROUP BY CrsCod"
|
" GROUP BY CrsCod"
|
||||||
" HAVING N>'%u'"
|
" HAVING N>'%u'"
|
||||||
" ORDER BY N DESC",
|
" ORDER BY N DESC",
|
||||||
UsrDat->UsrCod,(unsigned) Role,
|
Gbl.Usrs.Me.UsrDat.UsrCod,(unsigned) Role,
|
||||||
Rep_MIN_CLICKS_CRS);
|
Rep_MIN_CLICKS_CRS);
|
||||||
|
|
||||||
/***** List the courses (one row per course) *****/
|
/***** List the courses (one row per course) *****/
|
||||||
|
@ -1003,8 +1041,9 @@ static void Rep_GetAndWriteHistoricCrssOfAUsr (const struct UsrData *UsrDat,Rol_
|
||||||
/* Write data of this course */
|
/* Write data of this course */
|
||||||
Rep_WriteRowCrsData (CrsCod,Role,
|
Rep_WriteRowCrsData (CrsCod,Role,
|
||||||
FirstClickTimeUTC,tm_FirstClickTime,
|
FirstClickTimeUTC,tm_FirstClickTime,
|
||||||
MaxHitsPerYear);
|
MaxHitsPerYear,
|
||||||
}
|
false); // Do not write number of users in course
|
||||||
|
}
|
||||||
|
|
||||||
/* End of list */
|
/* End of list */
|
||||||
fprintf (Gbl.F.Rep,"</ol>"
|
fprintf (Gbl.F.Rep,"</ol>"
|
||||||
|
@ -1022,7 +1061,8 @@ static void Rep_GetAndWriteHistoricCrssOfAUsr (const struct UsrData *UsrDat,Rol_
|
||||||
static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
|
static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
|
||||||
time_t FirstClickTimeUTC,
|
time_t FirstClickTimeUTC,
|
||||||
const struct tm *tm_FirstClickTime,
|
const struct tm *tm_FirstClickTime,
|
||||||
unsigned long MaxHitsPerYear)
|
unsigned long MaxHitsPerYear,
|
||||||
|
bool WriteNumUsrs)
|
||||||
{
|
{
|
||||||
extern const char *Txt_YEAR_OF_DEGREE[1+Deg_MAX_YEARS_PER_DEGREE];
|
extern const char *Txt_YEAR_OF_DEGREE[1+Deg_MAX_YEARS_PER_DEGREE];
|
||||||
extern const char *Txt_teachers_ABBREVIATION;
|
extern const char *Txt_teachers_ABBREVIATION;
|
||||||
|
@ -1058,9 +1098,10 @@ static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
|
||||||
fprintf (Gbl.F.Rep," %s",Deg.FullName);
|
fprintf (Gbl.F.Rep," %s",Deg.FullName);
|
||||||
|
|
||||||
/***** Write number of teachers / students in course *****/
|
/***** Write number of teachers / students in course *****/
|
||||||
fprintf (Gbl.F.Rep," (%u %s / %u %s)",
|
if (WriteNumUsrs)
|
||||||
Usr_GetNumUsrsInCrs (Rol_TEACHER,Crs.CrsCod),Txt_teachers_ABBREVIATION,
|
fprintf (Gbl.F.Rep," (%u %s / %u %s)",
|
||||||
Usr_GetNumUsrsInCrs (Rol_STUDENT,Crs.CrsCod),Txt_students_ABBREVIATION);
|
Usr_GetNumUsrsInCrs (Rol_TEACHER,Crs.CrsCod),Txt_teachers_ABBREVIATION,
|
||||||
|
Usr_GetNumUsrsInCrs (Rol_STUDENT,Crs.CrsCod),Txt_students_ABBREVIATION);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fprintf (Gbl.F.Rep,"(%s)",Txt_unknown_removed_course);
|
fprintf (Gbl.F.Rep,"(%s)",Txt_unknown_removed_course);
|
||||||
|
|
21
swad_text.c
21
swad_text.c
|
@ -14056,6 +14056,27 @@ const char *Txt_Hits_as_a_USER = // hits = visits, clicks, page views... Warning
|
||||||
"Visitas (cliques) como %s";
|
"Visitas (cliques) como %s";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const char *Txt_Hits_without_course_selected = // hits = visits, clicks, page views...
|
||||||
|
#if L==1
|
||||||
|
"Accessos (clics) sense assignatura seleccionada";
|
||||||
|
#elif L==2
|
||||||
|
"Anmeldungen (Klicks) ohne Kurs ausgewählt";
|
||||||
|
#elif L==3
|
||||||
|
"Hits (clicks) without course selected";
|
||||||
|
#elif L==4
|
||||||
|
"Accesos (clics) sin asignatura seleccionada";
|
||||||
|
#elif L==5
|
||||||
|
"Visites (clics) sans matière sélectionnée";
|
||||||
|
#elif L==6
|
||||||
|
"Accesos (clics) sin asignatura seleccionada"; // Okoteve traducción
|
||||||
|
#elif L==7
|
||||||
|
"Visite (scatti) senza corso selezionato";
|
||||||
|
#elif L==8
|
||||||
|
"Odsłon (kliknięcia) bez oczywiście wybrana";
|
||||||
|
#elif L==9
|
||||||
|
"Visitas (cliques) sem disciplina selecionada";
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *Txt_Holiday =
|
const char *Txt_Holiday =
|
||||||
#if L==1
|
#if L==1
|
||||||
"Festivitat";
|
"Festivitat";
|
||||||
|
|
Loading…
Reference in New Issue
Block a user