From 52ea25d9db9107d4a1f11f768f2bc6ac114f0399 Mon Sep 17 00:00:00 2001 From: acanas Date: Mon, 3 Jan 2022 02:47:16 +0100 Subject: [PATCH] Version 21.82: Jan 03, 2022 Functions moved from swad_figure to other modules. --- swad_agenda.c | 69 ++ swad_agenda.h | 3 + swad_assignment.c | 62 + swad_assignment.h | 3 + swad_browser.c | 568 +++++++++ swad_browser.h | 15 + swad_calendar.c | 89 ++ swad_calendar.h | 3 + swad_changelog.h | 3 +- swad_cookie.c | 90 ++ swad_cookie.h | 3 + swad_date.c | 76 ++ swad_date.h | 3 + swad_degree_type.c | 12 +- swad_degree_type.h | 3 + swad_exam.c | 54 + swad_exam.h | 3 + swad_figure.c | 2898 +------------------------------------------ swad_follow.c | 90 ++ swad_follow.h | 3 + swad_forum.c | 323 +++++ swad_forum.h | 3 + swad_game.c | 54 + swad_game.h | 3 + swad_icon.c | 98 ++ swad_icon.h | 3 + swad_language.c | 79 ++ swad_language.h | 3 + swad_layout.c | 84 ++ swad_layout.h | 3 + swad_menu.c | 81 ++ swad_menu.h | 3 + swad_message.c | 96 ++ swad_message.h | 3 + swad_notice.c | 78 ++ swad_notice.h | 3 + swad_notification.c | 166 +++ swad_notification.h | 3 + swad_privacy.c | 110 ++ swad_privacy.h | 3 + swad_program.c | 55 + swad_program.h | 3 + swad_project.c | 55 + swad_project.h | 3 + swad_survey.c | 72 ++ swad_survey.h | 3 + swad_test.c | 147 +++ swad_test.h | 3 + swad_theme.c | 85 ++ swad_theme.h | 3 + swad_timeline.c | 157 +++ swad_timeline.h | 3 + 52 files changed, 2943 insertions(+), 2895 deletions(-) diff --git a/swad_agenda.c b/swad_agenda.c index c39c6181..40c59543 100644 --- a/swad_agenda.c +++ b/swad_agenda.c @@ -39,6 +39,7 @@ #include "swad_database.h" #include "swad_date.h" #include "swad_error.h" +#include "swad_figure.h" #include "swad_form.h" #include "swad_global.h" #include "swad_group.h" @@ -1659,3 +1660,71 @@ void Agd_PrintAgdQRCode (void) /***** End box *****/ Box_BoxEnd (); } + +/*****************************************************************************/ +/********* Get and show number of users who have chosen a language ***********/ +/*****************************************************************************/ + +void Agd_GetAndShowAgendasStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_agendas; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Number_of_events; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + extern const char *Txt_Number_of_events_per_user; + unsigned NumEvents; + unsigned NumUsrs; + unsigned NumUsrsTotal; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_AGENDAS], + NULL,NULL, + Hlp_ANALYTICS_Figures_agendas,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Number_of_events ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_events_per_user,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Number of agenda events *****/ + NumEvents = Agd_DB_GetNumEvents (Gbl.Scope.Current); + + /***** Number of users with agenda events *****/ + NumUsrs = Agd_DB_GetNumUsrsWithEvents (Gbl.Scope.Current); + + /***** Get total number of users in current scope *****/ + NumUsrsTotal = Usr_GetTotalNumberOfUsers (); + + /***** Write number of users who have chosen each language *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumEvents); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs * 100.0 / + (double) NumUsrsTotal : + 0); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumUsrs ? (double) NumEvents / + (double) NumUsrs : + 0); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_agenda.h b/swad_agenda.h index a90dc56e..a04aaee0 100644 --- a/swad_agenda.h +++ b/swad_agenda.h @@ -136,4 +136,7 @@ void Agd_ReceiveFormEvent (void); void Agd_PrintAgdQRCode (void); +//-------------------------------- Figures ------------------------------------ +void Agd_GetAndShowAgendasStats (void); + #endif diff --git a/swad_assignment.c b/swad_assignment.c index 23468d08..e91d7ea1 100644 --- a/swad_assignment.c +++ b/swad_assignment.c @@ -1636,3 +1636,65 @@ unsigned Asg_GetNumAssignments (HieLvl_Level_t Scope,unsigned *NumNotif) return NumAssignments; } + +/*****************************************************************************/ +/************************ Show stats about assignments ***********************/ +/*****************************************************************************/ + +void Asg_GetAndShowAssignmentsStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_assignments; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Number_of_BR_assignments; + extern const char *Txt_Number_of_BR_courses_with_BR_assignments; + extern const char *Txt_Average_number_BR_of_ASSIG_BR_per_course; + extern const char *Txt_Number_of_BR_notifications; + unsigned NumAssignments; + unsigned NumNotif; + unsigned NumCoursesWithAssignments = 0; + double NumAssignmentsPerCourse = 0.0; + + /***** Get the number of assignments from this location *****/ + if ((NumAssignments = Asg_GetNumAssignments (Gbl.Scope.Current,&NumNotif))) + if ((NumCoursesWithAssignments = Asg_DB_GetNumCoursesWithAssignments (Gbl.Scope.Current)) != 0) + NumAssignmentsPerCourse = (double) NumAssignments / + (double) NumCoursesWithAssignments; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_ASSIGNMENTS], + NULL,NULL, + Hlp_ANALYTICS_Figures_assignments,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Number_of_BR_assignments ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_courses_with_BR_assignments,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_number_BR_of_ASSIG_BR_per_course,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_notifications ,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Write number of assignments *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumAssignments); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumCoursesWithAssignments); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumAssignmentsPerCourse); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumNotif); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_assignment.h b/swad_assignment.h index 52f4ad86..d155d9b7 100644 --- a/swad_assignment.h +++ b/swad_assignment.h @@ -100,4 +100,7 @@ void Asg_RemoveCrsAssignments (long CrsCod); unsigned Asg_GetNumAssignments (HieLvl_Level_t Scope,unsigned *NumNotif); +//-------------------------------- Figures ------------------------------------ +void Asg_GetAndShowAssignmentsStats (void); + #endif diff --git a/swad_browser.c b/swad_browser.c index 474e3dc5..12a067d4 100644 --- a/swad_browser.c +++ b/swad_browser.c @@ -1335,6 +1335,24 @@ static void Brw_RemoveFileFromDiskAndDB (const char Path[PATH_MAX + 1], static int Brw_RemoveFolderFromDiskAndDB (const char Path[PATH_MAX + 1], const char FullPathInTree[PATH_MAX + 1]); +static void Brw_GetSizeOfFileZone (Brw_FileBrowser_t FileBrowser, + struct Brw_SizeOfFileZones *SizeOfFileZones); +static void Brw_WriteStatsFileZonesTableHead1 (void); +static void Brw_WriteStatsFileZonesTableHead2 (void); +static void Brw_WriteStatsFileZonesTableHead3 (void); +static void Brw_WriteRowStatsFileBrowsers1 (const char *NameOfFileZones, + Brw_FileBrowser_t FileZone, + struct Brw_SizeOfFileZones *SizeOfFileZones); +static void Brw_WriteRowStatsFileBrowsers2 (const char *NameOfFileZones, + Brw_FileBrowser_t FileZone, + struct Brw_SizeOfFileZones *SizeOfFileZones); +static void Brw_WriteRowStatsFileBrowsers3 (const char *NameOfFileZones, + Brw_FileBrowser_t FileZone, + struct Brw_SizeOfFileZones *SizeOfFileZones); + +static void Brw_GetNumberOfOERs (Brw_License_t License, + unsigned long NumFiles[2]); + /*****************************************************************************/ /***************** Get parameters related to file browser ********************/ /*****************************************************************************/ @@ -10430,3 +10448,553 @@ Act_Action_t Brw_GetActionContract (void) { return Brw_ActContractFolder[Gbl.FileBrowser.Type]; } + + +/*****************************************************************************/ +/********************* Show stats about exploration trees ********************/ +/*****************************************************************************/ +// TODO: add links to statistic + +void Brw_GetAndShowFileBrowsersStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_folders_and_files; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_STAT_COURSE_FILE_ZONES[Fig_NUM_STAT_CRS_FILE_ZONES]; + static const Brw_FileBrowser_t StatCrsFileZones[Fig_NUM_STAT_CRS_FILE_ZONES] = + { + Brw_ADMI_DOC_CRS, + Brw_ADMI_DOC_GRP, + Brw_ADMI_TCH_CRS, + Brw_ADMI_TCH_GRP, + Brw_ADMI_SHR_CRS, + Brw_ADMI_SHR_GRP, + Brw_ADMI_MRK_CRS, + Brw_ADMI_MRK_GRP, + Brw_ADMI_ASG_USR, + Brw_ADMI_WRK_USR, + Brw_UNKNOWN, + Brw_ADMI_BRF_USR, + }; + struct Brw_SizeOfFileZones SizeOfFileZones[Fig_NUM_STAT_CRS_FILE_ZONES]; + unsigned NumStat; + + /***** Get sizes of all file zones *****/ + for (NumStat = 0; + NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; + NumStat++) + Brw_GetSizeOfFileZone (StatCrsFileZones[NumStat], + &SizeOfFileZones[NumStat]); + + /***** Begin box *****/ + Box_BoxBegin (NULL,Txt_FIGURE_TYPES[Fig_FOLDERS_AND_FILES], + NULL,NULL, + Hlp_ANALYTICS_Figures_folders_and_files,Box_NOT_CLOSABLE); + + /***** Write sizes of all file zones *****/ + HTM_TABLE_BeginCenterPadding (2); + Brw_WriteStatsFileZonesTableHead1 (); + for (NumStat = 0; + NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; + NumStat++) + Brw_WriteRowStatsFileBrowsers1 (Txt_STAT_COURSE_FILE_ZONES[NumStat], + StatCrsFileZones[NumStat], + &SizeOfFileZones[NumStat]); + HTM_TABLE_End (); + + /***** Write sizes of all file zones per course *****/ + HTM_TABLE_BeginCenterPadding (2); + Brw_WriteStatsFileZonesTableHead2 (); + for (NumStat = 0; + NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; + NumStat++) + Brw_WriteRowStatsFileBrowsers2 (Txt_STAT_COURSE_FILE_ZONES[NumStat], + StatCrsFileZones[NumStat], + &SizeOfFileZones[NumStat]); + HTM_TABLE_End (); + + /***** Write sizes of all file zones per user *****/ + HTM_TABLE_BeginCenterPadding (2); + Brw_WriteStatsFileZonesTableHead3 (); + for (NumStat = 0; + NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; + NumStat++) + Brw_WriteRowStatsFileBrowsers3 (Txt_STAT_COURSE_FILE_ZONES[NumStat], + StatCrsFileZones[NumStat], + &SizeOfFileZones[NumStat]); + HTM_TABLE_End (); + + /***** End box *****/ + Box_BoxEnd (); + } + +/*****************************************************************************/ +/**************** Get the size of a file zone from database ******************/ +/*****************************************************************************/ + +static void Brw_GetSizeOfFileZone (Brw_FileBrowser_t FileBrowser, + struct Brw_SizeOfFileZones *SizeOfFileZones) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + + /***** Get the size of a file browser *****/ + /* Query database */ + Brw_DB_GetSizeOfFileBrowser (&mysql_res,FileBrowser); + + /* Get row */ + row = mysql_fetch_row (mysql_res); + + /* Reset default values to zero */ + SizeOfFileZones->NumCrss = + SizeOfFileZones->NumUsrs = 0; + SizeOfFileZones->MaxLevels = 0; + SizeOfFileZones->NumFolders = + SizeOfFileZones->NumFiles = 0; + SizeOfFileZones->Size = 0; + + /* Get number of courses (row[0]) */ + if (row[0]) + if (sscanf (row[0],"%d",&(SizeOfFileZones->NumCrss)) != 1) + Err_ShowErrorAndExit ("Error when getting number of courses."); + + /* Get number of groups (row[1]) */ + if (row[1]) + if (sscanf (row[1],"%d",&(SizeOfFileZones->NumGrps)) != 1) + Err_ShowErrorAndExit ("Error when getting number of groups."); + + /* Get number of users (row[2]) */ + if (row[2]) + if (sscanf (row[2],"%d",&(SizeOfFileZones->NumUsrs)) != 1) + Err_ShowErrorAndExit ("Error when getting number of users."); + + /* Get maximum number of levels (row[3]) */ + if (row[3]) + if (sscanf (row[3],"%u",&(SizeOfFileZones->MaxLevels)) != 1) + Err_ShowErrorAndExit ("Error when getting maximum number of levels."); + + /* Get number of folders (row[4]) */ + if (row[4]) + if (sscanf (row[4],"%lu",&(SizeOfFileZones->NumFolders)) != 1) + Err_ShowErrorAndExit ("Error when getting number of folders."); + + /* Get number of files (row[5]) */ + if (row[5]) + if (sscanf (row[5],"%lu",&(SizeOfFileZones->NumFiles)) != 1) + Err_ShowErrorAndExit ("Error when getting number of files."); + + /* Get total size (row[6]) */ + if (row[6]) + if (sscanf (row[6],"%llu",&(SizeOfFileZones->Size)) != 1) + Err_ShowErrorAndExit ("Error when getting toal size."); + + /* Free structure that stores the query result */ + DB_FreeMySQLResult (&mysql_res); + } + +/*****************************************************************************/ +/*************** Write table heading for stats of file zones *****************/ +/*****************************************************************************/ + +static void Brw_WriteStatsFileZonesTableHead1 (void) + { + extern const char *Txt_File_zones; + extern const char *Txt_Courses; + extern const char *Txt_Groups; + extern const char *Txt_Users; + extern const char *Txt_Max_levels; + extern const char *Txt_Folders; + extern const char *Txt_Files; + extern const char *Txt_Size; + + HTM_TR_Begin (NULL); + HTM_TH (Txt_File_zones,HTM_HEAD_LEFT); + HTM_TH (Txt_Courses ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Groups ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Max_levels,HTM_HEAD_RIGHT); + HTM_TH (Txt_Folders ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Files ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Size ,HTM_HEAD_RIGHT); + HTM_TR_End (); + } + +static void Brw_WriteStatsFileZonesTableHead2 (void) + { + extern const char *Txt_File_zones; + extern const char *Txt_Folders; + extern const char *Txt_Files; + extern const char *Txt_Size; + extern const char *Txt_course; + + HTM_TR_Begin (NULL); + + HTM_TH (Txt_File_zones,HTM_HEAD_LEFT); + + HTM_TH_Begin (HTM_HEAD_RIGHT); + HTM_TxtF ("%s/",Txt_Folders); + HTM_BR (); + HTM_Txt (Txt_course); + HTM_TH_End (); + + HTM_TH_Begin (HTM_HEAD_RIGHT); + HTM_TxtF ("%s/",Txt_Files); + HTM_BR (); + HTM_Txt (Txt_course); + HTM_TH_End (); + + HTM_TH_Begin (HTM_HEAD_RIGHT); + HTM_TxtF ("%s/",Txt_Size); + HTM_BR (); + HTM_Txt (Txt_course); + HTM_TH_End (); + + HTM_TR_End (); + } + +static void Brw_WriteStatsFileZonesTableHead3 (void) + { + extern const char *Txt_File_zones; + extern const char *Txt_Folders; + extern const char *Txt_Files; + extern const char *Txt_Size; + extern const char *Txt_user[Usr_NUM_SEXS]; + + HTM_TR_Begin (NULL); + + HTM_TH (Txt_File_zones,HTM_HEAD_LEFT); + + HTM_TH_Begin (HTM_HEAD_RIGHT); + HTM_TxtF ("%s/",Txt_Folders); + HTM_BR (); + HTM_Txt (Txt_user[Usr_SEX_UNKNOWN]); + HTM_TH_End (); + + HTM_TH_Begin (HTM_HEAD_RIGHT); + HTM_TxtF ("%s/",Txt_Files); + HTM_BR (); + HTM_Txt (Txt_user[Usr_SEX_UNKNOWN]); + HTM_TH_End (); + + HTM_TH_Begin (HTM_HEAD_RIGHT); + HTM_TxtF ("%s/",Txt_Size); + HTM_BR (); + HTM_Txt (Txt_user[Usr_SEX_UNKNOWN]); + HTM_TH_End (); + + HTM_TR_End (); + } + +/*****************************************************************************/ +/*************** Write a row of stats of exploration trees *******************/ +/*****************************************************************************/ + +static void Brw_WriteRowStatsFileBrowsers1 (const char *NameOfFileZones, + Brw_FileBrowser_t FileZone, + struct Brw_SizeOfFileZones *SizeOfFileZones) + { + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *The_ClassDatStrong[The_NUM_THEMES]; + char StrNumCrss[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; + char StrNumGrps[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; + char StrNumUsrs[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; + char FileSizeStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; + char *Cl; + const char *Class; + + if (FileZone == Brw_UNKNOWN) + { + if (asprintf (&Cl,"%s LINE_TOP",The_ClassDatStrong[Gbl.Prefs.Theme]) < 0) + Err_NotEnoughMemoryExit (); + Class = Cl; + } + else + Class = The_ClassDat[Gbl.Prefs.Theme]; + + Fil_WriteFileSizeFull ((double) SizeOfFileZones->Size,FileSizeStr); + + if (SizeOfFileZones->NumCrss == -1) // Not applicable + Str_Copy (StrNumCrss,"-",sizeof (StrNumCrss) - 1); + else + snprintf (StrNumCrss,sizeof (StrNumCrss),"%d", + SizeOfFileZones->NumCrss); + + if (SizeOfFileZones->NumGrps == -1) // Not applicable + Str_Copy (StrNumGrps,"-",sizeof (StrNumGrps) - 1); + else + snprintf (StrNumGrps,sizeof (StrNumGrps),"%d", + SizeOfFileZones->NumGrps); + + if (SizeOfFileZones->NumUsrs == -1) // Not applicable + Str_Copy (StrNumUsrs,"-",sizeof (StrNumUsrs) - 1); + else + snprintf (StrNumUsrs,sizeof (StrNumUsrs),"%d", + SizeOfFileZones->NumUsrs); + + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",Class); + HTM_Txt (NameOfFileZones); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Txt (StrNumCrss); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Txt (StrNumGrps); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Txt (StrNumUsrs); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Unsigned (SizeOfFileZones->MaxLevels); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_UnsignedLong (SizeOfFileZones->NumFolders); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_UnsignedLong (SizeOfFileZones->NumFiles); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Txt (FileSizeStr); + HTM_TD_End (); + + HTM_TR_End (); + + if (FileZone == Brw_UNKNOWN) + free (Cl); + } + +static void Brw_WriteRowStatsFileBrowsers2 (const char *NameOfFileZones, + Brw_FileBrowser_t FileZone, + struct Brw_SizeOfFileZones *SizeOfFileZones) + { + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *The_ClassDatStrong[The_NUM_THEMES]; + char StrNumFoldersPerCrs[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; + char StrNumFilesPerCrs[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; + char FileSizePerCrsStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; + char *Cl; + const char *Class; + + if (FileZone == Brw_UNKNOWN) + { + if (asprintf (&Cl,"%s LINE_TOP",The_ClassDatStrong[Gbl.Prefs.Theme]) < 0) + Err_NotEnoughMemoryExit (); + Class = Cl; + } + else + Class = The_ClassDat[Gbl.Prefs.Theme]; + + if (SizeOfFileZones->NumCrss == -1) // Not applicable + { + Str_Copy (StrNumFoldersPerCrs,"-",sizeof (StrNumFoldersPerCrs) - 1); + Str_Copy (StrNumFilesPerCrs ,"-",sizeof (StrNumFilesPerCrs ) - 1); + Str_Copy (FileSizePerCrsStr ,"-",sizeof (FileSizePerCrsStr ) - 1); + } + else + { + snprintf (StrNumFoldersPerCrs,sizeof (StrNumFoldersPerCrs),"%.1f", + SizeOfFileZones->NumCrss ? (double) SizeOfFileZones->NumFolders / + (double) SizeOfFileZones->NumCrss : + 0.0); + snprintf (StrNumFilesPerCrs,sizeof (StrNumFilesPerCrs),"%.1f", + SizeOfFileZones->NumCrss ? (double) SizeOfFileZones->NumFiles / + (double) SizeOfFileZones->NumCrss : + 0.0); + Fil_WriteFileSizeFull (SizeOfFileZones->NumCrss ? (double) SizeOfFileZones->Size / + (double) SizeOfFileZones->NumCrss : + 0.0, + FileSizePerCrsStr); + } + + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",Class); + HTM_Txt (NameOfFileZones); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Txt (StrNumFoldersPerCrs); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Txt (StrNumFilesPerCrs); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Txt (FileSizePerCrsStr); + HTM_TD_End (); + + HTM_TR_End (); + + if (FileZone == Brw_UNKNOWN) + free (Cl); + } + +static void Brw_WriteRowStatsFileBrowsers3 (const char *NameOfFileZones, + Brw_FileBrowser_t FileZone, + struct Brw_SizeOfFileZones *SizeOfFileZones) + { + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *The_ClassDatStrong[The_NUM_THEMES]; + char StrNumFoldersPerUsr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; + char StrNumFilesPerUsr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; + char FileSizePerUsrStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; + char *Cl; + const char *Class; + + if (FileZone == Brw_UNKNOWN) + { + if (asprintf (&Cl,"%s LINE_TOP",The_ClassDatStrong[Gbl.Prefs.Theme]) < 0) + Err_NotEnoughMemoryExit (); + Class = Cl; + } + else + Class = The_ClassDat[Gbl.Prefs.Theme]; + + if (SizeOfFileZones->NumUsrs == -1) // Not applicable + { + Str_Copy (StrNumFoldersPerUsr,"-",sizeof (StrNumFoldersPerUsr) - 1); + Str_Copy (StrNumFilesPerUsr ,"-",sizeof (StrNumFilesPerUsr ) - 1); + Str_Copy (FileSizePerUsrStr ,"-",sizeof (FileSizePerUsrStr ) - 1); + } + else + { + snprintf (StrNumFoldersPerUsr,sizeof (StrNumFoldersPerUsr),"%.1f", + SizeOfFileZones->NumUsrs ? (double) SizeOfFileZones->NumFolders / + (double) SizeOfFileZones->NumUsrs : + 0.0); + snprintf (StrNumFilesPerUsr,sizeof (StrNumFilesPerUsr),"%.1f", + SizeOfFileZones->NumUsrs ? (double) SizeOfFileZones->NumFiles / + (double) SizeOfFileZones->NumUsrs : + 0.0); + Fil_WriteFileSizeFull (SizeOfFileZones->NumUsrs ? (double) SizeOfFileZones->Size / + (double) SizeOfFileZones->NumUsrs : + 0.0, + FileSizePerUsrStr); + } + + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",Class); + HTM_Txt (NameOfFileZones); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Txt (StrNumFoldersPerUsr); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Txt (StrNumFilesPerUsr); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",Class); + HTM_Txt (FileSizePerUsrStr); + HTM_TD_End (); + + HTM_TR_End (); + + if (FileZone == Brw_UNKNOWN) + free (Cl); + } + +/*****************************************************************************/ +/************ Show stats about Open Educational Resources (OERs) *************/ +/*****************************************************************************/ + +void Brw_GetAndShowOERsStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_open_educational_resources_oer; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_License; + extern const char *Txt_Number_of_private_files; + extern const char *Txt_Number_of_public_files; + extern const char *Txt_LICENSES[Brw_NUM_LICENSES]; + Brw_License_t License; + unsigned long NumFiles[2]; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_OER], + NULL,NULL, + Hlp_ANALYTICS_Figures_open_educational_resources_oer,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_License ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_private_files,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_public_files ,HTM_HEAD_RIGHT); + HTM_TR_End (); + + for (License = (Brw_License_t) 0; + License <= (Brw_License_t) (Brw_NUM_LICENSES - 1); + License++) + { + Brw_GetNumberOfOERs (License,NumFiles); + + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (Txt_LICENSES[License]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_UnsignedLong (NumFiles[0]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_UnsignedLong (NumFiles[1]); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** End table and box *****/ + Box_BoxTableEnd (); + } + +/*****************************************************************************/ +/**************** Get the size of a file zone from database ******************/ +/*****************************************************************************/ + +static void Brw_GetNumberOfOERs (Brw_License_t License, + unsigned long NumFiles[2]) + { + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumRows = 0; // Initialized to avoid warning + unsigned NumRow; + unsigned Public; + + /***** Get the size of a file browser *****/ + /* Query database */ + NumRows = Brw_DB_GetNumberOfPublicFiles (&mysql_res,License); + + /* Reset values to zero */ + NumFiles[0] = NumFiles[1] = 0L; + + for (NumRow = 0; + NumRow < NumRows; + NumRow++) + { + /* Get row */ + row = mysql_fetch_row (mysql_res); + + /* Get if public (row[0]) */ + Public = (row[0][0] == 'Y') ? 1 : + 0; + + /* Get number of files (row[1]) */ + if (sscanf (row[1],"%lu",&NumFiles[Public]) != 1) + Err_ShowErrorAndExit ("Error when getting number of files."); + } + + /* Free structure that stores the query result */ + DB_FreeMySQLResult (&mysql_res); + } diff --git a/swad_browser.h b/swad_browser.h index 310eae15..75330c4b 100644 --- a/swad_browser.h +++ b/swad_browser.h @@ -147,6 +147,17 @@ struct FileMetadata unsigned NumLoggedUsrs; }; +struct Brw_SizeOfFileZones + { + int NumCrss; // -1 stands for not aplicable + int NumGrps; // -1 stands for not aplicable + int NumUsrs; // -1 stands for not aplicable + unsigned MaxLevels; + unsigned long NumFolders; + unsigned long NumFiles; + unsigned long long int Size; // Total size in bytes + }; + /*****************************************************************************/ /****************************** Public constants *****************************/ /*****************************************************************************/ @@ -266,4 +277,8 @@ void Brw_RemoveOldFilesBriefcase (void); Act_Action_t Brw_GetActionExpand (void); Act_Action_t Brw_GetActionContract (void); +//-------------------------------- Figures ------------------------------------ +void Brw_GetAndShowFileBrowsersStats (void); +void Brw_GetAndShowOERsStats (void); + #endif diff --git a/swad_calendar.c b/swad_calendar.c index 1daf5666..e12a9a26 100644 --- a/swad_calendar.c +++ b/swad_calendar.c @@ -43,6 +43,7 @@ #include "swad_parameter.h" #include "swad_setting.h" #include "swad_setting_database.h" +#include "swad_user_database.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -332,3 +333,91 @@ void Cal_PutIconToSeeCalendar (__attribute__((unused)) void *Args) "calendar.svg",Ico_BLACK, Txt_Calendar); } + +/*****************************************************************************/ +/***** Get and show number of users who have chosen a first day of week ******/ +/*****************************************************************************/ + +void Cal_GetAndShowNumUsrsPerFirstDayOfWeek (void) + { + extern const bool Cal_DayIsValidAsFirstDayOfWeek[7]; + extern const char *Hlp_ANALYTICS_Figures_calendar; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Calendar; + extern const char *Txt_First_day_of_the_week_X; + extern const char *Txt_DAYS_SMALL[7]; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + unsigned FirstDayOfWeek; + char *SubQuery; + char *Icon; + char *Title; + unsigned NumUsrs[7]; // 7: seven days in a week + unsigned NumUsrsTotal = 0; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_FIRST_DAY_OF_WEEK], + NULL,NULL, + Hlp_ANALYTICS_Figures_calendar,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Calendar ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** For each day... *****/ + for (FirstDayOfWeek = 0; // Monday + FirstDayOfWeek <= 6; // Sunday + FirstDayOfWeek++) + if (Cal_DayIsValidAsFirstDayOfWeek[FirstDayOfWeek]) + { + /* Get number of users who have chosen this first day of week from database */ + if (asprintf (&SubQuery,"usr_data.FirstDayOfWeek=%u", + (unsigned) FirstDayOfWeek) < 0) + Err_NotEnoughMemoryExit (); + NumUsrs[FirstDayOfWeek] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); + free (SubQuery); + + /* Update total number of users */ + NumUsrsTotal += NumUsrs[FirstDayOfWeek]; + } + + /***** Write number of users who have chosen each first day of week *****/ + for (FirstDayOfWeek = 0; // Monday + FirstDayOfWeek <= 6; // Sunday + FirstDayOfWeek++) + if (Cal_DayIsValidAsFirstDayOfWeek[FirstDayOfWeek]) + { + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"CM\""); + if (asprintf (&Icon,"first-day-of-week-%u.png", + FirstDayOfWeek) < 0) + Err_NotEnoughMemoryExit (); + if (asprintf (&Title,Txt_First_day_of_the_week_X, + Txt_DAYS_SMALL[FirstDayOfWeek]) < 0) + Err_NotEnoughMemoryExit (); + Ico_PutIcon (Icon,Ico_BLACK,Title,"ICOx20"); + free (Title); + free (Icon); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs[FirstDayOfWeek]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[FirstDayOfWeek] * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_calendar.h b/swad_calendar.h index dc5b2adf..37f7d474 100644 --- a/swad_calendar.h +++ b/swad_calendar.h @@ -52,4 +52,7 @@ void Cal_PrintCalendar (void); void Cal_PutIconToSeeCalendar (__attribute__((unused)) void *Args); +//-------------------------------- Figures ------------------------------------ +void Cal_GetAndShowNumUsrsPerFirstDayOfWeek (void); + #endif diff --git a/swad_changelog.h b/swad_changelog.h index e4826c0a..33a1ae6c 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -602,10 +602,11 @@ 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. */ -#define Log_PLATFORM_VERSION "SWAD 21.81.2 (2022-01-02)" +#define Log_PLATFORM_VERSION "SWAD 21.82 (2022-01-03)" #define CSS_FILE "swad21.81.css" #define JS_FILE "swad21.78.2.js" /* + Version 21.82: Jan 03, 2022 Functions moved from swad_figure to other modules. (322550 lines) Version 21.81.2: Jan 02, 2022 Functions moved from swad_figure to other modules. (322523 lines) Version 21.81.1: Jan 02, 2022 Fixed bug in projects. (322460 lines) Version 21.81: Jan 02, 2022 Code refactoring on table heads. (322457 lines) diff --git a/swad_cookie.c b/swad_cookie.c index c41cdcc6..ea4f2297 100644 --- a/swad_cookie.c +++ b/swad_cookie.c @@ -25,16 +25,21 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ +#define _GNU_SOURCE // For asprintf +#include // For asprintf + #include "swad_box.h" #include "swad_cookie.h" #include "swad_cookie_database.h" #include "swad_database.h" +#include "swad_error.h" #include "swad_figure.h" #include "swad_form.h" #include "swad_global.h" #include "swad_HTML.h" #include "swad_layout.h" #include "swad_setting.h" +#include "swad_user_database.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -128,3 +133,88 @@ void Coo_ChangeMyPrefsCookies (void) /***** Show forms again *****/ Set_EditSettings (); } + +/*****************************************************************************/ +/** Get and show number of users who have chosen a preference about cookies **/ +/*****************************************************************************/ + +void Coo_GetAndShowNumUsrsPerCookies (void) + { + extern const char *Hlp_ANALYTICS_Figures_cookies; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Cookies; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + static const struct + { + char InDB; + char *Icon; + Ico_Color_t Color; + char *Title; + } Accepted[2] = + { + [false] = {'N',"times.svg",Ico_RED ,"Don't accept third party cookies"}, // TODO: Need translation!!!! + [true ] = {'Y',"check.svg",Ico_GREEN,"Accept third party cookies"} // TODO: Need translation!!!! + }; + unsigned i; + char *SubQuery; + unsigned NumUsrs[Mnu_NUM_MENUS]; + unsigned NumUsrsTotal = 0; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_COOKIES], + NULL,NULL, + Hlp_ANALYTICS_Figures_cookies,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Cookies ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** For each option... *****/ + for (i = 0; + i < 2; + i++) + { + /* Get number of users who have chosen this menu from database */ + if (asprintf (&SubQuery,"usr_data.ThirdPartyCookies='%c'", + Accepted[i].InDB) < 0) + Err_NotEnoughMemoryExit (); + NumUsrs[i] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); + free (SubQuery); + + /* Update total number of users */ + NumUsrsTotal += NumUsrs[i]; + } + + /***** Write number of users who have chosen each option *****/ + for (i = 0; + i < 2; + i++) + { + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"CM\""); + Ico_PutIcon (Accepted[i].Icon,Accepted[i].Color, + Accepted[i].Title,"ICOx16"); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs[i]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[i] * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_cookie.h b/swad_cookie.h index 09f56581..5c359cae 100644 --- a/swad_cookie.h +++ b/swad_cookie.h @@ -36,4 +36,7 @@ void Coo_EditMyPrefsOnCookies (void); void Coo_ChangeMyPrefsCookies (void); +//-------------------------------- Figures ------------------------------------ +void Coo_GetAndShowNumUsrsPerCookies (void); + #endif diff --git a/swad_date.c b/swad_date.c index 821ca60f..94ccc289 100644 --- a/swad_date.c +++ b/swad_date.c @@ -44,6 +44,7 @@ #include "swad_parameter.h" #include "swad_setting.h" #include "swad_setting_database.h" +#include "swad_user_database.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -1743,3 +1744,78 @@ void Dat_PutHiddenParamOrder (Dat_StartEndTime_t SelectedOrder) { Par_PutHiddenParamUnsigned (NULL,"Order",(unsigned) SelectedOrder); } + +/*****************************************************************************/ +/******** Get and show number of users who have chosen a date format *********/ +/*****************************************************************************/ + +void Dat_GetAndShowNumUsrsPerDateFormat (void) + { + extern const char *Hlp_ANALYTICS_Figures_dates; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *The_ClassDatStrong[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Format; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + unsigned Format; + char *SubQuery; + unsigned NumUsrs[Dat_NUM_OPTIONS_FORMAT]; + unsigned NumUsrsTotal = 0; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_DATE_FORMAT], + NULL,NULL, + Hlp_ANALYTICS_Figures_dates,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Format ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** For each format... *****/ + for (Format = (Dat_Format_t) 0; + Format <= (Dat_Format_t) (Dat_NUM_OPTIONS_FORMAT - 1); + Format++) + { + /* Get number of users who have chosen this date format from database */ + if (asprintf (&SubQuery,"usr_data.DateFormat=%u", + (unsigned) Format) < 0) + Err_NotEnoughMemoryExit (); + NumUsrs[Format] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); + free (SubQuery); + + /* Update total number of users */ + NumUsrsTotal += NumUsrs[Format]; + } + + /***** Write number of users who have chosen each date format *****/ + for (Format = (Dat_Format_t) 0; + Format <= (Dat_Format_t) (Dat_NUM_OPTIONS_FORMAT - 1); + Format++) + { + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"LM %s\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + Dat_PutSpanDateFormat (Format); + Dat_PutScriptDateFormat (Format); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs[Format]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[Format] * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_date.h b/swad_date.h index d7de8d7b..f93cee73 100644 --- a/swad_date.h +++ b/swad_date.h @@ -213,4 +213,7 @@ void Dat_WriteLocalDateHMSFromUTC (const char *Id,time_t TimeUTC, void Dat_PutHiddenParamOrder (Dat_StartEndTime_t SelectedOrder); +//-------------------------------- Figures ------------------------------------ +void Dat_GetAndShowNumUsrsPerDateFormat (void); + #endif diff --git a/swad_degree_type.c b/swad_degree_type.c index 39820fd5..012b2f20 100644 --- a/swad_degree_type.c +++ b/swad_degree_type.c @@ -132,7 +132,7 @@ void DegTyp_WriteSelectorDegreeTypes (long SelectedDegTypCod) void DegTyp_SeeDegreeTypesInDegTab (void) { DegTyp_SeeDegreeTypes (ActSeeDegTyp,HieLvl_SYS, - DegTyp_ORDER_BY_DEGREE_TYPE); // Default order if not specified + DegTyp_ORDER_BY_DEGREE_TYPE); // Default order if not specified } void DegTyp_SeeDegreeTypesInStaTab (void) @@ -912,3 +912,13 @@ static void DegTyp_EditingDegreeTypeDestructor (void) DegTyp_EditingDegTyp = NULL; } } + +/*****************************************************************************/ +/****************** Get and show stats about institutions ********************/ +/*****************************************************************************/ + +void DegTyp_GetAndShowDegreeTypesStats (void) + { + /***** Show statistic about number of degrees in each type of degree *****/ + DegTyp_SeeDegreeTypesInStaTab (); + } diff --git a/swad_degree_type.h b/swad_degree_type.h index 9b1dd648..55c9f79d 100644 --- a/swad_degree_type.h +++ b/swad_degree_type.h @@ -82,4 +82,7 @@ void DegTyp_RenameDegreeType (void); void DegTyp_ContEditAfterChgDegTyp (void); +//-------------------------------- Figures ------------------------------------ +void DegTyp_GetAndShowDegreeTypesStats (void); + #endif diff --git a/swad_exam.c b/swad_exam.c index 68becb0e..4552878c 100644 --- a/swad_exam.c +++ b/swad_exam.c @@ -1581,3 +1581,57 @@ bool Exa_CheckIfEditable (const struct Exa_Exam *Exam) else return false; // Questions are not editable } + +/*****************************************************************************/ +/*************************** Show stats about exams **************************/ +/*****************************************************************************/ + +void Exa_GetAndShowExamsStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_exams; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Number_of_BR_exams; + extern const char *Txt_Number_of_BR_courses_with_BR_exams; + extern const char *Txt_Average_number_BR_of_exams_BR_per_course; + unsigned NumExams; + unsigned NumCoursesWithExams = 0; + double NumExamsPerCourse = 0.0; + + /***** Get the number of exams from this location *****/ + if ((NumExams = Exa_DB_GetNumExams (Gbl.Scope.Current))) + if ((NumCoursesWithExams = Exa_DB_GetNumCoursesWithExams (Gbl.Scope.Current)) != 0) + NumExamsPerCourse = (double) NumExams / (double) NumCoursesWithExams; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_EXAMS], + NULL,NULL, + Hlp_ANALYTICS_Figures_exams,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Number_of_BR_exams ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_courses_with_BR_exams ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_number_BR_of_exams_BR_per_course,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Write number of exams *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumExams); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumCoursesWithExams); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumExamsPerCourse); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_exam.h b/swad_exam.h index c78cc1ce..36a52b79 100644 --- a/swad_exam.h +++ b/swad_exam.h @@ -84,4 +84,7 @@ void Exa_ReceiveFormExam (void); bool Exa_CheckIfEditable (const struct Exa_Exam *Exam); +//-------------------------------- Figures ------------------------------------ +void Exa_GetAndShowExamsStats (void); + #endif diff --git a/swad_figure.c b/swad_figure.c index 4947917f..97eb7347 100644 --- a/swad_figure.c +++ b/swad_figure.c @@ -25,54 +25,28 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ -#define _GNU_SOURCE // For asprintf -#include // For asprintf -#include // For system, getenv, etc. -#include // For string functions - #include "swad_action.h" -#include "swad_agenda_database.h" -#include "swad_assignment_database.h" +#include "swad_agenda.h" #include "swad_box.h" -#include "swad_browser_database.h" -#include "swad_database.h" -#include "swad_error.h" -#include "swad_exam_database.h" +#include "swad_calendar.h" +#include "swad_cookie.h" +#include "swad_exam.h" #include "swad_figure.h" -#include "swad_figure_cache.h" #include "swad_follow.h" -#include "swad_follow_database.h" #include "swad_form.h" -#include "swad_forum.h" -#include "swad_forum_database.h" -#include "swad_game_database.h" #include "swad_global.h" #include "swad_hierarchy.h" -#include "swad_hierarchy_level.h" #include "swad_HTML.h" -#include "swad_institution.h" -#include "swad_institution_database.h" -#include "swad_logo.h" #include "swad_message.h" -#include "swad_message_database.h" #include "swad_network.h" #include "swad_notice.h" -#include "swad_notification_database.h" #include "swad_privacy.h" -#include "swad_profile.h" #include "swad_program.h" -#include "swad_program_database.h" #include "swad_project.h" -#include "swad_project_database.h" -#include "swad_role.h" -#include "swad_setting.h" #include "swad_survey.h" -#include "swad_survey_database.h" #include "swad_test.h" +#include "swad_theme.h" #include "swad_timeline.h" -#include "swad_timeline_database.h" -#include "swad_timeline_note.h" -#include "swad_user_database.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -80,29 +54,6 @@ extern struct Globals Gbl; -/*****************************************************************************/ -/******************************* Private types *******************************/ -/*****************************************************************************/ - -struct Fig_SizeOfFileZones - { - int NumCrss; // -1 stands for not aplicable - int NumGrps; // -1 stands for not aplicable - int NumUsrs; // -1 stands for not aplicable - unsigned MaxLevels; - unsigned long NumFolders; - unsigned long NumFiles; - unsigned long long int Size; // Total size in bytes - }; - -struct Fig_FiguresForum - { - unsigned NumForums; - unsigned NumThreads; - unsigned NumPosts; - unsigned NumUsrsToBeNotifiedByEMail; - }; - /*****************************************************************************/ /****************************** Private prototypes ***************************/ /*****************************************************************************/ @@ -112,69 +63,6 @@ static void Fig_ReqShowFigure (Fig_FigureType_t SelectedFigureType); static void Fig_PutHiddenParamFigureType (Fig_FigureType_t FigureType); static void Fig_PutHiddenParamScopeFig (HieLvl_Level_t ScopeFig); -static void DegTyp_GetAndShowDegreeTypesStats (void); - -static void Brw_GetAndShowFileBrowsersStats (void); -static void Fig_GetSizeOfFileZone (Brw_FileBrowser_t FileBrowser, - struct Fig_SizeOfFileZones *SizeOfFileZones); -static void Fig_WriteStatsExpTreesTableHead1 (void); -static void Fig_WriteStatsExpTreesTableHead2 (void); -static void Fig_WriteStatsExpTreesTableHead3 (void); -static void Fig_WriteRowStatsFileBrowsers1 (const char *NameOfFileZones, - Brw_FileBrowser_t FileZone, - struct Fig_SizeOfFileZones *SizeOfFileZones); -static void Fig_WriteRowStatsFileBrowsers2 (const char *NameOfFileZones, - Brw_FileBrowser_t FileZone, - struct Fig_SizeOfFileZones *SizeOfFileZones); -static void Fig_WriteRowStatsFileBrowsers3 (const char *NameOfFileZones, - Brw_FileBrowser_t FileZone, - struct Fig_SizeOfFileZones *SizeOfFileZones); - -static void Brw_GetAndShowOERsStats (void); -static void Fig_GetNumberOfOERs (Brw_License_t License, - unsigned long NumFiles[2]); - -static void Prg_GetAndShowCourseProgramStats (void); // TODO: Change function from assignments to schedule - -static void Asg_GetAndShowAssignmentsStats (void); -static void Prj_GetAndShowProjectsStats (void); -static void Tst_GetAndShowTestsStats (void); -static void Exa_GetAndShowExamsStats (void); -static void Gam_GetAndShowGamesStats (void); - -static void Tml_GetAndShowTimelineActivityStats (void); -static void Fol_GetAndShowFollowStats (void); - -static void For_GetAndShowForumStats (void); -static void Fig_ShowStatOfAForumType (For_ForumType_t ForumType, - long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod, - struct Fig_FiguresForum *FiguresForum); -static void Fig_WriteForumTitleAndStats (For_ForumType_t ForumType, - long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod, - const char *Icon,struct Fig_FiguresForum *FiguresForum, - const char *ForumName1,const char *ForumName2); -static void Fig_WriteForumTotalStats (struct Fig_FiguresForum *FiguresForum); - -static void Ntf_GetAndShowNumUsrsPerNotifyEvent (void); -static void Not_GetAndShowNoticesStats (void); -static void Msg_GetAndShowMsgsStats (void); - -static void Agd_GetAndShowAgendasStats (void); - -static void Svy_GetAndShowSurveysStats (void); -static void Pri_GetAndShowNumUsrsPerPrivacy (void); -static void Fig_GetAndShowNumUsrsPerPrivacyForAnObject (const char *TxtObject, - const char *FieldName, - unsigned MaskAllowedVisibility); -static void Coo_GetAndShowNumUsrsPerCookies (void); -static void Lan_GetAndShowNumUsrsPerLanguage (void); -static void Cal_GetAndShowNumUsrsPerFirstDayOfWeek (void); -static void Dat_GetAndShowNumUsrsPerDateFormat (void); -static void Ico_GetAndShowNumUsrsPerIconSet (void); -static void Mnu_GetAndShowNumUsrsPerMenu (void); -static void The_GetAndShowNumUsrsPerTheme (void); -static void Lay_GetAndShowNumUsrsPerSideColumns (void); - /*****************************************************************************/ /************************** Show use of the platform *************************/ /*****************************************************************************/ @@ -355,2779 +243,3 @@ void Fig_ShowFigures (void) /***** Show the stat of use selected by user *****/ Fig_Function[SelectedFigureType] (); } - -/*****************************************************************************/ -/****************** Get and show stats about institutions ********************/ -/*****************************************************************************/ - -static void DegTyp_GetAndShowDegreeTypesStats (void) - { - /***** Show statistic about number of degrees in each type of degree *****/ - DegTyp_SeeDegreeTypesInStaTab (); - } - -/*****************************************************************************/ -/********************* Show stats about exploration trees ********************/ -/*****************************************************************************/ -// TODO: add links to statistic - -static void Brw_GetAndShowFileBrowsersStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_folders_and_files; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_STAT_COURSE_FILE_ZONES[Fig_NUM_STAT_CRS_FILE_ZONES]; - static const Brw_FileBrowser_t StatCrsFileZones[Fig_NUM_STAT_CRS_FILE_ZONES] = - { - Brw_ADMI_DOC_CRS, - Brw_ADMI_DOC_GRP, - Brw_ADMI_TCH_CRS, - Brw_ADMI_TCH_GRP, - Brw_ADMI_SHR_CRS, - Brw_ADMI_SHR_GRP, - Brw_ADMI_MRK_CRS, - Brw_ADMI_MRK_GRP, - Brw_ADMI_ASG_USR, - Brw_ADMI_WRK_USR, - Brw_UNKNOWN, - Brw_ADMI_BRF_USR, - }; - struct Fig_SizeOfFileZones SizeOfFileZones[Fig_NUM_STAT_CRS_FILE_ZONES]; - unsigned NumStat; - - /***** Get sizes of all file zones *****/ - for (NumStat = 0; - NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; - NumStat++) - Fig_GetSizeOfFileZone (StatCrsFileZones[NumStat], - &SizeOfFileZones[NumStat]); - - /***** Begin box *****/ - Box_BoxBegin (NULL,Txt_FIGURE_TYPES[Fig_FOLDERS_AND_FILES], - NULL,NULL, - Hlp_ANALYTICS_Figures_folders_and_files,Box_NOT_CLOSABLE); - - /***** Write sizes of all file zones *****/ - HTM_TABLE_BeginCenterPadding (2); - Fig_WriteStatsExpTreesTableHead1 (); - for (NumStat = 0; - NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; - NumStat++) - Fig_WriteRowStatsFileBrowsers1 (Txt_STAT_COURSE_FILE_ZONES[NumStat], - StatCrsFileZones[NumStat], - &SizeOfFileZones[NumStat]); - HTM_TABLE_End (); - - /***** Write sizes of all file zones per course *****/ - HTM_TABLE_BeginCenterPadding (2); - Fig_WriteStatsExpTreesTableHead2 (); - for (NumStat = 0; - NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; - NumStat++) - Fig_WriteRowStatsFileBrowsers2 (Txt_STAT_COURSE_FILE_ZONES[NumStat], - StatCrsFileZones[NumStat], - &SizeOfFileZones[NumStat]); - HTM_TABLE_End (); - - /***** Write sizes of all file zones per user *****/ - HTM_TABLE_BeginCenterPadding (2); - Fig_WriteStatsExpTreesTableHead3 (); - for (NumStat = 0; - NumStat < Fig_NUM_STAT_CRS_FILE_ZONES; - NumStat++) - Fig_WriteRowStatsFileBrowsers3 (Txt_STAT_COURSE_FILE_ZONES[NumStat], - StatCrsFileZones[NumStat], - &SizeOfFileZones[NumStat]); - HTM_TABLE_End (); - - /***** End box *****/ - Box_BoxEnd (); - } - -/*****************************************************************************/ -/**************** Get the size of a file zone from database ******************/ -/*****************************************************************************/ - -static void Fig_GetSizeOfFileZone (Brw_FileBrowser_t FileBrowser, - struct Fig_SizeOfFileZones *SizeOfFileZones) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - - /***** Get the size of a file browser *****/ - /* Query database */ - Brw_DB_GetSizeOfFileBrowser (&mysql_res,FileBrowser); - - /* Get row */ - row = mysql_fetch_row (mysql_res); - - /* Reset default values to zero */ - SizeOfFileZones->NumCrss = - SizeOfFileZones->NumUsrs = 0; - SizeOfFileZones->MaxLevels = 0; - SizeOfFileZones->NumFolders = - SizeOfFileZones->NumFiles = 0; - SizeOfFileZones->Size = 0; - - /* Get number of courses (row[0]) */ - if (row[0]) - if (sscanf (row[0],"%d",&(SizeOfFileZones->NumCrss)) != 1) - Err_ShowErrorAndExit ("Error when getting number of courses."); - - /* Get number of groups (row[1]) */ - if (row[1]) - if (sscanf (row[1],"%d",&(SizeOfFileZones->NumGrps)) != 1) - Err_ShowErrorAndExit ("Error when getting number of groups."); - - /* Get number of users (row[2]) */ - if (row[2]) - if (sscanf (row[2],"%d",&(SizeOfFileZones->NumUsrs)) != 1) - Err_ShowErrorAndExit ("Error when getting number of users."); - - /* Get maximum number of levels (row[3]) */ - if (row[3]) - if (sscanf (row[3],"%u",&(SizeOfFileZones->MaxLevels)) != 1) - Err_ShowErrorAndExit ("Error when getting maximum number of levels."); - - /* Get number of folders (row[4]) */ - if (row[4]) - if (sscanf (row[4],"%lu",&(SizeOfFileZones->NumFolders)) != 1) - Err_ShowErrorAndExit ("Error when getting number of folders."); - - /* Get number of files (row[5]) */ - if (row[5]) - if (sscanf (row[5],"%lu",&(SizeOfFileZones->NumFiles)) != 1) - Err_ShowErrorAndExit ("Error when getting number of files."); - - /* Get total size (row[6]) */ - if (row[6]) - if (sscanf (row[6],"%llu",&(SizeOfFileZones->Size)) != 1) - Err_ShowErrorAndExit ("Error when getting toal size."); - - /* Free structure that stores the query result */ - DB_FreeMySQLResult (&mysql_res); - } - -/*****************************************************************************/ -/*********** Write table heading for stats of exploration trees **************/ -/*****************************************************************************/ - -static void Fig_WriteStatsExpTreesTableHead1 (void) - { - extern const char *Txt_File_zones; - extern const char *Txt_Courses; - extern const char *Txt_Groups; - extern const char *Txt_Users; - extern const char *Txt_Max_levels; - extern const char *Txt_Folders; - extern const char *Txt_Files; - extern const char *Txt_Size; - - HTM_TR_Begin (NULL); - HTM_TH (Txt_File_zones,HTM_HEAD_LEFT); - HTM_TH (Txt_Courses ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Groups ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Max_levels,HTM_HEAD_RIGHT); - HTM_TH (Txt_Folders ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Files ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Size ,HTM_HEAD_RIGHT); - HTM_TR_End (); - } - -static void Fig_WriteStatsExpTreesTableHead2 (void) - { - extern const char *Txt_File_zones; - extern const char *Txt_Folders; - extern const char *Txt_Files; - extern const char *Txt_Size; - extern const char *Txt_course; - - HTM_TR_Begin (NULL); - - HTM_TH (Txt_File_zones,HTM_HEAD_LEFT); - - HTM_TH_Begin (HTM_HEAD_RIGHT); - HTM_TxtF ("%s/",Txt_Folders); - HTM_BR (); - HTM_Txt (Txt_course); - HTM_TH_End (); - - HTM_TH_Begin (HTM_HEAD_RIGHT); - HTM_TxtF ("%s/",Txt_Files); - HTM_BR (); - HTM_Txt (Txt_course); - HTM_TH_End (); - - HTM_TH_Begin (HTM_HEAD_RIGHT); - HTM_TxtF ("%s/",Txt_Size); - HTM_BR (); - HTM_Txt (Txt_course); - HTM_TH_End (); - - HTM_TR_End (); - } - -static void Fig_WriteStatsExpTreesTableHead3 (void) - { - extern const char *Txt_File_zones; - extern const char *Txt_Folders; - extern const char *Txt_Files; - extern const char *Txt_Size; - extern const char *Txt_user[Usr_NUM_SEXS]; - - HTM_TR_Begin (NULL); - - HTM_TH (Txt_File_zones,HTM_HEAD_LEFT); - - HTM_TH_Begin (HTM_HEAD_RIGHT); - HTM_TxtF ("%s/",Txt_Folders); - HTM_BR (); - HTM_Txt (Txt_user[Usr_SEX_UNKNOWN]); - HTM_TH_End (); - - HTM_TH_Begin (HTM_HEAD_RIGHT); - HTM_TxtF ("%s/",Txt_Files); - HTM_BR (); - HTM_Txt (Txt_user[Usr_SEX_UNKNOWN]); - HTM_TH_End (); - - HTM_TH_Begin (HTM_HEAD_RIGHT); - HTM_TxtF ("%s/",Txt_Size); - HTM_BR (); - HTM_Txt (Txt_user[Usr_SEX_UNKNOWN]); - HTM_TH_End (); - - HTM_TR_End (); - } - -/*****************************************************************************/ -/*************** Write a row of stats of exploration trees *******************/ -/*****************************************************************************/ - -static void Fig_WriteRowStatsFileBrowsers1 (const char *NameOfFileZones, - Brw_FileBrowser_t FileZone, - struct Fig_SizeOfFileZones *SizeOfFileZones) - { - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *The_ClassDatStrong[The_NUM_THEMES]; - char StrNumCrss[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char StrNumGrps[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char StrNumUsrs[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char FileSizeStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; - char *Cl; - const char *Class; - - if (FileZone == Brw_UNKNOWN) - { - if (asprintf (&Cl,"%s LINE_TOP",The_ClassDatStrong[Gbl.Prefs.Theme]) < 0) - Err_NotEnoughMemoryExit (); - Class = Cl; - } - else - Class = The_ClassDat[Gbl.Prefs.Theme]; - - Fil_WriteFileSizeFull ((double) SizeOfFileZones->Size,FileSizeStr); - - if (SizeOfFileZones->NumCrss == -1) // Not applicable - Str_Copy (StrNumCrss,"-",sizeof (StrNumCrss) - 1); - else - snprintf (StrNumCrss,sizeof (StrNumCrss),"%d", - SizeOfFileZones->NumCrss); - - if (SizeOfFileZones->NumGrps == -1) // Not applicable - Str_Copy (StrNumGrps,"-",sizeof (StrNumGrps) - 1); - else - snprintf (StrNumGrps,sizeof (StrNumGrps),"%d", - SizeOfFileZones->NumGrps); - - if (SizeOfFileZones->NumUsrs == -1) // Not applicable - Str_Copy (StrNumUsrs,"-",sizeof (StrNumUsrs) - 1); - else - snprintf (StrNumUsrs,sizeof (StrNumUsrs),"%d", - SizeOfFileZones->NumUsrs); - - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",Class); - HTM_Txt (NameOfFileZones); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Txt (StrNumCrss); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Txt (StrNumGrps); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Txt (StrNumUsrs); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Unsigned (SizeOfFileZones->MaxLevels); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_UnsignedLong (SizeOfFileZones->NumFolders); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_UnsignedLong (SizeOfFileZones->NumFiles); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Txt (FileSizeStr); - HTM_TD_End (); - - HTM_TR_End (); - - if (FileZone == Brw_UNKNOWN) - free (Cl); - } - -static void Fig_WriteRowStatsFileBrowsers2 (const char *NameOfFileZones, - Brw_FileBrowser_t FileZone, - struct Fig_SizeOfFileZones *SizeOfFileZones) - { - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *The_ClassDatStrong[The_NUM_THEMES]; - char StrNumFoldersPerCrs[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char StrNumFilesPerCrs[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char FileSizePerCrsStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; - char *Cl; - const char *Class; - - if (FileZone == Brw_UNKNOWN) - { - if (asprintf (&Cl,"%s LINE_TOP",The_ClassDatStrong[Gbl.Prefs.Theme]) < 0) - Err_NotEnoughMemoryExit (); - Class = Cl; - } - else - Class = The_ClassDat[Gbl.Prefs.Theme]; - - if (SizeOfFileZones->NumCrss == -1) // Not applicable - { - Str_Copy (StrNumFoldersPerCrs,"-",sizeof (StrNumFoldersPerCrs) - 1); - Str_Copy (StrNumFilesPerCrs ,"-",sizeof (StrNumFilesPerCrs ) - 1); - Str_Copy (FileSizePerCrsStr ,"-",sizeof (FileSizePerCrsStr ) - 1); - } - else - { - snprintf (StrNumFoldersPerCrs,sizeof (StrNumFoldersPerCrs),"%.1f", - SizeOfFileZones->NumCrss ? (double) SizeOfFileZones->NumFolders / - (double) SizeOfFileZones->NumCrss : - 0.0); - snprintf (StrNumFilesPerCrs,sizeof (StrNumFilesPerCrs),"%.1f", - SizeOfFileZones->NumCrss ? (double) SizeOfFileZones->NumFiles / - (double) SizeOfFileZones->NumCrss : - 0.0); - Fil_WriteFileSizeFull (SizeOfFileZones->NumCrss ? (double) SizeOfFileZones->Size / - (double) SizeOfFileZones->NumCrss : - 0.0, - FileSizePerCrsStr); - } - - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",Class); - HTM_Txt (NameOfFileZones); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Txt (StrNumFoldersPerCrs); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Txt (StrNumFilesPerCrs); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Txt (FileSizePerCrsStr); - HTM_TD_End (); - - HTM_TR_End (); - - if (FileZone == Brw_UNKNOWN) - free (Cl); - } - -static void Fig_WriteRowStatsFileBrowsers3 (const char *NameOfFileZones, - Brw_FileBrowser_t FileZone, - struct Fig_SizeOfFileZones *SizeOfFileZones) - { - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *The_ClassDatStrong[The_NUM_THEMES]; - char StrNumFoldersPerUsr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char StrNumFilesPerUsr[Cns_MAX_DECIMAL_DIGITS_UINT + 1]; - char FileSizePerUsrStr[Fil_MAX_BYTES_FILE_SIZE_STRING + 1]; - char *Cl; - const char *Class; - - if (FileZone == Brw_UNKNOWN) - { - if (asprintf (&Cl,"%s LINE_TOP",The_ClassDatStrong[Gbl.Prefs.Theme]) < 0) - Err_NotEnoughMemoryExit (); - Class = Cl; - } - else - Class = The_ClassDat[Gbl.Prefs.Theme]; - - if (SizeOfFileZones->NumUsrs == -1) // Not applicable - { - Str_Copy (StrNumFoldersPerUsr,"-",sizeof (StrNumFoldersPerUsr) - 1); - Str_Copy (StrNumFilesPerUsr ,"-",sizeof (StrNumFilesPerUsr ) - 1); - Str_Copy (FileSizePerUsrStr ,"-",sizeof (FileSizePerUsrStr ) - 1); - } - else - { - snprintf (StrNumFoldersPerUsr,sizeof (StrNumFoldersPerUsr),"%.1f", - SizeOfFileZones->NumUsrs ? (double) SizeOfFileZones->NumFolders / - (double) SizeOfFileZones->NumUsrs : - 0.0); - snprintf (StrNumFilesPerUsr,sizeof (StrNumFilesPerUsr),"%.1f", - SizeOfFileZones->NumUsrs ? (double) SizeOfFileZones->NumFiles / - (double) SizeOfFileZones->NumUsrs : - 0.0); - Fil_WriteFileSizeFull (SizeOfFileZones->NumUsrs ? (double) SizeOfFileZones->Size / - (double) SizeOfFileZones->NumUsrs : - 0.0, - FileSizePerUsrStr); - } - - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",Class); - HTM_Txt (NameOfFileZones); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Txt (StrNumFoldersPerUsr); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Txt (StrNumFilesPerUsr); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",Class); - HTM_Txt (FileSizePerUsrStr); - HTM_TD_End (); - - HTM_TR_End (); - - if (FileZone == Brw_UNKNOWN) - free (Cl); - } - -/*****************************************************************************/ -/************ Show stats about Open Educational Resources (OERs) *************/ -/*****************************************************************************/ - -static void Brw_GetAndShowOERsStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_open_educational_resources_oer; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_License; - extern const char *Txt_Number_of_private_files; - extern const char *Txt_Number_of_public_files; - extern const char *Txt_LICENSES[Brw_NUM_LICENSES]; - Brw_License_t License; - unsigned long NumFiles[2]; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_OER], - NULL,NULL, - Hlp_ANALYTICS_Figures_open_educational_resources_oer,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_License ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_private_files,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_public_files ,HTM_HEAD_RIGHT); - HTM_TR_End (); - - for (License = (Brw_License_t) 0; - License <= (Brw_License_t) (Brw_NUM_LICENSES - 1); - License++) - { - Fig_GetNumberOfOERs (License,NumFiles); - - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (Txt_LICENSES[License]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_UnsignedLong (NumFiles[0]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_UnsignedLong (NumFiles[1]); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/**************** Get the size of a file zone from database ******************/ -/*****************************************************************************/ - -static void Fig_GetNumberOfOERs (Brw_License_t License, - unsigned long NumFiles[2]) - { - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumRows = 0; // Initialized to avoid warning - unsigned NumRow; - unsigned Public; - - /***** Get the size of a file browser *****/ - /* Query database */ - NumRows = Brw_DB_GetNumberOfPublicFiles (&mysql_res,License); - - /* Reset values to zero */ - NumFiles[0] = NumFiles[1] = 0L; - - for (NumRow = 0; - NumRow < NumRows; - NumRow++) - { - /* Get row */ - row = mysql_fetch_row (mysql_res); - - /* Get if public (row[0]) */ - Public = (row[0][0] == 'Y') ? 1 : - 0; - - /* Get number of files (row[1]) */ - if (sscanf (row[1],"%lu",&NumFiles[Public]) != 1) - Err_ShowErrorAndExit ("Error when getting number of files."); - } - - /* Free structure that stores the query result */ - DB_FreeMySQLResult (&mysql_res); - } - -/*****************************************************************************/ -/********************** Show stats about schedule items **********************/ -/*****************************************************************************/ - -static void Prg_GetAndShowCourseProgramStats (void) // TODO: Change function from assignments to course program items - { - extern const char *Hlp_ANALYTICS_Figures_course_programs; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Number_of_BR_program_items; - extern const char *Txt_Number_of_BR_courses_with_BR_program_items; - extern const char *Txt_Average_number_BR_of_items_BR_per_course; - unsigned NumItems; - unsigned NumCoursesWithItems = 0; - double NumItemsPerCourse = 0.0; - - /***** Get the number of program items from this location *****/ - if ((NumItems = Prg_DB_GetNumItems (Gbl.Scope.Current))) - if ((NumCoursesWithItems = Prg_DB_GetNumCoursesWithItems (Gbl.Scope.Current)) != 0) - NumItemsPerCourse = (double) NumItems / - (double) NumCoursesWithItems; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_ASSIGNMENTS], - NULL,NULL, - Hlp_ANALYTICS_Figures_course_programs,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Number_of_BR_program_items ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_courses_with_BR_program_items,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_number_BR_of_items_BR_per_course ,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Write number of assignments *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumItems); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumCoursesWithItems); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumItemsPerCourse); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/************************ Show stats about assignments ***********************/ -/*****************************************************************************/ - -static void Asg_GetAndShowAssignmentsStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_assignments; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Number_of_BR_assignments; - extern const char *Txt_Number_of_BR_courses_with_BR_assignments; - extern const char *Txt_Average_number_BR_of_ASSIG_BR_per_course; - extern const char *Txt_Number_of_BR_notifications; - unsigned NumAssignments; - unsigned NumNotif; - unsigned NumCoursesWithAssignments = 0; - double NumAssignmentsPerCourse = 0.0; - - /***** Get the number of assignments from this location *****/ - if ((NumAssignments = Asg_GetNumAssignments (Gbl.Scope.Current,&NumNotif))) - if ((NumCoursesWithAssignments = Asg_DB_GetNumCoursesWithAssignments (Gbl.Scope.Current)) != 0) - NumAssignmentsPerCourse = (double) NumAssignments / - (double) NumCoursesWithAssignments; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_ASSIGNMENTS], - NULL,NULL, - Hlp_ANALYTICS_Figures_assignments,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Number_of_BR_assignments ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_courses_with_BR_assignments,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_number_BR_of_ASSIG_BR_per_course,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_notifications ,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Write number of assignments *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumAssignments); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumCoursesWithAssignments); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumAssignmentsPerCourse); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumNotif); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/************************ Show figures about projects ************************/ -/*****************************************************************************/ - -static void Prj_GetAndShowProjectsStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_projects; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Number_of_BR_projects; - extern const char *Txt_Number_of_BR_courses_with_BR_projects; - extern const char *Txt_Average_number_BR_of_projects_BR_per_course; - unsigned NumProjects; - unsigned NumCoursesWithProjects = 0; - double NumProjectsPerCourse = 0.0; - - /***** Get the number of projects from this location *****/ - if ((NumProjects = Prj_DB_GetNumProjects (Gbl.Scope.Current))) - if ((NumCoursesWithProjects = Prj_DB_GetNumCoursesWithProjects (Gbl.Scope.Current)) != 0) - NumProjectsPerCourse = (double) NumProjects / - (double) NumCoursesWithProjects; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_PROJECTS], - NULL,NULL, - Hlp_ANALYTICS_Figures_projects,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Number_of_BR_projects ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_courses_with_BR_projects ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_number_BR_of_projects_BR_per_course,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Write number of projects *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumProjects); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumCoursesWithProjects); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumProjectsPerCourse); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/********************** Show figures about test questions ********************/ -/*****************************************************************************/ - -static void Tst_GetAndShowTestsStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_tests; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *The_ClassDatStrong[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Type_of_BR_answers; - extern const char *Txt_Number_of_BR_courses_BR_with_test_BR_questions; - extern const char *Txt_Number_of_BR_courses_with_BR_exportable_BR_test_BR_questions; - extern const char *Txt_Number_BR_of_test_BR_questions; - extern const char *Txt_Average_BR_number_BR_of_test_BR_questions_BR_per_course; - extern const char *Txt_Number_of_BR_times_that_BR_questions_BR_have_been_BR_responded; - extern const char *Txt_Average_BR_number_of_BR_times_that_BR_questions_BR_have_been_BR_responded_BR_per_course; - extern const char *Txt_Average_BR_number_of_BR_times_that_BR_a_question_BR_has_been_BR_responded; - extern const char *Txt_Average_BR_score_BR_per_question; - extern const char *Txt_TST_STR_ANSWER_TYPES[Qst_NUM_ANS_TYPES]; - extern const char *Txt_Total; - Qst_AnswerType_t AnsType; - struct Qst_Stats Stats; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_TESTS], - NULL,NULL, - Hlp_ANALYTICS_Figures_tests,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Type_of_BR_answers ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_BR_courses_BR_with_test_BR_questions ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_courses_with_BR_exportable_BR_test_BR_questions ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_BR_of_test_BR_questions ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_BR_number_BR_of_test_BR_questions_BR_per_course ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_times_that_BR_questions_BR_have_been_BR_responded ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_BR_number_of_BR_times_that_BR_questions_BR_have_been_BR_responded_BR_per_course,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_BR_number_of_BR_times_that_BR_a_question_BR_has_been_BR_responded ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_BR_score_BR_per_question ,HTM_HEAD_RIGHT); - HTM_TR_End (); - - for (AnsType = (Qst_AnswerType_t) 0; - AnsType <= (Qst_AnswerType_t) (Qst_NUM_ANS_TYPES - 1); - AnsType++) - { - /***** Get the stats about test questions from this location *****/ - Qst_GetTestStats (AnsType,&Stats); - - /***** Write stats *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (Txt_TST_STR_ANSWER_TYPES[AnsType]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (Stats.NumCoursesWithQuestions); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_TxtF ("%u (%.1lf%%)", - Stats.NumCoursesWithPluggableQuestions, - Stats.NumCoursesWithQuestions ? (double) Stats.NumCoursesWithPluggableQuestions * 100.0 / - (double) Stats.NumCoursesWithQuestions : - 0.0); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (Stats.NumQsts); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (Stats.AvgQstsPerCourse); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_UnsignedLong (Stats.NumHits); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (Stats.AvgHitsPerCourse); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (Stats.AvgHitsPerQuestion); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (Stats.AvgScorePerQuestion); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** Get the stats about test questions from this location *****/ - Qst_GetTestStats (Qst_ANS_UNKNOWN,&Stats); - - /***** Write stats *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"LM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Txt (Txt_Total); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (Stats.NumCoursesWithQuestions); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_TxtF ("%u (%.1f%%)", - Stats.NumCoursesWithPluggableQuestions, - Stats.NumCoursesWithQuestions ? (double) Stats.NumCoursesWithPluggableQuestions * 100.0 / - (double) Stats.NumCoursesWithQuestions : - 0.0); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (Stats.NumQsts); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Double2Decimals (Stats.AvgQstsPerCourse); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_UnsignedLong (Stats.NumHits); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Double2Decimals (Stats.AvgHitsPerCourse); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Double2Decimals (Stats.AvgHitsPerQuestion); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Double2Decimals (Stats.AvgScorePerQuestion); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/*************************** Show stats about exams **************************/ -/*****************************************************************************/ - -static void Exa_GetAndShowExamsStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_exams; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Number_of_BR_exams; - extern const char *Txt_Number_of_BR_courses_with_BR_exams; - extern const char *Txt_Average_number_BR_of_exams_BR_per_course; - unsigned NumExams; - unsigned NumCoursesWithExams = 0; - double NumExamsPerCourse = 0.0; - - /***** Get the number of exams from this location *****/ - if ((NumExams = Exa_DB_GetNumExams (Gbl.Scope.Current))) - if ((NumCoursesWithExams = Exa_DB_GetNumCoursesWithExams (Gbl.Scope.Current)) != 0) - NumExamsPerCourse = (double) NumExams / (double) NumCoursesWithExams; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_EXAMS], - NULL,NULL, - Hlp_ANALYTICS_Figures_exams,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Number_of_BR_exams ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_courses_with_BR_exams ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_number_BR_of_exams_BR_per_course,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Write number of exams *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumExams); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumCoursesWithExams); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumExamsPerCourse); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/*************************** Show stats about games **************************/ -/*****************************************************************************/ - -static void Gam_GetAndShowGamesStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_games; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Number_of_BR_games; - extern const char *Txt_Number_of_BR_courses_with_BR_games; - extern const char *Txt_Average_number_BR_of_games_BR_per_course; - unsigned NumGames; - unsigned NumCoursesWithGames = 0; - double NumGamesPerCourse = 0.0; - - /***** Get the number of games from this location *****/ - if ((NumGames = Gam_DB_GetNumGames (Gbl.Scope.Current))) - if ((NumCoursesWithGames = Gam_DB_GetNumCoursesWithGames (Gbl.Scope.Current)) != 0) - NumGamesPerCourse = (double) NumGames / (double) NumCoursesWithGames; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_GAMES], - NULL,NULL, - Hlp_ANALYTICS_Figures_games,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Number_of_BR_games ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_courses_with_BR_games ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_number_BR_of_games_BR_per_course,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Write number of games *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumGames); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumCoursesWithGames); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumGamesPerCourse); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/******************* Get and show number of timeline notes *******************/ -/*****************************************************************************/ - -static void Tml_GetAndShowTimelineActivityStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_timeline; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *The_ClassDatStrong[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Type; - extern const char *Txt_Number_of_posts; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - extern const char *Txt_Number_of_posts_BR_per_user; - extern const char *Txt_TIMELINE_NOTE[Tml_NOT_NUM_NOTE_TYPES]; - extern const char *Txt_Total; - MYSQL_RES *mysql_res; - MYSQL_ROW row; - TmlNot_Type_t NoteType; - unsigned NumNotes; - unsigned NumUsrs; - unsigned NumUsrsTotal; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_TIMELINE], - NULL,NULL, - Hlp_ANALYTICS_Figures_timeline,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Type ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_posts ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_posts_BR_per_user,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Get total number of users *****/ - NumUsrsTotal = Usr_GetTotalNumberOfUsers (); - - /***** Get total number of timeline notes and users for each note type *****/ - for (NoteType = (TmlNot_Type_t) 0; - NoteType <= (TmlNot_Type_t) (Tml_NOT_NUM_NOTE_TYPES - 1); - NoteType++) - { - /***** Get number of timeline notes and users for this type *****/ - if (Tml_DB_GetNumNotesAndUsrsByType (&mysql_res,NoteType)) - { - row = mysql_fetch_row (mysql_res); - - /* Get number of timeline notes */ - if (row[0]) - if (sscanf (row[0],"%u",&NumNotes) != 1) - NumNotes = 0; - - /* Get number of users */ - if (row[1]) - if (sscanf (row[1],"%u",&NumUsrs) != 1) - NumUsrs = 0; - } - else - { - NumNotes = 0; - NumUsrs = 0; - } - - /***** Free structure that stores the query result *****/ - DB_FreeMySQLResult (&mysql_res); - - /***** Write number of timeline notes and number of users *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (Txt_TIMELINE_NOTE[NoteType]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumNotes); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumUsrs ? (double) NumNotes / - (double) NumUsrs : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** Get and write totals *****/ - if (Tml_DB_GetNumNotesAndUsrsTotal (&mysql_res)) - { - /* Get number of social notes and number of users */ - row = mysql_fetch_row (mysql_res); - - /* Get number of social notes */ - if (row[0]) - if (sscanf (row[0],"%u",&NumNotes) != 1) - NumNotes = 0; - - /* Get number of users */ - if (row[1]) - if (sscanf (row[1],"%u",&NumUsrs) != 1) - NumUsrs = 0; - } - else - { - NumNotes = 0; - NumUsrs = 0; - } - - /* Free structure that stores the query result */ - DB_FreeMySQLResult (&mysql_res); - - /* Write totals */ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"LM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Txt (Txt_Total); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (NumNotes); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumUsrs ? (double) NumNotes / (double) NumUsrs : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/************** Get and show number of following and followers ***************/ -/*****************************************************************************/ - -static void Fol_GetAndShowFollowStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_followed_followers; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Users; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - extern const char *Txt_Followed; - extern const char *Txt_Followers; - extern const char *Txt_FollowPerFollow[2]; - unsigned Fol; - unsigned NumUsrsTotal; - unsigned NumUsrs; - double Average; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_FOLLOW], - NULL,NULL, - Hlp_ANALYTICS_Figures_followed_followers,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Users ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Get total number of users *****/ - NumUsrsTotal = Usr_GetTotalNumberOfUsers (); - - /***** Get total number of following/followers from database *****/ - for (Fol = 0; - Fol < 2; - Fol++) - { - NumUsrs = Fol_DB_GetNumFollowinFollowers (Fol); - - /***** Write number of followed / followers *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (Fol == 0 ? Txt_Followed : - Txt_Followers); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** Write number of followed/followers per follower/followed *****/ - for (Fol = 0; - Fol < 2; - Fol++) - { - Average = Fol_DB_GetNumFollowedPerFollower (Fol); - - /***** Write number of followed per follower *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (Txt_FollowPerFollow[Fol]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (Average); - HTM_TD_End (); - - HTM_TD_Empty (1); - - HTM_TR_End (); - } - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/************************** Show figures about forums ************************/ -/*****************************************************************************/ - -static void For_GetAndShowForumStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_forums; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Scope; - extern const char *Txt_Forums; - extern const char *Txt_Number_of_forums; - extern const char *Txt_Number_of_threads; - extern const char *Txt_Number_of_posts; - extern const char *Txt_Number_of_BR_notifications; - extern const char *Txt_Number_of_threads_BR_per_forum; - extern const char *Txt_Number_of_posts_BR_per_thread; - extern const char *Txt_Number_of_posts_BR_per_forum; - struct Fig_FiguresForum FiguresForum; - - /***** Reset total stats *****/ - FiguresForum.NumForums = 0; - FiguresForum.NumThreads = 0; - FiguresForum.NumPosts = 0; - FiguresForum.NumUsrsToBeNotifiedByEMail = 0; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_FORUMS], - NULL,NULL, - Hlp_ANALYTICS_Figures_forums,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH_Span_Begin (HTM_HEAD_CENTER,1,1,"BT"); - Ico_PutIcon ("comments.svg",Ico_BLACK,Txt_Scope,"ICOx16"); - HTM_TH_End (); - HTM_TH (Txt_Forums ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_forums ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_threads ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_posts ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_notifications ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_threads_BR_per_forum,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_posts_BR_per_thread ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_posts_BR_per_forum ,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Write a row for each type of forum *****/ - switch (Gbl.Scope.Current) - { - case HieLvl_SYS: - Fig_ShowStatOfAForumType (For_FORUM_GLOBAL_USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_GLOBAL_TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM__SWAD__USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM__SWAD__TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_INSTIT_USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_INSTIT_TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_CENTER_USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_CENTER_TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_DEGREE_USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_DEGREE_TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); - break; - case HieLvl_CTY: - Fig_ShowStatOfAForumType (For_FORUM_INSTIT_USRS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_INSTIT_TCHS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_CENTER_USRS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_CENTER_TCHS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_DEGREE_USRS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_DEGREE_TCHS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_USRS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); - break; - case HieLvl_INS: - Fig_ShowStatOfAForumType (For_FORUM_INSTIT_USRS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_INSTIT_TCHS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_CENTER_USRS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_CENTER_TCHS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_DEGREE_USRS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_DEGREE_TCHS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_USRS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); - break; - case HieLvl_CTR: - Fig_ShowStatOfAForumType (For_FORUM_CENTER_USRS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_CENTER_TCHS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_DEGREE_USRS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_DEGREE_TCHS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_USRS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); - break; - case HieLvl_DEG: - Fig_ShowStatOfAForumType (For_FORUM_DEGREE_USRS,-1L,-1L,-1L,Gbl.Hierarchy.Deg.DegCod,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_DEGREE_TCHS,-1L,-1L,-1L,Gbl.Hierarchy.Deg.DegCod,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_USRS,-1L,-1L,-1L,Gbl.Hierarchy.Deg.DegCod,-1L,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,-1L,-1L,-1L,Gbl.Hierarchy.Deg.DegCod,-1L,&FiguresForum); - break; - case HieLvl_CRS: - Fig_ShowStatOfAForumType (For_FORUM_COURSE_USRS,-1L,-1L,-1L,-1L,Gbl.Hierarchy.Crs.CrsCod,&FiguresForum); - Fig_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,-1L,-1L,-1L,-1L,Gbl.Hierarchy.Crs.CrsCod,&FiguresForum); - break; - default: - Err_WrongScopeExit (); - break; - } - - Fig_WriteForumTotalStats (&FiguresForum); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/************************* Show stats of a forum type ************************/ -/*****************************************************************************/ - -static void Fig_ShowStatOfAForumType (For_ForumType_t ForumType, - long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod, - struct Fig_FiguresForum *FiguresForum) - { - extern const char *Txt_Courses; - extern const char *Txt_Degrees; - extern const char *Txt_Centers; - extern const char *Txt_Institutions; - extern const char *Txt_General; - extern const char *Txt_only_teachers; - static const char *PlatformShortName = Cfg_PLATFORM_SHORT_NAME; - static const char *EmptyName = ""; - static const struct - { - const char *Icon; - const char **ForumName1; - const char **ForumName2; - } Params[For_NUM_TYPES_FORUM] = - { - [For_FORUM_COURSE_USRS] = {"chalkboard-teacher.svg",&Txt_Courses ,&EmptyName }, - [For_FORUM_COURSE_TCHS] = {"chalkboard-teacher.svg",&Txt_Courses ,&Txt_only_teachers}, - [For_FORUM_DEGREE_USRS] = {"graduation-cap.svg" ,&Txt_Degrees ,&EmptyName }, - [For_FORUM_DEGREE_TCHS] = {"graduation-cap.svg" ,&Txt_Degrees ,&Txt_only_teachers}, - [For_FORUM_CENTER_USRS] = {"building.svg" ,&Txt_Centers ,&EmptyName }, - [For_FORUM_CENTER_TCHS] = {"building.svg" ,&Txt_Centers ,&Txt_only_teachers}, - [For_FORUM_INSTIT_USRS] = {"university.svg" ,&Txt_Institutions ,&EmptyName }, - [For_FORUM_INSTIT_TCHS] = {"university.svg" ,&Txt_Institutions ,&Txt_only_teachers}, - [For_FORUM_GLOBAL_USRS] = {"comments.svg" ,&Txt_General ,&EmptyName }, - [For_FORUM_GLOBAL_TCHS] = {"comments.svg" ,&Txt_General ,&Txt_only_teachers}, - [For_FORUM__SWAD__USRS] = {"swad64x64.png" ,&PlatformShortName,&EmptyName }, - [For_FORUM__SWAD__TCHS] = {"swad64x64.png" ,&PlatformShortName,&Txt_only_teachers}, - }; - - if (Params[ForumType].Icon) - Fig_WriteForumTitleAndStats (ForumType,CtyCod,InsCod,CtrCod,DegCod,CrsCod, - Params[ForumType].Icon,FiguresForum, - *Params[ForumType].ForumName1, - *Params[ForumType].ForumName2); - } - -/*****************************************************************************/ -/******************* Write title and stats of a forum type *******************/ -/*****************************************************************************/ - -static void Fig_WriteForumTitleAndStats (For_ForumType_t ForumType, - long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod, - const char *Icon,struct Fig_FiguresForum *FiguresForum, - const char *ForumName1,const char *ForumName2) - { - extern const char *The_ClassDat[The_NUM_THEMES]; - unsigned NumForums; - unsigned NumThreads; - unsigned NumPosts; - unsigned NumUsrsToBeNotifiedByEMail; - double NumThrsPerForum; - double NumPostsPerThread; - double NumPostsPerForum; - char *ForumName; - - /***** Compute number of forums, number of threads and number of posts *****/ - NumForums = For_DB_GetNumTotalForumsOfType (ForumType,CtyCod,InsCod,CtrCod,DegCod,CrsCod); - NumThreads = For_DB_GetNumTotalThrsInForumsOfType (ForumType,CtyCod,InsCod,CtrCod,DegCod,CrsCod); - NumPosts = For_DB_GetNumTotalPstsInForumsOfType (ForumType,CtyCod,InsCod,CtrCod,DegCod,CrsCod,&NumUsrsToBeNotifiedByEMail); - - /***** Compute number of threads per forum, number of posts per forum and number of posts per thread *****/ - NumThrsPerForum = (NumForums ? (double) NumThreads / (double) NumForums : - 0.0); - NumPostsPerThread = (NumThreads ? (double) NumPosts / (double) NumThreads : - 0.0); - NumPostsPerForum = (NumForums ? (double) NumPosts / (double) NumForums : - 0.0); - - /***** Update total stats *****/ - FiguresForum->NumForums += NumForums; - FiguresForum->NumThreads += NumThreads; - FiguresForum->NumPosts += NumPosts; - FiguresForum->NumUsrsToBeNotifiedByEMail += NumUsrsToBeNotifiedByEMail; - - /***** Write forum name and stats *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"BT\""); - if (asprintf (&ForumName,"%s%s", - ForumName1,ForumName2) < 0) - Err_NotEnoughMemoryExit (); - Ico_PutIcon (Icon,Ico_BLACK,ForumName,"ICOx16"); - free (ForumName); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s LT\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (ForumName1); - HTM_Txt (ForumName2); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumForums); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumThreads); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumPosts); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrsToBeNotifiedByEMail); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumThrsPerForum); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumPostsPerThread); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumPostsPerForum); - HTM_TD_End (); - - HTM_TR_End (); - } - -/*****************************************************************************/ -/******************* Write title and stats of a forum type *******************/ -/*****************************************************************************/ - -static void Fig_WriteForumTotalStats (struct Fig_FiguresForum *FiguresForum) - { - extern const char *The_ClassDatStrong[The_NUM_THEMES]; - extern const char *Txt_Total; - double NumThrsPerForum; - double NumPostsPerThread; - double NumPostsPerForum; - - /***** Compute number of threads per forum, number of posts per forum and number of posts per thread *****/ - NumThrsPerForum = (FiguresForum->NumForums ? (double) FiguresForum->NumThreads / - (double) FiguresForum->NumForums : - 0.0); - NumPostsPerThread = (FiguresForum->NumThreads ? (double) FiguresForum->NumPosts / - (double) FiguresForum->NumThreads : - 0.0); - NumPostsPerForum = (FiguresForum->NumForums ? (double) FiguresForum->NumPosts / - (double) FiguresForum->NumForums : - 0.0); - - /***** Write forum name and stats *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LINE_TOP\" style=\"width:20px;\"", - The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"LM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Txt (Txt_Total); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (FiguresForum->NumForums); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (FiguresForum->NumThreads); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (FiguresForum->NumPosts); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP RM\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (FiguresForum->NumUsrsToBeNotifiedByEMail); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumThrsPerForum); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumPostsPerThread); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumPostsPerForum); - HTM_TD_End (); - - HTM_TR_End (); - } - -/*****************************************************************************/ -/****** Get and show number of users who want to be notified by email ********/ -/*****************************************************************************/ - -static void Ntf_GetAndShowNumUsrsPerNotifyEvent (void) - { - extern const char *Hlp_ANALYTICS_Figures_notifications; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *The_ClassDatStrong[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Event; - extern const char *Txt_NOTIFY_EVENTS_PLURAL[Ntf_NUM_NOTIFY_EVENTS]; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - extern const char *Txt_Number_of_events; - extern const char *Txt_Number_of_emails; - extern const char *Txt_Total; - Ntf_NotifyEvent_t NotifyEvent; - char *SubQuery; - MYSQL_RES *mysql_res; - MYSQL_ROW row; - unsigned NumUsrsTotal; - unsigned NumUsrsTotalWhoWantToBeNotifiedByEMailAboutSomeEvent; - unsigned NumUsrs[Ntf_NUM_NOTIFY_EVENTS]; - unsigned NumEventsTotal = 0; - unsigned NumEvents[Ntf_NUM_NOTIFY_EVENTS]; - unsigned NumMailsTotal = 0; - unsigned NumMails[Ntf_NUM_NOTIFY_EVENTS]; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_NOTIFY_EVENTS], - NULL,NULL, - Hlp_ANALYTICS_Figures_notifications,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Event ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_events,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_emails,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Get total number of users *****/ - NumUsrsTotal = Usr_GetTotalNumberOfUsers (); - - /***** Get total number of users who want to be - notified by email on some event, from database *****/ - NumUsrsTotalWhoWantToBeNotifiedByEMailAboutSomeEvent = - Usr_DB_GetNumUsrsWhoChoseAnOption ("usr_data.EmailNtfEvents<>0"); - - /***** For each notify event... *****/ - for (NotifyEvent = (Ntf_NotifyEvent_t) 1; - NotifyEvent <= (Ntf_NotifyEvent_t) (Ntf_NUM_NOTIFY_EVENTS - 1); - NotifyEvent++) // 0 is reserved for Ntf_EVENT_UNKNOWN - { - /* Get the number of users who want to be notified by email on this event, from database */ - if (asprintf (&SubQuery,"((usr_data.EmailNtfEvents & %u)<>0)", - (1 << NotifyEvent)) < 0) - Err_NotEnoughMemoryExit (); - NumUsrs[NotifyEvent] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); - free (SubQuery); - - /* Get number of notifications by email from database */ - if (Ntf_DB_GetNumNotifs (&mysql_res,NotifyEvent)) - { - row = mysql_fetch_row (mysql_res); - - /* Get number of events notified */ - if (row[0]) - { - if (sscanf (row[0],"%u",&NumEvents[NotifyEvent]) != 1) - Err_ShowErrorAndExit ("Error when getting the number of notifications by email."); - } - else - NumEvents[NotifyEvent] = 0; - - /* Get number of mails sent */ - if (row[1]) - { - if (sscanf (row[1],"%u",&NumMails[NotifyEvent]) != 1) - Err_ShowErrorAndExit ("Error when getting the number of emails to notify events3."); - } - else - NumMails[NotifyEvent] = 0; - } - else - { - NumEvents[NotifyEvent] = 0; - NumMails[NotifyEvent] = 0; - } - - /* Free structure that stores the query result */ - DB_FreeMySQLResult (&mysql_res); - - /* Update total number of events and mails */ - NumEventsTotal += NumEvents[NotifyEvent]; - NumMailsTotal += NumMails [NotifyEvent]; - } - - /***** Write number of users who want to be notified by email on each event *****/ - for (NotifyEvent = (Ntf_NotifyEvent_t) 1; - NotifyEvent <= (Ntf_NotifyEvent_t) (Ntf_NUM_NOTIFY_EVENTS - 1); - NotifyEvent++) // 0 is reserved for Ntf_EVENT_UNKNOWN - { - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (Txt_NOTIFY_EVENTS_PLURAL[NotifyEvent]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs[NotifyEvent]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[NotifyEvent] * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumEvents[NotifyEvent]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumMails[NotifyEvent]); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** Write total number of users who want to be notified by email on some event *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"LM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Txt (Txt_Total); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrsTotalWhoWantToBeNotifiedByEMailAboutSomeEvent); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrsTotalWhoWantToBeNotifiedByEMailAboutSomeEvent * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (NumEventsTotal); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (NumMailsTotal); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/************************** Show figures about notices ***********************/ -/*****************************************************************************/ - -static void Not_GetAndShowNoticesStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_notices; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *The_ClassDatStrong[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_NOTICE_Active_BR_notices; - extern const char *Txt_NOTICE_Obsolete_BR_notices; - extern const char *Txt_NOTICE_Deleted_BR_notices; - extern const char *Txt_Total; - extern const char *Txt_Number_of_BR_notifications; - Not_Status_t NoticeStatus; - unsigned NumNotices[Not_NUM_STATUS]; - unsigned NumNoticesDeleted; - unsigned NumTotalNotices = 0; - unsigned NumNotif; - unsigned NumTotalNotifications = 0; - - /***** Get the number of notices active and obsolete *****/ - for (NoticeStatus = (Not_Status_t) 0; - NoticeStatus <= (Not_Status_t) (Not_NUM_STATUS - 1); - NoticeStatus++) - { - NumNotices[NoticeStatus] = Not_GetNumNotices (Gbl.Scope.Current,NoticeStatus,&NumNotif); - NumTotalNotices += NumNotices[NoticeStatus]; - NumTotalNotifications += NumNotif; - } - NumNoticesDeleted = Not_GetNumNoticesDeleted (Gbl.Scope.Current,&NumNotif); - NumTotalNotices += NumNoticesDeleted; - NumTotalNotifications += NumNotif; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_NOTICES], - NULL,NULL, - Hlp_ANALYTICS_Figures_notices,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_NOTICE_Active_BR_notices ,HTM_HEAD_RIGHT); - HTM_TH (Txt_NOTICE_Obsolete_BR_notices,HTM_HEAD_RIGHT); - HTM_TH (Txt_NOTICE_Deleted_BR_notices ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Total ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_notifications,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Write number of notices *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumNotices[Not_ACTIVE_NOTICE]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumNotices[Not_OBSOLETE_NOTICE]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumNoticesDeleted); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned ( NumTotalNotices); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumTotalNotifications); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/************************ Show figures about messages ************************/ -/*****************************************************************************/ - -static void Msg_GetAndShowMsgsStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_messages; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *The_ClassDatStrong[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Messages; - extern const char *Txt_MSGS_Not_deleted; - extern const char *Txt_MSGS_Deleted; - extern const char *Txt_Total; - extern const char *Txt_Number_of_BR_notifications; - extern const char *Txt_MSGS_Sent; - extern const char *Txt_MSGS_Received; - unsigned NumMsgsSentNotDeleted,NumMsgsSentDeleted; - unsigned NumMsgsReceivedNotDeleted,NumMsgsReceivedAndDeleted; - unsigned NumMsgsReceivedAndNotified; - - /***** Get the number of unique messages sent from this location *****/ - NumMsgsSentNotDeleted = Msg_DB_GetNumSntMsgs (Gbl.Scope.Current,Msg_STATUS_ALL ); - NumMsgsSentDeleted = Msg_DB_GetNumSntMsgs (Gbl.Scope.Current,Msg_STATUS_DELETED ); - - NumMsgsReceivedNotDeleted = Msg_DB_GetNumRcvMsgs (Gbl.Scope.Current,Msg_STATUS_ALL ); - NumMsgsReceivedAndDeleted = Msg_DB_GetNumRcvMsgs (Gbl.Scope.Current,Msg_STATUS_DELETED ); - NumMsgsReceivedAndNotified = Msg_DB_GetNumRcvMsgs (Gbl.Scope.Current,Msg_STATUS_NOTIFIED); - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_MESSAGES], - NULL,NULL, - Hlp_ANALYTICS_Figures_messages,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Messages ,HTM_HEAD_LEFT); - HTM_TH (Txt_MSGS_Not_deleted ,HTM_HEAD_RIGHT); - HTM_TH (Txt_MSGS_Deleted ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Total ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_notifications,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Write number of messages *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"LM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (Txt_MSGS_Sent); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumMsgsSentNotDeleted); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumMsgsSentDeleted); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (NumMsgsSentNotDeleted + NumMsgsSentDeleted); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Hyphen (); - HTM_TD_End (); - - HTM_TR_End (); - - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"LM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (Txt_MSGS_Received); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumMsgsReceivedNotDeleted); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumMsgsReceivedAndDeleted); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - HTM_Unsigned (NumMsgsReceivedNotDeleted + NumMsgsReceivedAndDeleted); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumMsgsReceivedAndNotified); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/********* Get and show number of users who have chosen a language ***********/ -/*****************************************************************************/ - -static void Agd_GetAndShowAgendasStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_agendas; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Number_of_events; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - extern const char *Txt_Number_of_events_per_user; - unsigned NumEvents; - unsigned NumUsrs; - unsigned NumUsrsTotal; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_AGENDAS], - NULL,NULL, - Hlp_ANALYTICS_Figures_agendas,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Number_of_events ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_events_per_user,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Number of agenda events *****/ - NumEvents = Agd_DB_GetNumEvents (Gbl.Scope.Current); - - /***** Number of users with agenda events *****/ - NumUsrs = Agd_DB_GetNumUsrsWithEvents (Gbl.Scope.Current); - - /***** Get total number of users in current scope *****/ - NumUsrsTotal = Usr_GetTotalNumberOfUsers (); - - /***** Write number of users who have chosen each language *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumEvents); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs * 100.0 / - (double) NumUsrsTotal : - 0); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumUsrs ? (double) NumEvents / - (double) NumUsrs : - 0); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/***************************** Show stats of surveys *************************/ -/*****************************************************************************/ - -static void Svy_GetAndShowSurveysStats (void) - { - extern const char *Hlp_ANALYTICS_Figures_surveys; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Number_of_BR_surveys; - extern const char *Txt_Number_of_BR_courses_with_BR_surveys; - extern const char *Txt_Average_number_BR_of_surveys_BR_per_course; - extern const char *Txt_Average_number_BR_of_questions_BR_per_survey; - extern const char *Txt_Number_of_BR_notifications; - unsigned NumSurveys; - unsigned NumNotif; - unsigned NumCoursesWithSurveys = 0; - double NumSurveysPerCourse = 0.0; - double NumQstsPerSurvey = 0.0; - - /***** Get the number of surveys and the average number of questions per survey from this location *****/ - if ((NumSurveys = Svy_GetNumCrsSurveys (Gbl.Scope.Current,&NumNotif))) - { - if ((NumCoursesWithSurveys = Svy_DB_GetNumCrssWithCrsSurveys (Gbl.Scope.Current)) != 0) - NumSurveysPerCourse = (double) NumSurveys / - (double) NumCoursesWithSurveys; - NumQstsPerSurvey = Svy_DB_GetNumQstsPerCrsSurvey (Gbl.Scope.Current); - } - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_SURVEYS], - NULL,NULL, - Hlp_ANALYTICS_Figures_surveys,Box_NOT_CLOSABLE,2); - - /***** Write table heading *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Number_of_BR_surveys ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_courses_with_BR_surveys ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_number_BR_of_surveys_BR_per_course ,HTM_HEAD_RIGHT); - HTM_TH (Txt_Average_number_BR_of_questions_BR_per_survey,HTM_HEAD_RIGHT); - HTM_TH (Txt_Number_of_BR_notifications ,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** Write number of surveys *****/ - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumSurveys); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumCoursesWithSurveys); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumSurveysPerCourse); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Double2Decimals (NumQstsPerSurvey); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumNotif); - HTM_TD_End (); - - HTM_TR_End (); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/********** Get and show number of users who have chosen a privacy ***********/ -/*****************************************************************************/ - -static void Pri_GetAndShowNumUsrsPerPrivacy (void) - { - extern const char *Hlp_ANALYTICS_Figures_privacy; - extern const char *Txt_Photo; - extern const char *Txt_Basic_public_profile; - extern const char *Txt_Extended_public_profile; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_PRIVACY], - NULL,NULL, - Hlp_ANALYTICS_Figures_privacy,Box_NOT_CLOSABLE,2); - - /***** Privacy for photo *****/ - Fig_GetAndShowNumUsrsPerPrivacyForAnObject (Txt_Photo, - "PhotoVisibility", - Pri_PHOTO_ALLOWED_VIS); - - /***** Privacy for public profile *****/ - Fig_GetAndShowNumUsrsPerPrivacyForAnObject (Txt_Basic_public_profile, - "BaPrfVisibility", - Pri_BASIC_PROFILE_ALLOWED_VIS); - Fig_GetAndShowNumUsrsPerPrivacyForAnObject (Txt_Extended_public_profile, - "ExPrfVisibility", - Pri_EXTENDED_PROFILE_ALLOWED_VIS); - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/********** Get and show number of users who have chosen a privacy ***********/ -/*****************************************************************************/ - -static void Fig_GetAndShowNumUsrsPerPrivacyForAnObject (const char *TxtObject, - const char *FieldName, - unsigned MaskAllowedVisibility) - { - extern const char *Pri_VisibilityDB[Pri_NUM_OPTIONS_PRIVACY]; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - extern const char *Txt_PRIVACY_OPTIONS[Pri_NUM_OPTIONS_PRIVACY]; - Pri_Visibility_t Visibility; - char *SubQuery; - unsigned NumUsrs[Pri_NUM_OPTIONS_PRIVACY]; - unsigned NumUsrsTotal = 0; - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (TxtObject ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** For each privacy option... *****/ - for (Visibility = (Pri_Visibility_t) 0; - Visibility <= (Pri_Visibility_t) (Pri_NUM_OPTIONS_PRIVACY - 1); - Visibility++) - if (MaskAllowedVisibility & (1 << Visibility)) - { - /* Get the number of users who have chosen this privacy option from database */ - if (asprintf (&SubQuery,"usr_data.%s='%s'", - FieldName,Pri_VisibilityDB[Visibility]) < 0) - Err_NotEnoughMemoryExit (); - NumUsrs[Visibility] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); - free (SubQuery); - - /* Update total number of users */ - NumUsrsTotal += NumUsrs[Visibility]; - } - - /***** Write number of users who have chosen each privacy option *****/ - for (Visibility = (Pri_Visibility_t) 0; - Visibility <= (Pri_Visibility_t) (Pri_NUM_OPTIONS_PRIVACY - 1); - Visibility++) - if (MaskAllowedVisibility & (1 << Visibility)) - { - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (Txt_PRIVACY_OPTIONS[Visibility]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs[Visibility]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[Visibility] * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - } - } - -/*****************************************************************************/ -/** Get and show number of users who have chosen a preference about cookies **/ -/*****************************************************************************/ - -static void Coo_GetAndShowNumUsrsPerCookies (void) - { - extern const char *Hlp_ANALYTICS_Figures_cookies; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Cookies; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - static const struct - { - char InDB; - char *Icon; - Ico_Color_t Color; - char *Title; - } Accepted[2] = - { - [false] = {'N',"times.svg",Ico_RED ,"Don't accept third party cookies"}, // TODO: Need translation!!!! - [true ] = {'Y',"check.svg",Ico_GREEN,"Accept third party cookies"} // TODO: Need translation!!!! - }; - unsigned i; - char *SubQuery; - unsigned NumUsrs[Mnu_NUM_MENUS]; - unsigned NumUsrsTotal = 0; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_COOKIES], - NULL,NULL, - Hlp_ANALYTICS_Figures_cookies,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Cookies ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** For each option... *****/ - for (i = 0; - i < 2; - i++) - { - /* Get number of users who have chosen this menu from database */ - if (asprintf (&SubQuery,"usr_data.ThirdPartyCookies='%c'", - Accepted[i].InDB) < 0) - Err_NotEnoughMemoryExit (); - NumUsrs[i] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); - free (SubQuery); - - /* Update total number of users */ - NumUsrsTotal += NumUsrs[i]; - } - - /***** Write number of users who have chosen each option *****/ - for (i = 0; - i < 2; - i++) - { - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"CM\""); - Ico_PutIcon (Accepted[i].Icon,Accepted[i].Color, - Accepted[i].Title,"ICOx16"); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs[i]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[i] * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/********* Get and show number of users who have chosen a language ***********/ -/*****************************************************************************/ - -static void Lan_GetAndShowNumUsrsPerLanguage (void) - { - extern const char *Hlp_ANALYTICS_Figures_language; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Language; - extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; - extern const char *Txt_STR_LANG_NAME[1 + Lan_NUM_LANGUAGES]; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - Lan_Language_t Lan; - char *SubQuery; - unsigned NumUsrs[1 + Lan_NUM_LANGUAGES]; - unsigned NumUsrsTotal = 0; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_LANGUAGES], - NULL,NULL, - Hlp_ANALYTICS_Figures_language,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Language ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** For each language... *****/ - for (Lan = (Lan_Language_t) 1; - Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES; - Lan++) - { - /* Get the number of users who have chosen this language from database */ - if (asprintf (&SubQuery,"usr_data.Language='%s'", - Lan_STR_LANG_ID[Lan]) < 0) - Err_NotEnoughMemoryExit (); - NumUsrs[Lan] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); - free (SubQuery); - - /* Update total number of users */ - NumUsrsTotal += NumUsrs[Lan]; - } - - /***** Write number of users who have chosen each language *****/ - for (Lan = (Lan_Language_t) 1; - Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES; - Lan++) - { - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Txt (Txt_STR_LANG_NAME[Lan]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs[Lan]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[Lan] * 100.0 / - (double) NumUsrsTotal : - 0); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/***** Get and show number of users who have chosen a first day of week ******/ -/*****************************************************************************/ - -static void Cal_GetAndShowNumUsrsPerFirstDayOfWeek (void) - { - extern const bool Cal_DayIsValidAsFirstDayOfWeek[7]; - extern const char *Hlp_ANALYTICS_Figures_calendar; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Calendar; - extern const char *Txt_First_day_of_the_week_X; - extern const char *Txt_DAYS_SMALL[7]; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - unsigned FirstDayOfWeek; - char *SubQuery; - char *Icon; - char *Title; - unsigned NumUsrs[7]; // 7: seven days in a week - unsigned NumUsrsTotal = 0; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_FIRST_DAY_OF_WEEK], - NULL,NULL, - Hlp_ANALYTICS_Figures_calendar,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Calendar ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** For each day... *****/ - for (FirstDayOfWeek = 0; // Monday - FirstDayOfWeek <= 6; // Sunday - FirstDayOfWeek++) - if (Cal_DayIsValidAsFirstDayOfWeek[FirstDayOfWeek]) - { - /* Get number of users who have chosen this first day of week from database */ - if (asprintf (&SubQuery,"usr_data.FirstDayOfWeek=%u", - (unsigned) FirstDayOfWeek) < 0) - Err_NotEnoughMemoryExit (); - NumUsrs[FirstDayOfWeek] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); - free (SubQuery); - - /* Update total number of users */ - NumUsrsTotal += NumUsrs[FirstDayOfWeek]; - } - - /***** Write number of users who have chosen each first day of week *****/ - for (FirstDayOfWeek = 0; // Monday - FirstDayOfWeek <= 6; // Sunday - FirstDayOfWeek++) - if (Cal_DayIsValidAsFirstDayOfWeek[FirstDayOfWeek]) - { - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"CM\""); - if (asprintf (&Icon,"first-day-of-week-%u.png", - FirstDayOfWeek) < 0) - Err_NotEnoughMemoryExit (); - if (asprintf (&Title,Txt_First_day_of_the_week_X, - Txt_DAYS_SMALL[FirstDayOfWeek]) < 0) - Err_NotEnoughMemoryExit (); - Ico_PutIcon (Icon,Ico_BLACK,Title,"ICOx20"); - free (Title); - free (Icon); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs[FirstDayOfWeek]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[FirstDayOfWeek] * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/******** Get and show number of users who have chosen a date format *********/ -/*****************************************************************************/ - -static void Dat_GetAndShowNumUsrsPerDateFormat (void) - { - extern const char *Hlp_ANALYTICS_Figures_dates; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *The_ClassDatStrong[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Format; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - unsigned Format; - char *SubQuery; - unsigned NumUsrs[Dat_NUM_OPTIONS_FORMAT]; - unsigned NumUsrsTotal = 0; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_DATE_FORMAT], - NULL,NULL, - Hlp_ANALYTICS_Figures_dates,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Format ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** For each format... *****/ - for (Format = (Dat_Format_t) 0; - Format <= (Dat_Format_t) (Dat_NUM_OPTIONS_FORMAT - 1); - Format++) - { - /* Get number of users who have chosen this date format from database */ - if (asprintf (&SubQuery,"usr_data.DateFormat=%u", - (unsigned) Format) < 0) - Err_NotEnoughMemoryExit (); - NumUsrs[Format] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); - free (SubQuery); - - /* Update total number of users */ - NumUsrsTotal += NumUsrs[Format]; - } - - /***** Write number of users who have chosen each date format *****/ - for (Format = (Dat_Format_t) 0; - Format <= (Dat_Format_t) (Dat_NUM_OPTIONS_FORMAT - 1); - Format++) - { - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"LM %s\"",The_ClassDatStrong[Gbl.Prefs.Theme]); - Dat_PutSpanDateFormat (Format); - Dat_PutScriptDateFormat (Format); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs[Format]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[Format] * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/********* Get and show number of users who have chosen an icon set **********/ -/*****************************************************************************/ - -static void Ico_GetAndShowNumUsrsPerIconSet (void) - { - extern const char *Hlp_ANALYTICS_Figures_icons; - extern const char *Ico_IconSetId[Ico_NUM_ICON_SETS]; - extern const char *Ico_IconSetNames[Ico_NUM_ICON_SETS]; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Icons; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - static const char *ClassIco[Ico_NUM_ICON_SETS][The_NUM_THEMES] = - { - [Ico_ICON_SET_AWESOME][The_THEME_WHITE ] = "ICO20x20 BLACK_ICO_WHITE", - [Ico_ICON_SET_AWESOME][The_THEME_GREY ] = "ICO20x20 BLACK_ICO_GREY", - [Ico_ICON_SET_AWESOME][The_THEME_PURPLE] = "ICO20x20 BLACK_ICO_PURPLE", - [Ico_ICON_SET_AWESOME][The_THEME_BLUE ] = "ICO20x20 BLACK_ICO_BLUE", - [Ico_ICON_SET_AWESOME][The_THEME_YELLOW] = "ICO20x20 BLACK_ICO_YELLOW", - [Ico_ICON_SET_AWESOME][The_THEME_PINK ] = "ICO20x20 BLACK_ICO_PINK", - [Ico_ICON_SET_AWESOME][The_THEME_DARK ] = "ICO20x20 BLACK_ICO_DARK", - - [Ico_ICON_SET_NUVOLA ][The_THEME_WHITE ] = "ICO20x20", - [Ico_ICON_SET_NUVOLA ][The_THEME_GREY ] = "ICO20x20", - [Ico_ICON_SET_NUVOLA ][The_THEME_PURPLE] = "ICO20x20", - [Ico_ICON_SET_NUVOLA ][The_THEME_BLUE ] = "ICO20x20", - [Ico_ICON_SET_NUVOLA ][The_THEME_YELLOW] = "ICO20x20", - [Ico_ICON_SET_NUVOLA ][The_THEME_PINK ] = "ICO20x20", - [Ico_ICON_SET_NUVOLA ][The_THEME_DARK ] = "ICO20x20", - }; - Ico_IconSet_t IconSet; - char *SubQuery; - char *URL; - unsigned NumUsrs[Ico_NUM_ICON_SETS]; - unsigned NumUsrsTotal = 0; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_ICON_SETS], - NULL,NULL, - Hlp_ANALYTICS_Figures_icons,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Icons ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** For each icon set... *****/ - for (IconSet = (Ico_IconSet_t) 0; - IconSet <= (Ico_IconSet_t) (Ico_NUM_ICON_SETS - 1); - IconSet++) - { - /* Get the number of users who have chosen this icon set from database */ - if (asprintf (&SubQuery,"usr_data.IconSet='%s'", - Ico_IconSetId[IconSet]) < 0) - Err_NotEnoughMemoryExit (); - NumUsrs[IconSet] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); - free (SubQuery); - - /* Update total number of users */ - NumUsrsTotal += NumUsrs[IconSet]; - } - - /***** Write number of users who have chosen each icon set *****/ - for (IconSet = (Ico_IconSet_t) 0; - IconSet <= (Ico_IconSet_t) (Ico_NUM_ICON_SETS - 1); - IconSet++) - { - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"LM\""); - if (asprintf (&URL,"%s/%s", - Cfg_URL_ICON_SETS_PUBLIC,Ico_IconSetId[IconSet]) < 0) - Err_NotEnoughMemoryExit (); - HTM_IMG (URL,"cog.svg",Ico_IconSetNames[IconSet], - "class=\"%s\"",ClassIco[IconSet][Gbl.Prefs.Theme]); - free (URL); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs[IconSet]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[IconSet] * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/*********** Get and show number of users who have chosen a menu *************/ -/*****************************************************************************/ - -static void Mnu_GetAndShowNumUsrsPerMenu (void) - { - extern const char *Hlp_ANALYTICS_Figures_menu; - extern const char *Mnu_MenuIcons[Mnu_NUM_MENUS]; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Menu; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - extern const char *Txt_MENU_NAMES[Mnu_NUM_MENUS]; - Mnu_Menu_t Menu; - char *SubQuery; - unsigned NumUsrs[Mnu_NUM_MENUS]; - unsigned NumUsrsTotal = 0; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_MENUS], - NULL,NULL, - Hlp_ANALYTICS_Figures_menu,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Menu ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** For each menu... *****/ - for (Menu = (Mnu_Menu_t) 0; - Menu <= (Mnu_Menu_t) (Mnu_NUM_MENUS - 1); - Menu++) - { - /* Get number of users who have chosen this menu from database */ - if (asprintf (&SubQuery,"usr_data.Menu=%u", - (unsigned) Menu) < 0) - Err_NotEnoughMemoryExit (); - NumUsrs[Menu] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); - free (SubQuery); - - /* Update total number of users */ - NumUsrsTotal += NumUsrs[Menu]; - } - - /***** Write number of users who have chosen each menu *****/ - for (Menu = (Mnu_Menu_t) 0; - Menu <= (Mnu_Menu_t) (Mnu_NUM_MENUS - 1); - Menu++) - { - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"CM\""); - Ico_PutIcon (Mnu_MenuIcons[Menu],Ico_BLACK, - Txt_MENU_NAMES[Menu],"ICOx20"); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs[Menu]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[Menu] * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/********** Get and show number of users who have chosen a theme *************/ -/*****************************************************************************/ - -static void The_GetAndShowNumUsrsPerTheme (void) - { - extern const char *Hlp_ANALYTICS_Figures_theme; - extern const char *The_ThemeId[The_NUM_THEMES]; - extern const char *The_ThemeNames[The_NUM_THEMES]; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Theme_SKIN; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - The_Theme_t Theme; - char *SubQuery; - char *URL; - unsigned NumUsrs[The_NUM_THEMES]; - unsigned NumUsrsTotal = 0; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_THEMES], - NULL,NULL, - Hlp_ANALYTICS_Figures_theme,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Theme_SKIN ,HTM_HEAD_LEFT); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** For each theme... *****/ - for (Theme = (The_Theme_t) 0; - Theme <= (The_Theme_t) (The_NUM_THEMES - 1); - Theme++) - { - /* Get number of users who have chosen this theme from database */ - if (asprintf (&SubQuery,"usr_data.Theme='%s'", - The_ThemeId[Theme]) < 0) - Err_NotEnoughMemoryExit (); - NumUsrs[Theme] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); - free (SubQuery); - - /* Update total number of users */ - NumUsrsTotal += NumUsrs[Theme]; - } - - /***** Write number of users who have chosen each theme *****/ - for (Theme = (The_Theme_t) 0; - Theme <= (The_Theme_t) (The_NUM_THEMES - 1); - Theme++) - { - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"CM\""); - if (asprintf (&URL,"%s/%s", - Cfg_URL_ICON_THEMES_PUBLIC,The_ThemeId[Theme]) < 0) - Err_NotEnoughMemoryExit (); - HTM_IMG (URL,"theme_32x20.gif",The_ThemeNames[Theme], - "style=\"width:40px;height:25px;\""); - free (URL); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs[Theme]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[Theme] * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** End table and box *****/ - Box_BoxTableEnd (); - } - -/*****************************************************************************/ -/***** Get and show number of users who have chosen a layout of columns ******/ -/*****************************************************************************/ - -static void Lay_GetAndShowNumUsrsPerSideColumns (void) - { - extern const char *Hlp_ANALYTICS_Figures_columns; - extern const char *The_ClassDat[The_NUM_THEMES]; - extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; - extern const char *Txt_Columns; - extern const char *Txt_Number_of_users; - extern const char *Txt_PERCENT_of_users; - extern const char *Txt_LAYOUT_SIDE_COLUMNS[4]; - unsigned SideCols; - char *SubQuery; - char *Icon; - unsigned NumUsrs[4]; - unsigned NumUsrsTotal = 0; - - /***** Begin box and table *****/ - Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_SIDE_COLUMNS], - NULL,NULL, - Hlp_ANALYTICS_Figures_columns,Box_NOT_CLOSABLE,2); - - /***** Heading row *****/ - HTM_TR_Begin (NULL); - HTM_TH (Txt_Columns ,HTM_HEAD_CENTER); - HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); - HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); - HTM_TR_End (); - - /***** For each layout of columns... *****/ - for (SideCols = 0; - SideCols <= Lay_SHOW_BOTH_COLUMNS; - SideCols++) - { - /* Get the number of users who have chosen this layout of columns from database */ - if (asprintf (&SubQuery,"usr_data.SideCols=%u", - SideCols) < 0) - Err_NotEnoughMemoryExit (); - NumUsrs[SideCols] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); - free (SubQuery); - - /* Update total number of users */ - NumUsrsTotal += NumUsrs[SideCols]; - } - - /***** Write number of users who have chosen this layout of columns *****/ - for (SideCols = 0; - SideCols <= Lay_SHOW_BOTH_COLUMNS; - SideCols++) - { - HTM_TR_Begin (NULL); - - HTM_TD_Begin ("class=\"CM\""); - if (asprintf (&Icon,"layout%u%u_32x20.gif", - SideCols >> 1,SideCols & 1) < 0) - Err_NotEnoughMemoryExit (); - HTM_IMG (Cfg_URL_ICON_PUBLIC,Icon,Txt_LAYOUT_SIDE_COLUMNS[SideCols], - "style=\"width:40px;height:25px;\""); - free (Icon); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Unsigned (NumUsrs[SideCols]); - HTM_TD_End (); - - HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); - HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[SideCols] * 100.0 / - (double) NumUsrsTotal : - 0.0); - HTM_TD_End (); - - HTM_TR_End (); - } - - /***** End table and box *****/ - Box_BoxTableEnd (); - } diff --git a/swad_follow.c b/swad_follow.c index 577ba0e6..c12c9284 100644 --- a/swad_follow.c +++ b/swad_follow.c @@ -1194,3 +1194,93 @@ void Fol_RemoveUsrFromUsrFollow (long UsrCod) /***** Flush cache *****/ Fol_FlushCacheFollow (); } + +/*****************************************************************************/ +/************** Get and show number of following and followers ***************/ +/*****************************************************************************/ + +void Fol_GetAndShowFollowStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_followed_followers; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Users; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + extern const char *Txt_Followed; + extern const char *Txt_Followers; + extern const char *Txt_FollowPerFollow[2]; + unsigned Fol; + unsigned NumUsrsTotal; + unsigned NumUsrs; + double Average; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_FOLLOW], + NULL,NULL, + Hlp_ANALYTICS_Figures_followed_followers,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Users ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Get total number of users *****/ + NumUsrsTotal = Usr_GetTotalNumberOfUsers (); + + /***** Get total number of following/followers from database *****/ + for (Fol = 0; + Fol < 2; + Fol++) + { + NumUsrs = Fol_DB_GetNumFollowinFollowers (Fol); + + /***** Write number of followed / followers *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (Fol == 0 ? Txt_Followed : + Txt_Followers); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** Write number of followed/followers per follower/followed *****/ + for (Fol = 0; + Fol < 2; + Fol++) + { + Average = Fol_DB_GetNumFollowedPerFollower (Fol); + + /***** Write number of followed per follower *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (Txt_FollowPerFollow[Fol]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (Average); + HTM_TD_End (); + + HTM_TD_Empty (1); + + HTM_TR_End (); + } + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_follow.h b/swad_follow.h index f25085a2..8cbfb904 100644 --- a/swad_follow.h +++ b/swad_follow.h @@ -76,4 +76,7 @@ void Fol_GetNotifFollower (char SummaryStr[Ntf_MAX_BYTES_SUMMARY + 1], void Fol_RemoveUsrFromUsrFollow (long UsrCod); +//-------------------------------- Figures ------------------------------------ +void Fol_GetAndShowFollowStats (void); + #endif diff --git a/swad_forum.c b/swad_forum.c index 2b638f68..a9f80b36 100644 --- a/swad_forum.c +++ b/swad_forum.c @@ -296,6 +296,14 @@ static const unsigned PermissionThreadDeletion[For_NUM_TYPES_FORUM] = #define For_IMAGE_SAVED_MAX_HEIGHT 768 #define For_IMAGE_SAVED_QUALITY 90 // 1 to 100 +struct For_FiguresForum + { + unsigned NumForums; + unsigned NumThreads; + unsigned NumPosts; + unsigned NumUsrsToBeNotifiedByEMail; + }; + /*****************************************************************************/ /****************************** Private prototypes ***************************/ /*****************************************************************************/ @@ -385,6 +393,15 @@ static void For_PutAllHiddenParamsRemThread (void *Forums); static bool For_CheckIfICanMoveThreads (void); static void For_InsertThrInClipboard (long ThrCod); +static void For_ShowStatOfAForumType (For_ForumType_t ForumType, + long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod, + struct For_FiguresForum *FiguresForum); +static void For_WriteForumTitleAndStats (For_ForumType_t ForumType, + long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod, + const char *Icon,struct For_FiguresForum *FiguresForum, + const char *ForumName1,const char *ForumName2); +static void For_WriteForumTotalStats (struct For_FiguresForum *FiguresForum); + /*****************************************************************************/ /********************************** Reset forum ******************************/ /*****************************************************************************/ @@ -3179,3 +3196,309 @@ static void For_InsertThrInClipboard (long ThrCod) /***** Add thread to my clipboard *****/ For_DB_InsertThrInMyClipboard (ThrCod); } + + +/*****************************************************************************/ +/************************** Show figures about forums ************************/ +/*****************************************************************************/ + +void For_GetAndShowForumStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_forums; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Scope; + extern const char *Txt_Forums; + extern const char *Txt_Number_of_forums; + extern const char *Txt_Number_of_threads; + extern const char *Txt_Number_of_posts; + extern const char *Txt_Number_of_BR_notifications; + extern const char *Txt_Number_of_threads_BR_per_forum; + extern const char *Txt_Number_of_posts_BR_per_thread; + extern const char *Txt_Number_of_posts_BR_per_forum; + struct For_FiguresForum FiguresForum; + + /***** Reset total stats *****/ + FiguresForum.NumForums = 0; + FiguresForum.NumThreads = 0; + FiguresForum.NumPosts = 0; + FiguresForum.NumUsrsToBeNotifiedByEMail = 0; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_FORUMS], + NULL,NULL, + Hlp_ANALYTICS_Figures_forums,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH_Span_Begin (HTM_HEAD_CENTER,1,1,"BT"); + Ico_PutIcon ("comments.svg",Ico_BLACK,Txt_Scope,"ICOx16"); + HTM_TH_End (); + HTM_TH (Txt_Forums ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_forums ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_threads ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_posts ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_notifications ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_threads_BR_per_forum,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_posts_BR_per_thread ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_posts_BR_per_forum ,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Write a row for each type of forum *****/ + switch (Gbl.Scope.Current) + { + case HieLvl_SYS: + For_ShowStatOfAForumType (For_FORUM_GLOBAL_USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_GLOBAL_TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM__SWAD__USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM__SWAD__TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_INSTIT_USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_INSTIT_TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_CENTER_USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_CENTER_TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_DEGREE_USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_DEGREE_TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_USRS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,-1L,-1L,-1L,-1L,-1L,&FiguresForum); + break; + case HieLvl_CTY: + For_ShowStatOfAForumType (For_FORUM_INSTIT_USRS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_INSTIT_TCHS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_CENTER_USRS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_CENTER_TCHS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_DEGREE_USRS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_DEGREE_TCHS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_USRS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,Gbl.Hierarchy.Cty.CtyCod,-1L,-1L,-1L,-1L,&FiguresForum); + break; + case HieLvl_INS: + For_ShowStatOfAForumType (For_FORUM_INSTIT_USRS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_INSTIT_TCHS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_CENTER_USRS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_CENTER_TCHS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_DEGREE_USRS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_DEGREE_TCHS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_USRS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,-1L,Gbl.Hierarchy.Ins.InsCod,-1L,-1L,-1L,&FiguresForum); + break; + case HieLvl_CTR: + For_ShowStatOfAForumType (For_FORUM_CENTER_USRS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_CENTER_TCHS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_DEGREE_USRS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_DEGREE_TCHS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_USRS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,-1L,-1L,Gbl.Hierarchy.Ctr.CtrCod,-1L,-1L,&FiguresForum); + break; + case HieLvl_DEG: + For_ShowStatOfAForumType (For_FORUM_DEGREE_USRS,-1L,-1L,-1L,Gbl.Hierarchy.Deg.DegCod,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_DEGREE_TCHS,-1L,-1L,-1L,Gbl.Hierarchy.Deg.DegCod,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_USRS,-1L,-1L,-1L,Gbl.Hierarchy.Deg.DegCod,-1L,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,-1L,-1L,-1L,Gbl.Hierarchy.Deg.DegCod,-1L,&FiguresForum); + break; + case HieLvl_CRS: + For_ShowStatOfAForumType (For_FORUM_COURSE_USRS,-1L,-1L,-1L,-1L,Gbl.Hierarchy.Crs.CrsCod,&FiguresForum); + For_ShowStatOfAForumType (For_FORUM_COURSE_TCHS,-1L,-1L,-1L,-1L,Gbl.Hierarchy.Crs.CrsCod,&FiguresForum); + break; + default: + Err_WrongScopeExit (); + break; + } + + For_WriteForumTotalStats (&FiguresForum); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } + +/*****************************************************************************/ +/************************* Show stats of a forum type ************************/ +/*****************************************************************************/ + +static void For_ShowStatOfAForumType (For_ForumType_t ForumType, + long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod, + struct For_FiguresForum *FiguresForum) + { + extern const char *Txt_Courses; + extern const char *Txt_Degrees; + extern const char *Txt_Centers; + extern const char *Txt_Institutions; + extern const char *Txt_General; + extern const char *Txt_only_teachers; + static const char *PlatformShortName = Cfg_PLATFORM_SHORT_NAME; + static const char *EmptyName = ""; + static const struct + { + const char *Icon; + const char **ForumName1; + const char **ForumName2; + } Params[For_NUM_TYPES_FORUM] = + { + [For_FORUM_COURSE_USRS] = {"chalkboard-teacher.svg",&Txt_Courses ,&EmptyName }, + [For_FORUM_COURSE_TCHS] = {"chalkboard-teacher.svg",&Txt_Courses ,&Txt_only_teachers}, + [For_FORUM_DEGREE_USRS] = {"graduation-cap.svg" ,&Txt_Degrees ,&EmptyName }, + [For_FORUM_DEGREE_TCHS] = {"graduation-cap.svg" ,&Txt_Degrees ,&Txt_only_teachers}, + [For_FORUM_CENTER_USRS] = {"building.svg" ,&Txt_Centers ,&EmptyName }, + [For_FORUM_CENTER_TCHS] = {"building.svg" ,&Txt_Centers ,&Txt_only_teachers}, + [For_FORUM_INSTIT_USRS] = {"university.svg" ,&Txt_Institutions ,&EmptyName }, + [For_FORUM_INSTIT_TCHS] = {"university.svg" ,&Txt_Institutions ,&Txt_only_teachers}, + [For_FORUM_GLOBAL_USRS] = {"comments.svg" ,&Txt_General ,&EmptyName }, + [For_FORUM_GLOBAL_TCHS] = {"comments.svg" ,&Txt_General ,&Txt_only_teachers}, + [For_FORUM__SWAD__USRS] = {"swad64x64.png" ,&PlatformShortName,&EmptyName }, + [For_FORUM__SWAD__TCHS] = {"swad64x64.png" ,&PlatformShortName,&Txt_only_teachers}, + }; + + if (Params[ForumType].Icon) + For_WriteForumTitleAndStats (ForumType,CtyCod,InsCod,CtrCod,DegCod,CrsCod, + Params[ForumType].Icon,FiguresForum, + *Params[ForumType].ForumName1, + *Params[ForumType].ForumName2); + } + +/*****************************************************************************/ +/******************* Write title and stats of a forum type *******************/ +/*****************************************************************************/ + +static void For_WriteForumTitleAndStats (For_ForumType_t ForumType, + long CtyCod,long InsCod,long CtrCod,long DegCod,long CrsCod, + const char *Icon,struct For_FiguresForum *FiguresForum, + const char *ForumName1,const char *ForumName2) + { + extern const char *The_ClassDat[The_NUM_THEMES]; + unsigned NumForums; + unsigned NumThreads; + unsigned NumPosts; + unsigned NumUsrsToBeNotifiedByEMail; + double NumThrsPerForum; + double NumPostsPerThread; + double NumPostsPerForum; + char *ForumName; + + /***** Compute number of forums, number of threads and number of posts *****/ + NumForums = For_DB_GetNumTotalForumsOfType (ForumType,CtyCod,InsCod,CtrCod,DegCod,CrsCod); + NumThreads = For_DB_GetNumTotalThrsInForumsOfType (ForumType,CtyCod,InsCod,CtrCod,DegCod,CrsCod); + NumPosts = For_DB_GetNumTotalPstsInForumsOfType (ForumType,CtyCod,InsCod,CtrCod,DegCod,CrsCod,&NumUsrsToBeNotifiedByEMail); + + /***** Compute number of threads per forum, number of posts per forum and number of posts per thread *****/ + NumThrsPerForum = (NumForums ? (double) NumThreads / (double) NumForums : + 0.0); + NumPostsPerThread = (NumThreads ? (double) NumPosts / (double) NumThreads : + 0.0); + NumPostsPerForum = (NumForums ? (double) NumPosts / (double) NumForums : + 0.0); + + /***** Update total stats *****/ + FiguresForum->NumForums += NumForums; + FiguresForum->NumThreads += NumThreads; + FiguresForum->NumPosts += NumPosts; + FiguresForum->NumUsrsToBeNotifiedByEMail += NumUsrsToBeNotifiedByEMail; + + /***** Write forum name and stats *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"BT\""); + if (asprintf (&ForumName,"%s%s", + ForumName1,ForumName2) < 0) + Err_NotEnoughMemoryExit (); + Ico_PutIcon (Icon,Ico_BLACK,ForumName,"ICOx16"); + free (ForumName); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s LT\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (ForumName1); + HTM_Txt (ForumName2); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumForums); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumThreads); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumPosts); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrsToBeNotifiedByEMail); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumThrsPerForum); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumPostsPerThread); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RT\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumPostsPerForum); + HTM_TD_End (); + + HTM_TR_End (); + } + +/*****************************************************************************/ +/******************* Write title and stats of a forum type *******************/ +/*****************************************************************************/ + +static void For_WriteForumTotalStats (struct For_FiguresForum *FiguresForum) + { + extern const char *The_ClassDatStrong[The_NUM_THEMES]; + extern const char *Txt_Total; + double NumThrsPerForum; + double NumPostsPerThread; + double NumPostsPerForum; + + /***** Compute number of threads per forum, number of posts per forum and number of posts per thread *****/ + NumThrsPerForum = (FiguresForum->NumForums ? (double) FiguresForum->NumThreads / + (double) FiguresForum->NumForums : + 0.0); + NumPostsPerThread = (FiguresForum->NumThreads ? (double) FiguresForum->NumPosts / + (double) FiguresForum->NumThreads : + 0.0); + NumPostsPerForum = (FiguresForum->NumForums ? (double) FiguresForum->NumPosts / + (double) FiguresForum->NumForums : + 0.0); + + /***** Write forum name and stats *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LINE_TOP\" style=\"width:20px;\"", + The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"LM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Txt (Txt_Total); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (FiguresForum->NumForums); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (FiguresForum->NumThreads); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (FiguresForum->NumPosts); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP RM\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (FiguresForum->NumUsrsToBeNotifiedByEMail); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumThrsPerForum); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumPostsPerThread); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumPostsPerForum); + HTM_TD_End (); + + HTM_TR_End (); + } diff --git a/swad_forum.h b/swad_forum.h index 2129bb77..b21198e8 100644 --- a/swad_forum.h +++ b/swad_forum.h @@ -147,4 +147,7 @@ void For_RemoveThread (void); void For_CutThread (void); void For_PasteThread (void); +//-------------------------------- Figures ------------------------------------ +void For_GetAndShowForumStats (void); + #endif diff --git a/swad_game.c b/swad_game.c index 926b9cc9..7871854e 100644 --- a/swad_game.c +++ b/swad_game.c @@ -2316,3 +2316,57 @@ void Gam_GetScoreRange (long GamCod,double *MinScore,double *MaxScore) /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } + +/*****************************************************************************/ +/*************************** Show stats about games **************************/ +/*****************************************************************************/ + +void Gam_GetAndShowGamesStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_games; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Number_of_BR_games; + extern const char *Txt_Number_of_BR_courses_with_BR_games; + extern const char *Txt_Average_number_BR_of_games_BR_per_course; + unsigned NumGames; + unsigned NumCoursesWithGames = 0; + double NumGamesPerCourse = 0.0; + + /***** Get the number of games from this location *****/ + if ((NumGames = Gam_DB_GetNumGames (Gbl.Scope.Current))) + if ((NumCoursesWithGames = Gam_DB_GetNumCoursesWithGames (Gbl.Scope.Current)) != 0) + NumGamesPerCourse = (double) NumGames / (double) NumCoursesWithGames; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_GAMES], + NULL,NULL, + Hlp_ANALYTICS_Figures_games,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Number_of_BR_games ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_courses_with_BR_games ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_number_BR_of_games_BR_per_course,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Write number of games *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumGames); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumCoursesWithGames); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumGamesPerCourse); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_game.h b/swad_game.h index 41d6103e..faca3a87 100644 --- a/swad_game.h +++ b/swad_game.h @@ -164,4 +164,7 @@ void Gam_ShowTstTagsPresentInAGame (long GamCod); void Gam_GetScoreRange (long GamCod,double *MinScore,double *MaxScore); +//-------------------------------- Figures ------------------------------------ +void Gam_GetAndShowGamesStats (void); + #endif diff --git a/swad_icon.c b/swad_icon.c index f20def74..ba8f81cb 100644 --- a/swad_icon.c +++ b/swad_icon.c @@ -42,6 +42,7 @@ #include "swad_parameter.h" #include "swad_setting.h" #include "swad_setting_database.h" +#include "swad_user_database.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -559,3 +560,100 @@ void Ico_PutIconNotVisible (void) Ico_PutIconOff ("eye-slash.svg",Ico_RED,Txt_Not_visible); } + +/*****************************************************************************/ +/********* Get and show number of users who have chosen an icon set **********/ +/*****************************************************************************/ + +void Ico_GetAndShowNumUsrsPerIconSet (void) + { + extern const char *Hlp_ANALYTICS_Figures_icons; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Icons; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + static const char *ClassIco[Ico_NUM_ICON_SETS][The_NUM_THEMES] = + { + [Ico_ICON_SET_AWESOME][The_THEME_WHITE ] = "ICO20x20 BLACK_ICO_WHITE", + [Ico_ICON_SET_AWESOME][The_THEME_GREY ] = "ICO20x20 BLACK_ICO_GREY", + [Ico_ICON_SET_AWESOME][The_THEME_PURPLE] = "ICO20x20 BLACK_ICO_PURPLE", + [Ico_ICON_SET_AWESOME][The_THEME_BLUE ] = "ICO20x20 BLACK_ICO_BLUE", + [Ico_ICON_SET_AWESOME][The_THEME_YELLOW] = "ICO20x20 BLACK_ICO_YELLOW", + [Ico_ICON_SET_AWESOME][The_THEME_PINK ] = "ICO20x20 BLACK_ICO_PINK", + [Ico_ICON_SET_AWESOME][The_THEME_DARK ] = "ICO20x20 BLACK_ICO_DARK", + + [Ico_ICON_SET_NUVOLA ][The_THEME_WHITE ] = "ICO20x20", + [Ico_ICON_SET_NUVOLA ][The_THEME_GREY ] = "ICO20x20", + [Ico_ICON_SET_NUVOLA ][The_THEME_PURPLE] = "ICO20x20", + [Ico_ICON_SET_NUVOLA ][The_THEME_BLUE ] = "ICO20x20", + [Ico_ICON_SET_NUVOLA ][The_THEME_YELLOW] = "ICO20x20", + [Ico_ICON_SET_NUVOLA ][The_THEME_PINK ] = "ICO20x20", + [Ico_ICON_SET_NUVOLA ][The_THEME_DARK ] = "ICO20x20", + }; + Ico_IconSet_t IconSet; + char *SubQuery; + char *URL; + unsigned NumUsrs[Ico_NUM_ICON_SETS]; + unsigned NumUsrsTotal = 0; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_ICON_SETS], + NULL,NULL, + Hlp_ANALYTICS_Figures_icons,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Icons ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** For each icon set... *****/ + for (IconSet = (Ico_IconSet_t) 0; + IconSet <= (Ico_IconSet_t) (Ico_NUM_ICON_SETS - 1); + IconSet++) + { + /* Get the number of users who have chosen this icon set from database */ + if (asprintf (&SubQuery,"usr_data.IconSet='%s'", + Ico_IconSetId[IconSet]) < 0) + Err_NotEnoughMemoryExit (); + NumUsrs[IconSet] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); + free (SubQuery); + + /* Update total number of users */ + NumUsrsTotal += NumUsrs[IconSet]; + } + + /***** Write number of users who have chosen each icon set *****/ + for (IconSet = (Ico_IconSet_t) 0; + IconSet <= (Ico_IconSet_t) (Ico_NUM_ICON_SETS - 1); + IconSet++) + { + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"LM\""); + if (asprintf (&URL,"%s/%s", + Cfg_URL_ICON_SETS_PUBLIC,Ico_IconSetId[IconSet]) < 0) + Err_NotEnoughMemoryExit (); + HTM_IMG (URL,"cog.svg",Ico_IconSetNames[IconSet], + "class=\"%s\"",ClassIco[IconSet][Gbl.Prefs.Theme]); + free (URL); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs[IconSet]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[IconSet] * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_icon.h b/swad_icon.h index d3fb570b..9ed31c5b 100644 --- a/swad_icon.h +++ b/swad_icon.h @@ -109,4 +109,7 @@ void Ico_PutIconPaste (void); void Ico_PutIconNotVisible (void); +//-------------------------------- Figures ------------------------------------ +void Ico_GetAndShowNumUsrsPerIconSet (void); + #endif diff --git a/swad_language.c b/swad_language.c index a3762ba9..df85ed94 100644 --- a/swad_language.c +++ b/swad_language.c @@ -25,10 +25,13 @@ /********************************** Headers **********************************/ /*****************************************************************************/ +#define _GNU_SOURCE // For asprintf +#include // For asprintf #include // For strcasecmp #include "swad_box.h" #include "swad_database.h" +#include "swad_error.h" #include "swad_figure.h" #include "swad_form.h" #include "swad_global.h" @@ -36,6 +39,7 @@ #include "swad_language.h" #include "swad_setting.h" #include "swad_setting_database.h" +#include "swad_user_database.h" /*****************************************************************************/ /*************** External global variables from others modules ***************/ @@ -237,3 +241,78 @@ Lan_Language_t Lan_GetLanguageFromStr (const char *Str) return Lan_LANGUAGE_UNKNOWN; } + +/*****************************************************************************/ +/********* Get and show number of users who have chosen a language ***********/ +/*****************************************************************************/ + +void Lan_GetAndShowNumUsrsPerLanguage (void) + { + extern const char *Hlp_ANALYTICS_Figures_language; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Language; + extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; + extern const char *Txt_STR_LANG_NAME[1 + Lan_NUM_LANGUAGES]; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + Lan_Language_t Lan; + char *SubQuery; + unsigned NumUsrs[1 + Lan_NUM_LANGUAGES]; + unsigned NumUsrsTotal = 0; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_LANGUAGES], + NULL,NULL, + Hlp_ANALYTICS_Figures_language,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Language ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** For each language... *****/ + for (Lan = (Lan_Language_t) 1; + Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES; + Lan++) + { + /* Get the number of users who have chosen this language from database */ + if (asprintf (&SubQuery,"usr_data.Language='%s'", + Lan_STR_LANG_ID[Lan]) < 0) + Err_NotEnoughMemoryExit (); + NumUsrs[Lan] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); + free (SubQuery); + + /* Update total number of users */ + NumUsrsTotal += NumUsrs[Lan]; + } + + /***** Write number of users who have chosen each language *****/ + for (Lan = (Lan_Language_t) 1; + Lan <= (Lan_Language_t) Lan_NUM_LANGUAGES; + Lan++) + { + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (Txt_STR_LANG_NAME[Lan]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs[Lan]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[Lan] * 100.0 / + (double) NumUsrsTotal : + 0); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_language.h b/swad_language.h index 2118782a..d111c5c0 100644 --- a/swad_language.h +++ b/swad_language.h @@ -63,4 +63,7 @@ void Lan_UpdateMyLanguageToCurrentLanguage (void); Lan_Language_t Lan_GetParamLanguage (void); Lan_Language_t Lan_GetLanguageFromStr (const char *Str); +//-------------------------------- Figures ------------------------------------ +void Lan_GetAndShowNumUsrsPerLanguage (void); + #endif diff --git a/swad_layout.c b/swad_layout.c index 5161af51..b948bc2e 100644 --- a/swad_layout.c +++ b/swad_layout.c @@ -25,7 +25,9 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ +#define _GNU_SOURCE // For asprintf #include // For NULL +#include // For asprintf #include // For exit #include // For string functions @@ -41,6 +43,7 @@ #include "swad_database.h" #include "swad_error.h" #include "swad_exam_session.h" +#include "swad_figure.h" #include "swad_firewall_database.h" #include "swad_follow.h" #include "swad_form.h" @@ -66,6 +69,7 @@ #include "swad_theme.h" #include "swad_timeline.h" #include "swad_timeline_who.h" +#include "swad_user_database.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -1673,3 +1677,83 @@ void Lay_BeginHTMLFile (FILE *File,const char *Title) Lan_STR_LANG_ID[Gbl.Prefs.Language], // Language Title); // Page title } + +/*****************************************************************************/ +/***** Get and show number of users who have chosen a layout of columns ******/ +/*****************************************************************************/ + +void Lay_GetAndShowNumUsrsPerSideColumns (void) + { + extern const char *Hlp_ANALYTICS_Figures_columns; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Columns; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + extern const char *Txt_LAYOUT_SIDE_COLUMNS[4]; + unsigned SideCols; + char *SubQuery; + char *Icon; + unsigned NumUsrs[4]; + unsigned NumUsrsTotal = 0; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_SIDE_COLUMNS], + NULL,NULL, + Hlp_ANALYTICS_Figures_columns,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Columns ,HTM_HEAD_CENTER); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** For each layout of columns... *****/ + for (SideCols = 0; + SideCols <= Lay_SHOW_BOTH_COLUMNS; + SideCols++) + { + /* Get the number of users who have chosen this layout of columns from database */ + if (asprintf (&SubQuery,"usr_data.SideCols=%u", + SideCols) < 0) + Err_NotEnoughMemoryExit (); + NumUsrs[SideCols] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); + free (SubQuery); + + /* Update total number of users */ + NumUsrsTotal += NumUsrs[SideCols]; + } + + /***** Write number of users who have chosen this layout of columns *****/ + for (SideCols = 0; + SideCols <= Lay_SHOW_BOTH_COLUMNS; + SideCols++) + { + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"CM\""); + if (asprintf (&Icon,"layout%u%u_32x20.gif", + SideCols >> 1,SideCols & 1) < 0) + Err_NotEnoughMemoryExit (); + HTM_IMG (Cfg_URL_ICON_PUBLIC,Icon,Txt_LAYOUT_SIDE_COLUMNS[SideCols], + "style=\"width:40px;height:25px;\""); + free (Icon); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs[SideCols]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[SideCols] * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_layout.h b/swad_layout.h index 14a90653..89810b92 100644 --- a/swad_layout.h +++ b/swad_layout.h @@ -80,4 +80,7 @@ void Lay_HelpRichEditor (void); void Lay_BeginHTMLFile (FILE *File,const char *Title); +//-------------------------------- Figures ------------------------------------ +void Lay_GetAndShowNumUsrsPerSideColumns (void); + #endif diff --git a/swad_menu.c b/swad_menu.c index 00f4203b..66cb74e8 100644 --- a/swad_menu.c +++ b/swad_menu.c @@ -25,8 +25,12 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ +#define _GNU_SOURCE // For asprintf +#include // For asprintf + #include "swad_box.h" #include "swad_database.h" +#include "swad_error.h" #include "swad_figure.h" #include "swad_form.h" #include "swad_global.h" @@ -37,6 +41,7 @@ #include "swad_setting.h" #include "swad_setting_database.h" #include "swad_tab.h" +#include "swad_user_database.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -402,3 +407,79 @@ void Mnu_ContextMenuEnd (void) { HTM_DIV_End (); } + +/*****************************************************************************/ +/*********** Get and show number of users who have chosen a menu *************/ +/*****************************************************************************/ + +void Mnu_GetAndShowNumUsrsPerMenu (void) + { + extern const char *Hlp_ANALYTICS_Figures_menu; + extern const char *Mnu_MenuIcons[Mnu_NUM_MENUS]; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Menu; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + extern const char *Txt_MENU_NAMES[Mnu_NUM_MENUS]; + Mnu_Menu_t Menu; + char *SubQuery; + unsigned NumUsrs[Mnu_NUM_MENUS]; + unsigned NumUsrsTotal = 0; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_MENUS], + NULL,NULL, + Hlp_ANALYTICS_Figures_menu,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Menu ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** For each menu... *****/ + for (Menu = (Mnu_Menu_t) 0; + Menu <= (Mnu_Menu_t) (Mnu_NUM_MENUS - 1); + Menu++) + { + /* Get number of users who have chosen this menu from database */ + if (asprintf (&SubQuery,"usr_data.Menu=%u", + (unsigned) Menu) < 0) + Err_NotEnoughMemoryExit (); + NumUsrs[Menu] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); + free (SubQuery); + + /* Update total number of users */ + NumUsrsTotal += NumUsrs[Menu]; + } + + /***** Write number of users who have chosen each menu *****/ + for (Menu = (Mnu_Menu_t) 0; + Menu <= (Mnu_Menu_t) (Mnu_NUM_MENUS - 1); + Menu++) + { + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"CM\""); + Ico_PutIcon (Mnu_MenuIcons[Menu],Ico_BLACK, + Txt_MENU_NAMES[Menu],"ICOx20"); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs[Menu]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[Menu] * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_menu.h b/swad_menu.h index d0a592b5..795dd249 100644 --- a/swad_menu.h +++ b/swad_menu.h @@ -56,4 +56,7 @@ Mnu_Menu_t Mnu_GetMenuFromStr (const char *Str); void Mnu_ContextMenuBegin (void); void Mnu_ContextMenuEnd (void); +//-------------------------------- Figures ------------------------------------ +void Mnu_GetAndShowNumUsrsPerMenu (void); + #endif diff --git a/swad_message.c b/swad_message.c index 8c00dbf0..c5ef8bac 100644 --- a/swad_message.c +++ b/swad_message.c @@ -2976,3 +2976,99 @@ void Msg_ListBannedUsrs (void) /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); } + +/*****************************************************************************/ +/************************ Show figures about messages ************************/ +/*****************************************************************************/ + +void Msg_GetAndShowMsgsStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_messages; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *The_ClassDatStrong[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Messages; + extern const char *Txt_MSGS_Not_deleted; + extern const char *Txt_MSGS_Deleted; + extern const char *Txt_Total; + extern const char *Txt_Number_of_BR_notifications; + extern const char *Txt_MSGS_Sent; + extern const char *Txt_MSGS_Received; + unsigned NumMsgsSentNotDeleted,NumMsgsSentDeleted; + unsigned NumMsgsReceivedNotDeleted,NumMsgsReceivedAndDeleted; + unsigned NumMsgsReceivedAndNotified; + + /***** Get the number of unique messages sent from this location *****/ + NumMsgsSentNotDeleted = Msg_DB_GetNumSntMsgs (Gbl.Scope.Current,Msg_STATUS_ALL ); + NumMsgsSentDeleted = Msg_DB_GetNumSntMsgs (Gbl.Scope.Current,Msg_STATUS_DELETED ); + + NumMsgsReceivedNotDeleted = Msg_DB_GetNumRcvMsgs (Gbl.Scope.Current,Msg_STATUS_ALL ); + NumMsgsReceivedAndDeleted = Msg_DB_GetNumRcvMsgs (Gbl.Scope.Current,Msg_STATUS_DELETED ); + NumMsgsReceivedAndNotified = Msg_DB_GetNumRcvMsgs (Gbl.Scope.Current,Msg_STATUS_NOTIFIED); + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_MESSAGES], + NULL,NULL, + Hlp_ANALYTICS_Figures_messages,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Messages ,HTM_HEAD_LEFT); + HTM_TH (Txt_MSGS_Not_deleted ,HTM_HEAD_RIGHT); + HTM_TH (Txt_MSGS_Deleted ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Total ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_notifications,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Write number of messages *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"LM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (Txt_MSGS_Sent); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumMsgsSentNotDeleted); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumMsgsSentDeleted); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (NumMsgsSentNotDeleted + NumMsgsSentDeleted); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Hyphen (); + HTM_TD_End (); + + HTM_TR_End (); + + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"LM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (Txt_MSGS_Received); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumMsgsReceivedNotDeleted); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumMsgsReceivedAndDeleted); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (NumMsgsReceivedNotDeleted + NumMsgsReceivedAndDeleted); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumMsgsReceivedAndNotified); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_message.h b/swad_message.h index 83e2bd3b..ffa62692 100644 --- a/swad_message.h +++ b/swad_message.h @@ -125,4 +125,7 @@ void Msg_UnbanSenderWhenShowingMsgs (void); void Msg_UnbanSenderWhenListingUsrs (void); void Msg_ListBannedUsrs (void); +//-------------------------------- Figures ------------------------------------ +void Msg_GetAndShowMsgsStats (void); + #endif diff --git a/swad_notice.c b/swad_notice.c index 58a8563b..11c3c28c 100644 --- a/swad_notice.c +++ b/swad_notice.c @@ -836,3 +836,81 @@ static long Not_GetParamNotCod (void) /***** Get notice code *****/ return Par_GetParToLong ("NotCod"); } + +/*****************************************************************************/ +/************************** Show figures about notices ***********************/ +/*****************************************************************************/ + +void Not_GetAndShowNoticesStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_notices; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *The_ClassDatStrong[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_NOTICE_Active_BR_notices; + extern const char *Txt_NOTICE_Obsolete_BR_notices; + extern const char *Txt_NOTICE_Deleted_BR_notices; + extern const char *Txt_Total; + extern const char *Txt_Number_of_BR_notifications; + Not_Status_t NoticeStatus; + unsigned NumNotices[Not_NUM_STATUS]; + unsigned NumNoticesDeleted; + unsigned NumTotalNotices = 0; + unsigned NumNotif; + unsigned NumTotalNotifications = 0; + + /***** Get the number of notices active and obsolete *****/ + for (NoticeStatus = (Not_Status_t) 0; + NoticeStatus <= (Not_Status_t) (Not_NUM_STATUS - 1); + NoticeStatus++) + { + NumNotices[NoticeStatus] = Not_GetNumNotices (Gbl.Scope.Current,NoticeStatus,&NumNotif); + NumTotalNotices += NumNotices[NoticeStatus]; + NumTotalNotifications += NumNotif; + } + NumNoticesDeleted = Not_GetNumNoticesDeleted (Gbl.Scope.Current,&NumNotif); + NumTotalNotices += NumNoticesDeleted; + NumTotalNotifications += NumNotif; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_NOTICES], + NULL,NULL, + Hlp_ANALYTICS_Figures_notices,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_NOTICE_Active_BR_notices ,HTM_HEAD_RIGHT); + HTM_TH (Txt_NOTICE_Obsolete_BR_notices,HTM_HEAD_RIGHT); + HTM_TH (Txt_NOTICE_Deleted_BR_notices ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Total ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_notifications,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Write number of notices *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumNotices[Not_ACTIVE_NOTICE]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumNotices[Not_OBSOLETE_NOTICE]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumNoticesDeleted); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned ( NumTotalNotices); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumTotalNotifications); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_notice.h b/swad_notice.h index 0e0951e6..cb9eadd8 100644 --- a/swad_notice.h +++ b/swad_notice.h @@ -73,4 +73,7 @@ unsigned Not_GetNumNoticesDeleted (HieLvl_Level_t Scope,unsigned *NumNotif); void Not_PutHiddenParamNotCod (long NotCod); +//-------------------------------- Figures ------------------------------------ +void Not_GetAndShowNoticesStats (void); + #endif diff --git a/swad_notification.c b/swad_notification.c index ae947b8a..7596cad0 100644 --- a/swad_notification.c +++ b/swad_notification.c @@ -25,7 +25,9 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ +#define _GNU_SOURCE // For asprintf #include // For NULL +#include // For asprintf #include // For system #include #include // For the macro WEXITSTATUS @@ -68,6 +70,7 @@ #include "swad_timeline_database.h" #include "swad_timeline_notification.h" #include "swad_timeline_publication.h" +#include "swad_user_database.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -1670,3 +1673,166 @@ void Ntf_WriteNumberOfNewNtfs (void) /***** End form *****/ Frm_EndForm (); } + +/*****************************************************************************/ +/****** Get and show number of users who want to be notified by email ********/ +/*****************************************************************************/ + +void Ntf_GetAndShowNumUsrsPerNotifyEvent (void) + { + extern const char *Hlp_ANALYTICS_Figures_notifications; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *The_ClassDatStrong[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Event; + extern const char *Txt_NOTIFY_EVENTS_PLURAL[Ntf_NUM_NOTIFY_EVENTS]; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + extern const char *Txt_Number_of_events; + extern const char *Txt_Number_of_emails; + extern const char *Txt_Total; + Ntf_NotifyEvent_t NotifyEvent; + char *SubQuery; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + unsigned NumUsrsTotal; + unsigned NumUsrsTotalWhoWantToBeNotifiedByEMailAboutSomeEvent; + unsigned NumUsrs[Ntf_NUM_NOTIFY_EVENTS]; + unsigned NumEventsTotal = 0; + unsigned NumEvents[Ntf_NUM_NOTIFY_EVENTS]; + unsigned NumMailsTotal = 0; + unsigned NumMails[Ntf_NUM_NOTIFY_EVENTS]; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_NOTIFY_EVENTS], + NULL,NULL, + Hlp_ANALYTICS_Figures_notifications,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Event ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_events,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_emails,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Get total number of users *****/ + NumUsrsTotal = Usr_GetTotalNumberOfUsers (); + + /***** Get total number of users who want to be + notified by email on some event, from database *****/ + NumUsrsTotalWhoWantToBeNotifiedByEMailAboutSomeEvent = + Usr_DB_GetNumUsrsWhoChoseAnOption ("usr_data.EmailNtfEvents<>0"); + + /***** For each notify event... *****/ + for (NotifyEvent = (Ntf_NotifyEvent_t) 1; + NotifyEvent <= (Ntf_NotifyEvent_t) (Ntf_NUM_NOTIFY_EVENTS - 1); + NotifyEvent++) // 0 is reserved for Ntf_EVENT_UNKNOWN + { + /* Get the number of users who want to be notified by email on this event, from database */ + if (asprintf (&SubQuery,"((usr_data.EmailNtfEvents & %u)<>0)", + (1 << NotifyEvent)) < 0) + Err_NotEnoughMemoryExit (); + NumUsrs[NotifyEvent] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); + free (SubQuery); + + /* Get number of notifications by email from database */ + if (Ntf_DB_GetNumNotifs (&mysql_res,NotifyEvent)) + { + row = mysql_fetch_row (mysql_res); + + /* Get number of events notified */ + if (row[0]) + { + if (sscanf (row[0],"%u",&NumEvents[NotifyEvent]) != 1) + Err_ShowErrorAndExit ("Error when getting the number of notifications by email."); + } + else + NumEvents[NotifyEvent] = 0; + + /* Get number of mails sent */ + if (row[1]) + { + if (sscanf (row[1],"%u",&NumMails[NotifyEvent]) != 1) + Err_ShowErrorAndExit ("Error when getting the number of emails to notify events3."); + } + else + NumMails[NotifyEvent] = 0; + } + else + { + NumEvents[NotifyEvent] = 0; + NumMails[NotifyEvent] = 0; + } + + /* Free structure that stores the query result */ + DB_FreeMySQLResult (&mysql_res); + + /* Update total number of events and mails */ + NumEventsTotal += NumEvents[NotifyEvent]; + NumMailsTotal += NumMails [NotifyEvent]; + } + + /***** Write number of users who want to be notified by email on each event *****/ + for (NotifyEvent = (Ntf_NotifyEvent_t) 1; + NotifyEvent <= (Ntf_NotifyEvent_t) (Ntf_NUM_NOTIFY_EVENTS - 1); + NotifyEvent++) // 0 is reserved for Ntf_EVENT_UNKNOWN + { + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (Txt_NOTIFY_EVENTS_PLURAL[NotifyEvent]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs[NotifyEvent]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[NotifyEvent] * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumEvents[NotifyEvent]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumMails[NotifyEvent]); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** Write total number of users who want to be notified by email on some event *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"LM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Txt (Txt_Total); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrsTotalWhoWantToBeNotifiedByEMailAboutSomeEvent); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrsTotalWhoWantToBeNotifiedByEMailAboutSomeEvent * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (NumEventsTotal); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (NumMailsTotal); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_notification.h b/swad_notification.h index 1381065c..aae3297d 100644 --- a/swad_notification.h +++ b/swad_notification.h @@ -133,4 +133,7 @@ void Ntf_ChangeNotifyEvents (void); void Ntf_WriteNumberOfNewNtfs (void); +//-------------------------------- Figures ------------------------------------ +void Ntf_GetAndShowNumUsrsPerNotifyEvent (void); + #endif diff --git a/swad_privacy.c b/swad_privacy.c index 27982aa3..975a4fbc 100644 --- a/swad_privacy.c +++ b/swad_privacy.c @@ -25,11 +25,14 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ +#define _GNU_SOURCE // For asprintf +#include // For asprintf #include #include "swad_action.h" #include "swad_box.h" #include "swad_enrolment_database.h" +#include "swad_error.h" #include "swad_figure.h" #include "swad_form.h" #include "swad_global.h" @@ -37,6 +40,7 @@ #include "swad_parameter.h" #include "swad_privacy.h" #include "swad_theme.h" +#include "swad_user_database.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ @@ -75,6 +79,10 @@ static void Pri_PutFormVisibility (const char *TxtLabel, Pri_Visibility_t CurrentVisibilityInDB, unsigned MaskAllowedVisibility); +static void Pri_GetAndShowNumUsrsPerPrivacyForAnObject (const char *TxtObject, + const char *FieldName, + unsigned MaskAllowedVisibility); + /*****************************************************************************/ /******************************* Edit my privacy *****************************/ /*****************************************************************************/ @@ -275,3 +283,105 @@ bool Pri_ShowingIsAllowed (Pri_Visibility_t Visibility,struct UsrData *UsrDat) return false; // Never reached. To avoid warning } + +/*****************************************************************************/ +/********** Get and show number of users who have chosen a privacy ***********/ +/*****************************************************************************/ + +void Pri_GetAndShowNumUsrsPerPrivacy (void) + { + extern const char *Hlp_ANALYTICS_Figures_privacy; + extern const char *Txt_Photo; + extern const char *Txt_Basic_public_profile; + extern const char *Txt_Extended_public_profile; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_PRIVACY], + NULL,NULL, + Hlp_ANALYTICS_Figures_privacy,Box_NOT_CLOSABLE,2); + + /***** Privacy for photo *****/ + Pri_GetAndShowNumUsrsPerPrivacyForAnObject (Txt_Photo, + "PhotoVisibility", + Pri_PHOTO_ALLOWED_VIS); + + /***** Privacy for public profile *****/ + Pri_GetAndShowNumUsrsPerPrivacyForAnObject (Txt_Basic_public_profile, + "BaPrfVisibility", + Pri_BASIC_PROFILE_ALLOWED_VIS); + Pri_GetAndShowNumUsrsPerPrivacyForAnObject (Txt_Extended_public_profile, + "ExPrfVisibility", + Pri_EXTENDED_PROFILE_ALLOWED_VIS); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } + +/*****************************************************************************/ +/********** Get and show number of users who have chosen a privacy ***********/ +/*****************************************************************************/ + +static void Pri_GetAndShowNumUsrsPerPrivacyForAnObject (const char *TxtObject, + const char *FieldName, + unsigned MaskAllowedVisibility) + { + extern const char *Pri_VisibilityDB[Pri_NUM_OPTIONS_PRIVACY]; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + extern const char *Txt_PRIVACY_OPTIONS[Pri_NUM_OPTIONS_PRIVACY]; + Pri_Visibility_t Visibility; + char *SubQuery; + unsigned NumUsrs[Pri_NUM_OPTIONS_PRIVACY]; + unsigned NumUsrsTotal = 0; + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (TxtObject ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** For each privacy option... *****/ + for (Visibility = (Pri_Visibility_t) 0; + Visibility <= (Pri_Visibility_t) (Pri_NUM_OPTIONS_PRIVACY - 1); + Visibility++) + if (MaskAllowedVisibility & (1 << Visibility)) + { + /* Get the number of users who have chosen this privacy option from database */ + if (asprintf (&SubQuery,"usr_data.%s='%s'", + FieldName,Pri_VisibilityDB[Visibility]) < 0) + Err_NotEnoughMemoryExit (); + NumUsrs[Visibility] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); + free (SubQuery); + + /* Update total number of users */ + NumUsrsTotal += NumUsrs[Visibility]; + } + + /***** Write number of users who have chosen each privacy option *****/ + for (Visibility = (Pri_Visibility_t) 0; + Visibility <= (Pri_Visibility_t) (Pri_NUM_OPTIONS_PRIVACY - 1); + Visibility++) + if (MaskAllowedVisibility & (1 << Visibility)) + { + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (Txt_PRIVACY_OPTIONS[Visibility]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs[Visibility]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[Visibility] * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + } + } diff --git a/swad_privacy.h b/swad_privacy.h index 284c8430..9f38e291 100644 --- a/swad_privacy.h +++ b/swad_privacy.h @@ -67,4 +67,7 @@ Pri_Visibility_t Pri_GetParamVisibility (const char *ParamName, bool Pri_ShowingIsAllowed (Pri_Visibility_t Visibility,struct UsrData *UsrDat); +//-------------------------------- Figures ------------------------------------ +void Pri_GetAndShowNumUsrsPerPrivacy (void); + #endif diff --git a/swad_program.c b/swad_program.c index 5fcb6f38..f3769d96 100644 --- a/swad_program.c +++ b/swad_program.c @@ -1964,3 +1964,58 @@ static void Prg_InsertItem (const struct Prg_Item *ParentItem, /***** Free list items *****/ Prg_FreeListItems (); } + +/*****************************************************************************/ +/********************** Show stats about schedule items **********************/ +/*****************************************************************************/ + +void Prg_GetAndShowCourseProgramStats (void) // TODO: Change function from assignments to course program items + { + extern const char *Hlp_ANALYTICS_Figures_course_programs; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Number_of_BR_program_items; + extern const char *Txt_Number_of_BR_courses_with_BR_program_items; + extern const char *Txt_Average_number_BR_of_items_BR_per_course; + unsigned NumItems; + unsigned NumCoursesWithItems = 0; + double NumItemsPerCourse = 0.0; + + /***** Get the number of program items from this location *****/ + if ((NumItems = Prg_DB_GetNumItems (Gbl.Scope.Current))) + if ((NumCoursesWithItems = Prg_DB_GetNumCoursesWithItems (Gbl.Scope.Current)) != 0) + NumItemsPerCourse = (double) NumItems / + (double) NumCoursesWithItems; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_ASSIGNMENTS], + NULL,NULL, + Hlp_ANALYTICS_Figures_course_programs,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Number_of_BR_program_items ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_courses_with_BR_program_items,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_number_BR_of_items_BR_per_course ,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Write number of assignments *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumItems); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumCoursesWithItems); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumItemsPerCourse); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_program.h b/swad_program.h index f205f7d2..a63a1533 100644 --- a/swad_program.h +++ b/swad_program.h @@ -92,4 +92,7 @@ void Prg_MoveDownItem (void); void Prg_MoveLeftItem (void); void Prg_MoveRightItem (void); +//-------------------------------- Figures ------------------------------------ +void Prg_GetAndShowCourseProgramStats (void); // TODO: Change function from assignments to schedule + #endif diff --git a/swad_project.c b/swad_project.c index 79bed259..f52b3f35 100644 --- a/swad_project.c +++ b/swad_project.c @@ -4210,3 +4210,58 @@ void Prj_RemoveUsrFromProjects (long UsrCod) if (Usr_ItsMe (UsrCod)) Prj_FlushCacheMyRolesInProject (); } + +/*****************************************************************************/ +/************************ Show figures about projects ************************/ +/*****************************************************************************/ + +void Prj_GetAndShowProjectsStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_projects; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Number_of_BR_projects; + extern const char *Txt_Number_of_BR_courses_with_BR_projects; + extern const char *Txt_Average_number_BR_of_projects_BR_per_course; + unsigned NumProjects; + unsigned NumCoursesWithProjects = 0; + double NumProjectsPerCourse = 0.0; + + /***** Get the number of projects from this location *****/ + if ((NumProjects = Prj_DB_GetNumProjects (Gbl.Scope.Current))) + if ((NumCoursesWithProjects = Prj_DB_GetNumCoursesWithProjects (Gbl.Scope.Current)) != 0) + NumProjectsPerCourse = (double) NumProjects / + (double) NumCoursesWithProjects; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_PROJECTS], + NULL,NULL, + Hlp_ANALYTICS_Figures_projects,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Number_of_BR_projects ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_courses_with_BR_projects ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_number_BR_of_projects_BR_per_course,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Write number of projects *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumProjects); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumCoursesWithProjects); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumProjectsPerCourse); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_project.h b/swad_project.h index 1ccb693d..48364c8b 100644 --- a/swad_project.h +++ b/swad_project.h @@ -237,4 +237,7 @@ void Prj_UnloProjectEdition (void); void Prj_RemoveCrsProjects (long CrsCod); void Prj_RemoveUsrFromProjects (long UsrCod); +//-------------------------------- Figures ------------------------------------ +void Prj_GetAndShowProjectsStats (void); + #endif diff --git a/swad_survey.c b/swad_survey.c index 22a1294a..4f81664a 100644 --- a/swad_survey.c +++ b/swad_survey.c @@ -3365,3 +3365,75 @@ unsigned Svy_GetNumCrsSurveys (HieLvl_Level_t Scope,unsigned *NumNotif) return NumSurveys; } + +/*****************************************************************************/ +/***************************** Show stats of surveys *************************/ +/*****************************************************************************/ + +void Svy_GetAndShowSurveysStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_surveys; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Number_of_BR_surveys; + extern const char *Txt_Number_of_BR_courses_with_BR_surveys; + extern const char *Txt_Average_number_BR_of_surveys_BR_per_course; + extern const char *Txt_Average_number_BR_of_questions_BR_per_survey; + extern const char *Txt_Number_of_BR_notifications; + unsigned NumSurveys; + unsigned NumNotif; + unsigned NumCoursesWithSurveys = 0; + double NumSurveysPerCourse = 0.0; + double NumQstsPerSurvey = 0.0; + + /***** Get the number of surveys and the average number of questions per survey from this location *****/ + if ((NumSurveys = Svy_GetNumCrsSurveys (Gbl.Scope.Current,&NumNotif))) + { + if ((NumCoursesWithSurveys = Svy_DB_GetNumCrssWithCrsSurveys (Gbl.Scope.Current)) != 0) + NumSurveysPerCourse = (double) NumSurveys / + (double) NumCoursesWithSurveys; + NumQstsPerSurvey = Svy_DB_GetNumQstsPerCrsSurvey (Gbl.Scope.Current); + } + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_SURVEYS], + NULL,NULL, + Hlp_ANALYTICS_Figures_surveys,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Number_of_BR_surveys ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_courses_with_BR_surveys ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_number_BR_of_surveys_BR_per_course ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_number_BR_of_questions_BR_per_survey,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_notifications ,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Write number of surveys *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumSurveys); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumCoursesWithSurveys); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumSurveysPerCourse); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumQstsPerSurvey); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumNotif); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_survey.h b/swad_survey.h index e0d1dcb6..251cbe95 100644 --- a/swad_survey.h +++ b/swad_survey.h @@ -114,4 +114,7 @@ void Svy_ReceiveSurveyAnswers (void); unsigned Svy_GetNumCrsSurveys (HieLvl_Level_t Scope,unsigned *NumNotif); +//-------------------------------- Figures ------------------------------------ +void Svy_GetAndShowSurveysStats (void); + #endif diff --git a/swad_test.c b/swad_test.c index 68ce4dbb..abae0dbe 100644 --- a/swad_test.c +++ b/swad_test.c @@ -738,3 +738,150 @@ static unsigned Tst_GetParamNumQsts (void) (unsigned long) TstCfg_GetConfigMax (), (unsigned long) TstCfg_GetConfigDef ()); } + +/*****************************************************************************/ +/********************** Show figures about test questions ********************/ +/*****************************************************************************/ + +void Tst_GetAndShowTestsStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_tests; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *The_ClassDatStrong[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Type_of_BR_answers; + extern const char *Txt_Number_of_BR_courses_BR_with_test_BR_questions; + extern const char *Txt_Number_of_BR_courses_with_BR_exportable_BR_test_BR_questions; + extern const char *Txt_Number_BR_of_test_BR_questions; + extern const char *Txt_Average_BR_number_BR_of_test_BR_questions_BR_per_course; + extern const char *Txt_Number_of_BR_times_that_BR_questions_BR_have_been_BR_responded; + extern const char *Txt_Average_BR_number_of_BR_times_that_BR_questions_BR_have_been_BR_responded_BR_per_course; + extern const char *Txt_Average_BR_number_of_BR_times_that_BR_a_question_BR_has_been_BR_responded; + extern const char *Txt_Average_BR_score_BR_per_question; + extern const char *Txt_TST_STR_ANSWER_TYPES[Qst_NUM_ANS_TYPES]; + extern const char *Txt_Total; + Qst_AnswerType_t AnsType; + struct Qst_Stats Stats; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_TESTS], + NULL,NULL, + Hlp_ANALYTICS_Figures_tests,Box_NOT_CLOSABLE,2); + + /***** Write table heading *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Type_of_BR_answers ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_BR_courses_BR_with_test_BR_questions ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_courses_with_BR_exportable_BR_test_BR_questions ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_BR_of_test_BR_questions ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_BR_number_BR_of_test_BR_questions_BR_per_course ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_BR_times_that_BR_questions_BR_have_been_BR_responded ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_BR_number_of_BR_times_that_BR_questions_BR_have_been_BR_responded_BR_per_course,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_BR_number_of_BR_times_that_BR_a_question_BR_has_been_BR_responded ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Average_BR_score_BR_per_question ,HTM_HEAD_RIGHT); + HTM_TR_End (); + + for (AnsType = (Qst_AnswerType_t) 0; + AnsType <= (Qst_AnswerType_t) (Qst_NUM_ANS_TYPES - 1); + AnsType++) + { + /***** Get the stats about test questions from this location *****/ + Qst_GetTestStats (AnsType,&Stats); + + /***** Write stats *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (Txt_TST_STR_ANSWER_TYPES[AnsType]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (Stats.NumCoursesWithQuestions); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_TxtF ("%u (%.1lf%%)", + Stats.NumCoursesWithPluggableQuestions, + Stats.NumCoursesWithQuestions ? (double) Stats.NumCoursesWithPluggableQuestions * 100.0 / + (double) Stats.NumCoursesWithQuestions : + 0.0); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (Stats.NumQsts); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (Stats.AvgQstsPerCourse); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_UnsignedLong (Stats.NumHits); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (Stats.AvgHitsPerCourse); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (Stats.AvgHitsPerQuestion); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (Stats.AvgScorePerQuestion); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** Get the stats about test questions from this location *****/ + Qst_GetTestStats (Qst_ANS_UNKNOWN,&Stats); + + /***** Write stats *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"LM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Txt (Txt_Total); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (Stats.NumCoursesWithQuestions); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_TxtF ("%u (%.1f%%)", + Stats.NumCoursesWithPluggableQuestions, + Stats.NumCoursesWithQuestions ? (double) Stats.NumCoursesWithPluggableQuestions * 100.0 / + (double) Stats.NumCoursesWithQuestions : + 0.0); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (Stats.NumQsts); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Double2Decimals (Stats.AvgQstsPerCourse); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_UnsignedLong (Stats.NumHits); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Double2Decimals (Stats.AvgHitsPerCourse); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Double2Decimals (Stats.AvgHitsPerQuestion); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Double2Decimals (Stats.AvgScorePerQuestion); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_test.h b/swad_test.h index fa26711b..8bbb1859 100644 --- a/swad_test.h +++ b/swad_test.h @@ -69,4 +69,7 @@ void Tst_PutIconsTests (__attribute__((unused)) void *Args); bool Tst_GetParamsTst (struct Qst_Questions *Questions, Tst_ActionToDoWithQuestions_t ActionToDoWithQuestions); +//-------------------------------- Figures ------------------------------------ +void Tst_GetAndShowTestsStats (void); + #endif diff --git a/swad_theme.c b/swad_theme.c index 6231f8cb..03d8f982 100644 --- a/swad_theme.c +++ b/swad_theme.c @@ -25,11 +25,14 @@ /********************************** Headers **********************************/ /*****************************************************************************/ +#define _GNU_SOURCE // For asprintf +#include // For asprintf #include #include "swad_box.h" #include "swad_config.h" #include "swad_database.h" +#include "swad_error.h" #include "swad_figure.h" #include "swad_form.h" #include "swad_global.h" @@ -39,6 +42,7 @@ #include "swad_setting.h" #include "swad_setting_database.h" #include "swad_theme.h" +#include "swad_user_database.h" /*****************************************************************************/ /*************** External global variables from others modules ***************/ @@ -382,3 +386,84 @@ void The_SetColorRows (void) Gbl.ColorRows[0] = The_ClassColorRows[0][Gbl.Prefs.Theme]; // Darker Gbl.ColorRows[1] = The_ClassColorRows[1][Gbl.Prefs.Theme]; // Lighter } + +/*****************************************************************************/ +/********** Get and show number of users who have chosen a theme *************/ +/*****************************************************************************/ + +void The_GetAndShowNumUsrsPerTheme (void) + { + extern const char *Hlp_ANALYTICS_Figures_theme; + extern const char *The_ThemeId[The_NUM_THEMES]; + extern const char *The_ThemeNames[The_NUM_THEMES]; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Theme_SKIN; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + The_Theme_t Theme; + char *SubQuery; + char *URL; + unsigned NumUsrs[The_NUM_THEMES]; + unsigned NumUsrsTotal = 0; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_THEMES], + NULL,NULL, + Hlp_ANALYTICS_Figures_theme,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Theme_SKIN ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** For each theme... *****/ + for (Theme = (The_Theme_t) 0; + Theme <= (The_Theme_t) (The_NUM_THEMES - 1); + Theme++) + { + /* Get number of users who have chosen this theme from database */ + if (asprintf (&SubQuery,"usr_data.Theme='%s'", + The_ThemeId[Theme]) < 0) + Err_NotEnoughMemoryExit (); + NumUsrs[Theme] = Usr_DB_GetNumUsrsWhoChoseAnOption (SubQuery); + free (SubQuery); + + /* Update total number of users */ + NumUsrsTotal += NumUsrs[Theme]; + } + + /***** Write number of users who have chosen each theme *****/ + for (Theme = (The_Theme_t) 0; + Theme <= (The_Theme_t) (The_NUM_THEMES - 1); + Theme++) + { + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"CM\""); + if (asprintf (&URL,"%s/%s", + Cfg_URL_ICON_THEMES_PUBLIC,The_ThemeId[Theme]) < 0) + Err_NotEnoughMemoryExit (); + HTM_IMG (URL,"theme_32x20.gif",The_ThemeNames[Theme], + "style=\"width:40px;height:25px;\""); + free (URL); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs[Theme]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs[Theme] * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_theme.h b/swad_theme.h index 4fee491a..d7dcbc25 100644 --- a/swad_theme.h +++ b/swad_theme.h @@ -56,4 +56,7 @@ The_Theme_t The_GetThemeFromStr (const char *Str); void The_SetColorRows (void); +//-------------------------------- Figures ------------------------------------ +void The_GetAndShowNumUsrsPerTheme (void); + #endif diff --git a/swad_timeline.c b/swad_timeline.c index f5c66c7e..f5547d83 100644 --- a/swad_timeline.c +++ b/swad_timeline.c @@ -537,3 +537,160 @@ void Tml_WriteDateTime (time_t TimeUTC) Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA, true,true,false,0x6); } + +/*****************************************************************************/ +/******************* Get and show number of timeline notes *******************/ +/*****************************************************************************/ + +void Tml_GetAndShowTimelineActivityStats (void) + { + extern const char *Hlp_ANALYTICS_Figures_timeline; + extern const char *The_ClassDat[The_NUM_THEMES]; + extern const char *The_ClassDatStrong[The_NUM_THEMES]; + extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; + extern const char *Txt_Type; + extern const char *Txt_Number_of_posts; + extern const char *Txt_Number_of_users; + extern const char *Txt_PERCENT_of_users; + extern const char *Txt_Number_of_posts_BR_per_user; + extern const char *Txt_TIMELINE_NOTE[Tml_NOT_NUM_NOTE_TYPES]; + extern const char *Txt_Total; + MYSQL_RES *mysql_res; + MYSQL_ROW row; + TmlNot_Type_t NoteType; + unsigned NumNotes; + unsigned NumUsrs; + unsigned NumUsrsTotal; + + /***** Begin box and table *****/ + Box_BoxTableBegin (NULL,Txt_FIGURE_TYPES[Fig_TIMELINE], + NULL,NULL, + Hlp_ANALYTICS_Figures_timeline,Box_NOT_CLOSABLE,2); + + /***** Heading row *****/ + HTM_TR_Begin (NULL); + HTM_TH (Txt_Type ,HTM_HEAD_LEFT); + HTM_TH (Txt_Number_of_posts ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_PERCENT_of_users ,HTM_HEAD_RIGHT); + HTM_TH (Txt_Number_of_posts_BR_per_user,HTM_HEAD_RIGHT); + HTM_TR_End (); + + /***** Get total number of users *****/ + NumUsrsTotal = Usr_GetTotalNumberOfUsers (); + + /***** Get total number of timeline notes and users for each note type *****/ + for (NoteType = (TmlNot_Type_t) 0; + NoteType <= (TmlNot_Type_t) (Tml_NOT_NUM_NOTE_TYPES - 1); + NoteType++) + { + /***** Get number of timeline notes and users for this type *****/ + if (Tml_DB_GetNumNotesAndUsrsByType (&mysql_res,NoteType)) + { + row = mysql_fetch_row (mysql_res); + + /* Get number of timeline notes */ + if (row[0]) + if (sscanf (row[0],"%u",&NumNotes) != 1) + NumNotes = 0; + + /* Get number of users */ + if (row[1]) + if (sscanf (row[1],"%u",&NumUsrs) != 1) + NumUsrs = 0; + } + else + { + NumNotes = 0; + NumUsrs = 0; + } + + /***** Free structure that stores the query result *****/ + DB_FreeMySQLResult (&mysql_res); + + /***** Write number of timeline notes and number of users *****/ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"%s LM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Txt (Txt_TIMELINE_NOTE[NoteType]); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumNotes); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"%s RM\"",The_ClassDat[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumUsrs ? (double) NumNotes / + (double) NumUsrs : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + } + + /***** Get and write totals *****/ + if (Tml_DB_GetNumNotesAndUsrsTotal (&mysql_res)) + { + /* Get number of social notes and number of users */ + row = mysql_fetch_row (mysql_res); + + /* Get number of social notes */ + if (row[0]) + if (sscanf (row[0],"%u",&NumNotes) != 1) + NumNotes = 0; + + /* Get number of users */ + if (row[1]) + if (sscanf (row[1],"%u",&NumUsrs) != 1) + NumUsrs = 0; + } + else + { + NumNotes = 0; + NumUsrs = 0; + } + + /* Free structure that stores the query result */ + DB_FreeMySQLResult (&mysql_res); + + /* Write totals */ + HTM_TR_Begin (NULL); + + HTM_TD_Begin ("class=\"LM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Txt (Txt_Total); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (NumNotes); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Unsigned (NumUsrs); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Percentage (NumUsrsTotal ? (double) NumUsrs * 100.0 / + (double) NumUsrsTotal : + 0.0); + HTM_TD_End (); + + HTM_TD_Begin ("class=\"RM %s LINE_TOP\"",The_ClassDatStrong[Gbl.Prefs.Theme]); + HTM_Double2Decimals (NumUsrs ? (double) NumNotes / (double) NumUsrs : + 0.0); + HTM_TD_End (); + + HTM_TR_End (); + + /***** End table and box *****/ + Box_BoxTableEnd (); + } diff --git a/swad_timeline.h b/swad_timeline.h index e046ae38..32bece45 100644 --- a/swad_timeline.h +++ b/swad_timeline.h @@ -113,4 +113,7 @@ void Tml_RefreshOldTimelineUsr (void); void Tml_WriteDateTime (time_t TimeUTC); +//-------------------------------- Figures ------------------------------------ +void Tml_GetAndShowTimelineActivityStats (void); + #endif