Statistics: Fix errors and improve data handling in admin reports - refs BT#22248

pull/5966/head
Christian Beeznest 9 months ago
parent ac17881087
commit c6e300ee0c
  1. 4
      public/main/admin/statistics/index.php
  2. 1
      public/main/inc/lib/database.constants.inc.php
  3. 121
      public/main/inc/lib/statistics.lib.php
  4. 23
      public/main/inc/lib/zombie/zombie_manager.class.php
  5. 16
      public/main/inc/lib/zombie/zombie_report.class.php

@ -372,6 +372,8 @@ switch ($report) {
$sessions = [];
if ($validated) {
$values = $form->getSubmitValues();
$dateStart = $values['range_start'];
$dateEnd = $values['range_end'];
$first = DateTime::createFromFormat('Y-m-d', $dateStart);
$second = DateTime::createFromFormat('Y-m-d', $dateEnd);
$numberOfWeeks = 0;
@ -549,7 +551,7 @@ switch ($report) {
foreach ($sessions as $session) {
$courseList = SessionManager::getCoursesInSession($session['id']);
$table->setCellContents($row, 0, $session['name']);
$table->setCellContents($row, 0, $session['title']);
$table->setCellContents($row, 1, api_get_local_time($session['display_start_date']));
$table->setCellContents($row, 2, api_get_local_time($session['display_end_date']));

@ -232,6 +232,7 @@ define('TABLE_NOTEBOOK', 'notebook');
// Message
define('TABLE_MESSAGE', 'message');
define('TABLE_MESSAGE_ATTACHMENT', 'message_attachment');
define('TABLE_MESSAGE_REL_USER', 'message_rel_user');
// Attendance Sheet
define('TABLE_ATTENDANCE', 'attendance');

@ -2,6 +2,7 @@
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
use Chamilo\CoreBundle\Entity\MessageRelUser;
use Chamilo\CoreBundle\Entity\UserRelUser;
use Chamilo\CoreBundle\Component\Utils\ActionIcon;
@ -136,47 +137,48 @@ class Statistics
$tblCourseCategory = Database::get_main_table(TABLE_MAIN_CATEGORY);
$tblCourseRelCategory = Database::get_main_table(TABLE_MAIN_COURSE_REL_CATEGORY);
$urlId = api_get_current_access_url_id();
$active_filter = $onlyActive ? ' AND active = 1' : '';
$status_filter = isset($status) ? ' AND status = '.intval($status) : '';
$conditions = [];
$conditions[] = "u.active <> " . USER_SOFT_DELETED;
if ($onlyActive) {
$conditions[] = "u.active = 1";
}
if (isset($status)) {
$conditions[] = "u.status = " . intval($status);
}
$where = implode(' AND ', $conditions);
if (api_is_multiple_url_enabled()) {
$sql = "SELECT COUNT(DISTINCT(u.id)) AS number
FROM $user_table as u, $access_url_rel_user_table as url
WHERE
u.active <> ".USER_SOFT_DELETED." AND
u.id = url.user_id AND
access_url_id = $urlId
$status_filter $active_filter";
FROM $user_table as u
INNER JOIN $access_url_rel_user_table as url ON u.id = url.user_id
WHERE $where AND url.access_url_id = $urlId";
if (isset($categoryCode)) {
$categoryCode = Database::escape_string($categoryCode);
$sql = "SELECT COUNT(DISTINCT(cu.user_id)) AS number
FROM $course_user_table cu, $course_table c, $access_url_rel_user_table as url, $tblCourseRelCategory crc, $tblCourseCategory cc
WHERE
c.id = cu.c_id AND
cc.code = '$categoryCode' AND
crc.course_category_id = cc.id AND
crc.course_id = c.id AND
cu.user_id = url.user_id AND
access_url_id = $urlId
$status_filter $active_filter";
FROM $course_user_table cu
INNER JOIN $course_table c ON c.id = cu.c_id
INNER JOIN $access_url_rel_user_table as url ON cu.user_id = url.user_id
INNER JOIN $tblCourseRelCategory crc ON crc.course_id = c.id
INNER JOIN $tblCourseCategory cc ON cc.id = crc.course_category_id
WHERE $where AND url.access_url_id = $urlId AND cc.code = '$categoryCode'";
}
} else {
$sql = "SELECT COUNT(DISTINCT(id)) AS number
FROM $user_table
WHERE 1 = 1 AND active <> ".USER_SOFT_DELETED." $status_filter $active_filter";
FROM $user_table u
WHERE $where";
if (isset($categoryCode)) {
$categoryCode = Database::escape_string($categoryCode);
$status_filter = isset($status) ? ' AND status = '.intval($status) : '';
$sql = "SELECT COUNT(DISTINCT(cu.user_id)) AS number
FROM $course_user_table cu, $course_table c, $tblCourseRelCategory crc, $tblCourseCategory cc
WHERE
c.id = cu.c_id AND
cc.code = '$categoryCode' AND
crc.course_category_id = cc.id AND
crc.course_id = c.id AND
$status_filter
$active_filter
";
FROM $course_user_table cu
INNER JOIN $course_table c ON c.id = cu.c_id
INNER JOIN $tblCourseRelCategory crc ON crc.course_id = c.id
INNER JOIN $tblCourseCategory cc ON cc.id = crc.course_category_id
INNER JOIN $user_table u ON u.id = cu.user_id
WHERE $where AND cc.code = '$categoryCode'";
}
}
@ -890,7 +892,7 @@ class Statistics
'get',
api_get_path(WEB_CODE_PATH).'admin/statistics/index.php',
'',
'width=200px',
['style' => 'width:200px'],
false
);
$renderer = &$form->defaultRenderer();
@ -941,7 +943,7 @@ class Statistics
$access_url_rel_course_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
$urlId = api_get_current_access_url_id();
$columns[0] = 't.c_id';
$columns[0] = 'c_id';
$columns[1] = 'access_date';
$sql_order[SORT_ASC] = 'ASC';
$sql_order[SORT_DESC] = 'DESC';
@ -972,15 +974,15 @@ class Statistics
if (api_is_multiple_url_enabled()) {
$sql = "SELECT * FROM $table t , $access_url_rel_course_table a
WHERE
t.c_id = a.c_id AND
c_id = a.c_id AND
access_url_id='".$urlId."'
GROUP BY t.c_id
HAVING t.c_id <> ''
GROUP BY c_id
HAVING c_id <> ''
AND DATEDIFF( '".api_get_utc_datetime()."' , access_date ) <= ".$date_diff;
} else {
$sql = "SELECT * FROM $table t
GROUP BY t.c_id
HAVING t.c_id <> ''
GROUP BY c_id
HAVING c_id <> ''
AND DATEDIFF( '".api_get_utc_datetime()."' , access_date ) <= ".$date_diff;
}
$sql .= ' ORDER BY `'.$columns[$column].'` '.$sql_order[$direction];
@ -1030,33 +1032,42 @@ class Statistics
*/
public static function getMessages($messageType)
{
$message_table = Database::get_main_table(TABLE_MESSAGE);
$user_table = Database::get_main_table(TABLE_MAIN_USER);
$access_url_rel_user_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
$messageTable = Database::get_main_table(TABLE_MESSAGE);
$messageRelUserTable = Database::get_main_table(TABLE_MESSAGE_REL_USER);
$userTable = Database::get_main_table(TABLE_MAIN_USER);
$accessUrlRelUserTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
$urlId = api_get_current_access_url_id();
switch ($messageType) {
case 'sent':
$field = 'user_sender_id';
$field = 'm.user_sender_id';
$joinCondition = "m.id = mru.message_id AND mru.receiver_type = " . MessageRelUser::TYPE_SENDER;
break;
case 'received':
$field = 'user_receiver_id';
$field = 'mru.user_id';
$joinCondition = "m.id = mru.message_id AND mru.receiver_type = " . MessageRelUser::TYPE_TO;
break;
}
if (api_is_multiple_url_enabled()) {
$sql = "SELECT lastname, firstname, username, COUNT($field) AS count_message
FROM $access_url_rel_user_table as url, $message_table m
LEFT JOIN $user_table u ON m.$field = u.id AND u.active <> ".USER_SOFT_DELETED."
WHERE url.user_id = m.$field AND access_url_id='".$urlId."'
GROUP BY m.$field
ORDER BY count_message DESC ";
$sql = "SELECT u.lastname, u.firstname, u.username, COUNT(DISTINCT m.id) AS count_message
FROM $messageTable m
INNER JOIN $messageRelUserTable mru ON $joinCondition
INNER JOIN $userTable u ON $field = u.id
INNER JOIN $accessUrlRelUserTable url ON u.id = url.user_id
WHERE url.access_url_id = $urlId
AND u.active <> " . USER_SOFT_DELETED . "
GROUP BY $field
ORDER BY count_message DESC";
} else {
$sql = "SELECT lastname, firstname, username, COUNT($field) AS count_message
FROM $message_table m
LEFT JOIN $user_table u ON m.$field = u.id AND u.active <> ".USER_SOFT_DELETED."
GROUP BY m.$field ORDER BY count_message DESC ";
$sql = "SELECT u.lastname, u.firstname, u.username, COUNT(DISTINCT m.id) AS count_message
FROM $messageTable m
INNER JOIN $messageRelUserTable mru ON $joinCondition
INNER JOIN $userTable u ON $field = u.id
WHERE u.active <> " . USER_SOFT_DELETED . "
GROUP BY $field
ORDER BY count_message DESC";
}
$res = Database::query($sql);
$messages_sent = [];
@ -1065,9 +1076,9 @@ class Statistics
$messages['username'] = get_lang('Unknown');
}
$users = api_get_person_name(
$messages['firstname'],
$messages['lastname']
).'<br />('.$messages['username'].')';
$messages['firstname'],
$messages['lastname']
) . '<br />(' . $messages['username'] . ')';
$messages_sent[$users] = $messages['count_message'];
}
@ -1144,7 +1155,7 @@ class Statistics
"SELECT count(distinct(login_user_id)) AS number ".
" FROM $table $table_url ".
" WHERE DATE_ADD(login_date, INTERVAL 31 DAY) >= '$now' $where_url";
$sql[sprintf(get_lang('Last %i months'), 6)] =
$sql[sprintf(get_lang('Last %d months'), 6)] =
"SELECT count(distinct(login_user_id)) AS number ".
" FROM $table $table_url ".
" WHERE DATE_ADD(login_date, INTERVAL 6 MONTH) >= '$now' $where_url";

@ -36,8 +36,14 @@ class ZombieManager
$column = 'user.firstname',
$direction = 'desc'
) {
$column = str_replace('user.', '', $column);
if (empty($column)) {
$column = 'user.firstname';
$column = 'firstname';
}
$validColumns = ['id', 'official_code', 'firstname', 'lastname', 'username', 'auth_source', 'email', 'status', 'registration_date', 'active', 'login_date'];
if (!in_array($column, $validColumns)) {
$column = 'firstname';
}
$ceiling = is_numeric($ceiling) ? (int) $ceiling : strtotime($ceiling);
$ceiling = date('Y-m-d H:i:s', $ceiling);
@ -46,7 +52,7 @@ class ZombieManager
$login_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
$sql = 'SELECT
user.user_id,
user.id,
user.official_code,
user.firstname,
user.lastname,
@ -66,20 +72,20 @@ class ZombieManager
WHERE
access.login_date = (SELECT MAX(a.login_date)
FROM $login_table as a
WHERE a.login_user_id = user.user_id
WHERE a.login_user_id = user.id
) AND
access.login_date <= '$ceiling' AND
user.user_id = access.login_user_id AND
url.user_id = user.user_id AND url.access_url_id=$current_url_id";
user.id = access.login_user_id AND
url.user_id = user.id AND url.access_url_id=$current_url_id";
} else {
$sql .= " FROM $user_table as user, $login_table as access
WHERE
access.login_date = (SELECT MAX(a.login_date)
FROM $login_table as a
WHERE a.login_user_id = user.user_id
WHERE a.login_user_id = user.id
) AND
access.login_date <= '$ceiling' AND
user.user_id = access.login_user_id";
user.id = access.login_user_id";
}
if ($active_only) {
@ -87,6 +93,7 @@ class ZombieManager
}
$sql .= !str_contains($sql, 'WHERE') ? ' WHERE user.active <> '.USER_SOFT_DELETED : ' AND user.active <> '.USER_SOFT_DELETED;
$column = str_replace('user.', '', $column);
$sql .= " ORDER BY `$column` $direction";
if (!is_null($from) && !is_null($count)) {
$count = (int) $count;
@ -107,7 +114,7 @@ class ZombieManager
$zombies = self::listZombies($ceiling);
$ids = [];
foreach ($zombies as $zombie) {
$ids[] = $zombie['user_id'];
$ids[] = $zombie['id'];
}
UserManager::deactivate_users($ids);
}

