diff --git a/sql/cambios.sql b/sql/cambios.sql
index 95d0107a4..03a9bf542 100644
--- a/sql/cambios.sql
+++ b/sql/cambios.sql
@@ -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));
+
+
+
+
+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;
diff --git a/swad_changelog.h b/swad_changelog.h
index 9e1fd442c..361322c3f 100644
--- a/swad_changelog.h
+++ b/swad_changelog.h
@@ -146,13 +146,16 @@
/****************************** 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 JS_FILE "swad15.238.1.js"
// 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
/*
+ 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.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)
diff --git a/swad_report.c b/swad_report.c
index 773d0b7ee..3f4c9e75c 100644
--- a/swad_report.c
+++ b/swad_report.c
@@ -116,18 +116,22 @@ static void Rep_WriteSectionHistoricCourses (const struct UsrFigures *UsrFigures
unsigned long MaxHitsPerYear);
static unsigned long Rep_GetMaxHitsPerYear (time_t FirstClickTimeUTC);
-static void Rep_GetAndWriteCurrentCrssOfAUsr (const struct UsrData *UsrDat,Rol_Role_t Role,
- time_t FirstClickTimeUTC,
- const struct tm *tm_FirstClickTime,
- unsigned long MaxHitsPerYear);
-static void Rep_GetAndWriteHistoricCrssOfAUsr (const struct UsrData *UsrDat,Rol_Role_t Role,
+static void Rep_GetAndWriteMyCurrentCrss (Rol_Role_t Role,
+ time_t FirstClickTimeUTC,
+ const struct tm *tm_FirstClickTime,
+ unsigned long MaxHitsPerYear);
+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,
const struct tm *tm_FirstClickTime,
unsigned long MaxHitsPerYear);
static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
time_t FirstClickTimeUTC,
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,
time_t FirstClickTimeUTC,
@@ -789,9 +793,9 @@ static void Rep_WriteSectionCurrentCourses (const struct UsrFigures *UsrFigures,
Role <= Rol_TEACHER;
Role++)
/* List my courses with this role */
- Rep_GetAndWriteCurrentCrssOfAUsr (&Gbl.Usrs.Me.UsrDat,Role,
- UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
- MaxHitsPerYear);
+ Rep_GetAndWriteMyCurrentCrss (Role,
+ UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
+ MaxHitsPerYear);
/***** End of section *****/
fprintf (Gbl.F.Rep,""
@@ -819,12 +823,16 @@ static void Rep_WriteSectionHistoricCourses (const struct UsrFigures *UsrFigures
Rep_MIN_CLICKS_CRS);
fprintf (Gbl.F.Rep,"
");
- /***** 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;
Role <= Rol_TEACHER;
Role++)
/* List my courses with this role */
- Rep_GetAndWriteHistoricCrssOfAUsr (&Gbl.Usrs.Me.UsrDat,Role,
+ Rep_GetAndWriteMyHistoricCrss (Role,
UsrFigures->FirstClickTimeUTC,tm_FirstClickTime,
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,
- time_t FirstClickTimeUTC,
- const struct tm *tm_FirstClickTime,
- unsigned long MaxHitsPerYear)
+static void Rep_GetAndWriteMyCurrentCrss (Rol_Role_t Role,
+ time_t FirstClickTimeUTC,
+ const struct tm *tm_FirstClickTime,
+ unsigned long MaxHitsPerYear)
{
extern const char *Txt_USER_in_COURSE;
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;
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]);
fprintf (Gbl.F.Rep,"- %s %u %s",
Gbl.Title,
@@ -908,14 +916,16 @@ static void Rep_GetAndWriteCurrentCrssOfAUsr (const struct UsrData *UsrDat,Rol_R
Txt_students_ABBREVIATION);
/***** Get courses of a user from database *****/
- sprintf (Query,"SELECT courses.CrsCod,degrees.FullName,courses.Year,courses.FullName"
- " FROM crs_usr,courses,degrees"
- " WHERE crs_usr.UsrCod='%ld'"
- " AND crs_usr.Role='%u'"
- " AND crs_usr.CrsCod=courses.CrsCod"
- " AND courses.DegCod=degrees.DegCod"
- " ORDER BY degrees.FullName,courses.Year,courses.FullName",
- UsrDat->UsrCod,(unsigned) Role);
+ sprintf (Query,"SELECT crs_usr.CrsCod,log_full.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 crs_usr.UsrCod='%ld'"
+ " AND crs_usr.Role='%u'"
+ " 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) *****/
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 */
Rep_WriteRowCrsData (CrsCod,Role,
FirstClickTimeUTC,tm_FirstClickTime,
- MaxHitsPerYear);
+ MaxHitsPerYear,
+ true); // Write number of users in course
}
/* 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,
- time_t FirstClickTimeUTC,
- const struct tm *tm_FirstClickTime,
- unsigned long MaxHitsPerYear)
+static void Rep_GetAndWriteMyHistoricClicsWithoutCrs (time_t FirstClickTimeUTC,
+ const struct tm *tm_FirstClickTime,
+ unsigned long MaxHitsPerYear)
+ {
+ extern const char *Txt_Hits_without_course_selected;
+
+ /***** Heading row *****/
+ fprintf (Gbl.F.Rep,"
- %s:"
+ "
",
+ 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,"
"
+ " ");
+ }
+
+/*****************************************************************************/
+/********************** 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_ROLES_SINGUL_abc[Rol_NUM_ROLES][Usr_NUM_SEXS];
@@ -969,14 +1007,14 @@ static void Rep_GetAndWriteHistoricCrssOfAUsr (const struct UsrData *UsrDat,Rol_
unsigned NumCrs;
long CrsCod;
- /***** Get courses of a user from database *****/
+ /***** Get historic courses of a user from log *****/
sprintf (Query,"SELECT CrsCod,COUNT(*) AS N"
" FROM log_full"
- " WHERE UsrCod='%ld' AND Role='%u'"
+ " WHERE UsrCod='%ld' AND Role='%u' AND CrsCod>'0'"
" GROUP BY CrsCod"
" HAVING N>'%u'"
" ORDER BY N DESC",
- UsrDat->UsrCod,(unsigned) Role,
+ Gbl.Usrs.Me.UsrDat.UsrCod,(unsigned) Role,
Rep_MIN_CLICKS_CRS);
/***** 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 */
Rep_WriteRowCrsData (CrsCod,Role,
FirstClickTimeUTC,tm_FirstClickTime,
- MaxHitsPerYear);
- }
+ MaxHitsPerYear,
+ false); // Do not write number of users in course
+ }
/* End of list */
fprintf (Gbl.F.Rep,""
@@ -1022,7 +1061,8 @@ static void Rep_GetAndWriteHistoricCrssOfAUsr (const struct UsrData *UsrDat,Rol_
static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
time_t FirstClickTimeUTC,
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_teachers_ABBREVIATION;
@@ -1058,9 +1098,10 @@ static void Rep_WriteRowCrsData (long CrsCod,Rol_Role_t Role,
fprintf (Gbl.F.Rep," %s",Deg.FullName);
/***** Write number of teachers / students in course *****/
- fprintf (Gbl.F.Rep," (%u %s / %u %s)",
- Usr_GetNumUsrsInCrs (Rol_TEACHER,Crs.CrsCod),Txt_teachers_ABBREVIATION,
- Usr_GetNumUsrsInCrs (Rol_STUDENT,Crs.CrsCod),Txt_students_ABBREVIATION);
+ if (WriteNumUsrs)
+ fprintf (Gbl.F.Rep," (%u %s / %u %s)",
+ Usr_GetNumUsrsInCrs (Rol_TEACHER,Crs.CrsCod),Txt_teachers_ABBREVIATION,
+ Usr_GetNumUsrsInCrs (Rol_STUDENT,Crs.CrsCod),Txt_students_ABBREVIATION);
}
else
fprintf (Gbl.F.Rep,"(%s)",Txt_unknown_removed_course);
diff --git a/swad_text.c b/swad_text.c
index 89f8f55a4..f639932cd 100644
--- a/swad_text.c
+++ b/swad_text.c
@@ -14056,6 +14056,27 @@ const char *Txt_Hits_as_a_USER = // hits = visits, clicks, page views... Warning
"Visitas (cliques) como %s";
#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 =
#if L==1
"Festivitat";