From 6645ea2f74eb2c0e88fe34ac559f6caa7fa8b8a0 Mon Sep 17 00:00:00 2001 From: Angel Fernando Quiroz Campos Date: Fri, 18 Dec 2015 17:24:40 -0500 Subject: [PATCH] Add User Access Overview report --- main/inc/ajax/course.ajax.php | 26 +- main/inc/ajax/session.ajax.php | 14 +- main/inc/lib/myspace.lib.php | 238 ++++++++++++++++++ main/inc/lib/sessionmanager.lib.php | 12 +- main/mySpace/admin_view.php | 7 + .../default/my_space/accessoverview.tpl | 36 +++ 6 files changed, 313 insertions(+), 20 deletions(-) create mode 100644 main/template/default/my_space/accessoverview.tpl diff --git a/main/inc/ajax/course.ajax.php b/main/inc/ajax/course.ajax.php index babd99d765..b8a78dc73c 100755 --- a/main/inc/ajax/course.ajax.php +++ b/main/inc/ajax/course.ajax.php @@ -137,7 +137,7 @@ switch ($action) { $_GET['session_id'], $_GET['q'] ); - $results2 = array(); + $results2 = ['items' => []]; if (!empty($results)) { foreach ($results as $item) { $item2 = array(); @@ -149,12 +149,11 @@ switch ($action) { $item2['text'] = $internal; } } - $results2[] = $item2; + $results2['items'][] = $item2; } - echo json_encode($results2); - } else { - echo json_encode(array()); } + + echo json_encode($results2); } break; case 'search_user_by_course': @@ -164,6 +163,10 @@ switch ($action) { $course = api_get_course_info_by_id($_GET['course_id']); + $json = [ + 'items' => [] + ]; + $sql = "SELECT u.user_id as id, u.username, u.lastname, u.firstname FROM $user u INNER JOIN $session_course_user r ON u.user_id = r.user_id @@ -174,14 +177,15 @@ switch ($action) { $result = Database::query($sql_query); while ($user = Database::fetch_assoc($result)) { - $data[] = array('id' => $user['id'], 'text' => $user['username'] . ' (' . $user['firstname'] . ' ' . $user['lastname'] . ')'); + $userCompleteName = api_get_person_name($user['firstname'], $user['lastname']); + $json['items'][] = [ + 'id' => $user['id'], + 'text' => "{$user['username']} ($userCompleteName)" + ]; } - if (!empty($data)) { - echo json_encode($data); - } else { - echo json_encode(array()); - } + + echo json_encode($json); } break; case 'search_exercise_by_course': diff --git a/main/inc/ajax/session.ajax.php b/main/inc/ajax/session.ajax.php index c4e0fcc2c6..83633fd8cf 100755 --- a/main/inc/ajax/session.ajax.php +++ b/main/inc/ajax/session.ajax.php @@ -90,7 +90,11 @@ switch ($action) { 'c.id' => array('operator' => '=', 'value' => $_REQUEST['course_id']) ) ); - $results2 = array(); + $json = [ + 'items' => [ + ['id' => 'T', 'text' => get_lang('All')] + ] + ]; if (!empty($results)) { foreach ($results as $item) { $item2 = array(); @@ -102,13 +106,11 @@ switch ($action) { $item2['text'] = $internal; } } - $results2[] = $item2; + $json['items'][] = $item2; } - $results2[] = array('T', 'text' => 'TODOS', 'id' => 'T'); - echo json_encode($results2); - } else { - echo json_encode(array(array('T', 'text' => 'TODOS', 'id' => 'T'))); } + + echo json_encode($json); } break; case 'get_description': diff --git a/main/inc/lib/myspace.lib.php b/main/inc/lib/myspace.lib.php index 1414db74f9..b92378b299 100644 --- a/main/inc/lib/myspace.lib.php +++ b/main/inc/lib/myspace.lib.php @@ -25,6 +25,7 @@ class MySpace array('url' => api_get_path(WEB_CODE_PATH).'mySpace/admin_view.php?display=course', 'content' => get_lang('DisplayCourseOverview')), array('url' => api_get_path(WEB_CODE_PATH).'tracking/question_course_report.php?view=admin', 'content' => get_lang('LPQuestionListResults')), array('url' => api_get_path(WEB_CODE_PATH).'tracking/course_session_report.php?view=admin', 'content' => get_lang('LPExerciseResultsBySession')), + ['url' => api_get_path(WEB_CODE_PATH) . 'mySpace/admin_view.php?display=accessoverview', 'content' => get_lang('DisplayAccessOverview') . ' (' . get_lang('Beta') . ')'] ); return Display :: actions($actions, null); @@ -2726,6 +2727,243 @@ class MySpace xml_parser_free($parser); return $users; } + + public static function displayTrackingAccessOverView($courseId, $sessionId, $studentId) + { + $courseId = intval($courseId); + $sessionId = intval($sessionId); + $studentId = intval($studentId); + + $em = Database::getManager(); + $sessionRepo = $em->getRepository('ChamiloCoreBundle:Session'); + + $courseList = []; + $sessionList = []; + $studentList = []; + + if (!empty($courseId)) { + $course = $em->find('ChamiloCoreBundle:Course', $courseId); + + $courseList[$course->getId()] = $course->getTitle(); + } + + if (!empty($sessionId)) { + $session = $em->find('ChamiloCoreBundle:Session', $sessionId); + + $sessionList[$session->getId()] = $session->getName(); + } + + if (!empty($studentId)) { + $student = $em->find('ChamiloUserBundle:User', $studentId); + + $studentList[$student->getId()] = $student->getCompleteName(); + } + + $form = new FormValidator('access_overview', 'GET'); + $form->addElement( + 'select_ajax', + 'course_id', + get_lang('SearchCourse'), + $courseList, + [ + 'url' => api_get_path(WEB_AJAX_PATH) . 'course.ajax.php?' . http_build_query([ + 'a' => 'search_course_by_session_all', + 'session_id' => $sessionId + ]) + ] + ); + $form->addElement( + 'select_ajax', + 'session_id', + get_lang('SearchSession'), + $sessionList, + [ + 'url_function' => " + function () { + var params = $.param({ + a: 'search_session_by_course', + course_id: $('#course_id').val() || 0 + }); + + return '" . api_get_path(WEB_AJAX_PATH) . "session.ajax.php?' + params; + } + " + ] + ); + $form->addSelect( + 'profile', + get_lang('Profile'), + [ + '' => get_lang('Select'), + STUDENT => get_lang('Student'), + COURSEMANAGER => get_lang('CourseManager'), + DRH => get_lang('Drh') + ], + ['id' => 'profile'] + ); + $form->addElement( + 'select_ajax', + 'student_id', + get_lang('SearchUsers'), + $studentList, + [ + 'placeholder' => get_lang('All'), + 'url_function' => " + function () { + var params = $.param({ + a: 'search_user_by_course', + session_id: $('#session_id').val(), + course_id: $('#course_id').val() + }); + + return '" . api_get_path(WEB_AJAX_PATH) . "course.ajax.php?' + params; + } + " + ] + ); + $form->addDateRangePicker( + 'date', + get_lang('DateRange'), + true, + [ + 'id' => 'date_range', + 'format' => 'YYYY-MM-DD', + 'timePicker' => 'false', + 'validate_format' => 'Y-m-d' + ] + ); + $form->addHidden('display', 'accessoverview'); + $form->addRule('course_id', get_lang('Required'), 'required'); + $form->addRule('profile', get_lang('Required'), 'required'); + $form->addButton('submit', get_lang('Generate'), 'gear', 'primary'); + + $table = null; + + if ($form->validate()) { + $table = new SortableTable( + 'tracking_access_overview', + ['MySpace','getNumberOfRrackingAccessOverview'], + ['MySpace','getUserDataAccessTrackingOverview'], + 0 + ); + $table->additional_parameters = $form->exportValues(); + + $table->set_header(0, get_lang('LoginDate'), true); + $table->set_header(1, get_lang('Username'), true); + if (api_is_western_name_order()) { + $table->set_header(2, get_lang('FirstName'), true); + $table->set_header(3, get_lang('LastName'), true); + } else { + $table->set_header(2, get_lang('LastName'), true); + $table->set_header(3, get_lang('FirstName'), true); + } + $table->set_header(4, get_lang('Clicks'), false); + $table->set_header(5, get_lang('IP'), false); + $table->set_header(6, get_lang('TimeLoggedIn'), false); + } + + $template = new Template(null, false, false, false, false, false, false); + $template->assign('form', $form->returnForm()); + $template->assign('table', $table ? $table->return_table() : null); + + echo $template->fetch( + $template->get_template('my_space/accessoverview.tpl') + ); + } + + public static function getNumberOfRrackingAccessOverview() + { + $track_e_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); + + return Database::count_rows($track_e_course_access); + } + + public static function getUserDataAccessTrackingOverview($from, $numberItems, $column, $orderDirection) + { + $user = Database::get_main_table(TABLE_MAIN_USER); + $course = Database::get_main_table(TABLE_MAIN_COURSE); + $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN); + $track_e_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); + + global $export_csv; + + if ($export_csv) { + $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT); + } else { + $is_western_name_order = api_is_western_name_order(); + } + + //TODO add course name + $sql = "SELECT + a.login_course_date as col0, + u.username as col1, + " . ( + $is_western_name_order ? " + u.firstname AS col2, + u.lastname AS col3, + " : " + u.lastname AS col2, + u.firstname AS col3, + " ) . " + a.logout_course_date, + c.title, + c.code, + u.user_id + FROM $track_e_course_access a + INNER JOIN $user u ON a.user_id = u.user_id + INNER JOIN $course c ON a.c_id = c.id"; + + if (isset($_GET['session_id']) && !empty($_GET['session_id'])) { + $sessionId = intval($_GET['session_id']); + $sql .= " WHERE a.session_id = " . $sessionId; + } + + $sql .= " ORDER BY col$column $orderDirection "; + $sql .= " LIMIT $from,$numberItems"; + $result = Database::query($sql); + + //$clicks = Tracking::get_total_clicks_by_session(); + $data = array(); + + while ($user = Database::fetch_assoc($result)) { + $data[] = $user; + } + + $return = []; + + //TODO: Dont use numeric index + foreach ($data as $key => $info) { + $start_date = $info['col0']; + + $end_date = $info['logout_course_date']; + + $return[$info['user_id']] = array( + $start_date, + $info['col1'], + $info['col2'], + $info['col3'], + $info['user_id'], + 'ip', + //TODO is not correct/precise, it counts the time not logged between two loggins + gmdate("H:i:s", strtotime($end_date) - strtotime($start_date)) + ); + } + + foreach ($return as $key => $info) { + $ipResult = Database::select( + 'user_ip', + $track_e_login, + ['where' => [ + '? BETWEEN login_date AND logout_date' => $info[0] + ]], + 'first' + ); + + $return[$key][5] = $ipResult['user_ip']; + } + + return $return; + } } /** diff --git a/main/inc/lib/sessionmanager.lib.php b/main/inc/lib/sessionmanager.lib.php index 006f26afad..da997439ee 100755 --- a/main/inc/lib/sessionmanager.lib.php +++ b/main/inc/lib/sessionmanager.lib.php @@ -2631,6 +2631,7 @@ class SessionManager $availableFields = array( 's.id', 's.name', + 'c.id' ); $availableOperator = array( @@ -3340,12 +3341,17 @@ class SessionManager $course_name = Database::escape_string($course_name); // select the courses - $sql = "SELECT * FROM $tbl_course c + $sql = "SELECT c.id, c.title FROM $tbl_course c INNER JOIN $tbl_session_rel_course src ON c.id = src.c_id - WHERE src.session_id LIKE '$session_id'"; + WHERE "; + + if (!empty($session_id)) { + $sql .= "src.session_id LIKE '$session_id' AND "; + } + if (!empty($course_name)) { - $sql .= " AND UPPER(c.title) LIKE UPPER('%$course_name%') "; + $sql .= "UPPER(c.title) LIKE UPPER('%$course_name%') "; } $sql .= "ORDER BY title;"; diff --git a/main/mySpace/admin_view.php b/main/mySpace/admin_view.php index 6d2257ae1c..43d8b1932e 100644 --- a/main/mySpace/admin_view.php +++ b/main/mySpace/admin_view.php @@ -51,6 +51,13 @@ switch ($display) { case 'course': MySpace::display_tracking_course_overview(); break; + case 'accessoverview': + $courseId = isset($_GET['course_id']) ? intval($_GET['course_id']) : 0; + $sessionId = isset($_GET['session_id']) ? intval($_GET['session_id']) : 0; + $studentId = isset($_GET['student_id']) ? intval($_GET['student_id']) : 0; + + MySpace::displayTrackingAccessOverView($courseId, $sessionId, $studentId); + break; } Display::display_footer(); diff --git a/main/template/default/my_space/accessoverview.tpl b/main/template/default/my_space/accessoverview.tpl new file mode 100644 index 0000000000..0efdcdff27 --- /dev/null +++ b/main/template/default/my_space/accessoverview.tpl @@ -0,0 +1,36 @@ + + +{{ form }} + + + +{{ table }} + +