// swad_figure.c: figures (global stats) /* SWAD (Shared Workspace At a Distance), is a web platform developed at the University of Granada (Spain), and used to support university teaching. This file is part of SWAD core. Copyright (C) 1999-2021 Antonio Caņas Vargas This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ /*****************************************************************************/ /********************************* 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_box.h" #include "swad_browser_database.h" #include "swad_database.h" #include "swad_error.h" #include "swad_exam_database.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_timeline.h" #include "swad_timeline_database.h" #include "swad_timeline_note.h" #include "swad_user_database.h" /*****************************************************************************/ /************** External global variables from others modules ****************/ /*****************************************************************************/ 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 ***************************/ /*****************************************************************************/ 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 *************************/ /*****************************************************************************/ void Fig_ReqShowFigures (void) { Fig_ReqShowFigure (Fig_FIGURE_TYPE_DEF); } static void Fig_ReqShowFigure (Fig_FigureType_t SelectedFigureType) { extern const char *Hlp_ANALYTICS_Figures; extern const char *The_ClassFormInBox[The_NUM_THEMES]; extern const char *The_ClassInput[The_NUM_THEMES]; extern const char *Txt_Figures; extern const char *Txt_Scope; extern const char *Txt_Statistic; extern const char *Txt_FIGURE_TYPES[Fig_NUM_FIGURES]; extern const char *Txt_Show_statistic; Fig_FigureType_t FigType; unsigned FigureTypeUnsigned; /***** Form to show statistic *****/ Frm_BeginForm (ActSeeUseGbl); /***** Begin box *****/ Box_BoxBegin (NULL,Txt_Figures, NULL,NULL, Hlp_ANALYTICS_Figures,Box_NOT_CLOSABLE); /***** Compute stats for anywhere, degree or course? *****/ HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); HTM_TxtColonNBSP (Txt_Scope); Gbl.Scope.Allowed = 1 << HieLvl_SYS | 1 << HieLvl_CTY | 1 << HieLvl_INS | 1 << HieLvl_CTR | 1 << HieLvl_DEG | 1 << HieLvl_CRS; Gbl.Scope.Default = HieLvl_SYS; Sco_GetScope ("ScopeFig"); Sco_PutSelectorScope ("ScopeFig",HTM_DONT_SUBMIT_ON_CHANGE); HTM_LABEL_End (); HTM_BR (); /***** Type of statistic *****/ HTM_LABEL_Begin ("class=\"%s\"",The_ClassFormInBox[Gbl.Prefs.Theme]); HTM_TxtColonNBSP (Txt_Statistic); HTM_SELECT_Begin (HTM_DONT_SUBMIT_ON_CHANGE, "name=\"FigureType\" class=\"%s\"", The_ClassInput[Gbl.Prefs.Theme]); for (FigType = (Fig_FigureType_t) 0; FigType <= (Fig_FigureType_t) (Fig_NUM_FIGURES - 1); FigType++) { FigureTypeUnsigned = (unsigned) FigType; HTM_OPTION (HTM_Type_UNSIGNED,&FigureTypeUnsigned, FigType == SelectedFigureType,false, "%s",Txt_FIGURE_TYPES[FigType]); } HTM_SELECT_End (); HTM_LABEL_End (); /***** Send button and end box *****/ Box_BoxWithButtonEnd (Btn_CONFIRM_BUTTON,Txt_Show_statistic); /***** End form *****/ Frm_EndForm (); } /*****************************************************************************/ /************************* Put icon to show a figure *************************/ /*****************************************************************************/ void Fig_PutIconToShowFigure (Fig_FigureType_t FigureType) { extern const char *Txt_Show_statistic; struct Fig_Figures Figures; /***** Set default scope (used only if Gbl.Scope.Current is unknown) *****/ Gbl.Scope.Default = HieLvl_CRS; Sco_AdjustScope (); /***** Put icon to show figure *****/ Figures.Scope = Gbl.Scope.Current; Figures.FigureType = FigureType; Lay_PutContextualLinkOnlyIcon (ActSeeUseGbl,NULL, Fig_PutHiddenParamFigures,&Figures, "chart-pie.svg",Ico_BLACK, Txt_Show_statistic); } /*****************************************************************************/ /************* Put hidden parameters for figures (statistics) ****************/ /*****************************************************************************/ void Fig_PutHiddenParamFigures (void *Figures) { if (Figures) { Fig_PutHiddenParamScopeFig (((struct Fig_Figures *) Figures)->Scope); Fig_PutHiddenParamFigureType (((struct Fig_Figures *) Figures)->FigureType); } } /*****************************************************************************/ /********* Put hidden parameter for the type of figure (statistic) ***********/ /*****************************************************************************/ static void Fig_PutHiddenParamFigureType (Fig_FigureType_t FigureType) { Par_PutHiddenParamUnsigned (NULL,"FigureType",(unsigned) FigureType); } /*****************************************************************************/ /********* Put hidden parameter for the type of figure (statistic) ***********/ /*****************************************************************************/ static void Fig_PutHiddenParamScopeFig (HieLvl_Level_t ScopeFig) { Sco_PutParamScope ("ScopeFig",ScopeFig); } /*****************************************************************************/ /************************** Show use of the platform *************************/ /*****************************************************************************/ void Fig_ShowFigures (void) { static void (*Fig_Function[Fig_NUM_FIGURES])(void) = // Array of pointers to functions { [Fig_USERS ] = Usr_GetAndShowUsersStats, [Fig_USERS_RANKING ] = Usr_GetAndShowUsersRanking, [Fig_HIERARCHY ] = Hie_GetAndShowHierarchyStats, [Fig_INSTITS ] = Ins_GetAndShowInstitutionsStats, [Fig_DEGREE_TYPES ] = DegTyp_GetAndShowDegreeTypesStats, [Fig_FOLDERS_AND_FILES] = Brw_GetAndShowFileBrowsersStats, [Fig_OER ] = Brw_GetAndShowOERsStats, [Fig_COURSE_PROGRAMS ] = Prg_GetAndShowCourseProgramStats, [Fig_ASSIGNMENTS ] = Asg_GetAndShowAssignmentsStats, [Fig_PROJECTS ] = Prj_GetAndShowProjectsStats, [Fig_TESTS ] = Tst_GetAndShowTestsStats, [Fig_EXAMS ] = Exa_GetAndShowExamsStats, [Fig_GAMES ] = Gam_GetAndShowGamesStats, [Fig_SURVEYS ] = Svy_GetAndShowSurveysStats, [Fig_TIMELINE ] = Tml_GetAndShowTimelineActivityStats, [Fig_FOLLOW ] = Fol_GetAndShowFollowStats, [Fig_FORUMS ] = For_GetAndShowForumStats, [Fig_NOTIFY_EVENTS ] = Ntf_GetAndShowNumUsrsPerNotifyEvent, [Fig_NOTICES ] = Not_GetAndShowNoticesStats, [Fig_MESSAGES ] = Msg_GetAndShowMsgsStats, [Fig_AGENDAS ] = Agd_GetAndShowAgendasStats, [Fig_SOCIAL_NETWORKS ] = Net_ShowWebAndSocialNetworksStats, [Fig_LANGUAGES ] = Lan_GetAndShowNumUsrsPerLanguage, [Fig_FIRST_DAY_OF_WEEK] = Cal_GetAndShowNumUsrsPerFirstDayOfWeek, [Fig_DATE_FORMAT ] = Dat_GetAndShowNumUsrsPerDateFormat, [Fig_ICON_SETS ] = Ico_GetAndShowNumUsrsPerIconSet, [Fig_MENUS ] = Mnu_GetAndShowNumUsrsPerMenu, [Fig_THEMES ] = The_GetAndShowNumUsrsPerTheme, [Fig_SIDE_COLUMNS ] = Lay_GetAndShowNumUsrsPerSideColumns, [Fig_PHOTO_SHAPES ] = PhoSha_GetAndShowNumUsrsPerPhotoShape, [Fig_PRIVACY ] = Pri_GetAndShowNumUsrsPerPrivacy, [Fig_COOKIES ] = Coo_GetAndShowNumUsrsPerCookies, }; Fig_FigureType_t SelectedFigureType; /***** Get the type of figure ******/ SelectedFigureType = (Fig_FigureType_t) Par_GetParToUnsignedLong ("FigureType", 0, Fig_NUM_FIGURES - 1, (unsigned long) Fig_FIGURE_TYPE_DEF); /***** Show again the form to see use of the platform *****/ Fig_ReqShowFigure (SelectedFigureType); /***** 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 (); }