@ -3,7 +3,7 @@
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Component\Utils\StateIcon;
use Symfony\Component\HttpFoundation\Request;
/**
* Description of zombie_report.
*
@ -14,12 +14,14 @@ use Chamilo\CoreBundle\Component\Utils\StateIcon;
class ZombieReport implements Countable
{
protected $additional_parameters = [];
protected $request;
protected $parameters_form = null;
public function __construct($additional_parameters = [])
public function __construct($additional_parameters = [], Request $request = null)
{
$this->additional_parameters = $additional_parameters;
$this->request = $request ?? Request::createFromGlobals();
}
/**
@ -121,7 +123,7 @@ class ZombieReport implements Countable
public function get_ceiling($format = null)
{
$result = Request::get('ceiling');
$result = $this->request->get('ceiling');
$result = $result ? $result : ZombieManager::last_year();
$result = is_array($result) && 1 == count($result) ? reset($result) : $result;
@ -137,7 +139,7 @@ class ZombieReport implements Countable
public function get_active_only()
{
$result = Request::get('active_only', false);
$result = $this->request->get('active_only', $this->request->query->get('active_only'));
$result = 'true' === $result ? true : $result;
$result = 'false' === $result ? false : $result;
$result = (bool) $result;
@ -156,12 +158,12 @@ class ZombieReport implements Countable
return 'display';
}
return Request::post('action', 'display');
return $this->request->request->get('action', 'display');
}
public function perform_action()
{
$ids = Request::post('id');
$ids = $this->request->request->get('id');
if (empty($ids)) {
return $ids;
}
@ -198,7 +200,7 @@ class ZombieReport implements Countable
$result = [];
foreach ($items as $item) {
$row = [];
$row[] = $item['user_id'];
$row[] = $item['id'];
$row[] = $item['official_code'];
$row[] = $item['firstname'];
$row[] = $item['lastname'];

Loading…
Cancel
Save