From 4aa6a0ef4c8db6943975a6ef8df712b5fff90ab3 Mon Sep 17 00:00:00 2001 From: jmontoyaa Date: Mon, 9 Apr 2018 13:27:12 +0200 Subject: [PATCH] Minor - merge with 1.11.x --- main/inc/lib/image.lib.php | 2 + main/inc/lib/internationalization.lib.php | 5 +- main/inc/lib/legal.lib.php | 4 +- main/inc/lib/plugin.lib.php | 2 +- main/inc/lib/sessionmanager.lib.php | 75 ++++++ main/inc/lib/social.lib.php | 46 ++-- main/inc/lib/statistics.lib.php | 2 +- main/inc/lib/tracking.lib.php | 180 +++++++++++--- .../update-files-1.10.0-1.11.0.inc.php | 11 +- main/lp/learnpath.class.php | 83 +++++-- main/lp/learnpathItem.class.php | 102 ++++---- main/lp/lp_view.php | 39 ++- main/lp/lp_view_item.php | 1 - main/lp/scorm_api.php | 4 - main/mySpace/lp_tracking.php | 83 ++++--- main/mySpace/myStudents.php | 3 +- main/mySpace/student.php | 40 ++-- main/mySpace/users.php | 23 +- main/portfolio/add_category.php | 41 ++++ main/portfolio/add_item.php | 59 +++++ main/portfolio/edit_category.php | 40 ++++ main/portfolio/edit_item.php | 53 +++++ main/portfolio/index.php | 223 +++++++++++++++++- main/portfolio/list.php | 59 +++++ main/portfolio/share.php | 1 + main/session/about.php | 1 + main/session/index.php | 2 + 27 files changed, 983 insertions(+), 201 deletions(-) create mode 100644 main/portfolio/add_category.php create mode 100644 main/portfolio/add_item.php create mode 100644 main/portfolio/edit_category.php create mode 100644 main/portfolio/edit_item.php create mode 100644 main/portfolio/list.php 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 = '
'; + $preview = '
+ +
'; } $preview .= get_lang('ByClickingRegisterYouAgreeTermsAndConditions'); $courseInfo = api_get_course_info(); diff --git a/main/inc/lib/plugin.lib.php b/main/inc/lib/plugin.lib.php index 864aa38900..3015da6aef 100755 --- a/main/inc/lib/plugin.lib.php +++ b/main/inc/lib/plugin.lib.php @@ -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(); } diff --git a/main/inc/lib/sessionmanager.lib.php b/main/inc/lib/sessionmanager.lib.php index ce4b31a3d2..9b74a645ec 100755 --- a/main/inc/lib/sessionmanager.lib.php +++ b/main/inc/lib/sessionmanager.lib.php @@ -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). * diff --git a/main/inc/lib/social.lib.php b/main/inc/lib/social.lib.php index 5a9d2b049e..d03a8eac9c 100755 --- a/main/inc/lib/social.lib.php +++ b/main/inc/lib/social.lib.php @@ -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"], '
', $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 .= '
'; $media .= '
'; - $media .= 'x'; + $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 .= '
'; $media .= '
'; } @@ -1816,7 +1824,8 @@ class SocialManager extends UserManager $description = $graph->description; $title = $graph->title; $html = '
'; - $html .= empty($image) ? '' : ''; + $html .= empty($image) ? '' : ' + '; $html .= ''; } else { - $friendHtml .= '
'.get_lang('NoFriendsInYourContactList').' ' - .' '.get_lang('TryAndFindSomeFriends').'
'; + $friendHtml .= '
'.get_lang('NoFriendsInYourContactList').' + + '.get_lang('TryAndFindSomeFriends').'
'; } return $friendHtml; @@ -2226,8 +2237,12 @@ class SocialManager extends UserManager $htmlDelete = ''; if ($isOwnWall) { - $htmlDelete .= 'x'; + $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 .= '
'; } $html .= '
'; - $html .= ''.''.$nameCompleteAuthor.''; + $html .= ' + '.$nameCompleteAuthor.''; $html .= '
'; $html .= '
'; $html .= '
'.$nameCompleteAuthor.''.$htmlReceiver.'
'; 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 .= ''; + $return .= ''; $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[] = ' '+ '

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);