* @copyright 2001-2007 VIKO team and contributors * @license http://www.gnu.org/licenses/gpl.html GPL 2.0 */ require_once 'Module.php'; require_once 'VikoTable.php'; /** * Shows the statictics of all schools or one school in VIKO * * */ class Module_Statistics extends Module { /** * The school to show statistics about * * If null, then statistics of all schools is shown. * * @var School */ var $_selected_school = null; /** * Constructs new Statistics Module * * @param array $parameters parameters to the module */ function Module_Statistics( $parameters ) { if ( isset($parameters[0]) && (int)$parameters[0] > 0 ) { $this->_selected_school =& new School( (int)$parameters[0] ); } // schooladmins may only access the school of their own if ( !$_SESSION['user']->hasAccessToGroup("ADMIN") ) { $this->_selected_school = $_SESSION['user']->getSchool(); } } /** * Returns the module identifier string * * @access public * @static * @return string Identificator of module */ function getID() { return "statistics"; } /** * Log out from VIKO * * @return string HTML content */ function toHTML() { // access is only allowed for schooladmins and admins if ( !$_SESSION['user']->hasAccessToGroup("SCHOOLADMIN") ) { return $this->accessDeniedPage( _("You are not authorized to access school statistics.") ); } // test that the school to be accessed really exists if ( isset($this->_selected_school) && !$this->_selected_school->loadFromDatabaseByID() ) { return $this->errorPage( _("The school you are trying to access does not exist.") ); } if ( isset( $this->_selected_school ) ) { return $this->_schoolStatistics(); } else { return $this->_globalStatistics(); } } /** * Statistics about all the schools in VIKO * * @access private * @return string HTML */ function _globalStatistics() { $html = $this->title( _("VIKO server statistics") ); $html .= $this->_schoolsTable(); $html .= HTML::actionList( HTML::backLink( $this->URI("my-viko"), _("Return to the main page") ), HTML::newLink( $this->URI("school", "add"), _("Add school") ) ); return $html; } /** * Returns HTML table with all schools in VIKO * * @access private * @return string HTML */ function _schoolsTable() { $db = DBInstance::get(); $orderby = DBUtils::createOrderBy( array( 'school_name' ) ); $result = $db->query("SELECT school_id, school_name FROM Schools $orderby"); if ( $result->numRows() == 0 ) { return HTML::notice( _("There are no schools in VIKO. Create new school using the link below.") ); } $table =& new VikoTable( _("List of all schools in VIKO server.") ); $table->addHeader( _("School name"), _("Nr of teachers"), _("Nr of students"), _("Nr of courses"), _("Size of files"), HTML::abbr( "X", _("Delete school") ) ); $nr_of_schools = 0; $nr_of_active_schools = 0; $total_teachers = 0; $total_students = 0; $total_courses = 0; $total_files = 0; while ( $result->fetchInto( $school_r ) ) { $school =& new School( $school_r['school_id'] ); $school->setName( $school_r['school_name'] ); $school_link = HTML::a( $this->URI("statistics", $school->getID()), $school->getHTMLName() ); $delete_title = sprintf( _("Delete %s"), $school->getHTMLName() ); $delete_link = HTML::a( $this->URI("school", "delete", $school->getID()), "X", $delete_title ); $nr_of_schools++; $nr_of_teachers = $db->getOne( "SELECT COUNT(*) FROM Users WHERE user_group='TEACHER' AND school_id=?", array( $school->getID() ) ); $total_teachers += $nr_of_teachers; $nr_of_students = $db->getOne( "SELECT COUNT(*) FROM Users WHERE user_group='STUDENT' AND school_id=?", array( $school->getID() ) ); $total_students += $nr_of_students; // count active schools if ( $nr_of_students >= 10 ) { $nr_of_active_schools ++; } $nr_of_courses = $db->getOne( "SELECT COUNT(*) FROM Courses JOIN Users ON ( Courses.teacher_id = Users.user_id ) WHERE school_id=?", array( $school->getID() ) ); $total_courses += $nr_of_courses; $size_of_files = $db->getOne( "SELECT SUM(material_size)/1024/1024 FROM Materials JOIN Courses ON ( Materials.course_id = Courses.course_id ) JOIN Users ON ( Courses.teacher_id = Users.user_id ) WHERE school_id=?", array( $school->getID() ) ); $total_files += $size_of_files; $size_of_files = round($size_of_files) . " MB"; $table->addRow( $school_link, $nr_of_teachers, $nr_of_students, $nr_of_courses, $size_of_files, $delete_link ); } $table->addFooter( _("Total"), $total_teachers, $total_students, $total_courses, round($total_files) . " MB", "" ); $table->setColumnsToNumeric( array(1,2,3,4), TABLE_BODY_AND_FOOTER ); $table->setColumnToDelete( 5 ); $html = $table->toHTML(); $schools_text = _("Total %nr1% schools in VIKO. %nr2% of these having at least 10 students."); $schools_text = str_replace( '%nr1%', HTML::strong( $nr_of_schools ), $schools_text ); $schools_text = str_replace( '%nr2%', HTML::strong( $nr_of_active_schools ), $schools_text ); $html .= HTML::p( $schools_text ); return $html; } /** * Statistics about one school * * @access private * @return string HTML */ function _schoolStatistics() { $school = $this->_selected_school; $html = $this->title( _("School statistics") . ': ' . $school->getHTMLName() ); // admins need a simple way to add-remove schooladmins a school if ( $_SESSION['user']->hasAccessToGroup("ADMIN") ) { $html .= "

