Minor - merge with 1.11.x

pull/2487/head
jmontoyaa 8 years ago
parent 9ea0a4de77
commit 4aa6a0ef4c
  1. 2
      main/inc/lib/image.lib.php
  2. 5
      main/inc/lib/internationalization.lib.php
  3. 4
      main/inc/lib/legal.lib.php
  4. 2
      main/inc/lib/plugin.lib.php
  5. 75
      main/inc/lib/sessionmanager.lib.php
  6. 46
      main/inc/lib/social.lib.php
  7. 2
      main/inc/lib/statistics.lib.php
  8. 180
      main/inc/lib/tracking.lib.php
  9. 11
      main/install/update-files-1.10.0-1.11.0.inc.php
  10. 83
      main/lp/learnpath.class.php
  11. 102
      main/lp/learnpathItem.class.php
  12. 39
      main/lp/lp_view.php
  13. 1
      main/lp/lp_view_item.php
  14. 4
      main/lp/scorm_api.php
  15. 83
      main/mySpace/lp_tracking.php
  16. 3
      main/mySpace/myStudents.php
  17. 40
      main/mySpace/student.php
  18. 23
      main/mySpace/users.php
  19. 41
      main/portfolio/add_category.php
  20. 59
      main/portfolio/add_item.php
  21. 40
      main/portfolio/edit_category.php
  22. 53
      main/portfolio/edit_item.php
  23. 223
      main/portfolio/index.php
  24. 59
      main/portfolio/list.php
  25. 1
      main/portfolio/share.php
  26. 1
      main/session/about.php
  27. 2
      main/session/index.php

@ -519,6 +519,8 @@ class GDWrapper extends ImageWrapper
break;
case 'png':
$src = @imagecreatefrompng($this->path);
@imagealphablending($dest, false);
@imagesavealpha($dest, true);
@imagecopy($dest, $src, 0, 0, $x, $y, $src_width, $src_height);
@imagepng($dest, $this->path);
break;

@ -2069,9 +2069,9 @@ function _api_get_person_name_convention($language, $type)
],
];
}
// Overwrite classic conventions
$customConventions = api_get_configuration_value('name_order_conventions');
if (!empty($customConventions)) {
foreach ($customConventions as $key => $data) {
$conventions[$key] = $data;
@ -2128,7 +2128,8 @@ function _api_validate_person_name_format($format)
/**
* Removes leading, trailing and duplicate whitespace and/or commas in a full person name.
* Cleaning is needed for the cases when not all parts of the name are available or when the name is constructed using a "dirty" pattern.
* Cleaning is needed for the cases when not all parts of the name are available
* or when the name is constructed using a "dirty" pattern.
*
* @param string $person_name the input person name
*

@ -215,7 +215,9 @@ class LegalManager
switch ($term_preview['type']) {
case 0:
if (!empty($term_preview['content'])) {
$preview = '<div class="legal-terms">'.$term_preview['content'].'</div><br />';
$preview = '<div class="terms-conditions">
<div id="legal-terms" class="scrollbar-inner">'.$term_preview['content'].'</div>
</div>';
}
$preview .= get_lang('ByClickingRegisterYouAgreeTermsAndConditions');
$courseInfo = api_get_course_info();

@ -108,7 +108,7 @@ class AppPlugin
$pluginList = [];
if (!empty($pluginListName)) {
foreach ($pluginListName as $pluginName) {
$pluginInfo = $this->getPluginInfo($pluginName);
$pluginInfo = $this->getPluginInfo($pluginName, true);
if (isset($pluginInfo['plugin_class'])) {
$pluginList[] = $pluginInfo['plugin_class']::create();
}

@ -3199,6 +3199,81 @@ class SessionManager
}
}
/**
* Get the session image.
*
* @return image path
*/
public static function getSessionImage($id)
{
$extraFieldValuesTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
$sql = "SELECT value FROM extra_field_values WHERE field_id = 16 AND item_id = ".intval($id);
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
while ($row = Database::fetch_array($result, 'ASSOC')) {
$sessionImage = $row['value'];
$sessionImage = api_get_path(WEB_UPLOAD_PATH).$sessionImage;
}
return $sessionImage;
} else {
$sessionImage = api_get_path(WEB_IMG_PATH)."session_default.png";
return $sessionImage;
}
}
/**
* Get Hot Sessions (limit 8).
*
* @return array with sessions
*/
public static function getHotSessions()
{
$tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
$tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
$tbl_users = Database::get_main_table(TABLE_MAIN_USER);
$sql = "SELECT
s.id,
s.name,
s.id_coach,
u.firstname,
u.lastname,
s.session_category_id,
c.name as category_name,
s.description,
(SELECT COUNT(*) FROM session_rel_user WHERE session_id = s.id) as users,
(SELECT COUNT(*) FROM c_lp WHERE session_id = s.id) as lessons,
(SELECT value FROM extra_field_values WHERE field_id = 16 AND item_id = s.id) as image
FROM $tbl_session s
LEFT JOIN $tbl_session_category c
ON s.session_category_id = c.id
INNER JOIN $tbl_users u
ON s.id_coach = u.id
ORDER BY 9 DESC
LIMIT 8";
$result = Database::query($sql);
$plugin = BuyCoursesPlugin::create();
$checker = $plugin->isEnabled();
$sessions = [];
if (Database::num_rows($result) > 0) {
while ($row = Database::fetch_array($result, 'ASSOC')) {
if ($checker) {
$row['on_sale'] = $plugin->getItemByProduct(
$row['id'],
BuyCoursesPlugin::PRODUCT_TYPE_SESSION
);
}
$sessions[] = $row;
}
return $sessions;
} else {
return false;
}
}
/**
* Get all session categories (filter by access_url_id).
*

@ -1469,7 +1469,7 @@ class SocialManager extends UserManager
* @param int $messageId id parent
* @param string $messageStatus status type of message
*
* @return bool
* @return int
*
* @author Yannick Warnier
*/
@ -1481,9 +1481,13 @@ class SocialManager extends UserManager
$messageStatus = ''
) {
$tblMessage = Database::get_main_table(TABLE_MESSAGE);
$userId = intval($userId);
$friendId = intval($friendId);
$messageId = intval($messageId);
$userId = (int) $userId;
$friendId = (int) $friendId;
$messageId = (int) $messageId;
if (empty($userId) || empty($friendId)) {
return 0;
}
// Just in case we replace the and \n and \n\r while saving in the DB
$messageContent = str_replace(["\n", "\n\r"], '<br />', $messageContent);
@ -1662,7 +1666,7 @@ class SocialManager extends UserManager
$start = '0000-00-00';
}
$isOwnWall = (api_get_user_id() == $userId && $userId == $friendId);
$isOwnWall = api_get_user_id() == $userId && $userId == $friendId;
$messages = self::getWallMessages(
$userId,
MESSAGE_STATUS_WALL,
@ -1708,8 +1712,12 @@ class SocialManager extends UserManager
if ($isOwnWall) {
$media .= '<div class="col-md-1 col-xs-1 social-post-answers">';
$media .= '<div class="pull-right deleted-mgs">';
$media .= '<a title="'.get_lang("SocialMessageDelete").'" href="'.api_get_path(WEB_CODE_PATH).'social/profile.php?messageId='.
$message['id'].'">x</a>';
$url = api_get_path(WEB_CODE_PATH).'social/profile.php?messageId='.$message['id'];
$media .= Display::url(
Display::returnFontAwesomeIcon('trash'),
$url,
['title' => get_lang("SocialMessageDelete")]
);
$media .= '</div>';
$media .= '</div>';
}
@ -1816,7 +1824,8 @@ class SocialManager extends UserManager
$description = $graph->description;
$title = $graph->title;
$html = '<div class="thumbnail social-thumbnail">';
$html .= empty($image) ? '' : '<a target="_blank" href="'.$url.'"><img class="img-responsive social-image" src="'.$image.'" /></a>';
$html .= empty($image) ? '' : '<a target="_blank" href="'.$url.'">
<img class="img-responsive social-image" src="'.$image.'" /></a>';
$html .= '<div class="social-description">';
$html .= '<a target="_blank" href="'.$url.'"><h5 class="social-title"><b>'.$title.'</b></h5></a>';
$html .= empty($description) ? '' : '<span>'.$description.'</span>';
@ -2011,8 +2020,9 @@ class SocialManager extends UserManager
}
$friendHtml .= '</ul>';
} else {
$friendHtml .= '<div class="">'.get_lang('NoFriendsInYourContactList').'<br />'
.'<a class="btn btn-primary" href="'.api_get_path(WEB_PATH).'whoisonline.php"><em class="fa fa-search"></em> '.get_lang('TryAndFindSomeFriends').'</a></div>';
$friendHtml .= '<div class="">'.get_lang('NoFriendsInYourContactList').'<br />
<a class="btn btn-primary" href="'.api_get_path(WEB_PATH).'whoisonline.php">
<em class="fa fa-search"></em> '.get_lang('TryAndFindSomeFriends').'</a></div>';
}
$friendHtml = Display::panel($friendHtml, get_lang('SocialFriend').' ('.$number_friends.')');
@ -2087,8 +2097,9 @@ class SocialManager extends UserManager
}
$friendHtml .= '</div>';
} else {
$friendHtml .= '<div class="help">'.get_lang('NoFriendsInYourContactList').' '
.'<a href="'.api_get_path(WEB_PATH).'whoisonline.php"><em class="fa fa-search"></em> '.get_lang('TryAndFindSomeFriends').'</a></div>';
$friendHtml .= '<div class="help">'.get_lang('NoFriendsInYourContactList').'
<a href="'.api_get_path(WEB_PATH).'whoisonline.php">
<em class="fa fa-search"></em> '.get_lang('TryAndFindSomeFriends').'</a></div>';
}
return $friendHtml;
@ -2226,8 +2237,12 @@ class SocialManager extends UserManager
$htmlDelete = '';
if ($isOwnWall) {
$htmlDelete .= '<a title="'.get_lang("SocialMessageDelete").'" href="'.api_get_path(WEB_CODE_PATH).'social/profile.php?messageId='.
$message['id'].'">x</a>';
$url = api_get_path(WEB_CODE_PATH).'social/profile.php?messageId='.$message['id'];
$htmlDelete .= Display::url(
Display::returnFontAwesomeIcon('trash'),
$url,
['title' => get_lang('SocialMessageDelete')]
);
}
$html = '';
@ -2238,7 +2253,8 @@ class SocialManager extends UserManager
$html .= '</div>';
}
$html .= '<div class="user-image" >';
$html .= '<a href="'.$urlAuthor.'">'.'<img class="avatar-thumb" src="'.$avatarAuthor.'" alt="'.$nameCompleteAuthor.'"></a>';
$html .= '<a href="'.$urlAuthor.'">
<img class="avatar-thumb" src="'.$avatarAuthor.'" alt="'.$nameCompleteAuthor.'"></a>';
$html .= '</div>';
$html .= '<div class="user-data">';
$html .= '<div class="username"><a href="'.$urlAuthor.'">'.$nameCompleteAuthor.'</a>'.$htmlReceiver.'</div>';

