From 7aca7718fdc501269eddc276f319da67e473ce43 Mon Sep 17 00:00:00 2001 From: Angel Fernando Quiroz Campos Date: Thu, 20 May 2021 18:28:05 -0500 Subject: [PATCH 1/5] My Progress: show learnpaths by categories - refs BT#18671 --- main/inc/lib/tracking.lib.php | 263 ++++++++++++++++++---------------- 1 file changed, 140 insertions(+), 123 deletions(-) diff --git a/main/inc/lib/tracking.lib.php b/main/inc/lib/tracking.lib.php index 9de2a982f8..546e691f99 100755 --- a/main/inc/lib/tracking.lib.php +++ b/main/inc/lib/tracking.lib.php @@ -5,6 +5,7 @@ use Chamilo\CoreBundle\Entity\Course; use Chamilo\CoreBundle\Entity\ExtraField as EntityExtraField; use Chamilo\CoreBundle\Entity\Session as SessionEntity; +use Chamilo\CourseBundle\Entity\CLpCategory; use Chamilo\UserBundle\Entity\User; use ChamiloSession as Session; use CpChart\Cache as pCache; @@ -2258,7 +2259,8 @@ class Tracking * @param string code * @param int id (optional), filtered by exercise * @param int id (optional), if param $session_id is null - * it'll return results including sessions, 0 = session is not filtered + * it'll return results including sessions, 0 = session is not + * filtered * * @return string value (number %) Which represents a round integer about the score average */ @@ -4025,7 +4027,8 @@ class Tracking * * @param int|array Student id * @param string Course code - * @param int Session id if null(default) return count of messages including sessions, 0 = session is not filtered + * @param int Session id if null(default) return count of messages including sessions, 0 = session is not + * filtered * * @return int Count of messages */ @@ -5443,6 +5446,7 @@ class Tracking $html = ''; if (isset($course_code)) { $user_id = (int) $user_id; + $user = api_get_user_entity($user_id); $session_id = (int) $session_id; $course_info = api_get_course_info($course_code); if (empty($course_info)) { @@ -5464,7 +5468,7 @@ class Tracking // Show exercise results of invisible exercises? see BT#4091 $quizzesHtml = self::generateQuizzesTable($course_info, $session_id); // LP table results - $learningPathsHtml = self::generateLearningPathsTable($user_id, $course_info, $session_id); + $learningPathsHtml = self::generateLearningPathsTable($user, $course_info, $session_id); $skillsHtml = self::displayUserSkills($user_id, $course_info['id'], $session_id); $toolsHtml = [ @@ -7492,8 +7496,10 @@ class Tracking ); } - private static function generateLearningPathsTable(int $userId, array $courseInfo, int $sessionId = 0): string + private static function generateLearningPathsTable(User $user, array $courseInfo, int $sessionId = 0): string { + $html = []; + $columnHeaders = [ 'lp' => get_lang('LearningPath'), 'time' => get_lang('LatencyTimeSpent'), @@ -7533,163 +7539,174 @@ class Tracking $columnHeadersKeys = array_keys($columnHeaders); - $learningpathsTable = new SortableTableFromArray([], 0, 0, 'learningpaths'); - $learningpathsTable->setHeaders($columnHeaders); - - // LP table results - $list = new LearnpathList( - api_get_user_id(), - $courseInfo, - $sessionId, - 'lp.publicatedOn ASC', - true, - null, - true - ); - - $lpList = $list->get_flat_list(); - - if (empty($lpList)) { - return Display::return_message(get_lang('NoLearnpath')); - } + $categories = learnpath::getCategories($courseInfo['real_id'], true); + $countCategories = count($categories); $webCodePath = api_get_path(WEB_CODE_PATH); - foreach ($lpList as $lpId => $learnpath) { - $learningpathData = []; + /** @var CLpCategory $category */ + foreach ($categories as $category) { + // LP table results + $objLearnpathList = new LearnpathList( + $user->getId(), + $courseInfo, + $sessionId, + 'lp.publicatedOn ASC', + true, + $category->getId(), + false + ); + $lpList = $objLearnpathList->get_flat_list(); - if (!$learnpath['lp_visibility']) { - continue; - } + $learningpathsTable = new SortableTableFromArray([], 0, 0, 'learningpaths'); + $learningpathsTable->setHeaders($columnHeaders); - if ($addLpInvisibleCheckbox) { - if (!StudentFollowPage::isViewVisible($lpId, $userId, $courseInfo['real_id'], $sessionId)) { + foreach ($lpList as $lpId => $learnpath) { + $learningpathData = []; + + if (!$learnpath['lp_visibility']) { continue; } - } - $url = $webCodePath.'lp/lp_controller.php?' - .http_build_query( - ['cidReq' => $courseInfo['code'], 'id_session' => $sessionId, 'lp_id' => $lpId, 'action' => 'view'] - ); + if ($addLpInvisibleCheckbox) { + if (!StudentFollowPage::isViewVisible($lpId, $user->getId(), $courseInfo['real_id'], $sessionId)) { + continue; + } + } - if (in_array('lp', $columnHeadersKeys)) { - if ($learnpath['lp_visibility'] == 0) { - $learningpathData[] = $learnpath['lp_name']; - } else { - $learningpathData[] = Display::url( - $learnpath['lp_name'], - $url, - ['target' => SESSION_LINK_TARGET] + $url = $webCodePath.'lp/lp_controller.php?' + .http_build_query( + ['cidReq' => $courseInfo['code'], 'id_session' => $sessionId, 'lp_id' => $lpId, 'action' => 'view'] ); + + if (in_array('lp', $columnHeadersKeys)) { + if ($learnpath['lp_visibility'] == 0) { + $learningpathData[] = $learnpath['lp_name']; + } else { + $learningpathData[] = Display::url( + $learnpath['lp_name'], + $url, + ['target' => SESSION_LINK_TARGET] + ); + } } - } - if (in_array('time', $columnHeadersKeys)) { - $time_spent_in_lp = self::get_time_spent_in_lp( - $userId, - $courseInfo['code'], - [$lpId], - $sessionId - ); + if (in_array('time', $columnHeadersKeys)) { + $time_spent_in_lp = self::get_time_spent_in_lp( + $user->getId(), + $courseInfo['code'], + [$lpId], + $sessionId + ); - $learningpathData[] = api_time_to_hms($time_spent_in_lp); - } + $learningpathData[] = api_time_to_hms($time_spent_in_lp); + } - if (in_array('progress', $columnHeadersKeys)) { - $progress = self::get_avg_student_progress( - $userId, - $courseInfo['code'], - [$lpId], - $sessionId - ); + if (in_array('progress', $columnHeadersKeys)) { + $progress = self::get_avg_student_progress( + $user->getId(), + $courseInfo['code'], + [$lpId], + $sessionId + ); - if (is_numeric($progress)) { - $progress = sprintf(get_lang('XPercent'), $progress); + if (is_numeric($progress)) { + $progress = sprintf(get_lang('XPercent'), $progress); + } + + $learningpathData[] = $progress; } - $learningpathData[] = $progress; - } + if (in_array('score', $columnHeadersKeys)) { + $percentage_score = self::get_avg_student_score( + $user->getId(), + $courseInfo['code'], + [$lpId], + $sessionId + ); - if (in_array('score', $columnHeadersKeys)) { - $percentage_score = self::get_avg_student_score( - $userId, - $courseInfo['code'], - [$lpId], - $sessionId - ); + if (is_numeric($percentage_score)) { + $percentage_score = sprintf(get_lang('XPercent'), $percentage_score); + } else { + $percentage_score = sprintf(get_lang('XPercent'), 0); + } - if (is_numeric($percentage_score)) { - $percentage_score = sprintf(get_lang('XPercent'), $percentage_score); - } else { - $percentage_score = sprintf(get_lang('XPercent'), 0); + $learningpathData[] = $percentage_score; } - $learningpathData[] = $percentage_score; - } + if (in_array('best_score', $columnHeadersKeys)) { + $bestScore = self::get_avg_student_score( + $user->getId(), + $courseInfo['code'], + [$lpId], + $sessionId, + false, + false, + true + ); - if (in_array('best_score', $columnHeadersKeys)) { - $bestScore = self::get_avg_student_score( - $userId, - $courseInfo['code'], - [$lpId], - $sessionId, - false, - false, - true - ); + if (is_numeric($bestScore)) { + $bestScore = sprintf(get_lang('XPercent'), $bestScore); + } else { + $bestScore = '-'; + } - if (is_numeric($bestScore)) { - $bestScore = sprintf(get_lang('XPercent'), $bestScore); - } else { - $bestScore = '-'; + $learningpathData[] = $bestScore; } - $learningpathData[] = $bestScore; - } + if (in_array('last_connection', $columnHeadersKeys)) { + $lastConnectionInLp = self::get_last_connection_time_in_lp( + $user->getId(), + $courseInfo['code'], + $lpId, + $sessionId + ); - if (in_array('last_connection', $columnHeadersKeys)) { - $lastConnectionInLp = self::get_last_connection_time_in_lp( - $userId, - $courseInfo['code'], - $lpId, - $sessionId - ); + $lastConnection = '-'; - $lastConnection = '-'; + if (!empty($lastConnectionInLp)) { + $lastConnection = api_convert_and_format_date($lastConnectionInLp, DATE_TIME_FORMAT_LONG); + } + + $learningpathData[] = $lastConnection; + } + + if (in_array('student_follow_page_add_LP_subscription_info', $columnHeadersKeys)) { + $learningpathData[] = StudentFollowPage::getLpSubscription( + $learnpath, + $user->getId(), + $courseInfo['real_id'], + $sessionId + ); + } - if (!empty($lastConnectionInLp)) { - $lastConnection = api_convert_and_format_date($lastConnectionInLp, DATE_TIME_FORMAT_LONG); + if (in_array('student_follow_page_add_LP_acquisition_info', $columnHeadersKeys)) { + $learningpathData[] = StudentFollowPage::getLpAcquisition( + $learnpath, + $user->getId(), + $courseInfo['real_id'], + $sessionId + ); } - $learningpathData[] = $lastConnection; + $learningpathsTable->addRow($learningpathData); } - if (in_array('student_follow_page_add_LP_subscription_info', $columnHeadersKeys)) { - $learningpathData[] = StudentFollowPage::getLpSubscription( - $learnpath, - $userId, - $courseInfo['real_id'], - $sessionId - ); + if ($learningpathsTable->getRowCount() < 2) { + continue; } - if (in_array('student_follow_page_add_LP_acquisition_info', $columnHeadersKeys)) { - $learningpathData[] = StudentFollowPage::getLpAcquisition( - $learnpath, - $userId, - $courseInfo['real_id'], - $sessionId - ); + if ($countCategories > 1) { + $html[] = Display::tag('h5', $category->getName()); } - $learningpathsTable->addRow($learningpathData); + $html[] = Display::div( + $learningpathsTable->toHtml(), + ['class' => 'table-responsive'] + ); } - return Display::div( - $learningpathsTable->toHtml(), - ['class' => 'table-responsive'] - ); + return implode(PHP_EOL, $html); } } From 07be0f995a59c37379595058d8a418eb0d522f50 Mon Sep 17 00:00:00 2001 From: Angel Fernando Quiroz Campos Date: Fri, 21 May 2021 11:23:47 -0500 Subject: [PATCH 2/5] Tracking: Add title to exercise list - refs BT#18671 --- main/inc/lib/tracking.lib.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/main/inc/lib/tracking.lib.php b/main/inc/lib/tracking.lib.php index 006bc47c23..ce01ea4b8c 100755 --- a/main/inc/lib/tracking.lib.php +++ b/main/inc/lib/tracking.lib.php @@ -7369,7 +7369,7 @@ class Tracking $quizzesTable = new SortableTableFromArray([], 0, 0, 'quizzes'); $quizzesTable->setHeaders( [ - get_lang('Exercises'), + get_lang('Title'), get_lang('Attempts'), get_lang('BestAttempt'), get_lang('Ranking'), @@ -7508,10 +7508,11 @@ class Tracking $quizzesTable->addRow($quizData); } - return Display::div( - $quizzesTable->toHtml(), - ['class' => 'table-responsive'] - ); + return Display::page_subheader2(get_lang('Exercises')) + .Display::div( + $quizzesTable->toHtml(), + ['class' => 'table-responsive'] + ); } private static function generateLearningPathsTable(User $user, array $courseInfo, int $sessionId = 0): string From cb7050bc0d07e40bf26e717e0424dc1fc1462f9b Mon Sep 17 00:00:00 2001 From: Angel Fernando Quiroz Campos Date: Fri, 21 May 2021 12:07:18 -0500 Subject: [PATCH 3/5] Tracking: Don't show register/teacher when student_follow_page_add_LP_subscription_info is enabled - refs BT#18671 --- main/inc/lib/StudentFollowPage.php | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/main/inc/lib/StudentFollowPage.php b/main/inc/lib/StudentFollowPage.php index 3ae7da155c..39719e3da8 100644 --- a/main/inc/lib/StudentFollowPage.php +++ b/main/inc/lib/StudentFollowPage.php @@ -52,15 +52,7 @@ class StudentFollowPage return '-'; } - $insertUser = $itemProperty->getInsertUser()->getId() !== $studentId - ? $itemProperty->getInsertUser()->getCompleteName() - : '-'; - - return "$insertUser
" - .Display::tag( - 'small', - api_convert_and_format_date($itemProperty->getInsertDate(), DATE_TIME_FORMAT_LONG) - ); + return api_convert_and_format_date($itemProperty->getInsertDate(), DATE_TIME_FORMAT_LONG); } $subscriptionEvent = Event::findUserSubscriptionToCourse($studentId, $courseId, $sessionId); @@ -69,13 +61,7 @@ class StudentFollowPage return '-'; } - $creator = api_get_user_entity($subscriptionEvent['default_user_id']); - - return "{$creator->getCompleteName()}
" - .Display::tag( - 'small', - api_convert_and_format_date($subscriptionEvent['default_date'], DATE_TIME_FORMAT_LONG) - ); + return api_convert_and_format_date($subscriptionEvent['default_date'], DATE_TIME_FORMAT_LONG); } public static function getLpAcquisition( From 474ffc42c113c81f7fedc9b66a03b24447da8e96 Mon Sep 17 00:00:00 2001 From: Angel Fernando Quiroz Campos Date: Fri, 21 May 2021 12:48:18 -0500 Subject: [PATCH 4/5] Add student_follow_page_show_invisible_lp_students conf setting - refs BT#18671 Show the LP not marked as invisible by teacher in tracking page --- main/inc/lib/tracking.lib.php | 8 +++++++- main/install/configuration.dist.php | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/main/inc/lib/tracking.lib.php b/main/inc/lib/tracking.lib.php index ce01ea4b8c..2ebca40747 100755 --- a/main/inc/lib/tracking.lib.php +++ b/main/inc/lib/tracking.lib.php @@ -7555,6 +7555,11 @@ class Tracking } $addLpInvisibleCheckbox = api_get_configuration_value('student_follow_page_add_LP_invisible_checkbox'); + $showInvisibleLp = api_get_configuration_value('student_follow_page_show_invisible_lp_students'); + + if ($addLpInvisibleCheckbox && $showInvisibleLp) { + $addLpInvisibleCheckbox = false; + } $columnHeadersKeys = array_keys($columnHeaders); @@ -7573,7 +7578,8 @@ class Tracking 'lp.publicatedOn ASC', true, $category->getId(), - false + false, + $showInvisibleLp ); $lpList = $objLearnpathList->get_flat_list(); diff --git a/main/install/configuration.dist.php b/main/install/configuration.dist.php index 15786e5ec8..f4e2e5345f 100755 --- a/main/install/configuration.dist.php +++ b/main/install/configuration.dist.php @@ -399,6 +399,8 @@ INSERT INTO extra_field (extra_field_type, field_type, variable, display_text, d (20, 13, 'invisible', 'Invisible', '', 0, 1, 0, 0, 0, NOW()); */ //$_configuration['student_follow_page_add_LP_invisible_checkbox'] = false; +// Show the LP not marked as invisible by teacher in tracking page +//$_configuration['student_follow_page_show_invisible_lp_students'] = false; // Allow change the order to show the tools in "My progress" page. /*$_configuration['my_progress_course_tools_order'] = [ 'order' => ['quizzes', 'learning_paths', 'skills'], From a562622d50cfc1f9e31ba1ea384bfb7042a8d61f Mon Sep 17 00:00:00 2001 From: Angel Fernando Quiroz Campos Date: Fri, 21 May 2021 14:02:54 -0500 Subject: [PATCH 5/5] Tracking: Don't export empty LP tables - refs BT#18671 --- main/mySpace/student_follow_export.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/main/mySpace/student_follow_export.php b/main/mySpace/student_follow_export.php index ec9b8c9e42..a9cfa6b7a1 100644 --- a/main/mySpace/student_follow_export.php +++ b/main/mySpace/student_follow_export.php @@ -194,7 +194,7 @@ function generateHtmlForLearningPaths(int $studentId, array $courseInfo, int $se $html .= Display::page_subheader3($item->getName()); } - $lpTable = [$columnHeaders]; + $lpTable = []; foreach ($flatList as $learnpath) { $lpId = $learnpath['lp_old_id']; @@ -307,6 +307,12 @@ function generateHtmlForLearningPaths(int $studentId, array $courseInfo, int $se $lpTable[] = $contentToExport; } + if (empty($lpTable)) { + continue; + } + + array_unshift($lpTable, [$columnHeaders]); + $html .= Export::convert_array_to_html($lpTable); }