" . _("School administrators") . "

"; $html .= $this->_schooladminsManagement(); } $html .= "

" . _("Users") . "

"; $html .= $this->_usersStatistics(); $html .= "

" . _("General statistics") . "

"; $html .= $this->_generalSchoolStatistics(); $html .= "

" . _("Courses") . "

"; $html .= $this->_coursesStatistics(); // backlink if ( $_SESSION['user']->hasAccessToGroup("ADMIN") ) { $html.= HTML::actionList( HTML::backLink( $this->URI("statistics"), _("Return to the list of all schools") ), HTML::actionLink( $this->URI("school", "edit", $this->_selected_school->getID()), _("Change school name"), "edit" ) ); } else { $html.= HTML::backLink( $this->URI("my-viko"), _("Return to the main page"), STANDALONE ); } return $html; } /** * Controls for adding/deleting/managing schooladmins * * @access private * @return string HTML */ function _schooladminsManagement() { $list = $this->_schooladminsList(); $links = HTML::newLink( $this->URI("user", "add", "schooladmin", "0", $this->_selected_school->getID()), _("Add school administrator"), STANDALONE ); return $list . $links; } /** * Table with all the schooladmins in the school * * @access private * @return string HTML */ function _schooladminsList() { $db = DBInstance::get(); $orderby = DBUtils::createOrderBy( array( 'lastname', 'firstname' ) ); $result = $db->query( "SELECT user_id, lastname, firstname FROM Users WHERE school_id=? AND user_group='SCHOOLADMIN'", array( $this->_selected_school->getID() ) ); // If we get error here, we die. if ( PEAR::isError($result) ) { trigger_error( $result->getMessage(), E_USER_ERROR ); } if ( $result->numRows() == 0 ) { return HTML::notice( _("There are no school administrators in this school.") ); } $table =& new VikoTable( _("List of all schooladmins in this school") ); $table->addHeader( _("Name"), HTML::abbr( "X", _("Delete user") ) ); while ( $result->fetchInto( $row ) ) { $user =& new User(); $user->setID( $row['user_id'] ); $user->setFirstName( $row['firstname'] ); $user->setLastName( $row['lastname'] ); $user_link = $user->getUserLink( LASTNAME_FIRSTNAME ); $user_name = $user->getFullName( LASTNAME_FIRSTNAME ); $delete_title = sprintf( _("Delete %s"), $user_name ); $delete_link = HTML::a( $this->URI('user', 'delete', $user->getID()), 'X', $delete_title ); $table->addRow( $user_link, $delete_link ); } $table->setColumnToDelete( 1 ); return $table->toHTML(); } /** * General statistics about the school * * @access private * @return string HTML */ function _generalSchoolStatistics() { $table =& new VikoTable( _("Number of classes, courses and lessons in the school") ); $table->addHeader( _("Entity"), _("Count") ); $db = DBInstance::get(); // Forms $nr_of_forms = $db->getOne( "SELECT COUNT(*) FROM Forms WHERE school_id=?", array( $this->_selected_school->getID() ) ); $table->addRow( _("Forms"), $nr_of_forms ); // Courses $nr_of_courses = $db->getOne( "SELECT COUNT(*) FROM Courses JOIN Users ON (Courses.teacher_id=Users.user_id) WHERE school_id=? ", array( $this->_selected_school->getID() ) ); $table->addRow( _("Courses"), $nr_of_courses ); // Lessons $nr_of_lessons = $db->getOne( "SELECT COUNT(*) FROM Lessons JOIN Courses ON (Courses.course_id=Lessons.course_id) JOIN Users ON (Courses.teacher_id=Users.user_id) WHERE school_id=? ", array( $this->_selected_school->getID() ) ); $table->addRow( _("Lessons"), $nr_of_lessons ); $table->setColumnsToNumeric( array( 1 ) ); return $table->toHTML(); } /** * General statistics about user groups in school * * @access private * @return string HTML */ function _usersStatistics() { $table =& new VikoTable( _("Number of users from different groups in the school") ); $table->addHeader( _("User group"), _("Nr of users") ); // get information about all user groups of this school $db = DBInstance::get(); $users = $db->query( "SELECT user_group, COUNT(*) as count FROM Users WHERE school_id=? GROUP BY user_group ORDER BY count DESC ", array( $this->_selected_school->getID() ) ); $total_users = 0; if ( $users->numRows() == 0 ) { return HTML::notice( _("There are no users in this school.") ); } while ( $users->fetchInto( $user_group ) ) { switch ( $user_group['user_group'] ) { case 'ADMIN': $group_name = _("Administrators"); break; case 'SCHOOLADMIN': $group_name = _("School administrators"); break; case 'TEACHER': $group_name = _("Teachers"); break; case 'STUDENT': $group_name = _("Students"); break; } $table->addRow( $group_name, $user_group['count'] ); $total_users += $user_group['count']; } $table->addFooter( _("Total"), $total_users ); $table->setColumnsToNumeric( array( 1 ), TABLE_BODY_AND_FOOTER ); return $table->toHTML(); } /** * Statistics about all the courses in school * * @access private * @return string HTML */ function _coursesStatistics() { // table header $table =& new VikoTable( _("List of all courses in this school.") ); $table->addHeader( _("Course name"), _("Nr of students"), _("Nr of visits"), _("Nr of grades"), _("Nr of messages"), _("Nr of materials"), _("Size of files") ); $db = DBInstance::get(); $orderby = DBUtils::createOrderBy( array( 'course_name' ) ); $result = $db->query( "SELECT course_id AS id, course_name AS name FROM Courses JOIN Users ON (Courses.teacher_id=Users.user_id) WHERE school_id=? $orderby", array( $this->_selected_school->getID() ) ); if ( $result->numRows() == 0 ) { return HTML::notice( _("There are no courses in this school.") ); } $total_students = 0; $total_visits = 0; $total_grades = 0; $total_posts = 0; $total_materials = 0; $total_filesize = 0; while ( $result->fetchInto( $course_record ) ) { $course =& new Course(); $course->setID( $course_record['id'] ); $course->setName( $course_record['name'] ); $course_name = $course->getHTMLName(); $nr_of_students = StudentList::getCountFromCourse( $course ); $total_students += $nr_of_students; $nr_of_visits = $db->getOne( "SELECT SUM(total_views) FROM Courses_Users WHERE course_id=?", array( $course->getID() ) ); // if not a single user is on any of the courses, // the sum will result in empty string instead of zero. $nr_of_visits += 0; $total_visits += $nr_of_visits; $nr_of_grades = $db->getOne( "SELECT COUNT(*) FROM Marks JOIN Lessons USING (lesson_id) WHERE course_id=?", array( $course->getID() ) ); $total_grades += $nr_of_grades; $nr_of_posts = $db->getOne( "SELECT COUNT(*) FROM Posts JOIN Topics USING (topic_id) WHERE course_id=?", array( $course->getID() ) ); $total_posts += $nr_of_posts; $nr_of_materials = $db->getOne( "SELECT COUNT(*) FROM Materials WHERE course_id=?", array( $course->getID() ) ); $total_materials += $nr_of_materials; $size_of_files = $db->getOne( "SELECT SUM(material_size) FROM Materials WHERE course_id=?", array( $course->getID() ) ); $total_filesize += $size_of_files; $size_of_files = round( $size_of_files / 1024 ) . ' KB'; $table->addRow( $course_name, $nr_of_students, $nr_of_visits, $nr_of_grades, $nr_of_posts, $nr_of_materials, $size_of_files ); } $table->addFooter( _("Total"), $total_students, $total_visits, $total_grades, $total_posts, $total_materials, round( $total_filesize / 1024 / 1024 ) . ' MB' ); $table->setColumnsToNumeric( array( 1,2,3,4,5,6 ), TABLE_BODY_AND_FOOTER ); return $table->toHTML(); } } ?>