@ -300,7 +300,7 @@ class Statistics
WHERE track_default.default_user_id = user.user_id ";
}
if (isset($_GET['keyword'])) {
if (!empty($_GET['keyword'])) {
$keyword = Database::escape_string(trim($_GET['keyword']));
$sql .= " AND (user.username LIKE '%".$keyword."%' OR
default_event_type LIKE '%".$keyword."%' OR

@ -172,7 +172,6 @@ class Tracking
// Extend all button
$output = null;
$extend_all = 0;
if ($origin == 'tracking') {
$url_suffix = '&session_id='.$session_id.'&course='.$courseCode.'&student_id='.$user_id.'&lp_id='.$lp_id.'&origin='.$origin;
} else {
@ -612,7 +611,6 @@ class Tracking
$my_lp_view_id = $row['mylpviewid'];
$my_path = $row['path'];
$result_disabled_ext_all = false;
if ($row['item_type'] == 'quiz') {
// Check results_disabled in quiz table.
$my_path = Database::escape_string($my_path);
@ -698,7 +696,7 @@ class Tracking
switch ($row['item_type']) {
case 'sco':
if (!empty($row['myviewmaxscore']) and $row['myviewmaxscore'] > 0) {
if (!empty($row['myviewmaxscore']) && $row['myviewmaxscore'] > 0) {
$maxscore = $row['myviewmaxscore'];
} elseif ($row['myviewmaxscore'] === '') {
$maxscore = 0;
@ -708,13 +706,14 @@ class Tracking
break;
case 'quiz':
// Get score and total time from last attempt of a exercise en lp.
$sql = "SELECT score
$sql = "SELECT iid, score
FROM $TBL_LP_ITEM_VIEW
WHERE
c_id = $course_id AND
lp_item_id = '".(int) $my_id."' AND
lp_view_id = '".(int) $my_lp_view_id."'
ORDER BY view_count DESC limit 1";
ORDER BY view_count DESC
LIMIT 1";
$res_score = Database::query($sql);
$row_score = Database::fetch_array($res_score);
@ -727,16 +726,14 @@ class Tracking
$res_time = Database::query($sql);
$row_time = Database::fetch_array($res_time);
$score = 0;
$subtotal_time = 0;
if (Database::num_rows($res_score) > 0 &&
Database::num_rows($res_time) > 0
) {
$score = (float) $row_score['score'];
$subtotal_time = (int) $row_time['total_time'];
} else {
$score = 0;
$subtotal_time = 0;
}
// Selecting the max score from an attempt.
$sql = "SELECT SUM(t.ponderation) as maxscore
FROM (
@ -751,6 +748,34 @@ class Tracking
$result = Database::query($sql);
$row_max_score = Database::fetch_array($result);
$maxscore = $row_max_score['maxscore'];
// Get duration time from track_e_exercises.exe_duration instead of lp_view_item.total_time
$sql = 'SELECT SUM(exe_duration) exe_duration
FROM '.$tbl_stats_exercices.'
WHERE
exe_exo_id="'.$row['path'].'" AND
exe_user_id="'.$user_id.'" AND
orig_lp_id = "'.$lp_id.'" AND
orig_lp_item_id = "'.$row['myid'].'" AND
c_id = '.$course_id.' AND
status <> "incomplete" AND
session_id = '.$session_id.'
ORDER BY exe_date DESC ';
$sumScoreResult = Database::query($sql);
$durationRow = Database::fetch_array($sumScoreResult, 'ASSOC');
if (!empty($durationRow['exe_duration'])) {
$exeDuration = $durationRow['exe_duration'];
if ($exeDuration != $subtotal_time &&
!empty($row_score['iid']) &&
!empty($exeDuration)
) {
$subtotal_time = $exeDuration;
// Update c_lp_item_view.total_time
$sqlUpdate = "UPDATE $TBL_LP_ITEM_VIEW SET total_time = '$exeDuration'
WHERE iid = ".$row_score['iid'];
Database::query($sqlUpdate);
}
}
break;
default:
$maxscore = $row['mymaxscore'];
@ -758,10 +783,7 @@ class Tracking
}
$time_for_total = $subtotal_time;
$time = learnpathItem::getScormTimeFromParameter(
'js',
$subtotal_time
);
$time = learnpathItem::getScormTimeFromParameter('js', $subtotal_time);
if (empty($title)) {
$title = learnpath::rl_get_resource_name(
$courseInfo['code'],
@ -912,7 +934,6 @@ class Tracking
}
$counter++;
$action = null;
if ($type == 'classic') {
$action = '<td></td>';
@ -1004,9 +1025,6 @@ class Tracking
$my_score = $row_attempts['exe_result'];
$my_maxscore = $row_attempts['exe_weighting'];
$my_exe_id = $row_attempts['exe_id'];
$my_orig_lp = $row_attempts['orig_lp_id'];
$my_orig_lp_item = $row_attempts['orig_lp_item_id'];
$my_exo_exe_id = $row_attempts['exe_exo_id'];
$mktime_start_date = api_strtotime($row_attempts['start_date'], 'UTC');
$mktime_exe_date = api_strtotime($row_attempts['exe_date'], 'UTC');
$time_attemp = ' - ';
@ -1041,7 +1059,6 @@ class Tracking
}
}
$my_lesson_status = $row_attempts['status'];
if ($my_lesson_status == '') {
$my_lesson_status = learnpathitem::humanize_status('completed');
} elseif ($my_lesson_status == 'incomplete') {
@ -3006,6 +3023,7 @@ class Tracking
if ($debug) {
echo '<h3>Final return</h3>';
}
if ($lp_with_quiz != 0) {
if (!$return_array) {
$score_of_scorm_calculate = round(($global_result / $lp_with_quiz), 2);
@ -3140,9 +3158,11 @@ class Tracking
$total_time = 0;
if (!empty($course)) {
$lp_table = Database::get_course_table(TABLE_LP_MAIN);
$t_lpv = Database::get_course_table(TABLE_LP_VIEW);
$t_lpiv = Database::get_course_table(TABLE_LP_ITEM_VIEW);
$lpTable = Database::get_course_table(TABLE_LP_MAIN);
$lpItemTable = Database::get_course_table(TABLE_LP_ITEM);
$lpViewTable = Database::get_course_table(TABLE_LP_VIEW);
$lpItemViewTable = Database::get_course_table(TABLE_LP_ITEM_VIEW);
$trackExercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$course_id = $course['real_id'];
// Compose a filter based on optional learning paths list given
@ -3153,18 +3173,100 @@ class Tracking
// Check the real number of LPs corresponding to the filter in the
// database (and if no list was given, get them all)
$sql = "SELECT DISTINCT(id) FROM $lp_table
$sql = "SELECT DISTINCT(id) FROM $lpTable
WHERE c_id = $course_id $condition_lp";
$res_row_lp = Database::query($sql);
$count_row_lp = Database::num_rows($res_row_lp);
$result = Database::query($sql);
$session_condition = api_get_session_condition($session_id);
// calculates time
if ($count_row_lp > 0) {
while ($row_lp = Database::fetch_array($res_row_lp)) {
$lp_id = intval($row_lp['id']);
if (Database::num_rows($result) > 0) {
while ($row = Database::fetch_array($result)) {
$lp_id = (int) $row['id'];
// Start Exercise in LP total_time
// Get duration time from track_e_exercises.exe_duration instead of lp_view_item.total_time
$list = learnpath::get_flat_ordered_items_list($lp_id, 0, $course_id);
foreach ($list as $itemId) {
$sql = "SELECT max(view_count)
FROM $lpViewTable
WHERE
c_id = $course_id AND
lp_id = $lp_id AND
user_id = $student_id
$session_condition";
$res = Database::query($sql);
$view = '';
if (Database::num_rows($res) > 0) {
$myrow = Database::fetch_array($res);
$view = $myrow[0];
}
$viewCondition = null;
if (!empty($view)) {
$viewCondition = " AND v.view_count = $view ";
}
$sql = "SELECT
iv.iid,
iv.total_time as mytime,
i.id as myid,
iv.view_count as iv_view_count,
path
FROM $lpItemTable as i
INNER JOIN $lpItemViewTable as iv
ON (i.id = iv.lp_item_id AND i.c_id = iv.c_id)
INNER JOIN $lpViewTable as v
ON (iv.lp_view_id = v.id AND v.c_id = iv.c_id)
WHERE
v.c_id = $course_id AND
i.id = $itemId AND
i.lp_id = $lp_id AND
v.user_id = $student_id AND
item_type = 'quiz' AND
path <> '' AND
v.session_id = $session_id
$viewCondition
ORDER BY iv.view_count DESC ";
$result = Database::query($sql);
if (Database::num_rows($result)) {
$row = Database::fetch_array($result);
$totalTimeInLpItemView = $row['mytime'];
$lpItemViewId = $row['iid'];
$sql = 'SELECT SUM(exe_duration) exe_duration
FROM '.$trackExercises.'
WHERE
exe_exo_id="'.$row['path'].'" AND
exe_user_id="'.$student_id.'" AND
orig_lp_id = "'.$lp_id.'" AND
orig_lp_item_id = "'.$row['myid'].'" AND
c_id = '.$course_id.' AND
status <> "incomplete" AND
session_id = '.$session_id.'
ORDER BY exe_date DESC ';
$sumScoreResult = Database::query($sql);
$durationRow = Database::fetch_array($sumScoreResult, 'ASSOC');
if (!empty($durationRow['exe_duration'])) {
$exeDuration = $durationRow['exe_duration'];
if ($exeDuration != $totalTimeInLpItemView &&
!empty($lpItemViewId) &&
!empty($exeDuration)
) {
// Update c_lp_item_view.total_time
$sqlUpdate = "UPDATE $lpItemViewTable SET total_time = '$exeDuration'
WHERE iid = ".$lpItemViewId;
Database::query($sqlUpdate);
}
}
}
}
// End total_time fix
// Calculate total time
$sql = "SELECT SUM(total_time)
FROM $t_lpiv AS item_view
INNER JOIN $t_lpv AS view
FROM $lpItemViewTable AS item_view
INNER JOIN $lpViewTable AS view
ON (
item_view.lp_view_id = view.id AND
item_view.c_id = view.c_id
@ -3813,7 +3915,6 @@ class Tracking
ip.tool='work' AND
$conditionToString";
$rs = Database::query($sql);
$row = Database::fetch_array($rs, 'ASSOC');
return $row['count'];
@ -7390,10 +7491,13 @@ class TrackingCourseLog
}
}
while ($user = Database::fetch_array($res, 'ASSOC')) {
$courseInfo = api_get_course_info($course_code);
$courseId = $courseInfo['real_id'];
$courseInfo = api_get_course_info($course_code);
$courseId = $courseInfo['real_id'];
$urlBase = api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?details=true&cidReq='.$course_code.
'&course='.$course_code.'&origin=tracking_course&id_session='.$session_id;
while ($user = Database::fetch_array($res, 'ASSOC')) {
$user['official_code'] = $user['col0'];
$user['lastname'] = $user['col1'];
$user['firstname'] = $user['col2'];
@ -7476,11 +7580,11 @@ class TrackingCourseLog
$user['survey'] = (isset($survey_user_list[$user['user_id']]) ? $survey_user_list[$user['user_id']] : 0).' / '.$total_surveys;
}
$user['link'] = '<center>
<a href="../mySpace/myStudents.php?student='.$user['user_id'].'&details=true&course='.$course_code.'&origin=tracking_course&id_session='.$session_id.'">
'.Display::return_icon('2rightarrow.png', get_lang('Details')).'
</a>
</center>';
$url = $urlBase.'&student='.$user['user_id'];
$user['link'] = '<center><a href="'.$url.'">
'.Display::return_icon('2rightarrow.png', get_lang('Details')).'
</a></center>';
// store columns in array $users
$is_western_name_order = api_is_western_name_order();

@ -44,10 +44,10 @@ if (defined('SYSTEM_INSTALLATION')) {
// Some entities have been removed in 1.11. Delete the corresponding files
$entitiesToRemove = [
api_get_path(SYS_PATH).'src/CoreBundle/Entity/Groups.php',
api_get_path(SYS_PATH).'src/CoreBundle/Entity/GroupRelGroup.php',
api_get_path(SYS_PATH).'src/CoreBundle/Entity/GroupRelTag.php',
api_get_path(SYS_PATH).'src/CoreBundle/Entity/GroupRelUser.php',
api_get_path(SYS_PATH).'src/Chamilo/CoreBundle/Entity/Groups.php',
api_get_path(SYS_PATH).'src/Chamilo/CoreBundle/Entity/GroupRelGroup.php',
api_get_path(SYS_PATH).'src/Chamilo/CoreBundle/Entity/GroupRelTag.php',
api_get_path(SYS_PATH).'src/Chamilo/CoreBundle/Entity/GroupRelUser.php',
];
foreach ($entitiesToRemove as $entity) {
if (file_exists($entity)) {
@ -55,9 +55,10 @@ if (defined('SYSTEM_INSTALLATION')) {
if (!$success) {
error_log('Could not delete '.$entity.', probably due to permissions. Please delete manually to avoid entities inconsistencies');
}
} else {
error_log('Could not delete. It seems the file '.$entity.' does not exists.');
}
}
if ($debug) {
error_log('Folders cleaned up');
}

@ -1187,9 +1187,9 @@ class learnpath
/**
* Removes an item from the current learnpath.
*
* @param int $id Elem ID (0 if first)
* @param string $remove Whether to remove the resource/data from the system
* or leave it (default: 'keep', others 'remove')
* @param int $id Elem ID (0 if first)
* @param int $remove Whether to remove the resource/data from the
* system or leave it (default: 'keep', others 'remove')
*
* @return int Number of elements moved
*
@ -2568,7 +2568,8 @@ class learnpath
}
/**
* @param string $mode can be '%' or 'abs' otherwise this value will be used $this->progress_bar_mode
* @param string $mode can be '%' or 'abs'
* otherwise this value will be used $this->progress_bar_mode
*
* @return string
*/
@ -2583,8 +2584,8 @@ class learnpath
* Gets the progress bar info to display inside the progress bar.
* Also used by scorm_api.php.
*
* @param string $mode Mode of display (can be '%' or 'abs').abs means we display a number of completed elements
* per total elements
* @param string $mode Mode of display (can be '%' or 'abs').abs means
* we display a number of completed elements per total elements
* @param int $add Additional steps to fake as completed
*
* @return array Percentage or number and symbol (% or /xx)
@ -3281,7 +3282,7 @@ class learnpath
$classStyle = 'scorm_item_normal '.$classStyle.' ';
}
$subtree['title'] = $title;
$subtree['class'] = $cssStatus.' '.$classStyle;
$subtree['class'] = $classStyle.' '.$cssStatus;
$subtree['url'] = $this->get_link('http', $subtree['id'], $tree);
$subtree['current_id'] = $myCurrentId;
$listNotParent[] = $subtree;
@ -3355,7 +3356,7 @@ class learnpath
$subtree['title'] = stripslashes($title);
} else {
$subtree['title'] = $title;
$subtree['class'] = $cssStatus.' '.$classStyle;
$subtree['class'] = $classStyle.' '.$cssStatus;
$subtree['url'] = $this->get_link('http', $subtree['id'], $tree);
$subtree['current_id'] = $mycurrentitemid;
}
@ -4401,7 +4402,9 @@ class learnpath
}
/**
* Publishes a learnpath. This basically means show or hide the learnpath to normal users. Can be used as abstract.
* Publishes a learnpath. This basically means show or hide the learnpath
* to normal users.
* Can be used as abstract.
*
* @param int $lp_id Learnpath ID
* @param int $set_visibility New visibility
@ -8550,6 +8553,7 @@ class learnpath
);
$relative_prefix = '';
$editor_config = [
'ToolbarSet' => 'LearningPathDocuments',
'Width' => '100%',
@ -9791,7 +9795,6 @@ class learnpath
'min_score' => $row['min_score'],
'mastery_score' => $row['mastery_score'],
'prerequisite' => $row['prerequisite'],
'next_item_id' => $row['next_item_id'],
'display_order' => $row['display_order'],
'prerequisite_min_score' => $row['prerequisite_min_score'],
'prerequisite_max_score' => $row['prerequisite_max_score'],
@ -9836,27 +9839,64 @@ class learnpath
if ($item['item_type'] == TOOL_QUIZ) {
// lets update max_score Quiz information depending of the Quiz Advanced properties
$tmp_obj_lp_item = new LpItem($course_id, $item['id']);
$tmp_obj_exercice = new Exercise($course_id);
$tmp_obj_exercice->read($tmp_obj_lp_item->path);
$tmp_obj_lp_item->max_score = $tmp_obj_exercice->get_max_score();
$tmp_obj_lp_item->update();
$item['max_score'] = $tmp_obj_lp_item->max_score;
$lpItemObj = new LpItem($course_id, $item['id']);
$exercise = new Exercise($course_id);
$exercise->read($lpItemObj->path);
$lpItemObj->max_score = $exercise->get_max_score();
$lpItemObj->update();
$item['max_score'] = $lpItemObj->max_score;
$return .= '<td>';
$return .= '<input class="form-control" size="4" maxlength="3" name="min_'.$item['id'].'" type="number" min="0" step="1" max="'.$item['max_score'].'" value="'.$selectedMinScoreValue.'" />';
$return .= '<input
class="form-control"
size="4" maxlength="3"
name="min_'.$item['id'].'"
type="number"
min="0"
step="1"
max="'.$item['max_score'].'"
value="'.$selectedMinScoreValue.'"
/>';
$return .= '</td>';
$return .= '<td>';
$return .= '<input class="form-control" size="4" maxlength="3" readonly name="max_'.$item['id'].'" type="number" min="0" step="1" max="'.$item['max_score'].'" value="'.$selectedMaxScoreValue.'" />';
$return .= '<input
class="form-control"
size="4"
maxlength="3"
name="max_'.$item['id'].'"
type="number"
min="0"
step="1"
max="'.$item['max_score'].'"
value="'.$selectedMaxScoreValue.'"
/>';
$return .= '</td>';
}
if ($item['item_type'] == TOOL_HOTPOTATOES) {
$return .= '<td>';
$return .= '<input size="4" maxlength="3" name="min_'.$item['id'].'" type="number" min="0" step="1" max="'.$item['max_score'].'" value="'.$selectedMinScoreValue.'" />';
$return .= '<input
size="4"
maxlength="3"
name="min_'.$item['id'].'"
type="number"
min="0"
step="1"
max="'.$item['max_score'].'"
value="'.$selectedMinScoreValue.'"
/>';
$return .= '</td>';
$return .= '<td>';
$return .= '<input size="4" maxlength="3" name="max_'.$item['id'].'" readonly type="number" min="0" step="1" max="'.$item['max_score'].'" value="'.$selectedMaxScoreValue.'" />';
$return .= '<input
size="4"
maxlength="3"
name="max_'.$item['id'].'"
type="number"
min="0"
step="1"
max="'.$item['max_score'].'"
value="'.$selectedMaxScoreValue.'"
/>';
$return .= '</td>';
}
$return .= '</tr>';
@ -9867,7 +9907,8 @@ class learnpath
$return .= '</table>';
$return .= '</div>';
$return .= '<div class="form-group">';
$return .= '<button class="btn btn-primary" name="submit_button" type="submit">'.get_lang('ModifyPrerequisites').'</button>';
$return .= '<button class="btn btn-primary" name="submit_button" type="submit">'.
get_lang('ModifyPrerequisites').'</button>';
$return .= '</form>';
return $return;

@ -103,10 +103,8 @@ class learnpathItem
$user_id = api_get_user_id();
}
if (self::DEBUG > 0) {
error_log(
"learnpathItem constructor: id: $id user_id: ".
"$user_id course_id: $course_id item_content: ".print_r($item_content, 1)
);
error_log("learnpathItem constructor: id: $id user_id: $user_id course_id: $course_id");
error_log("item_content: ".print_r($item_content, 1));
}
$id = intval($id);
if (empty($item_content)) {
@ -1989,8 +1987,8 @@ class learnpathItem
}
$restart = 1;
$mystatus = $this->get_status(true);
if ($this->get_prevent_reinit() > 0
) { // If prevent_reinit == 1 (or more)
if ($this->get_prevent_reinit() > 0) {
// If prevent_reinit == 1 (or more)
// If status is not attempted or incomplete, authorize retaking (of the same) anyway. Otherwise:
if ($mystatus != $this->possible_status[0] && $mystatus != $this->possible_status[1]) {
$restart = -1;
@ -2113,6 +2111,7 @@ class learnpathItem
return false;
}
while (strpos($prereqs_string, '(') !== false) {
// Remove any () set and replace with its value.
$matches = [];
@ -2197,7 +2196,6 @@ class learnpathItem
}
} else {
// No ORs found, now look for ANDs.
if (self::DEBUG > 1) {
error_log('New LP - Didnt find any AND, looking for =', 0);
}
@ -2438,7 +2436,7 @@ class learnpathItem
}
} else {
// Nothing found there either. Now return the
// value of the corresponding resource completion status.
// value of the corresponding resource completion status.
if (self::DEBUG > 1) {
error_log(
'New LP - Didnt find any group, returning value for '.$prereqs_string,
@ -2449,12 +2447,19 @@ class learnpathItem
if (isset($refs_list[$prereqs_string]) &&
isset($items[$refs_list[$prereqs_string]])
) {
if ($items[$refs_list[$prereqs_string]]->type == 'quiz') {
/** @var learnpathItem $itemToCheck */
$itemToCheck = $items[$refs_list[$prereqs_string]];
if ($itemToCheck->type == 'quiz') {
// 1. Checking the status in current items.
$status = $items[$refs_list[$prereqs_string]]->get_status(true);
$status = $itemToCheck->get_status(true);
$returnstatus = $status == $this->possible_status[2] || $status == $this->possible_status[3];
if (!$returnstatus) {
$explanation = sprintf(
get_lang('ItemXBlocksThisElement'),
$itemToCheck->get_title()
);
$this->prereq_alert = $explanation;
if (self::DEBUG > 1) {
error_log(
'New LP - Prerequisite '.$prereqs_string.' not complete',
@ -2497,7 +2502,11 @@ class learnpathItem
) {
$returnstatus = true;
} else {
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
$explanation = sprintf(
get_lang('YourResultAtXBlocksThisElement'),
$itemToCheck->get_title()
);
$this->prereq_alert = $explanation;
$returnstatus = false;
}
} else {
@ -2507,14 +2516,16 @@ class learnpathItem
) {
$returnstatus = true;
} else {
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
$explanation = sprintf(
get_lang('YourResultAtXBlocksThisElement'),
$itemToCheck->get_title()
);
$this->prereq_alert = $explanation;
$returnstatus = false;
}
}
} else {
$this->prereq_alert = get_lang(
'LearnpathPrereqNotCompleted'
);
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
$returnstatus = false;
}
}
@ -2541,7 +2552,11 @@ class learnpathItem
$returnstatus = true;
break;
} else {
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
$explanation = sprintf(
get_lang('YourResultAtXBlocksThisElement'),
$itemToCheck->get_title()
);
$this->prereq_alert = $explanation;
$returnstatus = false;
}
} else {
@ -2549,26 +2564,27 @@ class learnpathItem
$returnstatus = true;
break;
} else {
$this->prereq_alert = get_lang(
'LearnpathPrereqNotCompleted'
);
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
$returnstatus = false;
}
}
}
} else {
$this->prereq_alert = get_lang(
'LearnpathPrereqNotCompleted'
);
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
$returnstatus = false;
}
}
return $returnstatus;
} else {
$status = $items[$refs_list[$prereqs_string]]->get_status(false);
$status = $itemToCheck->get_status(false);
$returnstatus = $status == $this->possible_status[2] || $status == $this->possible_status[3];
if (!$returnstatus) {
$explanation = sprintf(
get_lang('ItemXBlocksThisElement'),
$itemToCheck->get_title()
);
$this->prereq_alert = $explanation;
if (self::DEBUG > 1) {
error_log(
'New LP - Prerequisite '.$prereqs_string.' not complete',
@ -2586,12 +2602,8 @@ class learnpathItem
if ($returnstatus && $this->prevent_reinit == 1) {
// I would prefer check in the database.
$lp_item_view = Database::get_course_table(
TABLE_LP_ITEM_VIEW
);
$lp_view = Database::get_course_table(
TABLE_LP_VIEW
);
$lp_item_view = Database::get_course_table(TABLE_LP_ITEM_VIEW);
$lp_view = Database::get_course_table(TABLE_LP_VIEW);
$sql = 'SELECT iid FROM '.$lp_view.'
WHERE
@ -2601,9 +2613,7 @@ class learnpathItem
session_id = '.$sessionId.'
LIMIT 0, 1';
$rs_lp = Database::query($sql);
$lp_id = Database::fetch_row(
$rs_lp
);
$lp_id = Database::fetch_row($rs_lp);
$my_lp_id = $lp_id[0];
$sql = 'SELECT status FROM '.$lp_item_view.'
@ -2618,23 +2628,15 @@ class learnpathItem
$returnstatus = ($status == $this->possible_status[2]) || ($status == $this->possible_status[3]);
if (!$returnstatus && empty($this->prereq_alert)) {
$this->prereq_alert = get_lang(
'LearnpathPrereqNotCompleted'
);
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
}
if (!$returnstatus) {
if (self::DEBUG > 1) {
error_log(
'New LP - Prerequisite '.$prereqs_string.' not complete',
0
);
error_log('New LP - Prerequisite '.$prereqs_string.' not complete');
}
} else {
if (self::DEBUG > 1) {
error_log(
'New LP - Prerequisite '.$prereqs_string.' complete',
0
);
error_log('New LP - Prerequisite '.$prereqs_string.' complete');
}
}
}
@ -2706,16 +2708,13 @@ class learnpathItem
$status = $items[$refs_list[$list[0]]]->get_status(true);
$returnstatus = $status == 'completed' || $status == 'passed';
if (!$returnstatus && empty($this->prereq_alert)) {
$this->prereq_alert = get_lang(
'LearnpathPrereqNotCompleted'
);
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
}
return $returnstatus;
}
}
}
if (empty($this->prereq_alert)) {
$this->prereq_alert = get_lang('LearnpathPrereqNotCompleted');
}
@ -3404,6 +3403,10 @@ class learnpathItem
if ($debug) {
error_log('found asset - set time to '.$myTime);
}
} else {
if ($debug) {
error_log('Time not set');
}
}
} else {
switch ($format) {
@ -3422,11 +3425,16 @@ class learnpathItem
$totalSec = $hour * 3600 + $min * 60 + $sec;
if ($debug) {
error_log("totalSec : $totalSec");
error_log("Now calling to scorm_update_time()");
}
$this->scorm_update_time($totalSec);
}
break;
case 'int':
if ($debug) {
error_log("scorm_time = $scorm_time");
error_log("Now calling to scorm_update_time()");
}
$this->scorm_update_time($scorm_time);
break;
}

@ -115,7 +115,7 @@ if (!$is_allowed_to_edit) {
$platform_theme = api_get_setting('stylesheets'); // Platform's css.
$my_style = $platform_theme;
$ajaxUrl = api_get_path(WEB_AJAX_PATH).'lp.ajax.php?a=get_item_prerequisites&'.api_get_cidreq();
$htmlHeadXtra[] = '<script>
<!--
var jQueryFrameReadyConfigPath = \''.api_get_jquery_web_path().'\';
@ -124,9 +124,38 @@ var jQueryFrameReadyConfigPath = \''.api_get_jquery_web_path().'\';
$htmlHeadXtra[] = '<script type="text/javascript" src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/jquery.frameready.js"></script>';
$htmlHeadXtra[] = '<script>
$(document).ready(function() {
$("div#log_content_cleaner").bind("click", function() {
$("div#log_content").empty();
});
$(".scorm_item_normal").qtip({
content: {
text: function(event, api) {
var item = $(this);
var itemId = $(this).attr("id");
itemId = itemId.replace("toc_", "");
var textToShow = "";
$.ajax({
type: "GET",
url: "'.$ajaxUrl.'&item_id="+ itemId,
async: false
})
.then(function(content) {
if (content == 1) {
textToShow = "'.addslashes(get_lang('LPItemCanBeAccessed')).'";
api.set("style.classes", "qtip-green qtip-shadow");
} else {
textToShow = content;
api.set("style.classes", "qtip-red qtip-shadow");
}
return textToShow;
});
return textToShow;
}
}
});
});
var chamilo_xajax_handler = window.oxajax;
</script>';
@ -148,6 +177,8 @@ if (isset($exerciseResult) || isset($_SESSION['exerciseResult'])) {
Session::erase('exerciseResult');
Session::erase('objExercise');
Session::erase('questionList');
Session::erase('duration_time_previous');
Session::erase('duration_time');
}
// additional APIs
@ -522,7 +553,11 @@ if ($gamificationMode == 1) {
$template->assign('lp_author', $lp->get_author());
$template->assign('lp_mode', $lp->mode);
$template->assign('lp_title_scorm', $lp->name);
$template->assign('data_list', $lp->getListArrayToc($get_toc_list));
if (api_get_configuration_value('lp_view_accordion') === true && $lpType == 1) {
$template->assign('data_panel', $lp->getParentToc($get_toc_list));
} else {
$template->assign('data_list', $lp->getListArrayToc($get_toc_list));
}
$template->assign('lp_id', $lp->lp_id);
$template->assign('lp_current_item_id', $lp->get_current_item_id());
$template->assign('disable_js_in_lp_view', (int) api_get_configuration_value('disable_js_in_lp_view'));

@ -115,7 +115,6 @@ function confirmation(name) {
</script>
<?php
Session::write('oLP', $lp);
$id = isset($new_item_id) ? $new_item_id : $_GET['id'];
if (is_object($lp)) {
switch ($mode) {

@ -2034,7 +2034,6 @@ function xajax_save_objectives(lms_lp_id,lms_user_id,lms_view_id,lms_item_id,ite
* @uses lp_ajax_switch_item.php
*/
function xajax_switch_item_details(lms_lp_id,lms_user_id,lms_view_id,lms_item_id,next_item) {
var params = {
'lid': lms_lp_id,
'uid': lms_user_id,
@ -2157,7 +2156,6 @@ function attach_glossary_into_scorm(type) {
var complex_array = new Array();
$("iframe").contents().find("body").on("click", ".glossary-ajax", function() {
div_show_id="div_show_id";
div_content_id="div_content_id";
@ -2260,7 +2258,6 @@ function attach_glossary_into_scorm(type) {
objects.each(function (value, obj) {
var dialogId = this.id +'_dialog';
var openerId = this.id +'_opener';
var link = '<a id="'+openerId+'" href="#" class="generated btn">'+
'<div style="text-align: center"><img src="<?php echo Display::returnIconPath('play-circle-8x.png'); ?>"/><br />If video does not work, try clicking here.</div></a>';
var embed = $("iframe").contents().find("#"+this.id).find('embed').first();
@ -2373,6 +2370,5 @@ function attach_glossary_into_scorm(type) {
});
});
}
}
}

@ -18,7 +18,9 @@ if (isset($_GET['from']) && $_GET['from'] == 'myspace') {
$this_section = SECTION_COURSES;
}
$session_id = isset($_REQUEST['id_session']) && !empty($_REQUEST['id_session']) ? intval($_REQUEST['id_session']) : api_get_session_id();
$session_id = isset($_REQUEST['id_session']) && !empty($_REQUEST['id_session'])
? intval($_REQUEST['id_session'])
: api_get_session_id();
$export_csv = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
$user_id = isset($_GET['student_id']) ? intval($_GET['student_id']) : api_get_user_id();
$courseCode = isset($_GET['course']) ? Security::remove_XSS($_GET['course']) : api_get_course_id();
@ -35,9 +37,11 @@ $name = $userInfo['complete_name'];
$isBoss = UserManager::userIsBossOfStudent(api_get_user_id(), $user_id);
if (!api_is_platform_admin(true) &&
!CourseManager :: is_course_teacher(api_get_user_id(), $courseCode) &&
!CourseManager::is_course_teacher(api_get_user_id(), $courseCode) &&
!$isBoss &&
!Tracking::is_allowed_to_coach_student(api_get_user_id(), $user_id) && !api_is_drh() && !api_is_course_tutor()
!Tracking::is_allowed_to_coach_student(api_get_user_id(), $user_id) &&
!api_is_drh() &&
!api_is_course_tutor()
) {
api_not_allowed(
api_get_origin() !== 'learnpath'
@ -45,20 +49,29 @@ if (!api_is_platform_admin(true) &&
}
if ($origin == 'user_course') {
$interbreadcrumb[] = ["url" => api_get_path(WEB_COURSE_PATH).$course_info['directory'], 'name' => $course_info['name']];
$interbreadcrumb[] = ["url" => "../user/user.php?cidReq=".$courseCode, "name" => get_lang("Users")];
$interbreadcrumb[] = [
'url' => api_get_path(WEB_COURSE_PATH).$course_info['directory'],
'name' => $course_info['name'],
];
$interbreadcrumb[] = [
'url' => "../user/user.php?cidReq=$courseCode",
'name' => get_lang("Users"),
];
} elseif ($origin == 'tracking_course') {
$interbreadcrumb[] = ["url" => "../tracking/courseLog.php?cidReq=".$courseCode.'&id_session='.$session_id, "name" => get_lang("Tracking")];
$interbreadcrumb[] = [
'url' => "../tracking/courseLog.php?cidReq=$courseCode&id_session=$session_id",
'name' => get_lang("Tracking"),
];
} else {
$interbreadcrumb[] = ["url" => "index.php", "name" => get_lang('MySpace')];
$interbreadcrumb[] = ["url" => "student.php", "name" => get_lang("MyStudents")];
$interbreadcrumb[] = ["url" => "myStudents.php?student=".$user_id, "name" => get_lang("StudentDetails")];
$interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('MySpace')];
$interbreadcrumb[] = ['url' => 'student.php', 'name' => get_lang("MyStudents")];
$interbreadcrumb[] = ['url' => "myStudents.php?student=$user_id", 'name' => get_lang("StudentDetails")];
$nameTools = get_lang("DetailsStudentInCourse");
}
$interbreadcrumb[] = [
"url" => "myStudents.php?student=".$user_id."&course=".$courseCode."&details=true&origin=".$origin,
"name" => get_lang("DetailsStudentInCourse"),
'url' => "myStudents.php?student=$user_id&course=$courseCode&details=true&origin=$origin",
'name' => get_lang("DetailsStudentInCourse"),
];
$nameTools = get_lang('LearningPathDetails');
$sql = 'SELECT name FROM '.Database::get_course_table(TABLE_LP_MAIN).'
@ -70,29 +83,35 @@ $origin = 'tracking';
$output = require_once api_get_path(SYS_CODE_PATH).'lp/lp_stats.php';
Display :: display_header($nameTools);
echo '<div class ="actions">';
echo '<a href="javascript:history.back();">'.
Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM).'</a>';
echo '<a href="javascript: void(0);" onclick="javascript: window.print();">
'.Display::return_icon('printer.png', get_lang('Print'), '', ICON_SIZE_MEDIUM).'</a>';
echo '<a href="'.api_get_self().'?export=csv&'.Security::remove_XSS($_SERVER['QUERY_STRING']).'">
'.Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM).'</a>';
echo '</div>';
echo '<div class="clear"></div>';
$session_name = api_get_session_name($session_id);
$table_title = ($session_name ? Display::return_icon('session.png', get_lang('Session'), [], ICON_SIZE_SMALL).' '.$session_name.' ' : ' ').
Display::return_icon('course.png', get_lang('Course'), [], ICON_SIZE_SMALL).' '.$course_info['name'].' '.
Display::return_icon('user.png', get_lang('User'), [], ICON_SIZE_SMALL).' '.$name;
$actions = [];
$actions[] = Display::url(
Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM),
'javascript:history.back();'
);
$actions[] = Display::url(
Display::return_icon('printer.png', get_lang('Print'), '', ICON_SIZE_MEDIUM),
'window.print();'
);
$actions[] = Display::url(
Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '', ICON_SIZE_MEDIUM),
api_get_self().'?export=csv&'.Security::remove_XSS($_SERVER['QUERY_STRING'])
);
Display::display_header($nameTools);
echo Display::toolbarAction(
'actions',
[implode(PHP_EOL, $actions)]
);
$table_title = $session_id
? Display::return_icon('session.png', get_lang('Session')).PHP_EOL.api_get_session_name($session_id).PHP_EOL
: PHP_EOL;
$table_title .= Display::return_icon('course.png', get_lang('Course')).PHP_EOL.$course_info['name'].PHP_EOL
.Display::return_icon('user.png', get_lang('User')).' '.$name;
echo Display::page_header($table_title);
echo Display::page_subheader(
'<h3>'.Display::return_icon(
'learnpath.png',
get_lang('ToolLearnpath'),
[],
ICON_SIZE_SMALL
).' '.$lp_title.'</h3>'
Display::return_icon('learnpath.png', get_lang('ToolLearnpath')).PHP_EOL.$lp_title
);
echo $output;
Display :: display_footer();
Display::display_footer();

@ -675,7 +675,7 @@ $userGroups = $userGroupManager->getNameListByUser(
?>
<tr>
<td align="right"><?php echo get_lang('TimeSpentInTheCourse'); ?></td>
<td align="left"><?php echo $time_spent_on_the_course; ?></td>
<td align="left"><?php echo $time_spent_on_the_course; ?></td>
</tr>
<tr>
<td align="right">
@ -1086,7 +1086,6 @@ if (empty($details)) {
foreach ($flat_list as $learnpath) {
$lp_id = $learnpath['lp_old_id'];
$lp_name = $learnpath['lp_name'];
$any_result = false;
// Get progress in lp

@ -1,7 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Student report.
* Report on students subscribed to courses I am teaching.
*
* @package chamilo.reporting
*/
@ -38,15 +39,16 @@ if (isset($_GET["user_id"]) && $_GET["user_id"] != "" && isset($_GET["type"]) &&
function get_count_users()
{
$keyword = isset($_GET['keyword']) ? Security::remove_XSS($_GET['keyword']) : null;
$active = isset($_GET['active']) ? (int) $_GET['active'] : 1;
$sleepingDays = isset($_GET['sleeping_days']) ? (int) $_GET['sleeping_days'] : null;
$active = isset($_GET['active']) ? (int) $_GET['active'] : 1;
$keyword = isset($_GET['keyword']) ? Security::remove_XSS($_GET['keyword']) : null;
$lastConnectionDate = null;
if (!empty($sleepingDays)) {
$lastConnectionDate = api_get_utc_datetime(strtotime($sleepingDays.' days ago'));
}
$count = SessionManager::getCountUserTracking(
return SessionManager::getCountUserTracking(
$keyword,
$active,
$lastConnectionDate,
@ -54,17 +56,15 @@ function get_count_users()
null,
api_is_student_boss() ? null : STUDENT
);
return $count;
}
function get_users($from, $limit, $column, $direction)
{
global $export_csv;
$active = isset($_GET['active']) ? $_GET['active'] : 1;
$keyword = isset($_GET['keyword']) ? Security::remove_XSS($_GET['keyword']) : null;
$sleepingDays = isset($_GET['sleeping_days']) ? (int) $_GET['sleeping_days'] : null;
$sessionId = isset($_GET['id_session']) ? (int) $_GET['id_session'] : 0;
$export_csv = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
$lastConnectionDate = null;
if (!empty($sleepingDays)) {
@ -72,11 +72,10 @@ function get_users($from, $limit, $column, $direction)
}
$is_western_name_order = api_is_western_name_order();
$coach_id = api_get_user_id();
$column = 'u.user_id';
$drhLoaded = false;
if (api_is_drh()) {
$column = 'u.user_id';
if (api_drh_can_access_all_session_content()) {
$students = SessionManager::getAllUsersFromCoursesFromAllSessionFromStatus(
'drh_all',
@ -97,7 +96,7 @@ function get_users($from, $limit, $column, $direction)
}
}
if ($drhLoaded == false) {
if ($drhLoaded === false) {
$students = UserManager::getUsersFollowedByUser(
api_get_user_id(),
api_is_student_boss() ? null : STUDENT,
@ -130,13 +129,18 @@ function get_users($from, $limit, $column, $direction)
foreach ($courses as $course_code) {
$courseInfo = api_get_course_info($course_code);
$courseId = $courseInfo['real_id'];
if (CourseManager :: is_user_subscribed_in_course($student_id, $course_code, true)) {
$avg_time_spent += Tracking :: get_time_spent_on_the_course($student_id, $courseId, $sessionId);
$my_average = Tracking :: get_avg_student_score($student_id, $course_code);
if (CourseManager::is_user_subscribed_in_course($student_id, $course_code, true)) {
$avg_time_spent += Tracking::get_time_spent_on_the_course(
$student_id,
$courseId,
$_GET['id_session']
);
$my_average = Tracking::get_avg_student_score($student_id, $course_code);
if (is_numeric($my_average)) {
$avg_student_score += $my_average;
}
$avg_student_progress += Tracking :: get_avg_student_progress($student_id, $course_code);
$avg_student_progress += Tracking::get_avg_student_progress($student_id, $course_code);
$nb_courses_student++;
}
}
@ -253,7 +257,7 @@ if (api_is_drh()) {
'#'
);
$actionsLeft .= Display::url(
Display::return_icon("statistics.png", get_lang("CompanyReport"), [], ICON_SIZE_MEDIUM),
Display::return_icon("statistics.png", get_lang('CompanyReport'), [], ICON_SIZE_MEDIUM),
api_get_path(WEB_CODE_PATH)."mySpace/company_reports.php"
);
$actionsLeft .= Display::url(
@ -267,8 +271,7 @@ if (api_is_drh()) {
);
}
$actionsRight = '';
$actionsRight .= Display::url(
$actionsRight = Display::url(
Display::return_icon('printer.png', get_lang('Print'), [], ICON_SIZE_MEDIUM),
'javascript: void(0);',
['onclick' => 'javascript: window.print();']
@ -346,8 +349,7 @@ if ($export_csv) {
} else {
Display::display_header($nameTools);
echo $toolbar;
$page_title = get_lang('Students');
echo Display::page_subheader($page_title);
echo Display::page_subheader($nameTools);
if (isset($active)) {
if ($active) {
$activeLabel = get_lang('ActiveUsers');

@ -22,10 +22,16 @@ api_block_anonymous_users();
$this_section = SECTION_TRACKING;
$interbreadcrumb[] = ["url" => "index.php", "name" => get_lang('MySpace')];
$interbreadcrumb[] = [
"url" => "index.php",
"name" => get_lang('MySpace'),
];
if (isset($_GET["user_id"]) && $_GET["user_id"] != "" && !isset($_GET["type"])) {
$interbreadcrumb[] = ["url" => "teachers.php", "name" => get_lang('Teachers')];
$interbreadcrumb[] = [
"url" => "teachers.php",
"name" => get_lang('Teachers'),
];
}
if (isset($_GET["user_id"]) && $_GET["user_id"] != "" && isset($_GET["type"]) && $_GET["type"] == "coach") {
@ -34,8 +40,8 @@ if (isset($_GET["user_id"]) && $_GET["user_id"] != "" && isset($_GET["type"]) &&
function get_count_users()
{
$sleepingDays = isset($_GET['sleeping_days']) ? intval($_GET['sleeping_days']) : null;
$active = isset($_GET['active']) ? $_GET['active'] : 1;
$sleepingDays = isset($_GET['sleeping_days']) ? (int) $_GET['sleeping_days'] : null;
$active = isset($_GET['active']) ? (int) $_GET['active'] : 1;
$keyword = isset($_GET['keyword']) ? Security::remove_XSS($_GET['keyword']) : null;
$status = isset($_GET['status']) ? Security::remove_XSS($_GET['status']) : null;
@ -58,19 +64,18 @@ function get_users($from, $limit, $column, $direction)
{
$active = isset($_GET['active']) ? $_GET['active'] : 1;
$keyword = isset($_GET['keyword']) ? Security::remove_XSS($_GET['keyword']) : null;
$sleepingDays = isset($_GET['sleeping_days']) ? intval($_GET['sleeping_days']) : null;
$status = isset($_GET['status']) ? Security::remove_XSS($_GET['status']) : null;
$sleepingDays = isset($_GET['sleeping_days']) ? (int) $_GET['sleeping_days'] : null;
$sessionId = isset($_GET['id_session']) ? (int) $_GET['id_session'] : 0;
$status = isset($_GET['status']) ? Security::remove_XSS($_GET['status']) : null;
$lastConnectionDate = null;
if (!empty($sleepingDays)) {
$lastConnectionDate = api_get_utc_datetime(strtotime($sleepingDays.' days ago'));
}
$is_western_name_order = api_is_western_name_order();
$coach_id = api_get_user_id();
$column = 'u.user_id';
$drhLoaded = false;
if (api_is_drh()) {
if (api_drh_can_access_all_session_content()) {
$students = SessionManager::getAllUsersFromCoursesFromAllSessionFromStatus(
@ -114,7 +119,7 @@ function get_users($from, $limit, $column, $direction)
foreach ($students as $student_data) {
$student_id = $student_data['user_id'];
if (isset($_GET['id_session'])) {
$courses = Tracking :: get_course_list_in_session_from_student($student_id, $_GET['id_session']);
$courses = Tracking :: get_course_list_in_session_from_student($student_id, $sessionId);
}
$avg_time_spent = $avg_student_score = $avg_student_progress = 0;

@ -0,0 +1,41 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\PortfolioCategory;
$form = new FormValidator('add_category', 'post', "$baseUrl&action=add_category");
$form->addText('title', get_lang('Title'));
$form->addHtmlEditor('description', get_lang('Description'), false, false, ['ToolbarSet' => 'Minimal']);
$form->addButtonCreate(get_lang('Create'));
if ($form->validate()) {
$values = $form->exportValues();
$category = new PortfolioCategory();
$category
->setTitle($values['title'])
->setDescription($values['description'])
->setUser($user);
$em->persist($category);
$em->flush();
Display::addFlash(
Display::return_message(get_lang('CategoryAdded'), 'success')
);
header("Location: $baseUrl");
exit;
}
$toolName = get_lang('AddCategory');
$interbreadcrumb[] = [
'name' => get_lang('Portfolio'),
'url' => $baseUrl,
];
$actions[] = Display::url(
Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM),
$baseUrl
);
$content = $form->returnForm();

@ -0,0 +1,59 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\Portfolio;
$categories = $em
->getRepository('ChamiloCoreBundle:PortfolioCategory')
->findBy([
'user' => $user,
]);
$form = new FormValidator('add_portfolio', 'post', $baseUrl.'action=add_item');
$form->addText('title', get_lang('Title'));
$form->addHtmlEditor('content', get_lang('Content'), true, false, ['ToolbarSet' => 'NotebookStudent']);
$form->addSelectFromCollection('category', get_lang('Category'), $categories, [], true);
$form->addButtonCreate(get_lang('Create'));
if ($form->validate()) {
$values = $form->exportValues();
$currentTime = new DateTime(
api_get_utc_datetime(),
new DateTimeZone('UTC')
);
$portfolio = new Portfolio();
$portfolio
->setTitle($values['title'])
->setContent($values['content'])
->setUser($user)
->setCourse($course)
->setSession($session)
->setCategory(
$em->find('ChamiloCoreBundle:PortfolioCategory', $values['category'])
)
->setCreationDate($currentTime)
->setUpdateDate($currentTime);
$em->persist($portfolio);
$em->flush();
Display::addFlash(
Display::return_message(get_lang('PortfolioItemAdded'), 'success')
);
header("Location: $baseUrl");
exit;
}
$toolName = get_lang('AddPortfolioItem');
$interbreadcrumb[] = [
'name' => get_lang('Portfolio'),
'url' => $baseUrl,
];
$actions[] = Display::url(
Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM),
$baseUrl
);
$content = $form->returnForm();

@ -0,0 +1,40 @@
<?php
/* For licensing terms, see /license.txt */
$form = new FormValidator('edit_category', 'post', $baseUrl."action=edit_category&id={$category->getId()}");
$form->addText('title', get_lang('Title'));
$form->addHtmlEditor('description', get_lang('Description'), false, false, ['ToolbarSet' => 'Minimal']);
$form->addButtonUpdate(get_lang('Update'));
$form->setDefaults([
'title' => $category->getTitle(),
'description' => $category->getDescription(),
]);
if ($form->validate()) {
$values = $form->exportValues();
$category
->setTitle($values['title'])
->setDescription($values['description']);
$em->persist($category);
$em->flush();
Display::addFlash(
Display::return_message(get_lang('Updated'), 'success')
);
header("Location: $baseUrl");
exit;
}
$toolName = get_lang('EditCategory');
$interbreadcrumb[] = [
'name' => get_lang('Portfolio'),
'url' => $baseUrl,
];
$actions[] = Display::url(
Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM),
$baseUrl
);
$content = $form->returnForm();

@ -0,0 +1,53 @@
<?php
/* For licensing terms, see /license.txt */
$categories = $em
->getRepository('ChamiloCoreBundle:PortfolioCategory')
->findBy([
'user' => $user,
]);
$form = new FormValidator('edit_portfolio', 'post', $baseUrl."action=edit_item&id={$item->getId()}");
$form->addText('title', get_lang('Title'));
$form->addHtmlEditor('content', get_lang('Content'), true, false, ['ToolbarSet' => 'NotebookStudent']);
$form->addSelectFromCollection('category', get_lang('Category'), $categories, [], true, '__toString');
$form->addButtonUpdate(get_lang('Update'));
$form->setDefaults([
'title' => $item->getTitle(),
'content' => $item->getContent(),
'category' => $item->getCategory() ? $item->getCategory()->getId() : '',
]);
if ($form->validate()) {
$values = $form->exportValues();
$currentTime = new DateTime(api_get_utc_datetime(), new DateTimeZone('UTC'));
$item
->setTitle($values['title'])
->setContent($values['content'])
->setUpdateDate($currentTime)
->setCategory(
$em->find('ChamiloCoreBundle:PortfolioCategory', $values['category'])
);
$em->persist($item);
$em->flush();
Display::addFlash(
Display::return_message(get_lang('Updated'), 'success')
);
header("Location: $baseUrl");
exit;
}
$toolName = get_lang('EditPortfolioItem');
$interbreadcrumb[] = [
'name' => get_lang('Portfolio'),
'url' => $baseUrl,
];
$actions[] = Display::url(
Display::return_icon('back.png', get_lang('Back'), [], ICON_SIZE_MEDIUM),
$baseUrl
);
$content = $form->returnForm();

@ -1,5 +1,226 @@
<?php
/**
* @license see /license.txt
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
*/
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Portfolio;
use Chamilo\CoreBundle\Entity\PortfolioCategory;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\UserBundle\Entity\User;
require_once __DIR__.'/../inc/global.inc.php';
api_block_anonymous_users();
if (false === api_get_configuration_value('allow_portfolio_tool')) {
api_not_allowed(true);
}
$em = Database::getManager();
$currentUserId = api_get_user_id();
$userId = isset($_GET['user']) ? (int) $_GET['user'] : $currentUserId;
/** @var User $user */
$user = api_get_user_entity($userId);
/** @var Course $course */
$course = $em->find('ChamiloCoreBundle:Course', api_get_course_int_id());
/** @var Session $session */
$session = $em->find('ChamiloCoreBundle:Session', api_get_session_id());
$action = isset($_GET['action']) ? $_GET['action'] : 'list';
$cidreq = api_get_cidreq();
$baseUrl = api_get_self().'?'.($cidreq ? $cidreq.'&' : '');
$allowEdit = $currentUserId == $user->getId();
if (isset($_GET['preview'])) {
$allowEdit = false;
}
$toolName = get_lang('Portfolio');
$actions = [];
$content = '';
/**
* Check if the portfolio item or category is valid for the current user.
*
* @param $item
*
* @return bool
*/
$isValid = function ($item) use ($user, $course, $session) {
if (!$item) {
return false;
}
if (get_class($item) == Portfolio::class) {
if ($session && $item->getSession()->getId() != $session->getId()) {
return false;
}
if ($course && $item->getCourse()->getId() != $course->getId()) {
return false;
}
}
if ($item->getUser()->getId() != $user->getId()) {
return false;
}
return true;
};
switch ($action) {
case 'add_category':
require 'add_category.php';
break;
case 'edit_category':
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
if (!$id) {
break;
}
/** @var PortfolioCategory $category */
$category = $em->find('ChamiloCoreBundle:PortfolioCategory', $id);
if (!$isValid($category)) {
api_not_allowed(true);
}
require 'edit_category.php';
break;
case 'hide_category':
case 'show_category':
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
if (!$id) {
break;
}
/** @var PortfolioCategory $category */
$category = $em->find('ChamiloCoreBundle:PortfolioCategory', $id);
if (!$isValid($category)) {
api_not_allowed(true);
}
$category->setIsVisible(!$category->isVisible());
$em->persist($category);
$em->flush();
Display::addFlash(
Display::return_message(get_lang('VisibilityChanged'), 'success')
);
header("Location: $baseUrl");
exit;
case 'delete_category':
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
if (!$id) {
break;
}
/** @var PortfolioCategory $category */
$category = $em->find('ChamiloCoreBundle:PortfolioCategory', $id);
if (!$isValid($category)) {
api_not_allowed(true);
}
$em->remove($category);
$em->flush();
Display::addFlash(
Display::return_message(get_lang('PortfolioItemDeleted'), 'success')
);
header("Location: $baseUrl");
exit;
case 'add_item':
require 'add_item.php';
break;
case 'edit_item':
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
if (!$id) {
break;
}
/** @var CPortfolio $item */
$item = $em->find('ChamiloCoreBundle:Portfolio', $id);
if (!$isValid($item)) {
api_not_allowed(true);
}
require 'edit_item.php';
break;
case 'hide_item':
case 'show_item':
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
if (!$id) {
break;
}
/** @var Portfolio $item */
$item = $em->find('ChamiloCoreBundle:Portfolio', $id);
if (!$isValid($item)) {
api_not_allowed(true);
}
$item->setIsVisible(!$item->isVisible());
$em->persist($item);
$em->flush();
Display::addFlash(
Display::return_message(get_lang('VisibilityChanged'), 'success')
);
header("Location: $baseUrl");
exit;
case 'delete_item':
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
if (!$id) {
break;
}
/** @var Portfolio $item */
$item = $em->find('ChamiloCoreBundle:Portfolio', $id);
if (!$isValid($item)) {
api_not_allowed(true);
}
$em->remove($item);
$em->flush();
Display::addFlash(
Display::return_message(get_lang('PortfolioItemDeleted'), 'success')
);
header("Location: $baseUrl");
exit;
case 'list':
default:
require 'list.php';
}
/*
* View
*/
$this_section = $course ? SECTION_COURSES : SECTION_SOCIAL;
$actions = implode(PHP_EOL, $actions);
Display::display_header($toolName);
Display::display_introduction_section(TOOL_PORTFOLIO);
echo $actions ? Display::toolbarAction('portfolio-toolbar', [$actions]) : '';
echo Display::page_header($toolName);
echo $content;
Display::display_footer();

@ -0,0 +1,59 @@
<?php
/* For licensing terms, see /license.txt */
if ($currentUserId == $user->getId()) {
if ($allowEdit) {
$actions[] = Display::url(
Display::return_icon('add.png', get_lang('Add'), [], ICON_SIZE_MEDIUM),
$baseUrl.'action=add_item'
);
$actions[] = Display::url(
Display::return_icon('folder.png', get_lang('AddCategory'), [], ICON_SIZE_MEDIUM),
$baseUrl.'action=add_category'
);
$actions[] = Display::url(
Display::return_icon('shared_setting.png', get_lang('Preview'), [], ICON_SIZE_MEDIUM),
$baseUrl.'preview=&user='.$user->getId()
);
} else {
$actions[] = Display::url(
Display::return_icon('shared_setting_na.png', get_lang('Preview'), [], ICON_SIZE_MEDIUM),
$baseUrl
);
}
}
$form = new FormValidator('a');
$form->addUserAvatar('user', get_lang('User'), 'medium');
$form->setDefaults(['user' => $user]);
$criteria = ['user' => $user];
if (!$allowEdit) {
$criteria['isVisible'] = true;
}
$categories = $em
->getRepository('ChamiloCoreBundle:PortfolioCategory')
->findBy($criteria);
if ($course) {
$criteria['course'] = $course;
$criteria['session'] = $session;
}
$criteria['category'] = null;
$items = $em
->getRepository('ChamiloCoreBundle:Portfolio')
->findBy($criteria);
$template = new Template(null, false, false, false, false, false, false);
$template->assign('user', $user);
$template->assign('course', $course);
$template->assign('session', $session);
$template->assign('allow_edit', $allowEdit);
$template->assign('portfolio', $categories);
$template->assign('uncategorized_items', $items);
$layout = $template->get_template('portfolio/list.html.twig');
$content = $template->fetch($layout);

@ -1,6 +1,7 @@
<?php
/**
*
* @license see /license.txt
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
*/

@ -227,6 +227,7 @@ $template->assign(
);
$template->assign('has_requirements', $hasRequirements);
$template->assign('sequences', $sessionRequirements);
$template->assign('is_premiun', $sessionIsPremium);
$layout = $template->get_template('session/about.tpl');
$content = $template->fetch($layout);
$template->assign('header', $session->getName());

@ -37,6 +37,8 @@ Session::write('id_session', $session_id);
// Clear the exercise session just in case
Session::erase('objExercise');
Session::erase('duration_time_previous');
Session::erase('duration_time');
$userId = api_get_user_id();
$session_info = SessionManager::fetch($session_id);

Loading…
Cancel
Save