diff --git a/main/inc/lib/image.lib.php b/main/inc/lib/image.lib.php
index 74451f2a23..da13c880a0 100755
--- a/main/inc/lib/image.lib.php
+++ b/main/inc/lib/image.lib.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;
diff --git a/main/inc/lib/internationalization.lib.php b/main/inc/lib/internationalization.lib.php
index d5c9936f6f..fee7685de0 100755
--- a/main/inc/lib/internationalization.lib.php
+++ b/main/inc/lib/internationalization.lib.php
@@ -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
*
diff --git a/main/inc/lib/legal.lib.php b/main/inc/lib/legal.lib.php
index a467a5669d..1475b03678 100755
--- a/main/inc/lib/legal.lib.php
+++ b/main/inc/lib/legal.lib.php
@@ -215,7 +215,9 @@ class LegalManager
switch ($term_preview['type']) {
case 0:
if (!empty($term_preview['content'])) {
- $preview = '
';
$html .= '
';
diff --git a/main/inc/lib/statistics.lib.php b/main/inc/lib/statistics.lib.php
index cb87f958ea..a3d38fa9f9 100644
--- a/main/inc/lib/statistics.lib.php
+++ b/main/inc/lib/statistics.lib.php
@@ -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
diff --git a/main/inc/lib/tracking.lib.php b/main/inc/lib/tracking.lib.php
index 7400a6555c..820db29de2 100755
--- a/main/inc/lib/tracking.lib.php
+++ b/main/inc/lib/tracking.lib.php
@@ -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 = '
';
@@ -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 '
Final return ';
}
+
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'] = '
-
- '.Display::return_icon('2rightarrow.png', get_lang('Details')).'
-
- ';
+ $url = $urlBase.'&student='.$user['user_id'];
+
+ $user['link'] = '
+ '.Display::return_icon('2rightarrow.png', get_lang('Details')).'
+ ';
// store columns in array $users
$is_western_name_order = api_is_western_name_order();
diff --git a/main/install/update-files-1.10.0-1.11.0.inc.php b/main/install/update-files-1.10.0-1.11.0.inc.php
index ac5142c4a4..43469732d3 100644
--- a/main/install/update-files-1.10.0-1.11.0.inc.php
+++ b/main/install/update-files-1.10.0-1.11.0.inc.php
@@ -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');
}
diff --git a/main/lp/learnpath.class.php b/main/lp/learnpath.class.php
index d6d12cb55a..08a8db5816 100755
--- a/main/lp/learnpath.class.php
+++ b/main/lp/learnpath.class.php
@@ -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 .= '
';
- $return .= ' ';
+ $return .= ' ';
$return .= ' ';
$return .= '
';
- $return .= ' ';
+ $return .= ' ';
$return .= ' ';
}
if ($item['item_type'] == TOOL_HOTPOTATOES) {
$return .= '
';
- $return .= ' ';
+ $return .= ' ';
$return .= ' ';
$return .= '
';
- $return .= ' ';
+ $return .= ' ';
$return .= ' ';
}
$return .= '';
@@ -9867,7 +9907,8 @@ class learnpath
$return .= '';
$return .= '
';
$return .= '';
- $return .= '
'.get_lang('ModifyPrerequisites').' ';
+ $return .= '
'.
+ get_lang('ModifyPrerequisites').' ';
$return .= '';
return $return;
diff --git a/main/lp/learnpathItem.class.php b/main/lp/learnpathItem.class.php
index 8ae06e7ddf..d5460354af 100755
--- a/main/lp/learnpathItem.class.php
+++ b/main/lp/learnpathItem.class.php
@@ -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;
}
diff --git a/main/lp/lp_view.php b/main/lp/lp_view.php
index db3640d940..578a670951 100755
--- a/main/lp/lp_view.php
+++ b/main/lp/lp_view.php
@@ -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[] = '';
$htmlHeadXtra[] = '';
@@ -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'));
diff --git a/main/lp/lp_view_item.php b/main/lp/lp_view_item.php
index 61fad6a157..f2a8c830ab 100755
--- a/main/lp/lp_view_item.php
+++ b/main/lp/lp_view_item.php
@@ -115,7 +115,6 @@ function confirmation(name) {
'+
'
If video does not work, try clicking here.
';
var embed = $("iframe").contents().find("#"+this.id).find('embed').first();
@@ -2373,6 +2370,5 @@ function attach_glossary_into_scorm(type) {
});
});
}
-
}
}
diff --git a/main/mySpace/lp_tracking.php b/main/mySpace/lp_tracking.php
index 61c00a135a..92f34ae1f7 100755
--- a/main/mySpace/lp_tracking.php
+++ b/main/mySpace/lp_tracking.php
@@ -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 '
';
-echo '
';
-$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(
- '
'.Display::return_icon(
- 'learnpath.png',
- get_lang('ToolLearnpath'),
- [],
- ICON_SIZE_SMALL
- ).' '.$lp_title.' '
+ Display::return_icon('learnpath.png', get_lang('ToolLearnpath')).PHP_EOL.$lp_title
);
echo $output;
-Display :: display_footer();
+Display::display_footer();
diff --git a/main/mySpace/myStudents.php b/main/mySpace/myStudents.php
index 4a632677a2..776d9cbcc1 100755
--- a/main/mySpace/myStudents.php
+++ b/main/mySpace/myStudents.php
@@ -675,7 +675,7 @@ $userGroups = $userGroupManager->getNameListByUser(
?>
-
+
@@ -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
diff --git a/main/mySpace/student.php b/main/mySpace/student.php
index a98bf8cf64..45bb09ee10 100755
--- a/main/mySpace/student.php
+++ b/main/mySpace/student.php
@@ -1,7 +1,8 @@
'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');
diff --git a/main/mySpace/users.php b/main/mySpace/users.php
index e8a522f7fa..d50a5dddb9 100755
--- a/main/mySpace/users.php
+++ b/main/mySpace/users.php
@@ -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;
diff --git a/main/portfolio/add_category.php b/main/portfolio/add_category.php
new file mode 100644
index 0000000000..321ab55c5b
--- /dev/null
+++ b/main/portfolio/add_category.php
@@ -0,0 +1,41 @@
+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();
diff --git a/main/portfolio/add_item.php b/main/portfolio/add_item.php
new file mode 100644
index 0000000000..27107b69ea
--- /dev/null
+++ b/main/portfolio/add_item.php
@@ -0,0 +1,59 @@
+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();
diff --git a/main/portfolio/edit_category.php b/main/portfolio/edit_category.php
new file mode 100644
index 0000000000..2fdaf402a9
--- /dev/null
+++ b/main/portfolio/edit_category.php
@@ -0,0 +1,40 @@
+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();
diff --git a/main/portfolio/edit_item.php b/main/portfolio/edit_item.php
new file mode 100644
index 0000000000..7b560919fd
--- /dev/null
+++ b/main/portfolio/edit_item.php
@@ -0,0 +1,53 @@
+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();
diff --git a/main/portfolio/index.php b/main/portfolio/index.php
index 06c24a7398..f318d8d900 100755
--- a/main/portfolio/index.php
+++ b/main/portfolio/index.php
@@ -1,5 +1,226 @@
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();
diff --git a/main/portfolio/list.php b/main/portfolio/list.php
new file mode 100644
index 0000000000..3b28641761
--- /dev/null
+++ b/main/portfolio/list.php
@@ -0,0 +1,59 @@
+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);
diff --git a/main/portfolio/share.php b/main/portfolio/share.php
index 1b315bbbeb..b60355b130 100755
--- a/main/portfolio/share.php
+++ b/main/portfolio/share.php
@@ -1,6 +1,7 @@
for the Univesity of Geneva
*/
diff --git a/main/session/about.php b/main/session/about.php
index 6be6bc3a99..7aa890c027 100644
--- a/main/session/about.php
+++ b/main/session/about.php
@@ -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());
diff --git a/main/session/index.php b/main/session/index.php
index e64597f234..185d444ff6 100755
--- a/main/session/index.php
+++ b/main/session/index.php
@@ -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);