Minor - Merge from 1.11.x

pull/2487/head
jmontoyaa 8 years ago
parent 617e33a8b8
commit 0024316e0c
  1. 3
      assets/css/themes/chamilo/default.css
  2. 11
      main/admin/course_add.php
  3. 15
      main/admin/course_category.php
  4. 10
      main/admin/course_edit.php
  5. 2
      main/announcements/announcements.php
  6. 3
      main/attendance/attendance_add.php
  7. 18
      main/attendance/attendance_controller.php
  8. 8
      main/attendance/attendance_edit.php
  9. 1
      main/attendance/index.php
  10. 2
      main/auth/courses.php
  11. 21
      main/auth/courses_categories.php
  12. 1
      main/course_home/course_home.php
  13. 3
      main/course_home/vertical_activity.php
  14. 11
      main/create_course/add_course.php
  15. 58
      main/document/create_paint.php
  16. 56
      main/document/document.php
  17. 6
      main/document/download.php
  18. 30
      main/document/edit_paint.php
  19. 148
      main/document/save_pixlr.php
  20. 12
      main/document/show_content.php
  21. 14
      main/exercise/admin.php
  22. 19
      main/exercise/annotation_user.php
  23. 8
      main/exercise/answer.class.php
  24. 2
      main/exercise/calculated_answer.class.php
  25. 37
      main/exercise/exercise.class.php
  26. 2
      main/exercise/exercise_admin.php
  27. 5
      main/exercise/exercise_show.php
  28. 2
      main/exercise/hotspot.class.php
  29. 74
      main/exercise/question.class.php
  30. 2
      main/exercise/question_pool.php
  31. 10
      main/forum/editthread.php
  32. 52
      main/forum/forumfunction.inc.php
  33. 2
      main/forum/viewthread_flat.inc.php
  34. 9
      main/glossary/index.php
  35. 4
      main/gradebook/gradebook_add_cat.php
  36. 24
      main/gradebook/gradebook_display_summary.php
  37. 27
      main/gradebook/lib/be/abstractlink.class.php
  38. 1
      main/gradebook/lib/fe/catform.class.php
  39. 7
      main/gradebook/lib/fe/evalform.class.php
  40. 4
      main/gradebook/lib/fe/gradebooktable.class.php
  41. 5
      main/inc/ajax/course.ajax.php
  42. 6
      main/inc/ajax/document.ajax.php
  43. 4
      main/inc/ajax/model.ajax.php
  44. 69
      main/inc/ajax/skill.ajax.php
  45. 65
      main/inc/lib/AnnouncementEmail.php
  46. 10
      main/inc/lib/AnnouncementManager.php
  47. 5
      main/inc/lib/api.lib.php
  48. 11
      main/inc/lib/certificate.lib.php
  49. 18
      main/inc/lib/course.lib.php
  50. 65
      main/inc/lib/course_category.lib.php
  51. 27
      main/inc/lib/exercise.lib.php
  52. 2
      main/inc/lib/export.lib.inc.php
  53. 6
      main/inc/lib/fileUpload.lib.php
  54. 8
      main/inc/lib/formvalidator/Element/DateTimePicker.php
  55. 33
      main/inc/lib/formvalidator/FormValidator.class.php
  56. 89
      main/inc/lib/javascript/annotation/js/annotation.js
  57. 17
      main/inc/lib/link.lib.php
  58. 40
      main/inc/lib/login.lib.php
  59. 187
      main/inc/lib/message.lib.php
  60. 28
      main/inc/lib/plugin.class.php
  61. 41
      main/inc/lib/sessionmanager.lib.php
  62. 234
      main/inc/lib/skill.lib.php
  63. 5
      main/link/link.php
  64. 1
      main/lp/aicc_hacp.php
  65. 87
      main/lp/learnpath.class.php
  66. 2
      main/lp/lp_add.php
  67. 7
      main/lp/lp_add_item.php
  68. 30
      main/lp/lp_admin_view.php
  69. 2
      main/lp/lp_ajax_save_item.php
  70. 39
      main/lp/lp_build.php
  71. 45
      main/lp/lp_content.php
  72. 24
      main/lp/lp_controller.php
  73. 55
      main/lp/lp_edit.php
  74. 25
      main/lp/lp_edit_item.php
  75. 12
      main/lp/lp_list.php
  76. 20
      main/lp/lp_move_item.php
  77. 6
      main/lp/lp_subscribe_users_to_category.php
  78. 80
      main/lp/lp_upload.php
  79. 18
      main/lp/lp_view.php
  80. 5
      main/lp/lp_view_item.php
  81. 122
      main/lp/scorm.class.php
  82. 2
      main/mySpace/exercise_category_report.php
  83. 33
      main/mySpace/myStudents.php
  84. 30
      main/survey/create_new_survey.php
  85. 2
      main/survey/survey.lib.php
  86. 18
      main/survey/surveyUtil.class.php
  87. 2
      main/work/edit_work.php
  88. 2
      main/work/view.php
  89. 7
      main/work/work.lib.php
  90. 2
      main/work/work.php
  91. 13
      main/work/work_list.php

@ -5,6 +5,7 @@
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Based on Bootstrap v3
*/
@font-face {
font-family: 'Open Sans';
font-style: normal;
@ -33,7 +34,7 @@ body {
margin: 0;
font-family: 'Open Sans', sans-serif;
}
a {
color: #0099FF;
text-decoration: none;

@ -59,7 +59,10 @@ $form->addText(
$form->applyFilter('visual_code', 'api_strtoupper');
$form->applyFilter('visual_code', 'html_filter');
$countCategories = $courseCategoriesRepo->countAllInAccessUrl($accessUrlId);
$countCategories = $courseCategoriesRepo->countAllInAccessUrl(
$accessUrlId,
api_get_configuration_value('allow_base_course_category')
);
if ($countCategories >= 100) {
// Category code
@ -73,9 +76,11 @@ if ($countCategories >= 100) {
['url' => $url]
);
} else {
$categories = $courseCategoriesRepo->findAllInAccessUrl($accessUrlId);
$categories = $courseCategoriesRepo->findAllInAccessUrl(
$accessUrlId,
api_get_configuration_value('allow_base_course_category')
);
$categoriesOptions = [null => get_lang('None')];
/** @var CourseCategory $category */
foreach ($categories as $category) {
$categoriesOptions[$category->getCode()] = (string) $category;

@ -80,6 +80,7 @@ $interbreadcrumb[] = [
];
Display::display_header($tool_name);
$urlId = api_get_current_access_url_id();
if ($action == 'add' || $action == 'edit') {
echo '<div class="actions">';
@ -168,7 +169,7 @@ if ($action == 'add' || $action == 'edit') {
$form->display();
} else {
// If multiple URLs and not main URL, prevent deletion and inform user
if ($action == 'delete' && api_get_multiple_access_url() && api_get_current_access_url_id() != 1) {
if ($action == 'delete' && api_get_multiple_access_url() && $urlId != 1) {
echo Display::return_message(get_lang('CourseCategoriesAreGlobal'), 'warning');
}
echo '<div class="actions">';
@ -176,18 +177,22 @@ if ($action == 'add' || $action == 'edit') {
if (!empty($parentInfo)) {
$parentCode = $parentInfo['parent_id'];
echo Display::url(
Display::return_icon('back.png', get_lang("Back"), '', ICON_SIZE_MEDIUM),
Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM),
api_get_path(WEB_CODE_PATH).'admin/course_category.php?category='.$parentCode
);
}
if (empty($parentInfo) || $parentInfo['auth_cat_child'] == 'TRUE') {
echo Display::url(
Display::return_icon('new_folder.png', get_lang("AddACategory"), '', ICON_SIZE_MEDIUM),
$newCategoryLink = Display::url(
Display::return_icon('new_folder.png', get_lang('AddACategory'), '', ICON_SIZE_MEDIUM),
api_get_path(WEB_CODE_PATH).'admin/course_category.php?action=add&category='.Security::remove_XSS($category)
);
}
if (!empty($parentInfo) && $parentInfo['access_url_id'] != $urlId) {
$newCategoryLink = '';
}
echo $newCategoryLink;
}
echo '</div>';
if (!empty($parentInfo)) {
echo Display::page_subheader($parentInfo['name'].' ('.$parentInfo['code'].')');

@ -145,7 +145,10 @@ $form->addText(
$form->applyFilter('visual_code', 'strtoupper');
$form->applyFilter('visual_code', 'html_filter');
$countCategories = $courseCategoriesRepo->countAllInAccessUrl($urlId);
$countCategories = $courseCategoriesRepo->countAllInAccessUrl(
$urlId,
api_get_configuration_value('allow_base_course_category')
);
if ($countCategories >= 100) {
// Category code
$url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=search_category';
@ -164,7 +167,10 @@ if ($countCategories >= 100) {
}
} else {
$courseInfo['category_code'] = $courseInfo['categoryCode'];
$categories = $courseCategoriesRepo->findAllInAccessUrl($urlId);
$categories = $courseCategoriesRepo->findAllInAccessUrl(
$urlId,
api_get_configuration_value('allow_base_course_category')
);
$categoriesOptions = [null => get_lang('None')];
/** @var CourseCategory $category */

@ -39,7 +39,7 @@ $allowToEdit = (
);
$sessionId = api_get_session_id();
$drhHasAccessToSessionContent = api_get_configuration_value('drh_can_access_all_session_content');
$drhHasAccessToSessionContent = api_drh_can_access_all_session_content();
if (!empty($sessionId) && $drhHasAccessToSessionContent) {
$allowToEdit = $allowToEdit || api_is_drh();

@ -65,6 +65,9 @@ if ((api_get_session_id() != 0 && Gradebook::is_active()) || api_get_session_id(
);
$form->applyFilter('attendance_weight', 'html_filter');
$form->addElement('html', '</div>');
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_ATTENDANCE, 0);
$form->addElement('html', '</div>');
}
$form->addButtonCreate(get_lang('Save'));

@ -45,7 +45,6 @@ class AttendanceController
{
$attendance = new Attendance();
$data = [];
if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') {
if (!empty($_POST['title'])) {
$check = Security::check_token();
@ -62,10 +61,15 @@ class AttendanceController
$link_to_gradebook = true;
}
$attendance->category_id = isset($_POST['category_id']) ? $_POST['category_id'] : 0;
$last_id = $attendance->attendance_add($link_to_gradebook);
$attendanceId = $attendance->attendance_add($link_to_gradebook);
if ($attendanceId) {
$form = new FormValidator('attendance_add');
Skill::saveSkills($form, ITEM_TYPE_ATTENDANCE, $attendanceId);
}
Security::clear_token();
}
header('Location: index.php?action=calendar_add&attendance_id='.$last_id.'&'.api_get_cidreq());
header('Location: index.php?action=calendar_add&attendance_id='.$attendanceId.'&'.api_get_cidreq());
exit;
} else {
$data['error'] = true;
@ -119,8 +123,13 @@ class AttendanceController
$link_to_gradebook = true;
}
$attendance->attendance_edit($attendance_id, $link_to_gradebook);
$form = new FormValidator('attendance_edit');
Skill::saveSkills($form, ITEM_TYPE_ATTENDANCE, $attendance_id);
Display::addFlash(Display::return_message(get_lang('Updated')));
Security::clear_token();
header('location:index.php?action=attendance_list&'.api_get_cidreq());
header('Location:index.php?action=attendance_list&'.api_get_cidreq());
exit;
}
} else {
@ -167,6 +176,7 @@ class AttendanceController
$attendance = new Attendance();
if (!empty($attendance_id)) {
$affected_rows = $attendance->attendance_delete($attendance_id);
Skill::deleteSkillsFromItem($attendance_id, ITEM_TYPE_ATTENDANCE);
}
if ($affected_rows) {

@ -44,8 +44,8 @@ $form->addHtmlEditor(
]
);
// Adavanced Parameters
// Advanced Parameters
$skillList = [];
if (Gradebook::is_active()) {
if (!empty($attendance_qualify_title) || !empty($attendance_weight)) {
$form->addButtonAdvancedSettings('id_qualify');
@ -81,6 +81,9 @@ if (Gradebook::is_active()) {
);
$form->applyFilter('attendance_weight', 'html_filter');
$form->addElement('html', '</div>');
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_ATTENDANCE, $attendance_id);
$form->addElement('html', '</div>');
}
$form->addButtonUpdate(get_lang('Save'));
@ -90,6 +93,7 @@ $default['title'] = Security::remove_XSS($title);
$default['description'] = Security::remove_XSS($description, STUDENT);
$default['attendance_qualify_title'] = $attendance_qualify_title;
$default['attendance_weight'] = $attendance_weight;
$default['skills'] = array_keys($skillList);
$link_info = GradebookUtils::isResourceInCourseGradebook(
api_get_course_id(),

@ -247,6 +247,7 @@ switch ($action) {
case 'attendance_delete':
if ($allowToEdit) {
$attendanceController->attendance_delete($attendance_id);
Display::addFlash(Display::return_message(get_lang('Deleted')));
} else {
api_not_allowed(true);
}

@ -4,7 +4,7 @@
use Chamilo\CoreBundle\Entity\SequenceResource;
/**
* Template (front controller in MVC pattern) used for distpaching
* Template (front controller in MVC pattern) used for dispatching
* to the controllers depend on the current action
* @author Christian Fasanando <christian1827@gmail.com> - Beeznest
* @package chamilo.auth

@ -105,14 +105,19 @@ $code = isset($code) ? $code : null;
$form .= '<div class="form-group">';
$form .= '<label>'.get_lang('CourseCategories').'</label>';
$form .= '<select name="category_code" onchange="submit();" class="selectpicker show-tick form-control">';
foreach ($browse_course_categories[0] as $category) {
$categoryCode = $category['code'];
$countCourse = $category['count_courses'];
if (empty($countCourse)) {
continue;
}
$form .= '<option '.($categoryCode == $codeType ? 'selected="selected" ' : '')
.' value="'.$category['code'].'">'.$category['name'].' ('.$countCourse.') </option>';
if (!empty($browse_course_categories[$categoryCode])) {
foreach ($browse_course_categories[$categoryCode] as $subCategory) {
if (empty($subCategory['count_courses'])) {
continue;
}
$subCategoryCode = $subCategory['code'];
$form .= '<option '
.($subCategoryCode == $codeType
@ -163,10 +168,16 @@ if ($showCourses && $action != 'display_sessions') {
}
$showTeacher = api_get_setting('display_teacher_in_courselist') === 'true';
$ajax_url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=add_course_vote';
$user_id = api_get_user_id();
$categoryList = CourseManager::getCategoriesList();
$categoryListFromDatabase = CourseCategory::getCategories();
$categoryList = [];
if (!empty($categoryListFromDatabase)) {
foreach ($categoryListFromDatabase as $categoryItem) {
$categoryList[$categoryItem['code']] = $categoryItem['name'];
}
}
if (!empty($browse_courses_in_category)) {
echo '<div class="grid-courses row">';
@ -204,7 +215,6 @@ if ($showCourses && $action != 'display_sessions') {
$separator = null;
$subscribeButton = return_register_button($course, $stok, $code, $searchTerm);
// Start buy course validation
// display the course price and buy button if the buycourses plugin is enabled and this course is configured
$plugin = BuyCoursesPlugin::create();
@ -268,7 +278,6 @@ if ($showCourses && $action != 'display_sessions') {
$html .= '</div>';
echo $html;
}
echo '</div>';
} else {
if (!isset($_REQUEST['subscribe_user_with_password']) &&
@ -409,9 +418,7 @@ function return_teacher($courseInfo)
function return_title($course, $registeredUser)
{
$linkCourse = api_get_course_url($course['code']);
$html = '<div class="block-title"><h4 class="title">';
if (!$registeredUser) {
$html .= $course['title'];
} else {

@ -130,6 +130,7 @@ if (api_is_invitee()) {
// Deleting group session
Session::erase('toolgroup');
Session::erase('_gid');
//$check = \Chamilo\CoreBundle\Framework\Container::$container->get('security.authorization_checker');
$isSpecialCourse = CourseManager::isSpecialCourse($courseId);

@ -100,11 +100,12 @@ if (api_is_allowed_to_edit(null, true) && !api_is_coach()) {
}
$my_list = CourseHome::get_tools_category(TOOL_STUDENT_VIEW);
// TOOLS AUTHORING
$blocks[] = [
'class' => 'Authoringview',
'content' => CourseHome::show_tools_category($my_list)
];
// TOOLS AUTHORING
} else {
$my_list = CourseHome::get_tools_category(TOOL_STUDENT_VIEW);
if (count($my_list) > 0) {

@ -91,12 +91,14 @@ $form->addElement(
'<div id="advanced_params_options" style="display:none">'
);
$countCategories = $courseCategoriesRepo->countAllInAccessUrl($accessUrlId);
$countCategories = $courseCategoriesRepo->countAllInAccessUrl(
$accessUrlId,
api_get_configuration_value('allow_base_course_category')
);
if ($countCategories >= 100) {
// Category code
$url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=search_category';
$form->addElement(
'select_ajax',
'category_code',
@ -105,7 +107,10 @@ if ($countCategories >= 100) {
['url' => $url]
);
} else {
$categories = $courseCategoriesRepo->findAllInAccessUrl($accessUrlId);
$categories = $courseCategoriesRepo->findAllInAccessUrl(
$accessUrlId,
api_get_configuration_value('allow_base_course_category')
);
$categoriesOptions = [null => get_lang('None')];
/** @var CourseCategory $category */

@ -14,6 +14,11 @@ use ChamiloSession as Session;
*/
require_once __DIR__.'/../inc/global.inc.php';
if (api_get_setting('enabled_support_paint') === 'false') {
api_not_allowed(true);
}
$this_section = SECTION_COURSES;
$nameTools = get_lang('PhotoRetouching');
$groupRights = Session::read('group_member_with_upload_rights');
@ -21,11 +26,6 @@ $groupRights = Session::read('group_member_with_upload_rights');
api_protect_course_script();
api_block_anonymous_users();
$_course = api_get_course_info();
if (api_get_setting('enabled_support_paint') === 'false') {
api_not_allowed(true);
}
$document_data = DocumentManager::get_document_data_by_id($_GET['id'], api_get_course_id(), true);
if (empty($document_data)) {
if (api_is_in_group()) {
@ -37,15 +37,14 @@ if (empty($document_data)) {
$document_id = $document_data['id'];
$dir = $document_data['path'];
//$dir = isset($_GET['dir']) ? Security::remove_XSS($_GET['dir']) : Security::remove_XSS($_POST['dir']);
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
//path for pixlr save
// path for pixlr save
$paintDir = Security::remove_XSS($dir);
if ($paintDir == '/') {
$paintDir = '';
if (empty($paintDir)) {
$paintDir = '/';
}
Session::write('paint_dir', $paintDir);
Session::write('paint_file', get_lang('NewImage'));
@ -102,7 +101,7 @@ if (!($is_allowed_to_edit || $groupRights ||
api_not_allowed(true);
}
/* Header */
/* Header */
Event::event_access_tool(TOOL_DOCUMENT);
$display_dir = $dir;
if (isset($group)) {
@ -123,8 +122,8 @@ if (empty($document_data['parents'])) {
];
}
}
Display :: display_header($nameTools, 'Doc');
Display::display_header($nameTools, 'Doc');
echo '<div class="actions">';
echo '<a href="document.php?id='.$document_id.'">'.
Display::return_icon(
@ -139,21 +138,14 @@ echo '</div>';
// pixlr
// max size 1 Mb ??
$title = urlencode(utf8_encode(get_lang('NewImage'))); //TODO:check
//
$image = Display::returnIconPath('canvas1024x768.png');
//
$pixlr_code_translation_table = ['' => 'en', 'pt' => 'pt-Pt', 'sr' => 'sr_latn'];
$langpixlr = api_get_language_isocode();
$langpixlr = isset($pixlr_code_translation_table[$langpixlr]) ? $pixlredit_code_translation_table[$langpixlr] : $langpixlr;
$loc = $langpixlr; // deprecated ?? TODO:check pixlr read user browser
$exit_path = api_get_path(WEB_CODE_PATH).'document/exit_pixlr.php';
Session::write('exit_pixlr', $document_data['path']);
$referrer = "Chamilo";
$target_path = api_get_path(WEB_CODE_PATH).'document/save_pixlr.php';
$target = $target_path;
$locktarget = "true";
$locktitle = "false";
$locktarget = 'true';
$locktitle = 'false';
$referrer = 'Chamilo';
if ($_SERVER['HTTP_HOST'] == "localhost") {
$path_and_file = api_get_path(SYS_PATH).'/crossdomain.xml';
@ -167,28 +159,26 @@ if ($_SERVER['HTTP_HOST'] == "localhost") {
</cross-domain-policy>';//more open domain="*"
@file_put_contents($path_and_file, $crossdomain);
}
$credentials = "true";
$credentials = 'true';
} else {
$credentials = "false";
$credentials = 'false';
}
$pixlr_url = '//pixlr.com/editor/?title='.$title.'&image='.$image.'&loc='.$loc.'&referrer='.$referrer.'&target='.$target.'&exit='.$exit_path.'&locktarget='.$locktarget.'&locktitle='.$locktitle.'&credentials='.$credentials;
$pixlr_url = '//pixlr.com/editor/?title='.$title.'&image='.$image.'&referrer='.$referrer.'&target='.$target.'&exit='.$exit_path.'&locktarget='.$locktarget.'&locktitle='.$locktitle.'&credentials='.$credentials;
?>
<script>
document.write ('<iframe id="frame" frameborder="0" scrolling="no" src="<?php echo $pixlr_url; ?>" width="100%" height="100%"><noframes><p>Sorry, your browser does not handle frames</p></noframes></iframe></div>');
document.write('<iframe id="frame" frameborder="0" scrolling="no" src="<?php echo $pixlr_url; ?>" width="100%" height="100%"><noframes><p>Sorry, your browser does not handle frames</p></noframes></iframe></div>');
function resizeIframe() {
var height = window.innerHeight;
//max lower size
if (height<600) {
height=600;
}
document.getElementById('frame').style.height = height +"px";
var height = window.innerHeight;
//max lower size
if (height<600) {
height=600;
}
document.getElementById('frame').style.height = height +"px";
};
document.getElementById('frame').onload = resizeIframe;
window.onresize = resizeIframe;
</script>
<?php
echo '<noscript>';
echo '<iframe style="height: 600px; width: 100%;" scrolling="no" frameborder="0" src="'.$pixlr_url.'"><noframes><p>Sorry, your browser does not handle frames</p></noframes></iframe>';
echo '</noscript>';

@ -121,7 +121,7 @@ DocumentManager::create_directory_certificate_in_course($courseInfo);
$dbl_click_id = 0;
$selectcat = isset($_GET['selectcat']) ? Security::remove_XSS($_GET['selectcat']) : null;
$moveTo = isset($_POST['move_to']) ? Security::remove_XSS($_POST['move_to']) : null;
$moveFile = isset($_POST['move_file']) && is_int($_POST['move_file']) ? $_POST['move_file'] : null;
$moveFile = isset($_POST['move_file']) ? (int) $_POST['move_file'] : 0;
$certificateLink = '';
if ($is_certificate_mode) {
@ -596,17 +596,17 @@ if (isset($document_id) && empty($action)) {
$groupIid
);
if (!empty($document_data['filetype']) && $document_data['filetype'] == 'file' || $document_data['filetype'] == 'link') {
if (!empty($document_data['filetype']) &&
($document_data['filetype'] == 'file' || $document_data['filetype'] == 'link')
) {
if ($visibility && api_is_allowed_to_session_edit()) {
$url = api_get_path(WEB_COURSE_PATH).
$courseInfo['path'].'/document'.$document_data['path'].'?'
.api_get_cidreq();
$url = api_get_path(WEB_COURSE_PATH).$courseInfo['path'].'/document'.$document_data['path'].'?'.api_get_cidreq();
header("Location: $url");
exit;
}
exit;
} else {
if (!$visibility && !$isAllowedToEdit) {
api_not_allowed();
api_not_allowed(true);
}
}
$_GET['curdirpath'] = $document_data['path'];
@ -621,7 +621,6 @@ if (isset($document_id) && empty($action)) {
} else {
$curdirpath = '/';
}
$curdirpathurl = urlencode($curdirpath);
} else {
// What's the current path?
@ -714,12 +713,20 @@ if (isset($_GET['curdirpath']) && $_GET['curdirpath'] == '/certificates' &&
$path_image_in_default_course,
$new_content_html
);
$new_content_html = str_replace(
SYS_CODE_PATH.'img/',
api_get_path(WEB_IMG_PATH),
$new_content_html
);
// Remove media=screen to be available when printing a document
$new_content_html = str_replace(
api_get_path(WEB_CSS_PATH).'editor.css" media="screen"',
api_get_path(WEB_CSS_PATH).'editor.css" ',
$new_content_html
);
Display::display_reduced_header();
echo '<style>body {background:none;}</style>
@ -954,10 +961,11 @@ if ($isAllowedToEdit || $group_member_with_upload_rights ||
}
if (!$isAllowedToEdit) {
if (DocumentManager::check_readonly($courseInfo, api_get_user_id(), $my_get_move)) {
if (DocumentManager::check_readonly($courseInfo, api_get_user_id(), '', $my_get_move)) {
api_not_allowed(true);
}
}
// Get the document data from the ID
$document_to_move = DocumentManager::get_document_data_by_id(
$my_get_move,
@ -975,6 +983,7 @@ if ($isAllowedToEdit || $group_member_with_upload_rights ||
false,
$curdirpath
);
$moveForm .= '<legend>'.get_lang('Move').': '.$document_to_move['title'].'</legend>';
// filter if is my shared folder. TODO: move this code to build_move_to_selector function
if (DocumentManager::is_my_shared_folder(api_get_user_id(), $curdirpath, $sessionId) &&
@ -992,8 +1001,6 @@ if ($isAllowedToEdit || $group_member_with_upload_rights ||
$user_shared_folders[] = $fold;
}
}
$moveForm .= '<legend>'.get_lang('Move').'</legend>';
$moveForm .= DocumentManager::build_move_to_selector(
$user_shared_folders,
$move_path,
@ -1001,7 +1008,6 @@ if ($isAllowedToEdit || $group_member_with_upload_rights ||
$group_properties['directory']
);
} else {
$moveForm .= '<legend>'.get_lang('Move').'</legend>';
$moveForm .= DocumentManager::build_move_to_selector(
$folders,
$move_path,
@ -1014,7 +1020,7 @@ if ($isAllowedToEdit || $group_member_with_upload_rights ||
if (!empty($moveTo) && isset($moveFile)) {
if (!$isAllowedToEdit) {
if (DocumentManager::check_readonly($courseInfo, api_get_user_id(), $moveFile)) {
if (DocumentManager::check_readonly($courseInfo, api_get_user_id(), '', $moveFile)) {
api_not_allowed(true);
}
}
@ -1039,7 +1045,12 @@ if ($isAllowedToEdit || $group_member_with_upload_rights ||
$real_path_target = $base_work_dir.$moveTo.'/';
if (!DocumentManager::cloudLinkExists($_course, $moveTo, $document_to_move['comment'])) {
$doc_id = $moveFile;
DocumentManager::updateDBInfoCloudLink($document_to_move['path'], $moveTo.'/', $doc_id);
//DocumentManager::updateDbInfo($document_to_move['path'], $moveTo.'/', $doc_id);
DocumentManager::updateDbInfo(
'update',
$document_to_move['path'],
$moveTo.'/'.basename($document_to_move['path'])
);
// Update database item property
api_item_property_update(
@ -1048,7 +1059,7 @@ if ($isAllowedToEdit || $group_member_with_upload_rights ||
$doc_id,
'FileMoved',
api_get_user_id(),
$to_group_id,
$group_properties,
null,
null,
null,
@ -2045,19 +2056,20 @@ $table = new SortableTableFromArrayConfig(
'ASC',
true
);
$query_vars = [];
$queryVars = [];
if (isset($_GET['keyword'])) {
$query_vars['keyword'] = Security::remove_XSS($_GET['keyword']);
$queryVars['keyword'] = Security::remove_XSS($_GET['keyword']);
} else {
$query_vars['curdirpath'] = $curdirpath;
$queryVars['curdirpath'] = $curdirpath;
}
if ($groupId) {
$query_vars['gidReq'] = $groupId;
$queryVars['gidReq'] = $groupId;
}
$query_vars['cidReq'] = api_get_course_id();
$table->set_additional_parameters($query_vars);
$queryVars['cidReq'] = api_get_course_id();
$queryVars['id_session'] = api_get_session_id();
$queryVars['id'] = $document_id;
$table->set_additional_parameters($queryVars);
$column = 0;
if (($isAllowedToEdit || $group_member_with_upload_rights) &&

@ -82,7 +82,7 @@ if (isset($path_info['extension']) && $path_info['extension'] == 'swf') {
}
if (Security::check_abs_path($sys_course_path.$doc_url, $sys_course_path.'/')) {
$full_file_name = $sys_course_path.$doc_url;
$fullFileName = $sys_course_path.$doc_url;
if ($fix_file_name) {
$doc_url = $fixed_url;
}
@ -102,8 +102,8 @@ if (Security::check_abs_path($sys_course_path.$doc_url, $sys_course_path.'/')) {
}
// Launch event
Event::event_download($doc_url);
$download = (!empty($_GET['dl']) ? true : false);
$result = DocumentManager::file_send_for_download($full_file_name, $download);
$download = !empty($_GET['dl']) ? true : false;
$result = DocumentManager::file_send_for_download($fullFileName, $download);
if ($result === false) {
api_not_allowed(true);
}

@ -19,6 +19,7 @@ $groupRights = Session::read('group_member_with_upload_rights');
api_protect_course_script(true);
api_block_anonymous_users();
$_course = api_get_course_info();
$groupId = api_get_group_id();
$document_data = DocumentManager::get_document_data_by_id(
$_GET['id'],
@ -36,15 +37,16 @@ if (empty($document_data)) {
$my_cur_dir_path = isset($_GET['curdirpath']) ? Security::remove_XSS($_GET['curdirpath']) : null;
}
$dir = str_replace('\\', '/', $dir); //and urlencode each url $curdirpath (hack clean $curdirpath under Windows - Bug #3261)
//and urlencode each url $curdirpath (hack clean $curdirpath under Windows - Bug #3261)
$dir = str_replace('\\', '/', $dir);
if (empty($dir)) {
$dir = '/';
}
/* Constants & Variables */
$current_session_id = api_get_session_id();
//path for pixlr save
Session::write('paint_dir', Security::remove_XSS($dir));
if ($dir == '/') {
Session::write('paint_dir', '');
}
Session::write('paint_file', basename(Security::remove_XSS($file_path)));
$get_file = Security::remove_XSS($file_path);
$file = basename($get_file);
@ -53,9 +55,7 @@ $filename = $temp_file[0];
$nameTools = get_lang('EditDocument').': '.$filename;
$courseDir = $_course['path'].'/document';
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
/* Other initialization code */
/* Other initialization code */
/* Please, do not modify this dirname formatting */
if (strstr($dir, '..')) {
$dir = '/';
@ -131,9 +131,9 @@ echo '<a href="edit_document.php?'.api_get_cidreq().'&id='.$document_id.'&'.api_
Display::return_icon('edit.png', get_lang('Rename').'/'.get_lang('Comment'), '', ICON_SIZE_MEDIUM).'</a>';
echo '</div>';
///pixlr
// pixlr
$title = $file; //disk name. No sql name because pixlr return this when save
$pixlr_code_translation_table = ['' => 'en', 'pt' => 'pt-Pt', 'sr' => 'sr_latn'];
$langpixlr = api_get_language_isocode();
$langpixlr = isset($pixlr_code_translation_table[$langpixlr]) ? $pixlredit_code_translation_table[$langpixlr] : $langpixlr;
$loc = $langpixlr; // deprecated ?? TODO:check pixlr read user browser
@ -212,12 +212,12 @@ $pixlr_url = '//pixlr.com/editor/?title='.$title.'&image='.$image.'&loc='.$loc.'
<script>
document.write ('<iframe id="frame" frameborder="0" scrolling="no" src="<?php echo $pixlr_url; ?>" width="100%" height="100%"><noframes><p>Sorry, your browser does not handle frames</p></noframes></iframe>');
function resizeIframe() {
var height = window.innerHeight;
//max lower size
if (height<600) {
height=600;
}
document.getElementById('frame').style.height = height +"px";
var height = window.innerHeight;
//max lower size
if (height<600) {
height=600;
}
document.getElementById('frame').style.height = height +"px";
};
document.getElementById('frame').onload = resizeIframe;
window.onresize = resizeIframe;

@ -16,40 +16,42 @@ require_once __DIR__.'/../inc/global.inc.php';
api_protect_course_script();
api_block_anonymous_users();
if ($_user['user_id'] != api_get_user_id() || api_get_user_id() == 0 || $_user['user_id'] == 0) {
api_not_allowed();
die();
}
if (!isset($_GET['title']) || !isset($_GET['type']) || !isset($_GET['image'])) {
api_not_allowed();
die();
echo 'No title';
exit;
}
$paintDir = Session::read('paint_dir');
if (empty($paintDir)) {
api_not_allowed();
die();
echo 'No directory to save';
exit;
}
//pixlr return
$filename = Security::remove_XSS($_GET['title']); //The user preferred file name of the image.
$extension = Security::remove_XSS($_GET['type']); //The image type, "pdx", "jpg", "bmp" or "png".
$urlcontents = Security::remove_XSS($_GET['image']); //A URL to the image on Pixlr.com server or the raw file post of the saved image.
$courseInfo = api_get_course_info();
if (empty($courseInfo)) {
echo 'Course not set';
exit;
}
//make variables
// pixlr return
//The user preferred file name of the image.
$filename = Security::remove_XSS($_GET['title']);
//The image type, "pdx", "jpg", "bmp" or "png".
$extension = Security::remove_XSS($_GET['type']);
//A URL to the image on Pixlr.com server or the raw file post of the saved image.
$urlcontents = Security::remove_XSS($_GET['image']);
// make variables
$title = Database::escape_string(str_replace('_', ' ', $filename));
$current_session_id = api_get_session_id();
$sessionId = api_get_session_id();
$groupId = api_get_group_id();
$groupInfo = GroupManager::get_group_properties($groupId);
$relativeUrlPath = Session::read('paint_dir');
$dirBaseDocuments = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
$dirBaseDocuments = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document';
$saveDir = $dirBaseDocuments.$paintDir;
$contents = file_get_contents($urlcontents);
//Security. Verify that the URL is pointing to a file @ pixlr.com domain or an ip @ pixlr.com. Comment because sometimes return a ip number
//Security. Verify that the URL is pointing to a file @ pixlr.com domain or an ip @ pixlr.com.
// Comment because sometimes return a ip number
/*
if (strpos($urlcontents, "pixlr.com") === 0){
echo "Invalid referrer";
@ -72,7 +74,8 @@ $filename = api_replace_dangerous_char($filename);
$filename = disable_dangerous_file($filename);
if (strlen(trim($filename)) == 0) {
echo "The title is empty"; //if title is empty, headers Content-Type = application/octet-stream, then not create a new title here please
echo "The title is empty"; //if title is empty, headers Content-Type = application/octet-stream,
// then not create a new title here please
exit;
}
@ -87,7 +90,8 @@ if ($extension != 'jpg' && $extension != 'png' && $extension != 'pxd') {
die();
}
if ($extension == 'pxd') {
echo "pxd file type does not supported"; // not secure because check security headers and finfo() return Content-Type = application/octet-stream
echo "pxd file type does not supported";
// not secure because check security headers and finfo() return Content-Type = application/octet-stream
exit;
}
@ -108,13 +112,13 @@ if (strpos($current_mime, 'image') === false) {
exit;
}
//path, file and title
$paintFileName = $filename.'.'.$extension;
$title = $title.'.'.$extension;
$temp_file_2delete = Session::read('temp_realpath_image');
if ($currentTool == 'document/createpaint') {
//check save as and prevent rewrite an older file with same name
if (empty($temp_file_2delete)) {
// Create file
if (0 != $groupId) {
$group_properties = GroupManager :: get_group_properties($groupId);
$groupPath = $group_properties['directory'];
@ -131,79 +135,83 @@ if ($currentTool == 'document/createpaint') {
$title = $filename.'_'.$i.'.'.$extension;
}
//
$documentPath = $saveDir.'/'.$paintFileName;
//add new document to disk
// Add new document to disk
file_put_contents($documentPath, $contents);
//add document to database
$doc_id = add_document($_course, $relativeUrlPath.'/'.$paintFileName, 'file', filesize($documentPath), $title);
api_item_property_update(
$_course,
TOOL_DOCUMENT,
$doc_id,
'DocumentAdded',
$_user['user_id'],
$groupInfo,
null,
null,
null,
$current_session_id
);
} elseif ($currentTool == 'document/editpaint') {
// Add document to database
$documentId = add_document($courseInfo, $paintDir.$paintFileName, 'file', filesize($documentPath), $title);
if ($documentId) {
api_item_property_update(
$courseInfo,
TOOL_DOCUMENT,
$documentId,
'DocumentAdded',
api_get_user_id(),
$groupInfo,
null,
null,
null,
$sessionId
);
Display::addFlash(Display::return_message(get_lang('Saved')));
}
} else {
// Update
$documentPath = $saveDir.'/'.$paintFileName;
//add new document to disk
file_put_contents($documentPath, $contents);
$paintFile = Session::read('paint_file');
//check path
if (empty($paintFile)) {
api_not_allowed();
die();
echo 'No attribute paint_file';
exit;
}
if ($paintFile == $paintFileName) {
$document_id = DocumentManager::get_document_id($_course, $relativeUrlPath.'/'.$paintFileName);
update_existing_document($_course, $document_id, filesize($documentPath), null);
$documentId = DocumentManager::get_document_id($courseInfo, $paintDir.$paintFileName);
update_existing_document($courseInfo, $documentId, filesize($documentPath), null);
api_item_property_update(
$_course,
$courseInfo,
TOOL_DOCUMENT,
$document_id,
$documentId,
'DocumentUpdated',
$_user['user_id'],
$groupInfo,
null,
null,
null,
$current_session_id
$sessionId
);
} else {
//add a new document
$doc_id = add_document(
$_course,
$relativeUrlPath.'/'.$paintFileName,
$documentId = add_document(
$courseInfo,
$paintDir.$paintFileName,
'file',
filesize($documentPath),
$title
);
api_item_property_update(
$_course,
TOOL_DOCUMENT,
$doc_id,
'DocumentAdded',
$_user['user_id'],
$groupInfo,
null,
null,
null,
$current_session_id
);
if ($documentId) {
api_item_property_update(
$courseInfo,
TOOL_DOCUMENT,
$documentId,
'DocumentAdded',
api_get_user_id(),
$groupInfo,
null,
null,
null,
$sessionId
);
Display::addFlash(Display::return_message(get_lang('Updated')));
}
}
}
//delete temporal file
$temp_file_2delete = Session::read('temp_realpath_image');
unlink($temp_file_2delete);
if (!empty($temp_file_2delete)) {
// Delete temporal file
unlink($temp_file_2delete);
}
//Clean sessions and return to Chamilo file list
Session::erase('paint_dir');
@ -214,7 +222,7 @@ $exit = Session::read('exit_pixlr');
if (empty($exit)) {
$location = api_get_path(WEB_CODE_PATH).'document/document.php?'.api_get_cidreq();
echo '<script>window.parent.location.href="'.$location.'"</script>';
api_not_allowed(true);
exit;
} else {
echo '<div align="center" style="padding-top:150; font-family:Arial, Helvetica, Sans-serif;font-size:25px;color:#aaa;font-weight:bold;">'.get_lang('PleaseStandBy').'</div>';
$location = api_get_path(WEB_CODE_PATH).'document/document.php?id='.Security::remove_XSS($exit).'&'.api_get_cidreq();

@ -86,18 +86,16 @@ if (!api_is_allowed_to_edit() && !$is_visible) {
}
//TODO:clean all code
/* Main section */
/* Main section */
header('Expires: Wed, 01 Jan 1990 00:00:00 GMT');
//header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Last-Modified: Wed, 01 Jan 2100 00:00:00 GMT');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');
$browser_display_title = 'Documents - '.Security::remove_XSS($_GET['cidReq']).' - '.$file;
$file_url_web = api_get_path(WEB_COURSE_PATH).$_course['path'].'/document'.$header_file.'?'.api_get_cidreq();
$pathinfo = pathinfo($header_file);
$url = api_get_path(WEB_COURSE_PATH).$_course['path'].'/document'.$header_file.'?'.api_get_cidreq();
$pathInfo = pathinfo($header_file);
if ($pathinfo['extension'] == 'swf') {
if ($pathInfo['extension'] == 'swf') {
$width = '83%';
$height = '83%';
} else {
@ -105,4 +103,4 @@ if ($pathinfo['extension'] == 'swf') {
$height = '100%';
}
echo '<iframe border="0" frameborder="0" scrolling="no" style="width:'.$width.'; height:'.$height.';background-color:#ffffff;" id="mainFrame" name="mainFrame" src="'.$file_url_web.'?'.api_get_cidreq().'&amp;rand='.mt_rand(1, 1000).'"></iframe>';
echo '<iframe border="0" frameborder="0" scrolling="no" style="width:'.$width.'; height:'.$height.';background-color:#ffffff;" id="mainFrame" name="mainFrame" src="'.$url.'?'.api_get_cidreq().'&amp;rand='.mt_rand(1, 1000).'"></iframe>';

@ -254,6 +254,11 @@ if (!empty($clone_question) && !empty($objExercise->id)) {
$new_question_obj = Question::read($new_id);
$new_question_obj->addToList($exerciseId);
// Save category to the destination course
if (!empty($old_question_obj->category)) {
$new_question_obj->saveCategory($old_question_obj->category, api_get_course_int_id());
}
// This should be moved to the duplicate function
$new_answer_obj = new Answer($clone_question);
$new_answer_obj->read();
@ -329,7 +334,6 @@ function multiple_answer_true_false_onchange(variable) {
document.getElementById(weight_id).value = array_result[result];
}
</script>';
$htmlHeadXtra[] = api_get_js('jqueryui-touch-punch/jquery.ui.touch-punch.min.js');
@ -349,14 +353,6 @@ if (isset($_GET['message'])) {
}
Display::display_header($nameTools, 'Exercise');
/*
if ($objExercise->exercise_was_added_in_lp) {
if ($objExercise->force_edit_exercise_in_lp == true) {
Display::addFlash(Display::return_message(get_lang('ForceEditingExerciseInLPWarning'), 'warning'));
} else {
Display::addFlash(Display::return_message(get_lang('EditingExerciseCauseProblemsInLP'), 'warning'));
}
}*/
// If we are in a test
$inATest = isset($exerciseId) && $exerciseId > 0;

@ -3,15 +3,21 @@
use ChamiloSession as Session;
session_cache_limiter("none");
session_cache_limiter('none');
require_once __DIR__.'/../inc/global.inc.php';
$questionId = isset($_GET['question_id']) ? intval($_GET['question_id']) : 0;
$exerciseId = isset($_GET['exe_id']) ? intval($_GET['exe_id']) : 0;
$questionId = isset($_GET['question_id']) ? (int) $_GET['question_id'] : 0;
$exerciseId = isset($_GET['exe_id']) ? (int) $_GET['exe_id'] : 0;
$courseId = isset($_GET['course_id']) ? (int) $_GET['course_id'] : 0;
$courseInfo = api_get_course_info_by_id($courseId);
$objQuestion = Question::read($questionId);
$documentPath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
if (empty($courseInfo)) {
return '';
}
$objQuestion = Question::read($questionId, $courseId);
$documentPath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document';
$picturePath = $documentPath.'/images';
$pictureSize = getimagesize($picturePath.'/'.$objQuestion->getPictureFilename());
$pictureWidth = $pictureSize[0];
@ -34,10 +40,8 @@ $attemptList = Event::getAllExerciseEventByExeId($exerciseId);
if (!empty($attemptList) && isset($attemptList[$questionId])) {
$questionAttempt = $attemptList[$questionId][0];
if (!empty($questionAttempt['answer'])) {
$answers = explode('|', $questionAttempt['answer']);
foreach ($answers as $answer) {
$parts = explode(')(', $answer);
$type = array_shift($parts);
@ -45,7 +49,6 @@ if (!empty($attemptList) && isset($attemptList[$questionId])) {
switch ($type) {
case 'P':
$points = [];
foreach ($parts as $partPoint) {
$points[] = Geometry::decodePoint($partPoint);
}

@ -1011,9 +1011,11 @@ class Answer
public function isCorrectByAutoId($needle)
{
$key = 0;
foreach ($this->autoId as $autoIdKey => $autoId) {
if ($autoId == $needle) {
$key = $autoIdKey;
if (is_array($this->autoId)) {
foreach ($this->autoId as $autoIdKey => $autoId) {
if ($autoId == $needle) {
$key = $autoIdKey;
}
}
}

@ -173,7 +173,7 @@ class CalculatedAnswer extends Question
$form->addButtonSave($text, 'submitQuestion');
if (!empty($this->id)) {
$form -> setDefaults($defaults);
$form->setDefaults($defaults);
} else {
if ($this->isContent == 1) {
$form->setDefaults($defaults);

@ -1850,8 +1850,8 @@ class Exercise
*/
public function delete()
{
$TBL_EXERCISES = Database::get_course_table(TABLE_QUIZ_TEST);
$sql = "UPDATE $TBL_EXERCISES SET active='-1'
$table = Database::get_course_table(TABLE_QUIZ_TEST);
$sql = "UPDATE $table SET active='-1'
WHERE c_id = ".$this->course_id." AND id = ".intval($this->id);
Database::query($sql);
@ -1870,6 +1870,8 @@ class Exercise
api_get_user_id()
);
Skill::deleteSkillsFromItem($this->iId, ITEM_TYPE_EXERCISE);
if (api_get_setting('search_enabled') == 'true' &&
extension_loaded('xapian')
) {
@ -1936,7 +1938,6 @@ class Exercise
);
$skillList = [];
if ($type == 'full') {
//Can't modify a DirectFeedback question
if ($this->selectFeedbackType() != EXERCISE_FEEDBACK_TYPE_DIRECT) {
@ -2499,7 +2500,7 @@ class Exercise
}
}
//$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_EXERCISE, $this->iId);
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_EXERCISE, $this->iId);
$form->addElement('html', '</div>'); //End advanced setting
$form->addElement('html', '</div>');
@ -2565,7 +2566,7 @@ class Exercise
} else {
$defaults['enabletimercontroltotalminutes'] = 0;
}
// $defaults['skills'] = array_keys($skillList);
$defaults['skills'] = array_keys($skillList);
$defaults['notifications'] = $this->getNotifications();
} else {
$defaults['exerciseType'] = 2;
@ -2709,12 +2710,10 @@ class Exercise
}
}
$this->save($type);
//$iId = $this->save($type);
/*if (!empty($iId)) {
$iId = $this->save($type);
if (!empty($iId)) {
Skill::saveSkills($form, ITEM_TYPE_EXERCISE, $iId);
}*/
}
}
public function search_engine_save()
@ -2993,16 +2992,19 @@ class Exercise
$question_list = $exercise_obj->selectQuestionList();
if (!empty($question_list)) {
//Question creation
// Question creation
foreach ($question_list as $old_question_id) {
$old_question_obj = Question::read($old_question_id);
$new_id = $old_question_obj->duplicate();
if ($new_id) {
$new_question_obj = Question::read($new_id);
if (isset($new_question_obj) && $new_question_obj) {
$new_question_obj->addToList($new_exercise_id);
if (!empty($old_question_obj->category)) {
$new_question_obj->saveCategory($old_question_obj->category);
}
// This should be moved to the duplicate function
$new_answer_obj = new Answer($old_question_id);
$new_answer_obj->read();
@ -3377,7 +3379,8 @@ class Exercise
$(document).ready(function() {
var current_time = new Date().getTime();
var time_left = parseInt(".$time_left."); // time in seconds when using minutes there are some seconds lost
// time in seconds when using minutes there are some seconds lost
var time_left = parseInt(".$time_left.");
var expired_time = current_time + (time_left*1000);
var expired_date = get_expired_date_string(expired_time);
@ -5467,13 +5470,14 @@ class Exercise
} elseif ($answerType == ANNOTATION) {
if ($show_result) {
echo '
<p><em>' . get_lang('Annotation').'</em></p>
<p><em>'.get_lang('Annotation').'</em></p>
<div id="annotation-canvas-'.$questionId.'"></div>
<script>
AnnotationQuestion({
questionId: parseInt('.$questionId.'),
exerciseId: parseInt('.$exeId.'),
relPath: \''.$relPath.'\'
relPath: \''.$relPath.'\',
courseId: parseInt('.$course_id.')
});
</script>
';
@ -6074,7 +6078,6 @@ class Exercise
);
$html = '<div class="question-result">';
if (api_get_configuration_value('save_titles_as_html')) {
$html .= $this->get_formated_title();
$html .= Display::page_header(get_lang('Result'));

@ -189,8 +189,8 @@ if ($form->validate()) {
} else {
if (!empty($_GET['lp_id']) || !empty($_POST['lp_id'])) {
if (!empty($_POST['lp_id'])) {
//TODO:this remains to be implemented after press the first post
$lp_id = intval($_POST['lp_id']);
//TODO:this remains to be implemented after press the first post
} else {
$lp_id = intval($_GET['lp_id']);
}

@ -377,7 +377,7 @@ $objExercise->export = $action === 'export';
$countPendingQuestions = 0;
foreach ($questionList as $questionId) {
$choice = $exerciseResult[$questionId];
$choice = isset($exerciseResult[$questionId]) ? $exerciseResult[$questionId] : '';
// destruction of the Question object
unset($objQuestionTmp);
@ -664,7 +664,8 @@ foreach ($questionList as $questionId) {
AnnotationQuestion({
questionId: '.(int) $questionId.',
exerciseId: '.(int) $id.',
relPath: \''.$relPath.'\'
relPath: \''.$relPath.'\',
courseId: '.(int) $courseInfo['real_id'].'
});
</script>
';

@ -57,7 +57,6 @@ class HotSpot extends Question
// setting the save button here and not in the question class.php
// Saving a question
$form->addButtonSave(get_lang('GoToQuestion'), 'submitQuestion');
//$form->addButtonSave(get_lang('GoToQuestion'), 'submitQuestion');
$form->addRule(
'imageUpload',
get_lang('OnlyImagesAllowed'),
@ -136,7 +135,6 @@ class HotSpotDelineation extends HotSpot
*/
public function processCreation($form, $exercise)
{
$file_info = $form->getSubmitValue('imageUpload');
parent::processCreation($form, $exercise);
}

@ -509,23 +509,26 @@ abstract class Question
* in this version, a question can only have 1 category
* if category is 0, then question has no category then delete the category entry
* @param int $categoryId
* @param int $courseId
* @return bool
*
* @author Hubert Borderiou 12-10-2011
*/
public function saveCategory($categoryId)
public function saveCategory($categoryId, $courseId = 0)
{
$courseId = api_get_course_int_id();
$courseId = empty($courseId) ? api_get_course_int_id() : (int) $courseId;
if (empty($courseId)) {
return false;
}
if ($categoryId <= 0) {
$this->deleteCategory();
$this->deleteCategory($courseId);
} else {
// update or add category for a question
$table = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$categoryId = intval($categoryId);
$question_id = intval($this->id);
$categoryId = (int) $categoryId;
$question_id = (int) $this->id;
$sql = "SELECT count(*) AS nb FROM $table
WHERE
question_id = $question_id AND
@ -551,18 +554,25 @@ abstract class Question
/**
* @author hubert borderiou 12-10-2011
* @param int $courseId
* delete any category entry for question id
* delete the category for question
* @return bool
*/
public function deleteCategory()
public function deleteCategory($courseId = 0)
{
$courseId = empty($courseId) ? api_get_course_int_id() : (int) $courseId;
$table = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$question_id = intval($this->id);
$questionId = (int) $this->id;
if (empty($courseId) || empty($questionId)) {
return false;
}
$sql = "DELETE FROM $table
WHERE
question_id = $question_id AND
c_id = ".api_get_course_int_id();
question_id = $questionId AND
c_id = ".$courseId;
Database::query($sql);
return true;
}
/**
@ -599,7 +609,7 @@ abstract class Question
*/
public function updateType($type)
{
$TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
$table = Database::get_course_table(TABLE_QUIZ_ANSWER);
$course_id = $this->course['real_id'];
if (empty($course_id)) {
@ -612,7 +622,7 @@ abstract class Question
!in_array($type, [UNIQUE_ANSWER, MULTIPLE_ANSWER])
) {
// removes old answers
$sql = "DELETE FROM $TBL_REPONSES
$sql = "DELETE FROM $table
WHERE c_id = $course_id AND question_id = ".intval($this->id);
Database::query($sql);
}
@ -1409,17 +1419,17 @@ abstract class Question
* Duplicates the question
*
* @author Olivier Brouckaert
* @param array $course_info Course info of the destination course
* @param array $courseInfo Course info of the destination course
* @return false|string ID of the new question
*/
public function duplicate($course_info = [])
public function duplicate($courseInfo = [])
{
if (empty($course_info)) {
$course_info = $this->course;
} else {
$course_info = $course_info;
$courseInfo = empty($courseInfo) ? $this->course : $courseInfo;
if (empty($courseInfo)) {
return false;
}
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$questionTable = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_QUESTION_OPTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
$question = $this->question;
@ -1427,24 +1437,24 @@ abstract class Question
$weighting = $this->weighting;
$position = $this->position;
$type = $this->type;
$level = intval($this->level);
$level = (int) $this->level;
$extra = $this->extra;
// Using the same method used in the course copy to transform URLs
if ($this->course['id'] != $course_info['id']) {
if ($this->course['id'] != $courseInfo['id']) {
$description = DocumentManager::replaceUrlWithNewCourseCode(
$description,
$this->course['code'],
$course_info['id']
$courseInfo['id']
);
$question = DocumentManager::replaceUrlWithNewCourseCode(
$question,
$this->course['code'],
$course_info['id']
$courseInfo['id']
);
}
$course_id = $course_info['real_id'];
$course_id = $courseInfo['real_id'];
// Read the source options
$options = self::readQuestionOption($this->id, $this->course['real_id']);
@ -1460,10 +1470,10 @@ abstract class Question
'level' => $level,
'extra' => $extra
];
$newQuestionId = Database::insert($TBL_QUESTIONS, $params);
$newQuestionId = Database::insert($questionTable, $params);
if ($newQuestionId) {
$sql = "UPDATE $TBL_QUESTIONS
$sql = "UPDATE $questionTable
SET id = iid
WHERE iid = $newQuestionId";
Database::query($sql);
@ -1486,7 +1496,7 @@ abstract class Question
}
// Duplicates the picture of the hotspot
$this->exportPicture($newQuestionId, $course_info);
$this->exportPicture($newQuestionId, $courseInfo);
}
return $newQuestionId;
@ -1709,7 +1719,6 @@ abstract class Question
}
}
// default values
$defaults = [];
$defaults['questionName'] = $this->question;
@ -1979,7 +1988,10 @@ abstract class Question
}
// display question category, if any
$header = TestCategory::returnCategoryAndTitle($this->id);
$header = '';
if ($exercise->display_category_name) {
$header = TestCategory::returnCategoryAndTitle($this->id);
}
$show_media = null;
if ($show_media) {
$header .= $this->show_media_content();
@ -2193,11 +2205,11 @@ abstract class Question
}
/**
* @return integer[]
* @return array
*/
public static function get_default_levels()
{
$select_level = [
$levels = [
1 => 1,
2 => 2,
3 => 3,
@ -2205,7 +2217,7 @@ abstract class Question
5 => 5
];
return $select_level;
return $levels;
}
/**

@ -48,7 +48,7 @@ if (empty($objExercise) && !empty($fromExercise)) {
}
$nameTools = get_lang('QuestionPool');
$interbreadcrumb[] = ["url" => "exercise.php", "name" => get_lang('Exercises')];
$interbreadcrumb[] = ["url" => "exercise.php?".api_get_cidreq(), "name" => get_lang('Exercises')];
if (!empty($objExercise)) {
$interbreadcrumb[] = [

@ -179,7 +179,7 @@ $form->addElement('text', 'thread_title', get_lang('Title'));
$form->addElement('advanced_settings', 'advanced_params', get_lang('AdvancedParameters'));
$form->addElement('html', '<div id="advanced_params_options" style="display:none">');
if ((api_is_course_admin() || api_is_session_general_coach() || api_is_course_tutor()) && ($threadId)) {
if ((api_is_course_admin() || api_is_session_general_coach() || api_is_course_tutor()) && $threadId) {
// Thread qualify
if (Gradebook::is_active()) {
//Loading gradebook select
@ -224,6 +224,8 @@ if ($forumSettings['allow_sticky'] && api_is_allowed_to_edit(null, true)) {
$form->addElement('html', '</div>');
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_FORUM_THREAD, $threadId);
if (!empty($threadData)) {
$defaults['thread_qualify_gradebook'] = ($threadData['threadQualifyMax'] > 0 && empty($_POST)) ? 1 : 0;
$defaults['thread_title'] = prepare4display($threadData['threadTitle']);
@ -240,16 +242,20 @@ if (!empty($threadData)) {
$defaults['thread_peer_qualify'] = 0;
}
$defaults['skills'] = array_keys($skillList);
$form->addButtonUpdate(get_lang('ModifyThread'), 'SubmitPost');
if ($form->validate()) {
$redirectUrl = api_get_path(WEB_CODE_PATH).'forum/viewforum.php?forum='.$forumId.'&'.api_get_cidreq();
$check = Security::check_token('post');
if ($check) {
$values = $form->exportValues();
Security::clear_token();
updateThread($values);
Skill::saveSkills($form, ITEM_TYPE_FORUM_THREAD, $threadId);
header('Location: '.$redirectUrl);
exit;
}

@ -101,7 +101,7 @@ function handle_forum_and_forumcategories($lp_id = null)
$get_id = isset($_GET['id']) ? intval($_GET['id']) : '';
$forum_categories_list = get_forum_categories();
//Verify if forum category exists
// Verify if forum category exists
if (empty($forum_categories_list)) {
$get_content = 'forumcategory';
}
@ -117,10 +117,9 @@ function handle_forum_and_forumcategories($lp_id = null)
if ((($action_forum_cat == 'add' || $action_forum_cat == 'edit') && $get_content == 'forum') ||
$post_submit_forum
) {
$inputvalues = [];
if ($action_forum_cat == 'edit' && $get_id || $post_submit_forum) {
$inputvalues = get_forums($get_id);
} else {
$inputvalues = [];
}
$content = show_add_forum_form($inputvalues, $lp_id);
}
@ -246,10 +245,9 @@ function show_add_forum_form($inputvalues = [], $lp_id)
$form = new FormValidator('forumcategory', 'post', 'index.php?'.api_get_cidreq());
// The header for the form
$form_title = get_lang('AddForum');
if (!empty($inputvalues)) {
$form_title = get_lang('EditForum');
} else {
$form_title = get_lang('AddForum');
}
$form->addElement('header', $form_title);
@ -439,8 +437,15 @@ function show_add_forum_form($inputvalues = [], $lp_id)
$check = Security::check_token('post');
if ($check) {
$values = $form->getSubmitValues();
$return_message = store_forum($values);
Display::addFlash(Display::return_message($return_message, 'confirmation'));
$forumId = store_forum($values, '', true);
if ($forumId) {
// Skill::saveSkills($form, ITEM_TYPE_FORUM, $forumId);
if (isset($values['forum_id'])) {
Display::addFlash(Display::return_message(get_lang('ForumEdited'), 'confirmation'));
} else {
Display::addFlash(Display::return_message(get_lang('ForumAdded'), 'confirmation'));
}
}
}
Security::clear_token();
} else {
@ -647,11 +652,9 @@ function store_forum($values, $courseInfo = [], $returnId = false)
$courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
$course_id = $courseInfo['real_id'];
$session_id = api_get_session_id();
$group_id = api_get_group_id();
if (isset($values['group_id']) && !empty($values['group_id'])) {
$group_id = $values['group_id'];
} else {
$group_id = api_get_group_id();
}
$groupInfo = [];
if (!empty($group_id)) {
@ -677,11 +680,10 @@ function store_forum($values, $courseInfo = [], $returnId = false)
// Forum images
$image_moved = false;
$has_attachment = false;
$image_moved = true;
if (!empty($_FILES['picture']['name'])) {
$upload_ok = process_uploaded_file($_FILES['picture']);
$has_attachment = true;
} else {
$image_moved = true;
}
// Remove existing picture if it was requested.
@ -765,6 +767,7 @@ function store_forum($values, $courseInfo = [], $returnId = false)
);
$return_message = get_lang('ForumEdited');
$forumId = $values['forum_id'];
} else {
if ($image_moved) {
$new_file_name = isset($new_file_name) ? $new_file_name : '';
@ -793,31 +796,32 @@ function store_forum($values, $courseInfo = [], $returnId = false)
'forum_id' => 0
];
$last_id = Database::insert($table_forums, $params);
if ($last_id > 0) {
$sql = "UPDATE $table_forums SET forum_id = iid WHERE iid = $last_id";
$forumId = Database::insert($table_forums, $params);
if ($forumId > 0) {
$sql = "UPDATE $table_forums SET forum_id = iid WHERE iid = $forumId";
Database::query($sql);
api_item_property_update(
$courseInfo,
TOOL_FORUM,
$last_id,
$forumId,
'ForumAdded',
api_get_user_id(),
$groupInfo
);
api_set_default_visibility(
$last_id,
$forumId,
TOOL_FORUM,
$group_id,
$courseInfo
);
}
$return_message = get_lang('ForumAdded');
if ($returnId) {
return $last_id;
}
}
if ($returnId) {
return $forumId;
}
return $return_message;
@ -911,6 +915,7 @@ function deleteForumCategoryThread($content, $id)
if ($content == 'thread') {
$tool_constant = TOOL_FORUM_THREAD;
$return_message = get_lang('ThreadDeleted');
Skill::deleteSkillsFromItem($id, ITEM_TYPE_FORUM_THREAD);
}
api_item_property_update(
@ -2624,8 +2629,8 @@ function store_thread(
$visible = 1;
}
$clean_post_title = $values['post_title'];
// We first store an entry in the forum_thread table because the thread_id is used in the forum_post table.
// We first store an entry in the forum_thread table because the thread_id is used in the forum_post table.
$lastThread = new CForumThread();
$lastThread
->setCId($course_id)
@ -2975,6 +2980,10 @@ function show_add_post_form($current_forum, $forum_setting, $action, $id = '', $
$form->addElement('html', '</div>');
}
if ($action == 'newthread') {
Skill::addSkillsToForm($form, ITEM_TYPE_FORUM_THREAD, 0);
}
if ($forum_setting['allow_sticky'] && api_is_allowed_to_edit(null, true) && $action == 'newthread') {
$form->addElement('checkbox', 'thread_sticky', '', get_lang('StickyPost'));
}
@ -3082,6 +3091,7 @@ function show_add_post_form($current_forum, $forum_setting, $action, $id = '', $
switch ($action) {
case 'newthread':
$myThread = store_thread($current_forum, $values);
Skill::saveSkills($form, ITEM_TYPE_FORUM_THREAD, $myThread);
break;
case 'quote':
case 'replythread':

@ -354,9 +354,7 @@ if (isset($current_thread['thread_id'])) {
unset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']]);
unset($_SESSION['whatsnew_post_info'][$current_forum['forum_id']][$current_thread['thread_id']][$row['post_id']]);
unset($_SESSION['whatsnew_post_info'][$current_forum['forum_id']][$current_thread['thread_id']]);
$increment++;
$html .= '</div>';
$html .= '</div>';
echo $html;

@ -355,11 +355,16 @@ switch ($action) {
'ASC'
);
usort($data, "sorter");
usort($data, 'sorter');
$list = [];
$list[] = ['term', 'definition'];
$allowStrip = api_get_configuration_value('allow_remove_tags_in_glossary_export');
foreach ($data as $line) {
$list[] = [$line[0], $line[1]];
$definition = $line[1];
if ($allowStrip) {
$definition = strip_tags($definition);
}
$list[] = [$line[0], $definition];
}
$filename = 'glossary_course_'.api_get_course_id();
Export::arrayToCsv($list, $filename);

@ -57,9 +57,9 @@ if ($form->validate()) {
}
$cat->set_session_id(api_get_session_id());
//Always add the gradebook to the course
$cat->set_course_code(api_get_course_id());
// Always add the gradebook to the course
$cat->set_course_code(api_get_course_id());
if (isset($values['skills'])) {
$cat->set_skills($values['skills']);
}

@ -129,17 +129,35 @@ if (count($userList) > 0) {
}
echo '</div>';
$allowSkillRelItem = api_get_configuration_value('allow_skill_rel_items');
if (count($userList) == 0) {
echo Display::return_message(get_lang('NoResultsAvailable'), 'warning');
} else {
echo '<br /><br /><table class="data_table">';
echo '<tr><th>';
echo get_lang('Student');
echo '</th>';
echo '<th>';
echo get_lang('Action');
echo '</th></tr>';
foreach ($userList as $index => $value) {
echo '<tr>
<td width="100%" >'.
get_lang('Student').' : '.api_get_person_name($value['firstname'], $value['lastname']).' ('.$value['username'].') </td>';
<td width="70%">'
.api_get_person_name($value['firstname'], $value['lastname']).' ('.$value['username'].') </td>';
echo '<td>';
$link = '';
if ($allowSkillRelItem) {
$url = api_get_path(WEB_CODE_PATH).'gradebook/skill_rel_user.php?'.api_get_cidreq().'&user_id='.$value['user_id'].'&selectcat='.$cat_id;
$link = Display::url(
get_lang('Skills'),
$url,
['class' => 'btn btn-default']
).'&nbsp;';
}
$url = api_get_self().'?'.api_get_cidreq().'&action=download&user_id='.$value['user_id'].'&selectcat='.$cat_id;
$link = Display::url(
$link .= Display::url(
get_lang('ExportToPDF'),
$url,
['target' => '_blank', 'class' => 'btn btn-default']

@ -707,7 +707,32 @@ abstract class AbstractLink implements GradebookItem
*/
public function getSkillsFromItem()
{
$skillToString = Skill::getSkillRelItemsToString(ITEM_TYPE_EXERCISE, $this->get_ref_id());
$toolType = '';
switch ($this->type) {
case LINK_ATTENDANCE:
$toolType = ITEM_TYPE_ATTENDANCE;
break;
case LINK_EXERCISE:
$toolType = ITEM_TYPE_EXERCISE;
break;
case LINK_FORUM_THREAD:
$toolType = ITEM_TYPE_FORUM_THREAD;
break;
case LINK_LEARNPATH:
$toolType = ITEM_TYPE_LEARNPATH;
break;
case LINK_HOTPOTATOES:
$toolType = ITEM_TYPE_HOTPOTATOES;
break;
case LINK_STUDENTPUBLICATION:
$toolType = ITEM_TYPE_STUDENT_PUBLICATION;
break;
case LINK_SURVEY:
$toolType = ITEM_TYPE_SURVEY;
break;
}
$skillToString = Skill::getSkillRelItemsToString($toolType, $this->get_ref_id());
return $skillToString;
}
}

@ -235,7 +235,6 @@ class CatForm extends FormValidator
$skills = $this->category_object->get_skills();
foreach ($skills as $skill) {
$skillsDefaults[] = $skill['id'];
$skillSelect->addOption($skill['name'], $skill['id']);
}
}

@ -130,9 +130,7 @@ class EvalForm extends FormValidator
{
//extra field for check on maxvalue
$this->addElement('header', get_lang('EditResult'));
$renderer = &$this->defaultRenderer();
// set new form template
$form_template = '<form{attributes}>
<table class="data_table" border="0" cellpadding="5" cellspacing="5">{content}
@ -179,7 +177,6 @@ class EvalForm extends FormValidator
foreach ($results_and_users as $result_and_user) {
$user = $result_and_user['user'];
$result = $result_and_user['result'];
$renderer = &$this->defaultRenderer();
$this->addFloat(
'score['.$result->get_id().']',
@ -254,7 +251,7 @@ class EvalForm extends FormValidator
</form>'
);
$tblusers = GradebookUtils::get_users_in_course($this->evaluation_object->get_course_code());
$users = GradebookUtils::get_users_in_course($this->evaluation_object->get_course_code());
$nr_users = 0;
//extra field for check on maxvalue
$this->addElement('hidden', 'maxvalue', $this->evaluation_object->get_max());
@ -284,7 +281,7 @@ class EvalForm extends FormValidator
}
$firstUser = true;
foreach ($tblusers as $user) {
foreach ($users as $user) {
$element_name = 'score['.$user[0].']';
$scoreColumnProperties = ['maxlength' => 5];
if ($firstUser) {

@ -1073,18 +1073,18 @@ class GradebookTable extends SortableTable
$url = $item->get_link();
$text = $item->get_name();
if (isset($url) && $show_message === false) {
$text = '&nbsp;<a href="'.$item->get_link().'">'
.$item->get_name()
.'</a>';
} else {
$text = $item->get_name();
}
$extra = Display::label($item->get_type_name(), 'info');
if ($type == 'simple') {
$extra = '';
}
$extra .= $item->getSkillsFromItem();
$text .= "&nbsp;".$extra.$show_message;
$cc = $this->currentcat->get_course_code();

@ -1,9 +1,11 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
/**
* Responses to AJAX calls
*/
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
require_once __DIR__.'/../global.inc.php';
@ -349,6 +351,7 @@ switch ($action) {
'cid' => api_get_course_int_id(),
'sid' => api_get_session_id()
];
$result = (int) Event::courseLogout($logoutInfo);
echo $result;
break;

@ -17,7 +17,7 @@ switch ($action) {
break;
case 'get_document_quota':
// Getting the course quota
$course_quota = DocumentManager::get_course_quota();
$courseQuota = DocumentManager::get_course_quota();
// Calculating the total space
$already_consumed_space_course = DocumentManager::documents_total_space(
@ -26,7 +26,7 @@ switch ($action) {
// Displaying the quota
echo DocumentManager::displaySimpleQuota(
$course_quota,
$courseQuota,
$already_consumed_space_course
);
@ -110,11 +110,9 @@ switch ($action) {
api_htmlentities($result['url']),
['target'=>'_blank']
);
$json['url'] = $result['url'];
$json['size'] = format_file_size($file['size']);
$json['type'] = api_htmlentities($file['type']);
$json['result'] = Display::return_icon(
'accept.png',
get_lang('Uploaded')

@ -2195,6 +2195,9 @@ if (in_array($action, $allowed_actions)) {
switch ($exportFormat) {
case 'xls':
Export::arrayToXls($array, $fileName);
break;
case 'xls_html':
//TODO add date if exists
$browser = new Browser();
if ($browser->getPlatform() == Browser::PLATFORM_WINDOWS) {
@ -2205,7 +2208,6 @@ if (in_array($action, $allowed_actions)) {
break;
case 'csv':
default:
//TODO add date if exists
Export::arrayToCsv($array, $fileName);
break;
}

@ -53,7 +53,8 @@ switch ($action) {
//Only course gradebook with certificate
if (!empty($gradebooks)) {
foreach ($gradebooks as $gradebook) {
if ($gradebook['parent_id'] == 0 && !empty($gradebook['certif_min_score']) &&
if ($gradebook['parent_id'] == 0 &&
!empty($gradebook['certif_min_score']) &&
!empty($gradebook['document_id'])
) {
$gradebook_list[] = $gradebook;
@ -131,7 +132,6 @@ switch ($action) {
$template = Display::$global_template->get_template('skill/skill_info.tpl');
$html = Display::$global_template->fetch($template);
}
echo $html;
break;
case 'get_skills_tree_json':
@ -171,7 +171,6 @@ switch ($action) {
$id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : null;
$load_user_data = isset($_REQUEST['load_user_data']) ? $_REQUEST['load_user_data'] : null;
$skills = $skill->getChildren($id, $load_user_data);
$return = [];
foreach ($skills as $skill) {
if (isset($skill['data']) && !empty($skill['data'])) {
@ -265,10 +264,8 @@ switch ($action) {
Display::$global_template->assign('total_search_skills', $count_skills);
$skill_list = [];
if (!empty($total_skills_to_search)) {
$total_skills_to_search = $skill->getSkillsInfo($total_skills_to_search);
foreach ($total_skills_to_search as $skill_info) {
$skill_list[$skill_info['id']] = $skill_info;
}
@ -365,6 +362,68 @@ switch ($action) {
'items' => $returnSkills
]);
break;
case 'update_skill_rel_user':
$allowSkillInTools = api_get_configuration_value('allow_skill_rel_items');
if (empty($allowSkillInTools)) {
exit;
}
if (!api_is_allowed_to_edit()) {
exit;
}
$creatorId = api_get_user_id();
$typeId = isset($_REQUEST['type_id']) ? (int) $_REQUEST['type_id'] : 0;
$itemId = isset($_REQUEST['item_id']) ? (int) $_REQUEST['item_id'] : 0;
$skillId = isset($_REQUEST['skill_id']) ? (int) $_REQUEST['skill_id'] : 0;
$userId = isset($_REQUEST['user_id']) ? (int) $_REQUEST['user_id'] : 0;
$courseId = isset($_REQUEST['course_id']) ? (int) $_REQUEST['course_id'] : 0;
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : 0;
if (!empty($typeId) && !empty($itemId) && !empty($skillId) && !empty($userId) && !empty($courseId)) {
$em = Database::getManager();
$user = api_get_user_entity($userId);
$skill = $em->getRepository('ChamiloCoreBundle:Skill')->find($skillId);
if (empty($user) || empty($skill)) {
exit;
}
$course = api_get_course_entity($courseId);
if (empty($course)) {
exit;
}
$session = $em->getRepository('ChamiloCoreBundle:Session')->find($sessionId);
/** @var \Chamilo\SkillBundle\Entity\SkillRelItem $skillRelItem */
$skillRelItem = $em->getRepository('ChamiloSkillBundle:SkillRelItem')->findOneBy(
['itemId' => $itemId, 'itemType' => $typeId, 'skill' => $skillId]
);
if ($skillRelItem) {
$criteria = [
'user' => $userId,
'skillRelItem' => $skillRelItem
];
$skillRelItemRelUser = $em->getRepository('ChamiloSkillBundle:SkillRelItemRelUser')->findOneBy($criteria);
if ($skillRelItemRelUser) {
$em->remove($skillRelItemRelUser);
$em->flush();
$skillRelItemRelUser = null;
} else {
$skillRelItemRelUser = new Chamilo\SkillBundle\Entity\SkillRelItemRelUser();
$skillRelItemRelUser
->setUser($user)
->setSkillRelItem($skillRelItem)
->setCreatedBy($creatorId)
->setUpdatedBy($creatorId)
;
$em->persist($skillRelItemRelUser);
$em->flush();
}
}
echo Skill::getUserSkillStatusLabel($skillRelItem, $skillRelItemRelUser, false);
}
break;
default:
echo '';
}

@ -12,38 +12,28 @@ class AnnouncementEmail
protected $course = null;
protected $announcement = null;
public $session_id = null;
public $logger;
/**
*
* @param array $courseInfo
* @param int $sessionId
* @param int $announcementId
*
* @return AnnouncementEmail
* @param \Monolog\Logger $logger
*/
public static function create($courseInfo, $sessionId, $announcementId)
{
return new self($courseInfo, $sessionId, $announcementId);
}
/**
* @param array $courseInfo
* @param int $sessionId
* @param int $announcementId
*/
public function __construct($courseInfo, $sessionId, $announcementId)
public function __construct($courseInfo, $sessionId, $announcementId, $logger = null)
{
if (empty($courseInfo)) {
$courseInfo = api_get_course_info();
}
$this->course = $courseInfo;
$this->session_id = !empty($sessionId) ? (int) $sessionId : api_get_session_id();
$this->session_id = empty($sessionId) ? api_get_session_id() : (int) $sessionId;
if (is_numeric($announcementId)) {
$announcementId = AnnouncementManager::get_by_id($courseInfo['real_id'], $announcementId);
}
$this->announcement = $announcementId;
$this->logger = $logger;
}
/**
@ -181,6 +171,9 @@ class AnnouncementEmail
}
if (empty($users)) {
if (!empty($this->logger)) {
$this->logger->addInfo('User list is empty. No users found. Trying all_users()');
}
$users = self::all_users();
}
@ -195,21 +188,6 @@ class AnnouncementEmail
return $newListUsers;
}
/**
* Sender info
*
* @param string $key
* @param int $userId
*
* @return array
*/
public function sender($key = '', $userId = 0)
{
$_user = api_get_user_info($userId);
return $key ? $_user[$key] : $_user;
}
/**
* Email subject
*
@ -242,7 +220,6 @@ class AnnouncementEmail
$session_id
);
$user_email = $this->sender('mail');
// Build the link by hand because api_get_cidreq() doesn't accept course params
$course_param = 'cidReq='.$courseCode.'&id_session='.$session_id.'&gidReq='.api_get_group_id();
$course_name = $this->course('title');
@ -261,12 +238,10 @@ class AnnouncementEmail
}
$result .= '<hr />';
$sender_name = api_get_person_name(
$this->sender('firstName'),
$this->sender('lastName'),
PERSON_NAME_EMAIL_ADDRESS
);
$result .= '<a href="mailto:'.$user_email.'">'.$sender_name.'</a><br/>';
$userInfo = api_get_user_info();
if (!empty($userInfo)) {
$result .= '<a href="mailto:'.$userInfo['mail'].'">'.$userInfo['complete_name'].'</a><br/>';
}
$result .= '<a href="'.api_get_path(WEB_CODE_PATH).'announcements/announcements.php?'.$course_param.'">'.$course_name.'</a><br/>';
return $result;
@ -302,11 +277,12 @@ class AnnouncementEmail
* Send emails to users.
* @param bool $sendToUsersInSession
* @param bool $sendToDrhUsers send a copy of the message to the DRH users
* @param int $senderId
* related to the main user
*/
public function send($sendToUsersInSession = false, $sendToDrhUsers = false)
public function send($sendToUsersInSession = false, $sendToDrhUsers = false, $senderId = 0)
{
$sender = $this->sender();
$senderId = empty($senderId) ? api_get_user_id() : (int) $senderId;
$subject = $this->subject();
// Send email one by one to avoid antispam
@ -316,13 +292,20 @@ class AnnouncementEmail
$counter = 1;
$em = Database::getManager();
if (empty($users) && !empty($this->logger)) {
$this->logger->addInfo('User list is empty. No emails will be sent.');
}
foreach ($users as $user) {
if (!empty($this->logger)) {
$this->logger->addInfo('Announcement: #'.$this->announcement('id').'. Send email to user: #'.$user['user_id']);
}
$message = $this->message($user['user_id']);
MessageManager::send_message_simple(
$user['user_id'],
$subject,
$message,
$sender['user_id'],
$senderId,
$sendToDrhUsers,
true
);
@ -350,7 +333,7 @@ class AnnouncementEmail
$user['user_id'],
$subject,
$message,
$sender['user_id'],
$senderId,
false,
true
);

@ -1374,16 +1374,20 @@ class AnnouncementManager
* @param int $id
* @param bool $sendToUsersInSession
* @param bool $sendToDrhUsers
* @param Monolog\Handler\HandlerInterface logger
* @param int $senderId
*/
public static function sendEmail(
$courseInfo,
$sessionId,
$id,
$sendToUsersInSession = false,
$sendToDrhUsers = false
$sendToDrhUsers = false,
$logger = null,
$senderId = 0
) {
$email = AnnouncementEmail::create($courseInfo, $sessionId, $id);
$email->send($sendToUsersInSession, $sendToDrhUsers);
$email = new AnnouncementEmail($courseInfo, $sessionId, $id, $logger);
$email->send($sendToUsersInSession, $sendToDrhUsers, $senderId);
}
/**

@ -505,6 +505,11 @@ define('ITEM_TYPE_HOTPOTATOES', 2);
define('ITEM_TYPE_LINK', 3);
define('ITEM_TYPE_LEARNPATH', 4);
define('ITEM_TYPE_GRADEBOOK', 5);
define('ITEM_TYPE_STUDENT_PUBLICATION', 6);
//define('ITEM_TYPE_FORUM', 7);
define('ITEM_TYPE_ATTENDANCE', 8);
define('ITEM_TYPE_SURVEY', 9);
define('ITEM_TYPE_FORUM_THREAD', 10);
// one big string with all question types, for the validator in pear/HTML/QuickForm/Rule/QuestionType
define(

@ -621,7 +621,16 @@ class Certificate extends Model
$user_certificate = $this->certification_user_path.basename($this->certificate_data['path_certificate']);
if (file_exists($user_certificate)) {
$certificateContent = (string) file_get_contents($user_certificate);
// Needed in order to browsers don't add custom CSS
$certificateContent = '<!DOCTYPE html>';
$certificateContent .= (string) file_get_contents($user_certificate);
// Remove media=screen to be available when printing a document
$certificateContent = str_replace(
api_get_path(WEB_CSS_PATH).'editor.css" media="screen"',
api_get_path(WEB_CSS_PATH).'editor.css" ',
$certificateContent
);
if ($this->user_id == api_get_user_id() && !empty($this->certificate_data)) {
$certificateId = $this->certificate_data['id'];

@ -3141,24 +3141,6 @@ class CourseManager
return Database::fetch_array(Database::query($sql));
}
/**
* Returns the details of a course category
*
* @param string Category code
* @return array Course category list
*/
public static function getCategoriesList()
{
$table = Database::get_main_table(TABLE_MAIN_CATEGORY);
$sql = "SELECT * FROM $table";
$result = Database::query($sql);
$categoryList = [];
while ($row = Database::fetch_array($result, 'ASSOC')) {
$categoryList[$row['code']] = $row['name'];
}
return $categoryList;
}
/**
* Subscribes courses to human resource manager (Dashboard feature)
* @param int $hr_manager_id Human Resource Manager id

@ -36,7 +36,17 @@ class CourseCategory
$sql = "SELECT * FROM $table WHERE code ='$category'";
$result = Database::query($sql);
if (Database::num_rows($result)) {
return Database::fetch_array($result, 'ASSOC');
$category = Database::fetch_array($result, 'ASSOC');
// Get access url id
$table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
$sql = "SELECT * FROM $table WHERE course_category_id = ".$category['id'];
$result = Database::query($sql);
$result = Database::fetch_array($result);
if ($result) {
$category['access_url_id'] = $result['access_url_id'];
}
return $category;
}
return [];
@ -46,7 +56,7 @@ class CourseCategory
* @param string $category Optional. Parent category code
* @return array
*/
public static function getCategories($category = null)
public static function getCategories($category = '')
{
$tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
@ -54,8 +64,13 @@ class CourseCategory
$conditions = null;
$table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
$conditions = " INNER JOIN $table a ON (t1.id = a.course_category_id)";
$whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id();
$allowBaseCategories = api_get_configuration_value('allow_base_course_category');
if ($allowBaseCategories) {
$whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) ";
}
$parentIdCondition = " AND (t1.parent_id IS NULL OR t1.parent_id = '' )";
if (!empty($category)) {
@ -68,7 +83,8 @@ class CourseCategory
t1.parent_id,
t1.tree_pos,
t1.children_count,
COUNT(DISTINCT t3.code) AS nbr_courses
COUNT(DISTINCT t3.code) AS nbr_courses,
a.access_url_id
FROM $tbl_category t1
$conditions
LEFT JOIN $tbl_category t2
@ -87,7 +103,7 @@ class CourseCategory
ORDER BY t1.tree_pos";
$result = Database::query($sql);
$categories = Database::store_result($result);
$categories = Database::store_result($result, 'ASSOC');
return $categories;
}
@ -437,14 +453,19 @@ class CourseCategory
ICON_SIZE_SMALL
);
$urlId = api_get_current_access_url_id();
foreach ($categories as $category) {
$editUrl = $mainUrl.'&id='.$category['code'].'&action=edit';
$moveUrl = $mainUrl.'&id='.$category['code'].'&action=moveUp&tree_pos='.$category['tree_pos'];
$deleteUrl = $mainUrl.'&id='.$category['code'].'&action=delete';
$actions = Display::url($editIcon, $editUrl).
Display::url($moveIcon, $moveUrl).
Display::url($deleteIcon, $deleteUrl);
$actions = [];
if ($urlId == $category['access_url_id']) {
$actions[] = Display::url($editIcon, $editUrl);
$actions[] = Display::url($moveIcon, $moveUrl);
$actions[] = Display::url($deleteIcon, $deleteUrl);
}
$url = api_get_path(WEB_CODE_PATH).'admin/course_category.php?category='.$category['code'];
$title = Display::url(
@ -460,7 +481,7 @@ class CourseCategory
$title,
$category['children_count'],
$category['nbr_courses'],
$actions
implode('', $actions)
];
$column = 0;
foreach ($content as $value) {
@ -536,18 +557,6 @@ class CourseCategory
*/
public static function browseCourseCategories()
{
$tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
$conditions = null;
$table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
$conditions = " INNER JOIN $table a ON (c.id = a.course_category_id)";
$whereCondition = " WHERE a.access_url_id = ".api_get_current_access_url_id();
$sql = "SELECT c.* FROM $tbl_category c
$conditions
$whereCondition
ORDER BY tree_pos ASC";
$result = Database::query($sql);
$url_access_id = 1;
if (api_is_multiple_url_enabled()) {
$url_access_id = api_get_current_access_url_id();
@ -565,18 +574,17 @@ class CourseCategory
'count_courses' => $countCourses
];
while ($row = Database::fetch_array($result)) {
$categoriesFromDatabase = self::getCategories();
foreach ($categoriesFromDatabase as $row) {
$count_courses = self::countCoursesInCategory($row['code']);
$row['count_courses'] = $count_courses;
if (!isset($row['parent_id'])) {
if (empty($row['parent_id'])) {
$categories[0][$row['tree_pos']] = $row;
} else {
$categories[$row['parent_id']][$row['tree_pos']] = $row;
}
}
$count_courses = self::countCoursesInCategory();
$categories[0][count($categories[0]) + 1] = [
'id' => 0,
'name' => get_lang('None'),
@ -625,9 +633,11 @@ class CourseCategory
$searchFilter = '';
if (!empty($searchTerm)) {
$searchFilter = ' AND (code LIKE "%'.$searchTerm.'%"
OR title LIKE "%'.$searchTerm.'%"
OR tutor_name LIKE "%'.$searchTerm.'%") ';
$searchFilter = ' AND (
code LIKE "%'.$searchTerm.'%" OR
title LIKE "%'.$searchTerm.'%" OR
tutor_name LIKE "%'.$searchTerm.'%"
) ';
}
$url_access_id = api_get_current_access_url_id();
@ -1171,7 +1181,6 @@ class CourseCategory
}
$extension = getextension($fileData['name']);
$dirName = 'course_category/';
$fileDir = api_get_path(SYS_UPLOAD_PATH).$dirName;
$fileName = "cc_$categoryId.{$extension[0]}";

@ -67,7 +67,9 @@ class ExerciseLib
if (!$only_questions) {
$questionDescription = $objQuestionTmp->selectDescription();
if ($show_title) {
TestCategory::displayCategoryAndTitle($objQuestionTmp->id);
if ($exercise->display_category_name) {
TestCategory::displayCategoryAndTitle($objQuestionTmp->id);
}
$titleToDisplay = null;
if ($answerType == READING_COMPREHENSION) {
// In READING_COMPREHENSION, the title of the question
@ -1214,8 +1216,9 @@ HTML;
if (!$only_questions) {
if ($show_title) {
TestCategory::displayCategoryAndTitle($objQuestionTmp->id);
if ($exercise->display_category_name) {
TestCategory::displayCategoryAndTitle($objQuestionTmp->id);
}
echo $objQuestionTmp->getTitleToDisplay($current_item);
}
//@todo I need to the get the feedback type
@ -1283,7 +1286,9 @@ HOTSPOT;
if (!$only_questions) {
if ($show_title) {
TestCategory::displayCategoryAndTitle($objQuestionTmp->id);
if ($exercise->display_category_name) {
TestCategory::displayCategoryAndTitle($objQuestionTmp->id);
}
echo $objQuestionTmp->getTitleToDisplay($current_item);
}
echo '
@ -1298,7 +1303,8 @@ HOTSPOT;
AnnotationQuestion({
questionId: '.$questionId.',
exerciseId: '.$exe_id.',
relPath: \''.$relPath.'\'
relPath: \''.$relPath.'\',
courseId: '.$course_id.',
});
</script>
</div>
@ -1325,10 +1331,8 @@ HOTSPOT;
</div>
';
}
$objAnswerTmp = new Answer($questionId);
$nbrAnswers = $objAnswerTmp->selectNbrAnswers();
unset($objAnswerTmp, $objQuestionTmp);
}
return $nbrAnswers;
@ -2880,7 +2884,7 @@ EOT;
$course_id = 0,
$only_active_exercises = true
) {
$TBL_EXERCISES = Database::get_course_table(TABLE_QUIZ_TEST);
$table = Database::get_course_table(TABLE_QUIZ_TEST);
if ($only_active_exercises) {
// Only active exercises.
@ -2899,9 +2903,9 @@ EOT;
$course_id
];
if ($session_id == 0) {
if (empty($session_id)) {
$conditions = [
'where' => ["$sql_active_exercises session_id = ? AND c_id = ?" => $params],
'where' => ["$sql_active_exercises (session_id = 0 OR session_id IS NULL) AND c_id = ?" => [$course_id]],
'order' => 'title'
];
} else {
@ -2912,7 +2916,7 @@ EOT;
];
}
return Database::select('*', $TBL_EXERCISES, $conditions);
return Database::select('*', $table, $conditions);
}
/**
@ -3995,7 +3999,6 @@ EOT;
}
$showTotalScoreAndUserChoicesInLastAttempt = true;
if ($objExercise->results_disabled == RESULT_DISABLE_SHOW_SCORE_ATTEMPT_SHOW_ANSWERS_LAST_ATTEMPT) {
$show_only_score = true;
$show_results = true;

@ -82,7 +82,7 @@ class Export
$writer = new ExcelWriter($file);
$writer->prepare();
foreach ($data as $index => $row) {
foreach ($data as $row) {
$writer->writeItem($row);
}

@ -231,11 +231,9 @@ function handle_uploaded_document(
$uploadedFile['name'] = stripslashes($uploadedFile['name']);
// Add extension to files without one (if possible)
$uploadedFile['name'] = add_ext_on_mime($uploadedFile['name'], $uploadedFile['type']);
$sessionId = (int) $sessionId;
if (empty($sessionId)) {
$sessionId = api_get_session_id();
} else {
$sessionId = intval($sessionId);
}
$groupInfo = [];
@ -379,7 +377,7 @@ function handle_uploaded_document(
}*/
//if ($found == false) {
$whatIfFileExists = 'rename';
//$whatIfFileExists = 'rename';
//}
}

@ -98,13 +98,13 @@ class DateTimePicker extends HTML_QuickForm_text
timeFormat: 'HH:mm',
altField: '#{$id}_alt',
altFormat: \"".get_lang('DateFormatLongNoDayJS')."\",
altTimeFormat: \"" . get_lang('TimeFormatNoSecJS')."\",
altSeparator: \" " . get_lang('AtTime')." \",
altTimeFormat: \"".get_lang('TimeFormatNoSecJS')."\",
altSeparator: \" ".get_lang('AtTime')." \",
altFieldTimeOnly: false,
showOn: 'both',
buttonImage: '" . Display::return_icon('attendance.png', null, [], ICON_SIZE_TINY, true, true)."',
buttonImage: '".Display::return_icon('attendance.png', null, [], ICON_SIZE_TINY, true, true)."',
buttonImageOnly: true,
buttonText: '" . get_lang('SelectDate')."',
buttonText: '".get_lang('SelectDate')."',
changeMonth: true,
changeYear: true
})

@ -301,6 +301,7 @@ EOT;
* @param string $size large|default|small|extra-small
* @param string $class Example plus is transformed to icon fa fa-plus
* @param array $attributes
* @param bool $createElement
*
* @return HTML_QuickForm_button
*/
@ -942,9 +943,8 @@ EOT;
if ($geolocalization) {
$gmapsApiKey = $gMapsPlugin->get('api_key');
$this->addHtml(
'<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?key='.$gmapsApiKey.'" ></script>'
);
$url = '//maps.googleapis.com/maps/api/js?key='.$gmapsApiKey;
$this->addHtml('<script type="text/javascript" src="'.$url.'" ></script>');
}
$this->addElement(
'text',
@ -958,10 +958,10 @@ EOT;
<div class="form-group">
<label for="geolocalization_'.$name.'" class="col-sm-2 control-label"></label>
<div class="col-sm-8">
<button class="null btn btn-default " id="geolocalization_'.$name.'" name="geolocalization_'.$name.'" type="submit">
<button class="null btn btn-default" id="geolocalization_'.$name.'" name="geolocalization_'.$name.'" type="submit">
<em class="fa fa-map-marker"></em> '.get_lang('Geolocalization').'
</button>
<button class="null btn btn-default " id="myLocation_'.$name.'" name="myLocation_'.$name.'" type="submit">
<button class="null btn btn-default" id="myLocation_'.$name.'" name="myLocation_'.$name.'" type="submit">
<em class="fa fa-crosshairs"></em>
'.get_lang('MyLocation').'
</button>
@ -982,7 +982,7 @@ EOT;
');
$this->addHtml('<script>
$(document).ready(function() {
$(function() {
if (typeof google === "object") {
var address = $("#' . $name.'").val();
initializeGeo'.$name.'(address, false);
@ -1044,9 +1044,7 @@ EOT;
};
map_'.$name.' = new google.maps.Map(document.getElementById("map_'.$name.'"), myOptions);
var parameter = address ? { "address": address } : latLng ? { "latLng": latLng } : false;
if (geocoder && parameter) {
geocoder.geocode(parameter, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
@ -1072,7 +1070,7 @@ EOT;
alert("' . get_lang("NotFound").'");
}
} else {
alert("Geocode ' . get_lang('Error').': '.get_lang("AddressField").' '.get_lang("NotFound").'");
alert("Geocode '.get_lang('Error').': '.get_lang("AddressField").' '.get_lang("NotFound").'");
}
});
}
@ -1626,7 +1624,6 @@ EOT;
.on('click', function () {
var \$this = $(this),
data = \$this.data();
\$this
.off('click')
.text('".addslashes(get_lang('Cancel'))."')
@ -1688,11 +1685,15 @@ EOT;
.prop('href', file.url);
$(data.context.children()[index]).parent().wrap(link);
// Update file name with new one from Chamilo
$(data.context.children()[index]).parent().find('.file_name').html(file.name);
var successMessage = $('<div class=\"col-sm-3\">').html($('<span class=\"message-image-success\"/>').text('".addslashes(get_lang('UplUploadSucceeded'))."'));
$(data.context.children()[index]).parent().find('.file_name').html(file.name);
var successMessage = $('<div class=\"col-sm-3\">').html(
$('<span class=\"message-image-success\"/>').text('".addslashes(get_lang('UplUploadSucceeded'))."')
);
$(data.context.children()[index]).parent().append(successMessage);
} else if (file.error) {
var error = $('<div class=\"col-sm-3\">').html($('<span class=\"message-image-danger\"/>').text(file.error));
var error = $('<div class=\"col-sm-3\">').html(
$('<span class=\"message-image-danger\"/>').text(file.error)
);
$(data.context.children()[index]).parent().append(error);
}
});
@ -1701,11 +1702,13 @@ EOT;
}).on('fileuploadfail', function (e, data) {
$.each(data.files, function (index) {
var failedMessage = '" . addslashes(get_lang('UplUploadFailed'))."';
var error = $('<div class=\"col-sm-3\">').html($('<span class=\"alert alert-danger\"/>').text(failedMessage));
var error = $('<div class=\"col-sm-3\">').html(
$('<span class=\"alert alert-danger\"/>').text(failedMessage)
);
$(data.context.children()[index]).parent().append(error);
});
$('#dropzone').removeClass('hover');
}).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled');
}).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled');
$('#dropzone').on('dragover', function (e) {
// dragleave callback implementation

@ -227,28 +227,21 @@
}
var point = getPointOnImage(self.el, e.clientX, e.clientY);
elementModel = new TextModel({x: point.x, y: point.y, text: ''});
self.elementsCollection.add(elementModel);
elementModel = null;
isMoving = false;
})
.on('mousedown', function (e) {
e.preventDefault();
var point = getPointOnImage(self.el, e.clientX, e.clientY);
if (isMoving || "0" !== self.$rdbOptions.filter(':checked').val() || elementModel) {
return;
}
elementModel = new SvgPathModel({points: [[point.x, point.y]]});
self.elementsCollection.add(elementModel);
isMoving = true;
})
.on('mousemove', function (e) {
@ -259,7 +252,6 @@
}
var point = getPointOnImage(self.el, e.clientX, e.clientY);
elementModel.addPoint(point.x, point.y);
})
.on('mouseup', function (e) {
@ -270,7 +262,6 @@
}
elementModel = null;
isMoving = false;
});
};
@ -334,49 +325,43 @@
window.AnnotationQuestion = function (userSettings) {
$(document).on('ready', function () {
var
settings = $.extend(
{
questionId: 0,
exerciseId: 0,
relPath: '/'
},
userSettings
),
xhrUrl = 'exercise/annotation_user.php',
$container = $('#annotation-canvas-' + settings.questionId);
$
.getJSON(settings.relPath + xhrUrl, {
question_id: parseInt(settings.questionId),
exe_id: parseInt(settings.exerciseId)
})
.done(function (questionInfo) {
var image = new Image();
image.onload = function () {
var elementsCollection = new ElementsCollection(),
canvas = new AnnotationCanvasView(elementsCollection, this, settings.questionId);
$container
.html(canvas.render().el);
/** @namespace questionInfo.answers.paths */
$.each(questionInfo.answers.paths, function (i, pathInfo) {
var pathModel = SvgPathModel.decode(pathInfo);
elementsCollection.add(pathModel);
});
/** @namespace questionInfo.answers.texts */
$(questionInfo.answers.texts).each(function (i, textInfo) {
var textModel = TextModel.decode(textInfo);
elementsCollection.add(textModel);
});
};
image.src = questionInfo.image.path;
});
var settings = $.extend(
{
questionId: 0,
exerciseId: 0,
relPath: '/'
},
userSettings
),
xhrUrl = 'exercise/annotation_user.php?' + _p.web_cid_query,
$container = $('#annotation-canvas-' + settings.questionId);
$.getJSON(settings.relPath + xhrUrl, {
question_id: parseInt(settings.questionId),
exe_id: parseInt(settings.exerciseId),
course_id: parseInt(settings.courseId)
})
.done(function (questionInfo) {
var image = new Image();
image.onload = function () {
var elementsCollection = new ElementsCollection(),
canvas = new AnnotationCanvasView(elementsCollection, this, settings.questionId);
$container.html(canvas.render().el);
/** @namespace questionInfo.answers.paths */
$.each(questionInfo.answers.paths, function (i, pathInfo) {
var pathModel = SvgPathModel.decode(pathInfo);
elementsCollection.add(pathModel);
});
/** @namespace questionInfo.answers.texts */
$(questionInfo.answers.texts).each(function (i, textInfo) {
var textModel = TextModel.decode(textInfo);
elementsCollection.add(textModel);
});
};
image.src = questionInfo.image.path;
});
});
};
})(window, window.jQuery);

@ -167,15 +167,13 @@ class Link extends Model
$description = Security::remove_XSS($_POST['description']);
$selectcategory = Security::remove_XSS($_POST['category_id']);
if (!isset($_POST['on_homepage'])) {
$onhomepage = 0;
} else {
$onhomepage = 0;
if (isset($_POST['on_homepage'])) {
$onhomepage = Security::remove_XSS($_POST['on_homepage']);
}
if (empty($_POST['target'])) {
$target = '_self'; // Default target.
} else {
$target = '_self'; // Default target.
if (!empty($_POST['target'])) {
$target = Security::remove_XSS($_POST['target']);
}
@ -201,7 +199,6 @@ class Link extends Model
return false;
} else {
// Looking for the largest order number for this category.
$link = new Link();
$params = [
'c_id' => $course_id,
@ -317,6 +314,7 @@ class Link extends Model
}
}
Display::addFlash(Display::return_message(get_lang('LinkAdded')));
return $link_id;
}
} elseif ($type == 'category') {
$tbl_categories = Database::get_course_table(TABLE_LINK_CATEGORY);
@ -366,6 +364,7 @@ class Link extends Model
}
Display::addFlash(Display::return_message(get_lang('CategoryAdded')));
return $linkId;
}
}
@ -393,7 +392,6 @@ class Link extends Model
}
$result = false;
switch ($type) {
case 'link':
// -> Items are no longer physically deleted,
@ -411,6 +409,7 @@ class Link extends Model
api_get_user_id()
);
self::delete_link_from_search_engine(api_get_course_id(), $id);
Skill::deleteSkillsFromItem($id, ITEM_TYPE_LINK);
Display::addFlash(Display::return_message(get_lang('LinkDeleted')));
$result = true;
break;
@ -1798,8 +1797,10 @@ class Link extends Model
}
}
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_LINK, $linkId);
$form->addHidden('lp_id', $lpId);
$form->addButtonSave(get_lang('SaveLink'), 'submitLink');
$defaults['skills'] = array_keys($skillList);
$form->setDefaults($defaults);
return $form;

@ -37,10 +37,13 @@ class Login
$secret_word = self::get_secret_word($user['email']);
if ($reset) {
$reset_link = $portal_url."main/auth/lostPassword.php?reset=".$secret_word."&id=".$user['uid'];
$reset_link = Display::url($reset_link, $reset_link);
} else {
$reset_link = get_lang('Pass')." : $user[password]";
}
$user_account_list = get_lang('YourRegistrationData')." : \n".get_lang('UserName').' : '.$user['loginName']."\n".get_lang('ResetLink').' : '.$reset_link.'';
$user_account_list = get_lang('YourRegistrationData')." : \n".
get_lang('UserName').' : '.$user['loginName']."\n".
get_lang('ResetLink').' : '.$reset_link;
if ($user_account_list) {
$user_account_list = "\n-----------------------------------------------\n".$user_account_list;
@ -50,10 +53,14 @@ class Login
$secret_word = self::get_secret_word($this_user['email']);
if ($reset) {
$reset_link = $portal_url."main/auth/lostPassword.php?reset=".$secret_word."&id=".$this_user['uid'];
$reset_link = Display::url($reset_link, $reset_link);
} else {
$reset_link = get_lang('Pass')." : $this_user[password]";
}
$user_account_list[] = get_lang('YourRegistrationData')." : \n".get_lang('UserName').' : '.$this_user['loginName']."\n".get_lang('ResetLink').' : '.$reset_link.'';
$user_account_list[] =
get_lang('YourRegistrationData')." : \n".
get_lang('UserName').' : '.$this_user['loginName']."\n".
get_lang('ResetLink').' : '.$reset_link;
}
if ($user_account_list) {
$user_account_list = implode("\n-----------------------------------------------\n", $user_account_list);
@ -64,7 +71,10 @@ class Login
$user = $user[0];
}
$reset_link = get_lang('Pass')." : $user[password]";
$user_account_list = get_lang('YourRegistrationData')." : \n".get_lang('UserName').' : '.$user['loginName']."\n".$reset_link.'';
$user_account_list =
get_lang('YourRegistrationData')." : \n".
get_lang('UserName').' : '.$user['loginName']."\n".
$reset_link.'';
}
return $user_account_list;
}
@ -149,8 +159,12 @@ class Login
$email_body = get_lang('DearUser')." :\n".get_lang('password_request')."\n";
$email_body .= $user_account_list."\n-----------------------------------------------\n\n";
$email_body .= get_lang('PasswordEncryptedForSecurity');
$email_body .= "\n\n".get_lang('SignatureFormula').",\n".api_get_setting('administratorName')." ".api_get_setting('administratorSurname')."\n".get_lang('PlataformAdmin')." - ".api_get_setting('siteName');
$email_body .= "\n\n".
get_lang('SignatureFormula').",\n".
api_get_setting('administratorName')." ".
api_get_setting('administratorSurname')."\n".
get_lang('PlataformAdmin')." - ".
api_get_setting('siteName');
$sender_name = api_get_person_name(
api_get_setting('administratorName'),
@ -205,16 +219,16 @@ class Login
$url = api_get_path(WEB_CODE_PATH).'auth/reset.php?token='.$uniqueId;
$mailSubject = get_lang('ResetPasswordInstructions');
$mailBody = sprintf(
get_lang('ResetPasswordCommentWithUrl'),
$url
);
get_lang('ResetPasswordCommentWithUrl'),
$url
);
api_mail_html(
$user->getCompleteName(),
$user->getEmail(),
$mailSubject,
$mailBody
);
$user->getCompleteName(),
$user->getEmail(),
$mailSubject,
$mailBody
);
Display::addFlash(Display::return_message(get_lang('CheckYourEmailAndFollowInstructions')));
//}
}

@ -43,6 +43,7 @@ class MessageManager
return $count;
}
/**
* Execute the SQL necessary to know the number of messages in the database
* @param int $userId The user for which we need the unread messages count
@ -110,10 +111,12 @@ class MessageManager
$from,
$number_of_items,
$column,
$direction
$direction,
$userId = 0
) {
$from = (int) $from;
$number_of_items = (int) $number_of_items;
$from = (int)$from;
$number_of_items = (int)$number_of_items;
$userId = empty($userId) ? api_get_user_id() : (int)$userId;
//forcing this order
if (!isset($direction)) {
@ -146,7 +149,7 @@ class MessageManager
user_sender_id
FROM $table
WHERE
user_receiver_id=".api_get_user_id()." AND
user_receiver_id=".$userId." AND
msg_status IN (".MESSAGE_STATUS_NEW.", ".MESSAGE_STATUS_UNREAD.")
$keywordCondition
ORDER BY col$column $direction
@ -179,7 +182,7 @@ class MessageManager
Display::url(
Display::returnFontAwesomeIcon('reply', 2),
$newMessageLink.'?re_id='.$messageId,
['title' => get_lang('ReplyToMessage') ]
['title' => get_lang('ReplyToMessage')]
);
} else {
$message[1] = '<a '.$class.' href="view_message.php?id='.$messageId.'">'.$title.'</a><br />';
@ -199,9 +202,13 @@ class MessageManager
Display::url(
Display::returnFontAwesomeIcon('share', 2),
$newMessageLink.'?forward_id='.$messageId,
['title' => get_lang('ForwardMessage') ]
['title' => get_lang('ForwardMessage')]
).
'&nbsp;&nbsp;<a title="'.addslashes(get_lang('DeleteMessage')).'" onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmDeleteMessage')))."'".')) return false;" href="inbox.php?action=deleteone&id='.$messageId.'">'.
'&nbsp;&nbsp;<a title="'.addslashes(
get_lang('DeleteMessage')
).'" onclick="javascript:if(!confirm('."'".addslashes(
api_htmlentities(get_lang('ConfirmDeleteMessage'))
)."'".')) return false;" href="inbox.php?action=deleteone&id='.$messageId.'">'.
Display::returnFontAwesomeIcon('trash', 2).'</a>';
foreach ($message as $key => $value) {
$message[$key] = api_xml_http_response_encode($value);
@ -262,8 +269,8 @@ class MessageManager
{
if (!empty($aboutUserInfo)) {
$criteria = [
'userReceiverId' => $aboutUserInfo['id'],
'msgStatus' => MESSAGE_STATUS_CONVERSATION
'userReceiverId' => $aboutUserInfo['id'],
'msgStatus' => MESSAGE_STATUS_CONVERSATION
];
$repo = Database::getManager()->getRepository('ChamiloCoreBundle:Message');
$messages = $repo->findBy($criteria, ['sendDate' => 'DESC']);
@ -648,7 +655,7 @@ class MessageManager
SET msg_status = ".MESSAGE_STATUS_DELETED."
WHERE
user_receiver_id=".$user_receiver_id." AND
id = " . $id;
id = ".$id;
Database::query($query);
return true;
@ -1135,15 +1142,15 @@ class MessageManager
$query = "UPDATE $table SET
msg_status = '".MESSAGE_STATUS_NEW."'
WHERE
user_receiver_id=" . api_get_user_id()." AND
id='" . $messageId."'";
user_receiver_id=".api_get_user_id()." AND
id='".$messageId."'";
Database::query($query);
$query = "SELECT * FROM $table
WHERE
msg_status<> ".MESSAGE_STATUS_OUTBOX." AND
user_receiver_id=".api_get_user_id()." AND
id='" . $messageId."'";
id='".$messageId."'";
$result = Database::query($query);
}
}
@ -1156,6 +1163,7 @@ class MessageManager
$source
);
$row['content'] = str_replace('</br>', '<br />', $row['content']);
$title = Security::remove_XSS($row['title'], STUDENT, true);
$content = Security::remove_XSS($row['content'], STUDENT, true);
@ -1188,7 +1196,9 @@ class MessageManager
$message_content .= '<li>'.$userImage.'</li>';
$message_content .= '<li>'.$name.'&nbsp;';
if (!empty($receiverUserInfo)) {
$message_content .= api_strtolower(get_lang('To')).'&nbsp;<b>'.$receiverUserInfo['complete_name_with_username'].'</b></li>';
$message_content .= api_strtolower(
get_lang('To')
).'&nbsp;<b>'.$receiverUserInfo['complete_name_with_username'].'</b></li>';
} else {
$message_content .= api_strtolower(get_lang('To')).'&nbsp;<b>-</b></li>';
}
@ -1201,7 +1211,9 @@ class MessageManager
$message_content .= '<ul class="list-message">';
if (!empty($user_sender_id)) {
$message_content .= '<li>'.$userImage.'</li>';
$message_content .= '<li><a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$user_sender_id.'">'.$name.'</a>';
$message_content .= '<li><a href="'.api_get_path(
WEB_PATH
).'main/social/profile.php?u='.$user_sender_id.'">'.$name.'</a>';
} else {
$message_content .= '<li>'.$name;
}
@ -1226,10 +1238,10 @@ class MessageManager
<hr style="color:#ddd" />
<table width="100%">
<tr>
<td valign=top class="view-message-content">' . str_replace("\\", "", $content).'</td>
<td valign=top class="view-message-content">'.str_replace("\\", "", $content).'</td>
</tr>
</table>
<div id="message-attach">' . (!empty($files_attachments) ? implode('<br />', $files_attachments) : '').'</div>
<div id="message-attach">'.(!empty($files_attachments) ? implode('<br />', $files_attachments) : '').'</div>
<div style="padding: 15px 0px 5px 0px">';
$social_link = '';
if (isset($_GET['f']) && $_GET['f'] == 'social') {
@ -1264,7 +1276,7 @@ class MessageManager
{
$tbl_user = Database::get_main_table(TABLE_MAIN_USER);
$sql = 'SELECT user_id FROM '.$tbl_user.'
WHERE email="' . Database::escape_string($user_email).'";';
WHERE email="'.Database::escape_string($user_email).'";';
$rs = Database::query($sql);
$row = Database::fetch_array($rs, 'ASSOC');
if (isset($row['user_id'])) {
@ -1345,19 +1357,25 @@ class MessageManager
$my_group_role == GROUP_USER_PERMISSION_MODERATOR
) {
$actions = '<br />'.Display::url(
get_lang('Delete'),
api_get_path(WEB_CODE_PATH).'social/group_topics.php?action=delete&id='.$group_id.'&topic_id='.$topic['id'],
['class' => 'btn btn-default']
);
get_lang('Delete'),
api_get_path(
WEB_CODE_PATH
).'social/group_topics.php?action=delete&id='.$group_id.'&topic_id='.$topic['id'],
['class' => 'btn btn-default']
);
}
$date = '';
if ($topic['send_date'] != $topic['update_date']) {
if (!empty($topic['update_date'])) {
$date .= '<i class="fa fa-calendar"></i> '.get_lang('LastUpdate').' '.Display::dateToStringAgoAndLongDate($topic['update_date']);
$date .= '<i class="fa fa-calendar"></i> '.get_lang(
'LastUpdate'
).' '.Display::dateToStringAgoAndLongDate($topic['update_date']);
}
} else {
$date .= '<i class="fa fa-calendar"></i> '.get_lang('Created').' '.Display::dateToStringAgoAndLongDate($topic['send_date']);
$date .= '<i class="fa fa-calendar"></i> '.get_lang(
'Created'
).' '.Display::dateToStringAgoAndLongDate($topic['send_date']);
}
$html .= '<div class="date">'.$label.' - '.$date.$actions.'</div>';
$html .= '</div>';
@ -1365,7 +1383,9 @@ class MessageManager
$image = $user_sender_info['avatar'];
$user_info = '<div class="author"><img class="img-responsive img-circle" src="'.$image.'" alt="'.$name.'" width="64" height="64" title="'.$name.'" /></div>';
$user_info .= '<div class="name"><a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$topic['user_sender_id'].'">'.$name.'&nbsp;</a></div>';
$user_info .= '<div class="name"><a href="'.api_get_path(
WEB_PATH
).'main/social/profile.php?u='.$topic['user_sender_id'].'">'.$name.'&nbsp;</a></div>';
$html .= '<div class="col-xs-4 col-md-2">';
$html .= $user_info;
@ -1438,16 +1458,18 @@ class MessageManager
) {
$urlEdit = api_get_path(WEB_CODE_PATH);
$urlEdit .= 'social/message_for_group_form.inc.php?';
$urlEdit .= http_build_query([
'user_friend' => $current_user_id,
'group_id' => $group_id,
'message_id' => $main_message['id'],
'action' => 'edit_message_group',
'anchor_topic' => 'topic_'.$main_message['id'],
'topics_page_nr' => $topic_page_nr,
'items_page_nr' => $items_page_nr,
'topic_id' => $main_message['id']
]);
$urlEdit .= http_build_query(
[
'user_friend' => $current_user_id,
'group_id' => $group_id,
'message_id' => $main_message['id'],
'action' => 'edit_message_group',
'anchor_topic' => 'topic_'.$main_message['id'],
'topics_page_nr' => $topic_page_nr,
'items_page_nr' => $items_page_nr,
'topic_id' => $main_message['id']
]
);
$links .= Display::url(
Display::returnFontAwesomeIcon('pencil'),
@ -1463,15 +1485,17 @@ class MessageManager
$urlReply = api_get_path(WEB_CODE_PATH);
$urlReply .= 'social/message_for_group_form.inc.php?';
$urlReply .= http_build_query([
'user_friend' => api_get_user_id(),
'group_id' => $group_id,
'message_id' => $main_message['id'],
'action' => 'reply_message_group',
'anchor_topic' => 'topic_'.$main_message['id'],
'topics_page_nr' => $topic_page_nr,
'topic_id' => $main_message['id']
]);
$urlReply .= http_build_query(
[
'user_friend' => api_get_user_id(),
'group_id' => $group_id,
'message_id' => $main_message['id'],
'action' => 'reply_message_group',
'anchor_topic' => 'topic_'.$main_message['id'],
'topics_page_nr' => $topic_page_nr,
'topic_id' => $main_message['id']
]
);
$links .= Display::url(
Display::returnFontAwesomeIcon('commenting'),
@ -1521,9 +1545,14 @@ class MessageManager
Display::dateToStringAgoAndLongDate($main_message['send_date']).
'</div>';
}
$attachment = '<div class="message-attach">'.(!empty($files_attachments) ? implode('<br />', $files_attachments) : '').'</div>';
$attachment = '<div class="message-attach">'.(!empty($files_attachments) ? implode(
'<br />',
$files_attachments
) : '').'</div>';
$main_content .= '<div class="col-md-10">';
$user_link = '<a href="'.api_get_path(WEB_PATH).'main/social/profile.php?u='.$main_message['user_sender_id'].'">'.$name.'</a>';
$user_link = '<a href="'.api_get_path(
WEB_PATH
).'main/social/profile.php?u='.$main_message['user_sender_id'].'">'.$name.'</a>';
$main_content .= '<div class="message-content"> ';
$main_content .= '<div class="username">'.$user_link.'</div>';
$main_content .= $date;
@ -1794,6 +1823,7 @@ class MessageManager
}
//@todo this functions should be in the message class
/**
* @param string $keyword
* @return string
@ -2203,4 +2233,69 @@ class MessageManager
return array_reverse($mail_queue);
}
/**
* @param int $userId
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public static function getUsersThatHadConversationWithUser($userId)
{
$messagesTable = Database::get_main_table(TABLE_MESSAGE);
$userId = (int) $userId;
$sql = "SELECT DISTINCT
user_sender_id
FROM $messagesTable
WHERE
user_receiver_id = ".$userId;
$result = Database::query($sql);
$users = Database::store_result($result);
$userList = [];
foreach ($users as $userData) {
$userId = $userData['user_sender_id'];
if (empty($userId)) {
continue;
}
$userInfo = api_get_user_info($userId);
if ($userInfo) {
$userList[$userId] = $userInfo;
}
}
return $userList;
}
/**
* @param int $userId
* @param int $otherUserId
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public static function getAllMessagesBetweenStudents($userId, $otherUserId)
{
$messagesTable = Database::get_main_table(TABLE_MESSAGE);
$userId = (int) $userId;
$otherUserId = (int) $otherUserId;
if (empty($otherUserId) || empty($userId)) {
return [];
}
$sql = "SELECT DISTINCT *
FROM $messagesTable
WHERE
(user_receiver_id = $userId AND user_sender_id = $otherUserId) OR
(user_receiver_id = $otherUserId AND user_sender_id = $userId)
ORDER BY send_date DESC
";
$result = Database::query($sql);
$messages = Database::store_result($result);
$list = [];
foreach ($messages as $message) {
$list[] = $message;
}
return $list;
}
}

@ -526,7 +526,7 @@ class Plugin
if (empty($courseId)) {
return false;
}
$plugin_name = $this->get_name();
$pluginName = $this->get_name();
$t_course = Database::get_course_table(TABLE_COURSE_SETTING);
$t_tool = Database::get_course_table(TABLE_TOOL_LIST);
@ -546,9 +546,14 @@ class Plugin
}
}
$plugin_name = Database::escape_string($plugin_name);
$pluginName = Database::escape_string($pluginName);
$sql = "DELETE FROM $t_tool
WHERE c_id = $courseId AND name = '$plugin_name'";
WHERE c_id = $courseId AND
(
name = '$pluginName' OR
name = '$pluginName:student' OR
name = '$pluginName:teacher'
)";
Database::query($sql);
}
@ -570,6 +575,8 @@ class Plugin
return null;
}
$visibility = $this->getToolIconVisibility();
$em = Database::getManager();
/** @var CTool $tool */
@ -588,7 +595,7 @@ class Plugin
$tool
->setId($cToolId)
->setCId($courseId)
->setName($name)
->setName($name.$visibility)
->setLink($link ?: "$pluginName/start.php")
->setImage($iconName ?: "$pluginName.png")
->setVisibility(true)
@ -895,6 +902,19 @@ class Plugin
return $this;
}
/**
* This function allows to change the visibility of the icon inside a course
* :student tool will be visible only for students
* :teacher tool will be visible only for teachers
* If nothing it's set then tool will be visible for both as a normal icon.
*
* @return string
*/
public function getToolIconVisibility()
{
return '';
}
/**
* Get the admin URL for the plugin if Plugin::isAdminPlugin is true
* @return string

@ -4566,6 +4566,8 @@ class SessionManager
}
$sessionList = [];
$report = [];
// Looping the sessions.
foreach ($sessions as $enreg) {
$user_counter = 0;
@ -4627,28 +4629,20 @@ class SessionManager
$coachBefore = '';
$coachAfter = '';
if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
$date = new \DateTime($dateStart);
$interval = new DateInterval(
'P'.$daysCoachAccessBeforeBeginning.'D'
);
$interval = new DateInterval('P'.$daysCoachAccessBeforeBeginning.'D');
$date->sub($interval);
$coachBefore = $date->format('Y-m-d h:i');
$coachAccessStartDate = $coachBefore;
$coachBefore = api_get_utc_datetime($coachBefore);
//$extraParameters .= " , coach_access_start_date = '$coachBefore'";
//$extraParams['coach_access_start_date'] = $coachBefore;
$date = new \DateTime($dateEnd);
$interval = new DateInterval('P'.$daysCoachAccessAfterBeginning.'D');
$date->add($interval);
$coachAfter = $date->format('Y-m-d h:i');
$coachAccessEndDate = $coachAfter;
$coachAfter = api_get_utc_datetime($coachAfter);
//$extraParameters .= " , coach_access_end_date = '$coachAfter'";
//$extraParams['coach_access_end_date'] = $coachAfter;
}
$dateStart = api_get_utc_datetime($dateStart);
@ -4701,7 +4695,6 @@ class SessionManager
$sql = 'SELECT 1 FROM '.$tbl_session.'
WHERE name="' . Database::escape_string($session_name).$suffix.'"';
$rs = Database::query($sql);
if (Database::result($rs, 0, 0)) {
$i++;
} else {
@ -4735,7 +4728,6 @@ class SessionManager
self::update_session_extra_field_value($session_id, substr($key, 6), $value);
}
}
$logger->addInfo("Sessions - Session created: #$session_id - $session_name");
} else {
$logger->addError("Sessions - Session NOT created: $session_name");
@ -4854,9 +4846,17 @@ class SessionManager
if (isset($sessionId) && !empty($sessionId)) {
$session_id = $sessionId;
if (!empty($enreg['SessionName'])) {
$sessionName = Database::escape_string($enreg['SessionName']);
$sql = "UPDATE $tbl_session SET name = '$sessionName' WHERE id = $session_id";
Database::query($sql);
$sessionExistsWithName = self::get_session_by_name($session_name);
if ($sessionExistsWithName === false) {
$sessionName = Database::escape_string($enreg['SessionName']);
$sql = "UPDATE $tbl_session SET name = '$sessionName' WHERE id = $session_id";
Database::query($sql);
} else {
if ($debug) {
$report[] = "Error when update session: Name already exists: Session #$session_id Name: '$session_name' External id: ".$enreg['extra_'.$extraFieldId];
}
continue;
}
}
} else {
$my_session_result = self::get_session_by_name($session_name);
@ -4961,7 +4961,6 @@ class SessionManager
if ($deleteUsersNotInList) {
// Getting user in DB in order to compare to the new list.
$usersListInDatabase = self::get_users_by_session($session_id, 0);
if (!empty($usersListInDatabase)) {
if (empty($userList)) {
foreach ($usersListInDatabase as $userInfo) {
@ -4983,7 +4982,6 @@ class SessionManager
if (count($courses) >= 2) {
// Only first teacher in course session;
$onlyAddFirstCoachOrTeacher = true;
// Remove all teachers from course.
$removeAllTeachersFromCourse = false;
}
@ -5368,7 +5366,6 @@ class SessionManager
// Adding Students, updating relationship "Session - Course - User".
$course_users = array_filter($course_users);
if (!empty($course_users)) {
foreach ($course_users as $user) {
$user_id = UserManager::get_user_id_from_username($user);
@ -5387,7 +5384,6 @@ class SessionManager
}
}
}
$inserted_in_course[$course_code] = $courseInfo['title'];
}
}
@ -5399,6 +5395,15 @@ class SessionManager
self::addClassesByName($session_id, $classes, false);
}
if (!empty($report)) {
if ($debug) {
$logger->addInfo("--Summary--");
foreach ($report as $line) {
$logger->addInfo($line);
}
}
}
}
return [

@ -640,7 +640,6 @@ class Skill extends Model
}
$path = api_get_path(WEB_UPLOAD_PATH).'badges/';
if (!empty($result['icon'])) {
$iconSmall = sprintf(
"%s-small.png",
@ -2324,6 +2323,102 @@ class Skill extends Model
return $actions;
}
/**
* @param \Chamilo\SkillBundle\Entity\SkillRelItem $skillRelItem
* @param \Chamilo\SkillBundle\Entity\SkillRelItemRelUser $skillRelItemRelUser
* @param bool $addHeader
* @return string
*/
public static function getUserSkillStatusLabel($skillRelItem, $skillRelItemRelUser, $addHeader = true)
{
if (empty($skillRelItem)) {
return '';
}
$type = 'success';
if (empty($skillRelItemRelUser)) {
$type = 'danger';
}
$label = '';
$skill = $skillRelItem->getSkill();
if ($addHeader) {
$label .= '<span id="'.$skill->getId().'" class="user_skill" style="cursor:pointer">';
}
$label .= Display::label($skill->getName(), $type);
if ($addHeader) {
$label .= '</span>&nbsp;';
}
return $label;
}
/**
* Assign a user with a SkilRelItem object
*
* @param FormValidator $form
* @param int $typeId see ITEM_TYPE_* constants
* @param int $itemId
* @param int $userId
*/
public static function addSkillsToUserForm(FormValidator $form, $typeId, $itemId, $userId)
{
$allowSkillInTools = api_get_configuration_value('allow_skill_rel_items');
if ($allowSkillInTools && !empty($typeId) && !empty($itemId) && !empty($userId)) {
$em = Database::getManager();
$items = $em->getRepository('ChamiloSkillBundle:SkillRelItem')->findBy(
['itemId' => $itemId, 'itemType' => $typeId]
);
$skillRelUser = new SkillRelUser();
$skillUserList = $skillRelUser->getUserSkills($userId);
if (!empty($skillUserList)) {
$skillUserList = array_column($skillUserList, 'skill_id');
}
$skills = '';
/** @var SkillRelItem $skillRelItem */
foreach ($items as $skillRelItem) {
$criteria = [
'user' => $userId,
'skillRelItem' => $skillRelItem
];
$skillRelItemRelUser = $em->getRepository('ChamiloSkillBundle:SkillRelItemRelUser')->findOneBy($criteria);
$skills .= self::getUserSkillStatusLabel($skillRelItem, $skillRelItemRelUser);
}
if (!empty($skills)) {
$url = api_get_path(WEB_AJAX_PATH).'skill.ajax.php?a=update_skill_rel_user&'.api_get_cidreq();
$params = [
'item_id' => $itemId,
'type_id' => $typeId,
'user_id' => $userId,
'course_id' => api_get_course_int_id(),
'session_id' => api_get_session_id()
];
$params = json_encode($params);
$html = '
<script>
$(function() {
$(".user_skill").on("click", function() {
var skillId = this.id;
var params = '.$params.';
$.ajax({
type: "GET",
async: false,
data: params,
url: "'.$url.'&skill_id="+skillId,
success: function(result) {
$("#" +skillId+ ".user_skill").html(result);
}
});
});
});
</script>
';
$form->addHtml($html);
$form->addLabel(get_lang('Skills'), $skills);
}
}
}
/**
* Add skills select ajax for an item (exercise, lp)
@ -2365,6 +2460,103 @@ class Skill extends Model
return $skillList;
}
/**
* @param int $courseId
* @param int $sessionId
* @return array
*/
public static function getSkillRelItemsPerCourse($courseId, $sessionId = null)
{
$allowSkillInTools = api_get_configuration_value('allow_skill_rel_items');
$skills = [];
if (empty($sessionId)) {
$sessionId = null;
}
if ($allowSkillInTools) {
$em = Database::getManager();
$skills = $em->getRepository('ChamiloSkillBundle:SkillRelItem')->findBy(
['courseId' => $courseId, 'sessionId' => $sessionId]
);
}
return $skills;
}
/**
* @param int $itemId
* @param int $itemType
* @return array
*/
public static function getItemInfo($itemId, $itemType)
{
$itemInfo = [];
$itemId = (int) $itemId;
$itemType = (int) $itemType;
$em = Database::getManager();
switch ($itemType) {
case ITEM_TYPE_EXERCISE:
/** @var \Chamilo\CourseBundle\Entity\CQuiz $item */
$item = $em->getRepository('ChamiloCourseBundle:CQuiz')->find($itemId);
if ($item) {
$itemInfo['name'] = $item->getTitle();
}
break;
case ITEM_TYPE_HOTPOTATOES:
break;
case ITEM_TYPE_LINK:
/** @var \Chamilo\CourseBundle\Entity\CLink $item */
$item = $em->getRepository('ChamiloCourseBundle:CLink')->find($itemId);
if ($item) {
$itemInfo['name'] = $item->getTitle();
}
break;
case ITEM_TYPE_LEARNPATH:
/** @var \Chamilo\CourseBundle\Entity\CLp $item */
$item = $em->getRepository('ChamiloCourseBundle:CLp')->find($itemId);
if ($item) {
$itemInfo['name'] = $item->getName();
}
break;
case ITEM_TYPE_GRADEBOOK:
break;
case ITEM_TYPE_STUDENT_PUBLICATION:
/** @var \Chamilo\CourseBundle\Entity\CStudentPublication $item */
$item = $em->getRepository('ChamiloCourseBundle:CStudentPublication')->find($itemId);
if ($item) {
$itemInfo['name'] = $item->getTitle();
}
break;
//ITEM_TYPE_FORUM', 7);
case ITEM_TYPE_ATTENDANCE:
/** @var \Chamilo\CourseBundle\Entity\CAttendance $item */
$item = $em->getRepository('ChamiloCourseBundle:CAttendance')->find($itemId);
if ($item) {
$itemInfo['name'] = $item->getName();
}
break;
case ITEM_TYPE_SURVEY:
/** @var \Chamilo\CourseBundle\Entity\CSurvey $item */
$item = $em->getRepository('ChamiloCourseBundle:CSurvey')->find($itemId);
if ($item) {
$itemInfo['name'] = strip_tags($item->getTitle());
}
break;
case ITEM_TYPE_FORUM_THREAD:
/** @var \Chamilo\CourseBundle\Entity\CForumThread $item */
$item = $em->getRepository('ChamiloCourseBundle:CForumThread')->find($itemId);
if ($item) {
$itemInfo['name'] = $item->getThreadTitle();
}
break;
}
return $itemInfo;
}
/**
* @param int $typeId
* @param int $itemId
@ -2406,6 +2598,31 @@ class Skill extends Model
return $skillToString;
}
/**
* @param int $itemId
* @param int $typeId
*/
public static function deleteSkillsFromItem($itemId, $typeId)
{
$allowSkillInTools = api_get_configuration_value('allow_skill_rel_items');
if ($allowSkillInTools) {
$itemId = (int) $itemId;
$typeId = (int) $typeId;
$em = Database::getManager();
// Delete old ones
$items = $em->getRepository('ChamiloSkillBundle:SkillRelItem')->findBy(
['itemId' => $itemId, 'itemType' => $typeId]
);
/** @var SkillRelItem $skillRelItem */
foreach ($items as $skillRelItem) {
$em->remove($skillRelItem);
}
$em->flush();
}
}
/**
* Relate skill with an item (exercise, gradebook, lp, etc)
* @param FormValidator $form
@ -2418,6 +2635,15 @@ class Skill extends Model
$allowSkillInTools = api_get_configuration_value('allow_skill_rel_items');
if ($allowSkillInTools) {
$userId = api_get_user_id();
$courseId = api_get_course_int_id();
if (empty($courseId)) {
$courseId = null;
}
$sessionId = api_get_session_id();
if (empty($sessionId)) {
$sessionId = null;
}
$em = Database::getManager();
$skills = (array) $form->getSubmitValue('skills');
@ -2426,7 +2652,7 @@ class Skill extends Model
['itemId' => $itemId, 'itemType' => $typeId]
);
if (!empty($items)) {
/** @var \Chamilo\SkillBundle\Entity\SkillRelItem $skillRelItem */
/** @var SkillRelItem $skillRelItem */
foreach ($items as $skillRelItem) {
if (!in_array($skillRelItem->getSkill()->getId(), $skills)) {
$em->remove($skillRelItem);
@ -2442,10 +2668,12 @@ class Skill extends Model
$skill = $em->getRepository('ChamiloCoreBundle:Skill')->find($skillId);
if ($skill) {
if (!$skill->hasItem($typeId, $itemId)) {
$skillRelItem = new \Chamilo\SkillBundle\Entity\SkillRelItem();
$skillRelItem = new SkillRelItem();
$skillRelItem
->setItemType($typeId)
->setItemId($itemId)
->setCourseId($courseId)
->setSessionId($sessionId)
->setCreatedBy($userId)
->setUpdatedBy($userId)
;

@ -107,7 +107,9 @@ switch ($action) {
$form = Link::getLinkForm(null, 'addlink', $token);
if ($form->validate() && Security::check_token('get')) {
// Here we add a link
Link::addlinkcategory("link");
$linkId = Link::addlinkcategory('link');
Skill::saveSkills($form, ITEM_TYPE_LINK, $linkId);
Security::clear_token();
header('Location: '.$linkListUrl);
exit;
@ -119,6 +121,7 @@ switch ($action) {
$form = Link::getLinkForm($id, 'editlink');
if ($form->validate()) {
Link::editLink($id, $form->getSubmitValues());
Skill::saveSkills($form, ITEM_TYPE_LINK, $id);
header('Location: '.$linkListUrl);
exit;
}

@ -60,7 +60,6 @@ if ($debug > 2) {
}
// Is this needed? This is probabaly done in the header file.
//$_user = $_SESSION['_user'];
$file = Session::read('file');
$oLP = unserialize(Session::read('lpobject'));
$oItem = & $oLP->items[$oLP->current];

@ -1970,8 +1970,8 @@ class learnpath
$idBar = 'control-top';
}
$navbar = null;
$lp_id = $this->lp_id;
$navbar = '';
$lpId = $this->lp_id;
$mycurrentitemid = $this->get_current_item_id();
$reportingText = get_lang('Reporting');
@ -1979,34 +1979,53 @@ class learnpath
$nextText = get_lang('ScormNext');
$fullScreenText = get_lang('ScormExitFullScreen');
$settings = api_get_configuration_value('lp_view_settings');
$display = isset($settings['display']) ? $settings['display'] : false;
$reportingIcon = '
<a class="icon-toolbar"
id="stats_link"
href="lp_controller.php?action=stats&'.api_get_cidreq(true).'&lp_id='.$lpId.'"
onclick="window.parent.API.save_asset(); return true;"
target="content_name" title="'.$reportingText.'">
<span class="fa fa-info"></span><span class="sr-only">'.$reportingText.'</span>
</a>';
if (!empty($display)) {
$showReporting = isset($display['show_reporting_icon']) ? $display['show_reporting_icon'] : true;
if ($showReporting == false) {
$reportingIcon = '';
}
}
$previousIcon = '
<a class="icon-toolbar" id="scorm-previous" href="#"
onclick="switch_item('.$mycurrentitemid.',\'previous\');return false;" title="'.$previousText.'">
<span class="fa fa-chevron-left"></span><span class="sr-only">'.$previousText.'</span>
</a>';
$nextIcon = '
<a class="icon-toolbar" id="scorm-next" href="#"
onclick="switch_item('.$mycurrentitemid.',\'next\');return false;" title="'.$nextText.'">
<span class="fa fa-chevron-right"></span><span class="sr-only">' . $nextText.'</span>
</a>';
if ($this->mode == 'fullscreen') {
$navbar = '
<span id="'.$idBar.'" class="buttons">
<a class="icon-toolbar" href="lp_controller.php?action=stats&'.api_get_cidreq(true).'&lp_id='.$lp_id.'" onclick="window.parent.API.save_asset();return true;" target="content_name" title="'.$reportingText.'" id="stats_link">
<span class="fa fa-info"></span><span class="sr-only">' . $reportingText.'</span>
</a>
<a class="icon-toolbar" id="scorm-previous" href="#" onclick="switch_item(' . $mycurrentitemid.',\'previous\');return false;" title="'.$previousText.'">
<span class="fa fa-chevron-left"></span><span class="sr-only">' . $previousText.'</span>
</a>
<a class="icon-toolbar" id="scorm-next" href="#" onclick="switch_item(' . $mycurrentitemid.',\'next\');return false;" title="'.$nextText.'">
<span class="fa fa-chevron-right"></span><span class="sr-only">' . $nextText.'</span>
</a>
<a class="icon-toolbar" id="view-embedded" href="lp_controller.php?action=mode&mode=embedded" target="_top" title="'.$fullScreenText.'">
<span class="fa fa-columns"></span><span class="sr-only">' . $fullScreenText.'</span>
'.$reportingIcon.'
'.$previousIcon.'
'.$nextIcon.'
<a class="icon-toolbar" id="view-embedded"
href="lp_controller.php?action=mode&mode=embedded" target="_top" title="'.$fullScreenText.'">
<span class="fa fa-columns"></span><span class="sr-only">'.$fullScreenText.'</span>
</a>
</span>';
} else {
$navbar = '
<span id="'.$idBar.'" class="buttons text-right">
<a class="icon-toolbar" href="lp_controller.php?action=stats&'.api_get_cidreq(true).'&lp_id='.$lp_id.'" onclick="window.parent.API.save_asset();return true;" target="content_name" title="'.$reportingText.'" id="stats_link">
<span class="fa fa-info"></span><span class="sr-only">' . $reportingText.'</span>
</a>
<a class="icon-toolbar" id="scorm-previous" href="#" onclick="switch_item(' . $mycurrentitemid.',\'previous\');return false;" title="'.$previousText.'">
<span class="fa fa-chevron-left"></span><span class="sr-only">' . $previousText.'</span>
</a>
<a class="icon-toolbar" id="scorm-next" href="#" onclick="switch_item(' . $mycurrentitemid.',\'next\');return false;" title="'.$nextText.'">
<span class="fa fa-chevron-right"></span><span class="sr-only">' . $nextText.'</span>
</a>
'.$reportingIcon.'
'.$previousIcon.'
'.$nextIcon.'
</span>';
}
@ -3439,7 +3458,6 @@ class learnpath
public function get_link($type = 'http', $item_id = null, $provided_toc = false)
{
$course_id = $this->get_course_int_id();
if ($this->debug > 0) {
error_log('New LP - In learnpath::get_link('.$type.','.$item_id.')', 0);
}
@ -3456,7 +3474,7 @@ class learnpath
}
//still empty, this means there was no item_id given and we are not in an object context or
//the object property is empty, return empty link
$item_id = $this->first();
$this->first();
return '';
}
@ -4205,6 +4223,13 @@ class learnpath
*/
public function prerequisites_match($itemId = null)
{
$allow = api_get_configuration_value('allow_teachers_to_access_blocked_lp_by_prerequisite');
if ($allow) {
if (api_is_allowed_to_edit() || api_is_platform_admin() || api_is_drh()) {
return true;
}
}
$debug = $this->debug;
if ($debug > 0) {
error_log('In learnpath::prerequisites_match()', 0);
@ -6084,10 +6109,13 @@ class learnpath
$edit_icon .= '</a>';
if (!in_array($arrLP[$i]['item_type'], ['forum', 'thread'])) {
$forumThread = $this->items[$arrLP[$i]['id']]->getForumThread(
$this->course_int_id,
$this->lp_session_id
);
$forumThread = null;
if (isset($this->items[$arrLP[$i]['id']])) {
$forumThread = $this->items[$arrLP[$i]['id']]->getForumThread(
$this->course_int_id,
$this->lp_session_id
);
}
if ($forumThread) {
$forumIconUrl = api_get_self().'?'.api_get_cidreq().'&'.http_build_query([
'action' => 'dissociate_forum',
@ -7704,8 +7732,6 @@ class learnpath
$arrHide = [
$id
];
//$parent_item_id = $_SESSION['parent_item_id'];
for ($i = 0; $i < count($arrLP); $i++) {
if ($action != 'add') {
if ($arrLP[$i]['item_type'] == 'dir' &&
@ -12308,6 +12334,7 @@ EOD;
$main_course_path = api_get_path(WEB_COURSE_PATH).$course_info['directory'].'/';
$link = '';
$extraParams = api_get_cidreq(true, true, 'learnpath').'&session_id='.$session_id;
switch ($type) {
case 'dir':
return $main_dir_path.'lp/blank.php';

@ -151,6 +151,8 @@ $form->addElement('html', '<div id="end_date_div" style="display:none;">');
$form->addDatePicker('expired_on', get_lang('ExpirationDate'));
$form->addElement('html', '</div>');
Skill::addSkillsToForm($form, ITEM_TYPE_LEARNPATH, 0);
$form->addElement('html', '</div>');
$defaults['activate_start_date_check'] = 1;

@ -20,14 +20,14 @@ $this_section = SECTION_COURSES;
api_protect_course_script();
$isStudentView = isset($_REQUEST['isStudentView']) ? $_REQUEST['isStudentView'] : null;
$learnpath_id = isset($_REQUEST['lp_id']) ? intval($_REQUEST['lp_id']) : null;
$lpId = isset($_REQUEST['lp_id']) ? (int) $_REQUEST['lp_id'] : 0;
$submit = isset($_POST['submit_button']) ? $_POST['submit_button'] : null;
$type = isset($_GET['type']) ? $_GET['type'] : null;
$action = isset($_GET['action']) ? $_GET['action'] : null;
$is_allowed_to_edit = api_is_allowed_to_edit(null, false);
$listUrl = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?action=view&lp_id='.$learnpath_id.'&'.api_get_cidreq().'&isStudentView=true';
$listUrl = api_get_path(WEB_CODE_PATH).'lp/lp_controller.php?action=view&lp_id='.$lpId.'&'.api_get_cidreq().'&isStudentView=true';
if (!$is_allowed_to_edit) {
header("Location: $listUrl");
exit;
@ -98,7 +98,7 @@ $interbreadcrumb[] = [
'name' => get_lang('LearningPaths'),
];
$interbreadcrumb[] = [
'url' => api_get_self()."?action=build&lp_id=$learnpath_id&".api_get_cidreq(),
'url' => api_get_self()."?action=build&lp_id=$lpId&".api_get_cidreq(),
'name' => $learnPath->get_name(),
];
@ -192,7 +192,6 @@ $(document).ready(function() {
// hide the current template list for new documment until it tab clicked
$('#frmModel').hide();
});
// document template for new document tab handler

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
/**
* This is a learning path creation and player tool in Chamilo - previously learnpath_handler.php
*
@ -17,6 +19,9 @@ api_protect_course_script();
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
/** @var learnpath $learnPath */
$learnPath = Session::read('oLP');
$tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
$tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM);
@ -29,14 +34,6 @@ if ((!$is_allowed_to_edit) || ($isStudentView)) {
error_log('New LP - User not authorized in lp_admin_view.php');
header('location:lp_controller.php?action=view&lp_id='.$learnpath_id);
}
// From here on, we are admin because of the previous condition, so don't check anymore.
$course_id = api_get_course_int_id();
$sql_query = "SELECT * FROM $tbl_lp
WHERE iid = $learnpath_id";
$result = Database::query($sql_query);
$therow = Database::fetch_array($result);
if (api_is_in_gradebook()) {
$interbreadcrumb[] = [
@ -51,7 +48,7 @@ $interbreadcrumb[] = [
];
$interbreadcrumb[] = [
'url' => api_get_self()."?action=build&lp_id=$learnpath_id&".api_get_cidreq(),
"name" => stripslashes("{$therow['name']}"),
"name" => Security::remove_XSS($learnPath->get_name()),
];
$interbreadcrumb[] = [
'url' => api_get_self()."?action=add_item&type=step&lp_id=$learnpath_id&".api_get_cidreq(),
@ -66,12 +63,12 @@ if (isset($_REQUEST['updateaudio'])) {
// Theme calls.
$show_learn_path = true;
$lp_theme_css = $_SESSION['oLP']->get_theme();
$lp_theme_css = $learnPath->get_theme();
// POST action handling (uploading mp3, deleting mp3)
if (isset($_POST['save_audio'])) {
//Updating the lp.modified_on
$_SESSION['oLP']->set_modified_on();
$learnPath->set_modified_on();
$lp_items_to_remove_audio = [];
$tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM);
@ -150,7 +147,7 @@ if (isset($_POST['save_audio'])) {
}
}
//echo Display::return_message(get_lang('ItemUpdated'), 'confirm');
$url = api_get_self().'?action=add_item&type=step&lp_id='.intval($_SESSION['oLP']->lp_id).'&'.api_get_cidreq();
$url = api_get_self().'?action=add_item&type=step&lp_id='.$learnPath->get_id().'&'.api_get_cidreq();
header('Location: '.$url);
exit;
}
@ -162,7 +159,6 @@ $suredel = trim(get_lang('AreYouSureToDeleteJS'));
<script>
var newOrderData= "";
//source code found in http://www.swartzfager.org/blog/dspNestedList.cfm
$(function() {
<?php
if (!isset($_REQUEST['updateaudio'])) {
@ -264,11 +260,11 @@ function confirmation(name) {
</script>
<?php
echo $_SESSION['oLP']->build_action_menu();
echo $learnPath->build_action_menu();
echo '<div class="row">';
echo '<div class="col-md-4">';
echo $_SESSION['oLP']->return_new_tree(null, true);
echo $learnPath->return_new_tree(null, true);
echo '</div>';
echo '<div class="col-md-8">';
@ -280,7 +276,7 @@ switch ($_GET['action']) {
'confirm'
);
} else {
echo $_SESSION['oLP']->display_edit_item($_GET['id']);
echo $learnPath->display_edit_item($_GET['id']);
}
break;
case 'delete_item':
@ -294,7 +290,7 @@ switch ($_GET['action']) {
}
if (!empty($_GET['updateaudio'])) {
// list of items to add audio files
echo $_SESSION['oLP']->overview();
echo $learnPath->overview();
}
echo '</div>';

@ -444,7 +444,7 @@ function save_item(
}
$return .= "update_progress_bar('$myComplete', '$myTotal', '$myProgressMode');";
if (!isset($_SESSION['login_as'])) {
if (!Session::read('login_as')) {
// If $_SESSION['login_as'] is set, then the user is an admin logged as the user.
$tbl_track_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
/**
* This is a learning path creation and player tool in Chamilo - previously learnpath_handler.php
*
@ -18,8 +20,8 @@ api_protect_course_script();
/* Constants and variables */
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
$tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
/** @var learnpath $learnPath */
$learnPath = Session::read('oLP');
$isStudentView = (int) $_REQUEST['isStudentView'];
$learnpath_id = (int) $_REQUEST['lp_id'];
$submit = $_POST['submit_button'];
@ -27,40 +29,26 @@ $submit = $_POST['submit_button'];
/* MAIN CODE */
if ((!$is_allowed_to_edit) || ($isStudentView)) {
error_log('New LP - User not authorized in lp_build.php');
header('location:lp_controller.php?action=view&lp_id='.$learnpath_id);
header('location:lp_controller.php?action=view&lp_id='.$learnpath_id.'&'.api_get_cidreq());
exit;
}
// From here on, we are admin because of the previous condition, so don't check anymore.
/* The learnpath has been just created, go get the last id. */
$is_new = false;
$course_id = api_get_course_int_id();
if ($learnpath_id == 0) {
$is_new = true;
$sql = "SELECT iid FROM $tbl_lp
WHERE c_id = $course_id
ORDER BY id DESC LIMIT 0, 1";
$result = Database::query($sql);
$row = Database::fetch_array($result);
$learnpath_id = $row['iid'];
}
$sql_query = "SELECT * FROM $tbl_lp WHERE iid = $learnpath_id";
$result = Database::query($sql_query);
$therow = Database::fetch_array($result);
if (api_is_in_gradebook()) {
$interbreadcrumb[] = [
'url' => Category::getUrl(),
'name' => get_lang('ToolGradebook')
];
}
$interbreadcrumb[] = ['url' => 'lp_controller.php?action=list', 'name' => get_lang('LearningPaths')];
$interbreadcrumb[] = ['url' => '#', "name" => $therow['name']];
$interbreadcrumb[] = ['url' => 'lp_controller.php?action=list?'.api_get_cidreq(), 'name' => get_lang('LearningPaths')];
$interbreadcrumb[] = ['url' => '#', "name" => $learnPath->get_name()];
// Theme calls.
$lp_theme_css = $_SESSION['oLP']->get_theme();
$lp_theme_css = $learnPath->get_theme();
$show_learn_path = true;
Display::display_header('', 'Path');
$suredel = trim(get_lang('AreYouSureToDeleteJS'));
@ -87,13 +75,12 @@ function confirmation(name) {
<?php
/* DISPLAY SECTION */
echo $_SESSION['oLP']->build_action_menu();
echo $learnPath->build_action_menu();
echo '<div class="row">';
echo '<div class="col-md-4">';
// Build the tree with the menu items in it.
echo $_SESSION['oLP']->return_new_tree();
echo $learnPath->return_new_tree();
echo '</div>';
echo '<div class="col-md-8">';
@ -106,13 +93,13 @@ if (isset($is_success) && $is_success === true) {
echo Display::page_subheader(get_lang('LearnPathAddedTitle'));
echo '<ul id="lp_overview" class="thumbnails">';
echo show_block(
'lp_controller.php?'.api_get_cidreq().'&action=add_item&type=step&lp_id='.$_SESSION['oLP']->lp_id,
'lp_controller.php?'.api_get_cidreq().'&action=add_item&type=step&lp_id='.$learnPath->get_id(),
get_lang("NewStep"),
get_lang('NewStepComment'),
'tools.png'
);
echo show_block(
'lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$_SESSION['oLP']->lp_id,
'lp_controller.php?'.api_get_cidreq().'&action=view&lp_id='.$learnPath->get_id(),
get_lang("Display"),
get_lang('DisplayComment'),
'view.png'

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
/**
* Script that displays an error message when no content could be loaded
* @package chamilo.learnpath
@ -20,9 +22,12 @@ if (empty($lp_controller_touched)) {
header('location: lp_controller.php?action=content&lp_id='.intval($_REQUEST['lp_id']).'&item_id='.intval($_REQUEST['item_id']).'&'.api_get_cidreq());
exit;
}
$_SESSION['oLP']->error = '';
$lp_type = $_SESSION['oLP']->get_type();
$lp_item_id = $_SESSION['oLP']->get_current_item_id();
/** @var learnpath $learnPath */
$learnPath = Session::read('oLP');
$learnPath->error = '';
$lp_type = $learnPath->get_type();
$lp_item_id = $learnPath->get_current_item_id();
/**
* Get a link to the corresponding document
@ -32,7 +37,7 @@ if ($debug > 0) {
error_log('New lp - In lp_content.php - Looking for file url', 0);
}
$list = $_SESSION['oLP']->get_toc();
$list = $learnPath->get_toc();
$dir = false;
foreach ($list as $toc) {
@ -40,18 +45,19 @@ foreach ($list as $toc) {
$dir = true;
}
}
if ($dir) {
$src = 'blank.php';
} else {
switch ($lp_type) {
case 1:
$_SESSION['oLP']->stop_previous_item();
$prereq_check = $_SESSION['oLP']->prerequisites_match($lp_item_id);
$learnPath->stop_previous_item();
$prereq_check = $learnPath->prerequisites_match($lp_item_id);
if ($prereq_check === true) {
$src = $_SESSION['oLP']->get_link('http', $lp_item_id);
$_SESSION['oLP']->start_current_item(); // starts time counter manually if asset
$src = $_SESSION['oLP']->fixBlockedLinks($src);
$src = $learnPath->get_link('http', $lp_item_id);
$learnPath->start_current_item(); // starts time counter manually if asset
$src = $learnPath->fixBlockedLinks($src);
break;
}
@ -59,23 +65,23 @@ if ($dir) {
$src = 'blank.php?error=prerequisites';
break;
case 2:
$_SESSION['oLP']->stop_previous_item();
$prereq_check = $_SESSION['oLP']->prerequisites_match($lp_item_id);
$learnPath->stop_previous_item();
$prereq_check = $learnPath->prerequisites_match($lp_item_id);
if ($prereq_check === true) {
$src = $_SESSION['oLP']->get_link('http', $lp_item_id);
$_SESSION['oLP']->start_current_item(); // starts time counter manually if asset
$src = $learnPath->get_link('http', $lp_item_id);
$learnPath->start_current_item(); // starts time counter manually if asset
} else {
$src = 'blank.php?error=prerequisites';
}
break;
case 3:
// save old if asset
$_SESSION['oLP']->stop_previous_item(); // save status manually if asset
$prereq_check = $_SESSION['oLP']->prerequisites_match($lp_item_id);
$learnPath->stop_previous_item(); // save status manually if asset
$prereq_check = $learnPath->prerequisites_match($lp_item_id);
if ($prereq_check === true) {
$src = $_SESSION['oLP']->get_link('http', $lp_item_id);
$_SESSION['oLP']->start_current_item(); // starts time counter manually if asset
$src = $learnPath->get_link('http', $lp_item_id);
$learnPath->start_current_item(); // starts time counter manually if asset
} else {
$src = 'blank.php';
}
@ -88,7 +94,7 @@ if ($dir) {
if ($debug > 0) {
error_log('New lp - In lp_content.php - File url is '.$src, 0);
}
$_SESSION['oLP']->set_previous_item($lp_item_id);
$learnPath->set_previous_item($lp_item_id);
if (api_is_in_gradebook()) {
$interbreadcrumb[] = [
@ -97,7 +103,7 @@ if (api_is_in_gradebook()) {
];
}
// Define the 'doc.inc.php' as language file.
$nameTools = $_SESSION['oLP']->get_name();
$nameTools = $learnPath->get_name();
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'lp/lp_list.php?'.api_get_cidreq(),
'name' => get_lang('Doc'),
@ -109,5 +115,6 @@ $_setting['show_navigation_menu'] = false;
if ($debug > 0) {
error_log('New LP - In lp_content.php - Loading '.$src, 0);
}
Session::write('oLP', $learnPath);
header("Location: ".urldecode($src));
exit;

@ -283,21 +283,21 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
$lp_table = Database::get_course_table(TABLE_LP_MAIN);
if (is_numeric($lp_id)) {
$sel = "SELECT lp_type FROM $lp_table WHERE c_id = $course_id AND id = $lp_id";
$sel = "SELECT iid, lp_type FROM $lp_table WHERE c_id = $course_id AND id = $lp_id";
if ($debug > 0) {
error_log('New LP - querying '.$sel, 0);
}
$res = Database::query($sel);
if (Database::num_rows($res)) {
$row = Database::fetch_array($res);
$lpIid = $row['iid'];
$type = $row['lp_type'];
if ($debug > 0) {
error_log('New LP - found row - type '.$type.' - Calling constructor with '.api_get_course_id().' - '.$lp_id.' - '.api_get_user_id(), 0);
}
switch ($type) {
case 1:
$oLP = new learnpath(api_get_course_id(), $lp_id, api_get_user_id());
$oLP = new learnpath(api_get_course_id(), $lpIid, api_get_user_id());
if ($oLP !== false) {
$lp_found = true;
} else {
@ -305,7 +305,7 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
}
break;
case 2:
$oLP = new scorm(api_get_course_id(), $lp_id, api_get_user_id());
$oLP = new scorm(api_get_course_id(), $lpIid, api_get_user_id());
if ($oLP !== false) {
$lp_found = true;
} else {
@ -313,7 +313,7 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
}
break;
case 3:
$oLP = new aicc(api_get_course_id(), $lp_id, api_get_user_id());
$oLP = new aicc(api_get_course_id(), $lpIid, api_get_user_id());
if ($oLP !== false) {
$lp_found = true;
} else {
@ -321,7 +321,7 @@ if (!$lp_found || (!empty($_REQUEST['lp_id']) && $_SESSION['oLP']->get_id() != $
}
break;
default:
$oLP = new learnpath(api_get_course_id(), $lp_id, api_get_user_id());
$oLP = new learnpath(api_get_course_id(), $lpIid, api_get_user_id());
if ($oLP !== false) {
$lp_found = true;
} else {
@ -605,6 +605,11 @@ switch ($action) {
);
if (is_numeric($new_lp_id)) {
// Create temp form validator to save skills
$form = new FormValidator('lp_add');
$form->addSelect('skills', 'skills');
Skill::saveSkills($form, ITEM_TYPE_LEARNPATH, $new_lp_id);
// TODO: Maybe create a first directory directly to avoid bugging the user with useless queries
$_SESSION['oLP'] = new learnpath(
api_get_course_id(),
@ -863,6 +868,9 @@ switch ($action) {
} else {
Session::write('refresh', 1);
$_SESSION['oLP']->delete(null, $_GET['lp_id'], 'remove');
Skill::deleteSkillsFromItem($_GET['lp_id'], ITEM_TYPE_LEARNPATH);
Display::addFlash(Display::return_message(get_lang('Deleted')));
Session::erase('oLP');
require 'lp_list.php';
@ -1028,6 +1036,10 @@ switch ($action) {
$_SESSION['oLP']->upload_image($_FILES['lp_preview_image']);
}
$form = new FormValidator('form1');
$form->addSelect('skills', 'skills');
Skill::saveSkills($form, ITEM_TYPE_LEARNPATH, $_SESSION['oLP']->get_id());
if (api_get_setting('search_enabled') === 'true') {
require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
$specific_fields = get_specific_field_list();

@ -1,5 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
/**
* Script allowing simple edition of learnpath information (title, description, etc)
* @package chamilo.learnpath
@ -10,11 +13,15 @@ require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
api_protect_course_script();
$show_description_field = false; //for now
/** @var learnpath $learnPath */
$learnPath = Session::read('oLP');
$nameTools = get_lang('Doc');
$this_section = SECTION_COURSES;
Event::event_access_tool(TOOL_LEARNPATH);
$lpId = $learnPath->get_id();
if (api_is_in_gradebook()) {
$interbreadcrumb[] = [
'url' => Category::getUrl(),
@ -26,8 +33,8 @@ $interbreadcrumb[] = [
'name' => get_lang('LearningPaths')
];
$interbreadcrumb[] = [
'url' => api_get_self()."?action=build&lp_id=".$_SESSION['oLP']->get_id().'&'.api_get_cidreq(),
'name' => $_SESSION['oLP']->get_name()
'url' => api_get_self()."?action=build&lp_id=".$lpId.'&'.api_get_cidreq(),
'name' => $learnPath->get_name()
];
$htmlHeadXtra[] = '<script>
@ -81,7 +88,7 @@ if (api_get_setting('allow_course_theme') === 'true') {
$theme_select = $form->addElement('SelectTheme', 'lp_theme', get_lang('Theme'));
$form->applyFilter('lp_theme', 'trim');
$s_theme = $_SESSION['oLP']->get_theme();
$s_theme = $learnPath->get_theme();
$theme_select->setSelected($s_theme); //default
}
}
@ -97,12 +104,12 @@ $form->addElement(
$form->applyFilter('lp_author', 'html_filter');
// LP image
if (strlen($_SESSION['oLP']->get_preview_image()) > 0) {
$show_preview_image = '<img src='.api_get_path(WEB_COURSE_PATH).api_get_course_path().'/upload/learning_path/images/'.$_SESSION['oLP']->get_preview_image().'>';
if (strlen($learnPath->get_preview_image()) > 0) {
$show_preview_image = '<img src='.api_get_path(WEB_COURSE_PATH).api_get_course_path().'/upload/learning_path/images/'.$learnPath->get_preview_image().'>';
$form->addElement('label', get_lang('ImagePreview'), $show_preview_image);
$form->addElement('checkbox', 'remove_picture', null, get_lang('DelImage'));
}
$label = ($_SESSION['oLP']->get_preview_image() != '' ? get_lang('UpdateImage') : get_lang('AddImage'));
$label = ($learnPath->get_preview_image() != '' ? get_lang('UpdateImage') : get_lang('AddImage'));
$form->addElement('file', 'lp_preview_image', [$label, get_lang('ImageWillResizeMsg')]);
$form->addRule('lp_preview_image', get_lang('OnlyImagesAllowed'), 'filetype', ['jpg', 'jpeg', 'png', 'gif']);
@ -115,7 +122,7 @@ if (api_get_setting('search_enabled') === 'true') {
$filter = [
'c_id' => "'".api_get_course_int_id()."'",
'field_id' => $specific_field['id'],
'ref_id' => $_SESSION['oLP']->lp_id,
'ref_id' => $learnPath->lp_id,
'tool_id' => '\''.TOOL_LEARNPATH.'\'',
];
$values = get_specific_field_values_list($filter, ['value']);
@ -129,21 +136,20 @@ if (api_get_setting('search_enabled') === 'true') {
}
}
$hideTableOfContents = $_SESSION['oLP']->getHideTableOfContents();
$defaults['lp_encoding'] = Security::remove_XSS($_SESSION['oLP']->encoding);
$defaults['lp_name'] = Security::remove_XSS($_SESSION['oLP']->get_name());
$defaults['lp_author'] = Security::remove_XSS($_SESSION['oLP']->get_author());
$hideTableOfContents = $learnPath->getHideTableOfContents();
$defaults['lp_encoding'] = Security::remove_XSS($learnPath->encoding);
$defaults['lp_name'] = Security::remove_XSS($learnPath->get_name());
$defaults['lp_author'] = Security::remove_XSS($learnPath->get_author());
$defaults['hide_toc_frame'] = $hideTableOfContents;
$defaults['category_id'] = intval($_SESSION['oLP']->getCategoryId());
$defaults['accumulate_scorm_time'] = $_SESSION['oLP']->getAccumulateScormTime();
$defaults['category_id'] = intval($learnPath->getCategoryId());
$defaults['accumulate_scorm_time'] = $learnPath->getAccumulateScormTime();
$expired_on = $_SESSION['oLP']->expired_on;
$publicated_on = $_SESSION['oLP']->publicated_on;
$expired_on = $learnPath->expired_on;
$publicated_on = $learnPath->publicated_on;
// Prerequisites
$form->addElement('html', '<div class="form-group">');
$items = $_SESSION['oLP']->display_lp_prerequisites_list();
$items = $learnPath->display_lp_prerequisites_list();
$form->addElement('html', '<label class="col-md-2">'.get_lang('LearnpathPrerequisites').'</label>');
$form->addElement('html', '<div class="col-md-8">');
$form->addElement('html', $items);
@ -190,7 +196,7 @@ $form->addElement('html', '</div>');
if (api_is_platform_admin()) {
$form->addElement('checkbox', 'use_max_score', null, get_lang('UseMaxScore100'));
$defaults['use_max_score'] = $_SESSION['oLP']->use_max_score;
$defaults['use_max_score'] = $learnPath->use_max_score;
}
$subscriptionSettings = learnpath::getSubscriptionSettings();
@ -214,15 +220,17 @@ $form->addElement(
$enableLpExtraFields = false;
if ($enableLpExtraFields) {
$extraField = new ExtraField('lp');
$extra = $extraField->addElements($form, $_SESSION['oLP']->get_id());
$extra = $extraField->addElements($form, $lpId);
}
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_LEARNPATH, $lpId);
// Submit button
$form->addButtonSave(get_lang('SaveLPSettings'));
// Hidden fields
$form->addElement('hidden', 'action', 'update_lp');
$form->addElement('hidden', 'lp_id', $_SESSION['oLP']->get_id());
$form->addElement('hidden', 'lp_id', $lpId);
if ($enableLpExtraFields) {
$htmlHeadXtra[] = '<script>
@ -234,12 +242,13 @@ if ($enableLpExtraFields) {
$defaults['publicated_on'] = !empty($publicated_on) && $publicated_on !== '0000-00-00 00:00:00' ? api_get_local_time($publicated_on) : null;
$defaults['expired_on'] = (!empty($expired_on)) ? api_get_local_time($expired_on) : date('Y-m-d 12:00:00', time() + 84600);
$defaults['subscribe_users'] = $_SESSION['oLP']->getSubscribeUsers();
$defaults['subscribe_users'] = $learnPath->getSubscribeUsers();
$defaults['skills'] = array_keys($skillList);
$form->setDefaults($defaults);
Display::display_header(get_lang('CourseSettings'), 'Path');
echo $_SESSION['oLP']->build_action_menu(false, false, true, false);
echo $learnPath->build_action_menu(false, false, true, false);
echo '<div class="row">';
echo '<div class="'.($hideTableOfContents ? 'col-md-12' : 'col-md-8').'" id="pnl-frm">';
$form->display();

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
/**
* This is a learning path creation and player tool in Chamilo - previously learnpath_handler.php
*
@ -15,9 +17,12 @@
$this_section = SECTION_COURSES;
api_protect_course_script();
/** @var learnpath $learnPath */
$learnPath = Session::read('oLP');
/* Header and action code */
$htmlHeadXtra[] = '
<script>'.$_SESSION['oLP']->get_js_dropdown_array().
<script>'.$learnPath->get_js_dropdown_array().
"
function load_cbo(id) {
if (!id) {
@ -101,7 +106,7 @@ $interbreadcrumb[] = [
// Theme calls.
$show_learn_path = true;
$lp_theme_css = $_SESSION['oLP']->get_theme();
$lp_theme_css = $learnPath->get_theme();
Display::display_header(get_lang('Edit'), 'Path');
$suredel = trim(get_lang('AreYouSureToDeleteJS'));
@ -152,7 +157,7 @@ $(document).ready(function() {
</script>
<?php
echo $_SESSION['oLP']->build_action_menu();
echo $learnPath->build_action_menu();
echo '<div class="row">';
echo '<div id="lp_sidebar" class="col-md-4">';
@ -169,12 +174,12 @@ $path_parts = pathinfo($path_file);
if (Database::num_rows($res_doc) > 0 &&
isset($path_parts['extension']) && $path_parts['extension'] == 'html'
) {
echo $_SESSION['oLP']->return_new_tree();
echo $learnPath->return_new_tree();
// Show the template list
echo '<div id="frmModel" class="scrollbar-inner lp-add-item"></div>';
} else {
echo $_SESSION['oLP']->return_new_tree();
echo $learnPath->return_new_tree();
}
echo '</div>';
@ -184,17 +189,17 @@ if (isset($is_success) && $is_success === true) {
$msg = '<div class="lp_message" style="margin-bottom:10px;">';
$msg .= 'The item has been edited.';
$msg .= '</div>';
echo $_SESSION['oLP']->display_item($_GET['id'], $msg);
echo $learnPath->display_item($_GET['id'], $msg);
} else {
echo $_SESSION['oLP']->display_edit_item($_GET['id']);
if (isset($_SESSION['finalItem'])) {
echo $learnPath->display_edit_item($_GET['id']);
$finalItem = Session::read('finalItem');
if ($finalItem) {
echo '<script>$("#frmModel").remove()</script>';
}
unset($_SESSION['finalItem']);
Session::erase('finalItem');
}
echo '</div>';
echo '</div>';
/* FOOTER */
Display::display_footer();

@ -385,6 +385,7 @@ foreach ($categories as $item) {
$copy = null;
$lp_auto_launch_icon = null;
$actionSeriousGame = null;
$actionUpdateScormFile = '';
if ($is_allowed_to_edit) {
// EDIT LP
@ -618,7 +619,7 @@ foreach ($categories as $item) {
}
/* DEBUG */
if ($test_mode == 'test' or api_is_platform_admin()) {
if ($test_mode == 'test' || api_is_platform_admin()) {
if ($details['lp_scorm_debug'] == 1) {
$dsp_debug = Display::url(
Display::return_icon(
@ -769,6 +770,14 @@ foreach ($categories as $item) {
}
}
if ($details['lp_type'] == 2) {
$url = api_get_path(WEB_CODE_PATH)."lp/lp_update_scorm.php?".api_get_cidreq()."&lp_id=$id";
$actionUpdateScormFile = Display::url(
Display::return_icon('upload_file.png', get_lang('Update')),
$url
);
}
if ($is_allowed_to_edit) {
$start_time = $start_time;
$end_time = $end_time;
@ -852,6 +861,7 @@ foreach ($categories as $item) {
'action_order' => $dsp_order,
'action_serious_game' => $actionSeriousGame,
'action_subscribe_users' => $subscribeUsers,
'action_update_scorm' => $actionUpdateScormFile
];
$lpIsShown = true;

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
/**
* This is a learning path creation and player tool in Chamilo - previously learnpath_handler.php
*
@ -12,12 +14,14 @@
*/
$this_section = SECTION_COURSES;
api_protect_course_script();
/** @var learnpath $learnPath */
$learnPath = Session::read('oLP');
/* Header and action code */
$htmlHeadXtra[] = '<script>'.
$_SESSION['oLP']->get_js_dropdown_array().
$learnPath->get_js_dropdown_array().
"
function load_cbo(id) {
if (!id) {
@ -96,7 +100,7 @@ $interbreadcrumb[] = [
// Theme calls
$show_learn_path = true;
$lp_theme_css = $_SESSION['oLP']->get_theme();
$lp_theme_css = $learnPath->get_theme();
Display::display_header(get_lang('Move'), 'Path');
@ -125,10 +129,10 @@ function confirmation(name) {
</script>
<?php
echo $_SESSION['oLP']->build_action_menu();
echo $learnPath->build_action_menu();
echo '<div class="row">';
echo '<div class="col-md-3">';
echo $_SESSION['oLP']->return_new_tree();
echo $learnPath->return_new_tree();
echo '</div>';
echo '<div class="col-md-9">';
@ -137,13 +141,11 @@ if (isset($is_success) && $is_success === true) {
$msg = '<div class="lp_message" style="margin-bottom:10px;">';
$msg .= 'The item has been moved.';
$msg .= '</div>';
echo $_SESSION['oLP']->display_item($_GET['id'], $msg);
echo $learnPath->display_item($_GET['id'], $msg);
} else {
echo $_SESSION['oLP']->display_move_item($_GET['id']);
echo $learnPath->display_move_item($_GET['id']);
}
echo '</div>';
echo '</div>';
/* FOOTER */
Display::display_footer();

@ -205,8 +205,6 @@ if ($formUsers->validate()) {
get_lang('SubscribeGroupsToLpCategory')
];
$tabs = Display::tabs($headers, [$formUsers->toHtml(), $form->toHtml()]);
$tpl->assign('tabs', $tabs);
$tpl->assign('content', $tabs);
$tpl->display_one_col_template();
}
$layout = $tpl->get_template('learnpath/subscribe_users.tpl');
$tpl->display($layout);

@ -65,86 +65,6 @@ if (isset($_POST) && $is_error) {
$manifest = $oScorm->import_package($_FILES['user_file'], $current_dir);
if (!empty($manifest)) {
$oScorm->parse_manifest($manifest);
$fixTemplate = api_get_configuration_value('learnpath_fix_xerte_template');
$proxyPath = api_get_configuration_value('learnpath_proxy_url');
if ($fixTemplate && !empty($proxyPath)) {
// Check organisations:
if (isset($oScorm->manifest['organizations'])) {
foreach ($oScorm->manifest['organizations'] as $data) {
if (strpos(strtolower($data), 'xerte') !== false) {
// Check if template.xml exists:
$templatePath = str_replace('imsmanifest.xml', 'template.xml', $manifest);
if (file_exists($templatePath) && is_file($templatePath)) {
$templateContent = file_get_contents($templatePath);
$find = [
'href="www.',
'href="https://',
'href="http://',
'url="www.',
'pdfs/download.php?'
];
$replace = [
'href="http://www.',
'target = "_blank" href="'.$proxyPath.'?type=link&src=https://',
'target = "_blank" href="'.$proxyPath.'?type=link&src=http://',
'url="http://www.',
'pdfs/download.php&'
];
$templateContent = str_replace($find, $replace, $templateContent);
file_put_contents($templatePath, $templateContent);
}
// Fix link generation:
$linkPath = str_replace('imsmanifest.xml', 'models_html5/links.html', $manifest);
if (file_exists($linkPath) && is_file($linkPath)) {
$linkContent = file_get_contents($linkPath);
$find = [
':this.getAttribute("url")'
];
$replace = [
':"'.$proxyPath.'?type=link&src=" + this.getAttribute("url")'
];
$linkContent = str_replace($find, $replace, $linkContent);
file_put_contents($linkPath, $linkContent);
}
// Fix iframe generation
$framePath = str_replace('imsmanifest.xml', 'models_html5/embedDiv.html', $manifest);
if (file_exists($framePath) && is_file($framePath)) {
$content = file_get_contents($framePath);
$find = [
'$iFrameHolder.html(iFrameTag);'
];
$replace = [
'iFrameTag = \'<a target ="_blank" href="'.$proxyPath.'?type=link&src=\'+ pageSrc + \'">Open website. <img src="'.api_get_path(WEB_CODE_PATH).'img/link-external.png"></a>\'; $iFrameHolder.html(iFrameTag); '
];
$content = str_replace($find, $replace, $content);
file_put_contents($framePath, $content);
}
// Fix new window generation
$newWindowPath = str_replace('imsmanifest.xml', 'models_html5/newWindow.html', $manifest);
if (file_exists($newWindowPath) && is_file($newWindowPath)) {
$content = file_get_contents($newWindowPath);
$find = [
'var src = x_currentPageXML'
];
$replace = [
'var src = "'.$proxyPath.'?type=link&src=" + x_currentPageXML'
];
$content = str_replace($find, $replace, $content);
file_put_contents($newWindowPath, $content);
}
}
}
}
}
$oScorm->import_manifest(api_get_course_id(), $_REQUEST['use_max_score']);
Display::addFlash(Display::return_message(get_lang('UplUploadSucceeded')));
}

@ -140,8 +140,8 @@ if ($lp->mode == 'impress') {
}
// Prepare variables for the test tool (just in case) - honestly, this should disappear later on.
$_SESSION['scorm_view_id'] = $lp->get_view_id();
$_SESSION['scorm_item_id'] = $lp_item_id;
Session::write('scorm_view_id', $lp->get_view_id());
Session::write('scorm_item_id', $lp_item_id);
// Reinit exercises variables to avoid spacename clashes (see exercise tool)
if (isset($exerciseResult) || isset($_SESSION['exerciseResult'])) {
@ -328,7 +328,6 @@ if (!empty($_REQUEST['exeId']) &&
score = $score,
total_time = $mytime
WHERE iid = $lp_item_view_id";
if ($debug) {
error_log($sql);
}
@ -361,18 +360,13 @@ $scorm_css_header = true;
$lp_theme_css = $lp->get_theme();
// Sets the css theme of the LP this call is also use at the frames (toc, nav, message).
if ($lp->mode == 'fullscreen') {
$htmlHeadXtra[] = "<script>window.open('$src','content_id','toolbar=0,location=0,status=0,scrollbars=1,resizable=1');</script>";
}
// Not in fullscreen mode.
// Check if audio recorder needs to be in studentview.
$audio_recorder_studentview = false;
if (isset($_SESSION['status']) && $_SESSION['status'][$course_code] == 5) {
$audio_recorder_studentview = true;
$htmlHeadXtra[] = "<script>
window.open('$src','content_id','toolbar=0,location=0,status=0,scrollbars=1,resizable=1');
</script>";
}
// Set flag to ensure lp_header.php is loaded by this script (flag is unset in lp_header.php).
$_SESSION['loaded_lp_view'] = true;
Session::write('loaded_lp_view', true);
$display_none = '';
$margin_left = '340px';

@ -47,8 +47,8 @@ if (empty($lp)) {
}
$mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : 'fullpage';
if (isset($_SESSION['oLP']) && isset($_GET['id'])) {
$_SESSION['oLP']->current = intval($_GET['id']);
if (isset($lp) && isset($_GET['id'])) {
$lp->current = intval($_GET['id']);
}
$this_section = SECTION_COURSES;
/* Header and action code */
@ -114,6 +114,7 @@ function confirmation(name) {
</script>
<?php
Session::write('oLP', $lp);
$id = isset($new_item_id) ? $new_item_id : $_GET['id'];
if (is_object($lp)) {
switch ($mode) {

@ -85,8 +85,10 @@ class scorm extends learnpath
if ($this->debug > 0) {
error_log('In scorm::parse_manifest() - Parsing using PHP5 method');
}
//$this->manifest_encoding = api_detect_encoding_xml($xml); // This is the usual way for reading the encoding.
// This method reads the encoding, it tries to be correct even in cases of wrong or missing encoding declarations.
// $this->manifest_encoding = api_detect_encoding_xml($xml);
// This is the usual way for reading the encoding.
// This method reads the encoding, it tries to be correct even in cases
// of wrong or missing encoding declarations.
$this->manifest_encoding = self::detect_manifest_encoding($xml);
// UTF-8 is supported by DOMDocument class, this is for sure.
@ -217,8 +219,8 @@ class scorm extends learnpath
}
}
}
// End parsing using PHP5 DOMXML methods.
unset($doc);
// End parsing using PHP5 DOMXML methods.
} else {
if ($this->debug > 1) {
error_log('New LP - Could not open/read file '.$file);
@ -227,6 +229,85 @@ class scorm extends learnpath
return null;
}
$fixTemplate = api_get_configuration_value('learnpath_fix_xerte_template');
$proxyPath = api_get_configuration_value('learnpath_proxy_url');
if ($fixTemplate && !empty($proxyPath)) {
// Check organisations:
if (isset($this->manifest['organizations'])) {
foreach ($this->manifest['organizations'] as $data) {
if (strpos(strtolower($data), 'xerte') !== false) {
// Check if template.xml exists:
$templatePath = str_replace('imsmanifest.xml', 'template.xml', $file);
if (file_exists($templatePath) && is_file($templatePath)) {
$templateContent = file_get_contents($templatePath);
$find = [
'href="www.',
'href="https://',
'href="http://',
'url="www.',
'pdfs/download.php?'
];
$replace = [
'href="http://www.',
'target = "_blank" href="'.$proxyPath.'?type=link&src=https://',
'target = "_blank" href="'.$proxyPath.'?type=link&src=http://',
'url="http://www.',
'pdfs/download.php&'
];
$templateContent = str_replace($find, $replace, $templateContent);
file_put_contents($templatePath, $templateContent);
}
// Fix link generation:
$linkPath = str_replace('imsmanifest.xml', 'models_html5/links.html', $file);
if (file_exists($linkPath) && is_file($linkPath)) {
$linkContent = file_get_contents($linkPath);
$find = [
':this.getAttribute("url")'
];
$replace = [
':"'.$proxyPath.'?type=link&src=" + this.getAttribute("url")'
];
$linkContent = str_replace($find, $replace, $linkContent);
file_put_contents($linkPath, $linkContent);
}
// Fix iframe generation
$framePath = str_replace('imsmanifest.xml', 'models_html5/embedDiv.html', $file);
if (file_exists($framePath) && is_file($framePath)) {
$content = file_get_contents($framePath);
$find = [
'$iFrameHolder.html(iFrameTag);'
];
$replace = [
'iFrameTag = \'<a target ="_blank" href="'.$proxyPath.'?type=link&src=\'+ pageSrc + \'">Open website. <img src="'.api_get_path(WEB_CODE_PATH).'img/link-external.png"></a>\'; $iFrameHolder.html(iFrameTag); '
];
$content = str_replace($find, $replace, $content);
file_put_contents($framePath, $content);
}
// Fix new window generation
$newWindowPath = str_replace('imsmanifest.xml', 'models_html5/newWindow.html', $file);
if (file_exists($newWindowPath) && is_file($newWindowPath)) {
$content = file_get_contents($newWindowPath);
$find = [
'var src = x_currentPageXML'
];
$replace = [
'var src = "'.$proxyPath.'?type=link&src=" + x_currentPageXML'
];
$content = str_replace($find, $replace, $content);
file_put_contents($newWindowPath, $content);
}
}
}
}
}
// TODO: Close the DOM handler.
return $this->manifest;
}
@ -527,28 +608,32 @@ class scorm extends learnpath
* @param string Current path (optional)
* @return string Absolute path to the imsmanifest.xml file or empty string on error
*/
public function import_local_package($file_path, $current_dir = '')
public function import_local_package($file_path, $currentDir = '')
{
// TODO: Prepare info as given by the $_FILES[''] vector.
$file_info = [];
$file_info['tmp_name'] = $file_path;
$file_info['name'] = basename($file_path);
$fileInfo = [];
$fileInfo['tmp_name'] = $file_path;
$fileInfo['name'] = basename($file_path);
// Call the normal import_package function.
return $this->import_package($file_info, $current_dir);
return $this->import_package($fileInfo, $currentDir);
}
/**
* Imports a zip file into the Chamilo structure
* @param string $zip_file_info Zip file info as given by $_FILES['userFile']
* @param string
* @param array
* @param string $zip_file_info Zip file info as given by $_FILES['userFile']
* @param string $current_dir
* @param array $courseInfo
* @param bool $updateDirContents
* @param learnpath $lpToCheck
*
* @return string $current_dir Absolute path to the imsmanifest.xml file or empty string on error
*/
public function import_package(
$zip_file_info,
$current_dir = '',
$courseInfo = []
$courseInfo = [],
$updateDirContents = false,
$lpToCheck = null
) {
if ($this->debug > 0) {
error_log('In scorm::import_package('.print_r($zip_file_info, true).',"'.$current_dir.'") method', 0);
@ -587,15 +672,12 @@ class scorm extends learnpath
}
$zipFile = new PclZip($zip_file_path);
// Check the zip content (real size and file extension).
$zipContentArray = $zipFile->listContent();
$package_type = '';
$at_root = false;
$manifest = '';
$manifest_list = [];
// The following loop should be stopped as soon as we found the right imsmanifest.xml (how to recognize it?).
$realFileSize = 0;
foreach ($zipContentArray as $thisContent) {
@ -656,6 +738,14 @@ class scorm extends learnpath
return false;
}
if ($updateDirContents && $lpToCheck) {
$originalPath = str_replace('/.', '', $lpToCheck->path);
if ($originalPath != $new_dir) {
Display::addFlash(Display::return_message(get_lang('FileError')));
return false;
}
}
// It happens on Linux that $new_dir sometimes doesn't start with '/'
if ($new_dir[0] != '/') {
$new_dir = '/'.$new_dir;
@ -760,7 +850,7 @@ class scorm extends learnpath
}
}
} else {
return '';
return false;
}
return $course_sys_dir.$new_dir.$manifest;

@ -54,7 +54,7 @@ if (empty($courseId)) {
$courseInfo = api_get_course_info_by_id($courseId);
if (!empty($courseInfo)) {
$form->addHidden('course_id', $courseId);
$form->addLabel(get_lang('Course'), $courseInfo['name']);
$form->addLabel(get_lang('Course'), $courseInfo['name'].' ('.$courseInfo['code'].')');
$exerciseList = ExerciseLib::get_all_exercises_for_course_id(
$courseInfo,
0,

@ -1653,6 +1653,37 @@ if ($allowMessages === true) {
$form->display();
}
$allow = api_get_configuration_value('allow_user_message_tracking');
if ($allow && api_is_drh() || api_is_platform_admin()) {
$users = MessageManager::getUsersThatHadConversationWithUser($student_id);
echo Display::page_subheader2(get_lang('MessageTracking'));
$table = new HTML_Table(['class' => 'table']);
$column = 0;
$row = 0;
$headers = [
get_lang('User')
];
foreach ($headers as $header) {
$table->setHeaderContents($row, $column, $header);
$column++;
}
$column = 0;
$row++;
foreach ($users as $userFollowed) {
$followedUserId = $userFollowed['user_id'];
$url = api_get_path(WEB_CODE_PATH).'tracking/messages.php?from_user='.$student_id.'&to_user='.$followedUserId;
$link = Display::url(
$userFollowed['complete_name'],
$url
);
$table->setCellContents($row, $column, $link);
$row++;
}
$table->display();
}
if ($export) {
ob_end_clean();
switch ($export) {
@ -1666,4 +1697,4 @@ if ($export) {
exit;
}
Display :: display_footer();
Display::display_footer();

@ -36,7 +36,7 @@ if (!api_is_allowed_to_edit()) {
}
// Getting the survey information
$survey_id = isset($_GET['survey_id']) ? intval($_GET['survey_id']) : null;
$survey_id = isset($_GET['survey_id']) ? (int) $_GET['survey_id'] : null;
$survey_data = SurveyManager::get_survey($survey_id);
// Additional information
@ -160,8 +160,20 @@ if (api_get_configuration_value('hide_survey_reporting_button')) {
$form->addElement('select', 'visible_results', get_lang('ResultsVisibility'), $visibleResults);
}
//$defaults['visible_results'] = 0;
$form->addElement('html_editor', 'survey_introduction', get_lang('SurveyIntroduction'), null, ['ToolbarSet' => 'Survey', 'Width' => '100%', 'Height' => '130', 'ToolbarStartExpanded' => false]);
$form->addElement('html_editor', 'survey_thanks', get_lang('SurveyThanks'), null, ['ToolbarSet' => 'Survey', 'Width' => '100%', 'Height' => '130', 'ToolbarStartExpanded' => false]);
$form->addElement(
'html_editor',
'survey_introduction',
get_lang('SurveyIntroduction'),
null,
['ToolbarSet' => 'Survey', 'Width' => '100%', 'Height' => '130', 'ToolbarStartExpanded' => false]
);
$form->addElement(
'html_editor',
'survey_thanks',
get_lang('SurveyThanks'),
null,
['ToolbarSet' => 'Survey', 'Width' => '100%', 'Height' => '130', 'ToolbarStartExpanded' => false]
);
$extraField = new ExtraField('survey');
$extraField->addElements($form, $survey_id);
@ -261,20 +273,17 @@ if (isset($_GET['action']) && $_GET['action'] == 'edit' && !empty($survey_id)) {
}
}
}
$form->addElement('html', '</div>');
}
}
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_SURVEY, $survey_id);
$form->addElement('html', '</div><br />');
if (isset($_GET['survey_id']) && $_GET['action'] == 'edit') {
$class = 'save';
$text = get_lang('ModifySurvey');
$form->addButtonUpdate(get_lang('ModifySurvey'), 'submit_survey');
} else {
$class = 'add';
$text = get_lang('CreateSurvey');
$form->addButtonCreate(get_lang('CreateSurvey'), 'submit_survey');
}
@ -293,6 +302,8 @@ $form->addRule(
'lte'
);
$defaults['skills'] = array_keys($skillList);
// Setting the default values
$form->setDefaults($defaults);
@ -302,13 +313,14 @@ if ($form->validate()) {
$values = $form->getSubmitValues();
// Storing the survey
$return = SurveyManager::store_survey($values);
Skill::saveSkills($form, ITEM_TYPE_SURVEY, $return['id']);
$values['item_id'] = $return['id'];
$extraFieldValue = new ExtraFieldValue('survey');
$extraFieldValue->saveFieldValues($values);
// Redirecting to the survey page (whilst showing the return message)
header('location: '.api_get_path(WEB_CODE_PATH).'survey/survey.php?survey_id='.$return['id'].'&'.api_get_cidreq());
header('Location: '.api_get_path(WEB_CODE_PATH).'survey/survey.php?survey_id='.$return['id'].'&'.api_get_cidreq());
exit;
} else {
// Displaying the header

@ -653,6 +653,8 @@ class SurveyManager
api_get_user_id()
);
Skill::deleteSkillsFromItem($survey_id, ITEM_TYPE_SURVEY);
return true;
}

@ -2688,7 +2688,7 @@ class SurveyUtil
if (api_get_configuration_value('allow_mandatory_survey')) {
$table->set_header(9, get_lang('IsMandatory'));
$table->set_header(10, get_lang('Modify'), false, 'width="150"');
$table->set_column_filter(9, 'anonymous_filter');
$table->set_column_filter(8, 'anonymous_filter');
$table->set_column_filter(10, 'modify_filter');
} else {
$table->set_header(9, get_lang('Modify'), false, 'width="150"');
@ -2726,8 +2726,6 @@ class SurveyUtil
$table->set_header(2, get_lang('SurveyCode'));
$table->set_header(3, get_lang('NumberOfQuestions'));
$table->set_header(4, get_lang('Author'));
//$table->set_header(5, get_lang('Language'));
//$table->set_header(6, get_lang('Shared'));
$table->set_header(5, get_lang('AvailableFrom'));
$table->set_header(6, get_lang('AvailableUntil'));
$table->set_header(7, get_lang('Invite'));
@ -2736,7 +2734,7 @@ class SurveyUtil
if (api_get_configuration_value('allow_mandatory_survey')) {
$table->set_header(9, get_lang('Modify'), false, 'width="130"');
$table->set_header(10, get_lang('Modify'), false, 'width="130"');
$table->set_column_filter(9, 'anonymous_filter');
$table->set_column_filter(8, 'anonymous_filter');
$table->set_column_filter(10, 'modify_filter_for_coach');
} else {
$table->set_header(9, get_lang('Modify'), false, 'width="130"');
@ -3032,6 +3030,7 @@ class SurveyUtil
ORDER BY col$column $direction
LIMIT $from,$number_of_items
";
$res = Database::query($sql);
$surveys = [];
$array = [];
@ -3067,9 +3066,8 @@ class SurveyUtil
api_get_path(WEB_CODE_PATH).'survey/survey_invitation.php?view=invited&survey_id='.$survey[0].'&'
.api_get_cidreq()
);
$array[8] = $survey[8];
// Anon
$array[8] = $survey['col8'];
if ($mandatoryAllowed) {
$efvMandatory = $efv->get_values_by_handler_and_field_variable(
$survey[9],
@ -3077,9 +3075,11 @@ class SurveyUtil
);
$array[9] = $efvMandatory ? $efvMandatory['value'] : 0;
$array[10] = $survey[9];
// Survey id
$array[10] = $survey['col9'];
} else {
$array[9] = $survey[9];
// Survey id
$array[9] = $survey['col9'];
}
if ($isDrh) {

@ -119,7 +119,7 @@ if ($form->validate()) {
updateWork($workData['iid'], $params, $courseInfo, $sessionId);
updatePublicationAssignment($workId, $params, $courseInfo, $groupId);
updateDirName($workData, $params['new_dir']);
Skill::saveSkills($form, ITEM_TYPE_STUDENT_PUBLICATION, $workData['iid']);
Display::addFlash(Display::return_message(get_lang('Updated'), 'success'));
header('Location: '.$currentUrl);
exit;

@ -162,12 +162,10 @@ if ((user_is_author($id) || $isDrhOfCourse || (api_is_allowed_to_edit() || api_i
$commentForm = getWorkCommentForm($work, $my_folder_data);
$tpl = new Template();
$tpl->assign('work', $work);
$tpl->assign('comments', $comments);
$actions = '';
if (isset($work['contains_file']) && !empty($work['contains_file'])) {
if (isset($work['download_url']) && !empty($work['download_url'])) {
$actions = Display::url(

@ -885,6 +885,8 @@ function deleteDirWork($id)
WHERE c_id = $course_id AND publication_id = $id";
Database::query($sql);
Skill::deleteSkillsFromItem($id, ITEM_TYPE_STUDENT_PUBLICATION);
Event::addEvent(
LOG_WORK_DIR_DELETE,
LOG_WORK_DATA,
@ -3590,6 +3592,7 @@ function getWorkCommentForm($work, $workParent)
}
}
Skill::addSkillsToUserForm($form, ITEM_TYPE_STUDENT_PUBLICATION, $workParent['id'], $work['user_id']);
$form->addHtmlEditor('comment', get_lang('Comment'), false);
$form->addFile('attachment', get_lang('Attachment'));
$form->addElement('hidden', 'id', $work['id']);
@ -4795,7 +4798,11 @@ function getFormWork($form, $defaults = [], $workId = 0)
</script>';
$form->addHtml('</div>');
$skillList = Skill::addSkillsToForm($form, ITEM_TYPE_STUDENT_PUBLICATION, $workId);
if (!empty($defaults)) {
$defaults['skills'] = array_keys($skillList);
$form->setDefaults($defaults);
}

@ -197,6 +197,8 @@ switch ($action) {
);
if ($result) {
Skill::saveSkills($form, ITEM_TYPE_STUDENT_PUBLICATION, $result);
$message = Display::return_message(get_lang('DirectoryCreated'), 'success');
} else {
$currentUrl = $addUrl;

@ -1,6 +1,8 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CourseBundle\Entity\CStudentPublication;
require_once __DIR__.'/../inc/global.inc.php';
$current_course_tool = TOOL_STUDENTPUBLICATION;
@ -10,19 +12,20 @@ require_once 'work.lib.php';
$this_section = SECTION_COURSES;
$workId = isset($_GET['id']) ? intval($_GET['id']) : null;
$courseInfo = api_get_course_info();
if (empty($workId)) {
if (empty($workId) || empty($courseInfo)) {
api_not_allowed(true);
}
$courseInfo = api_get_course_info();
// Student publications are saved with the iid in a LP
$origin = api_get_origin();
if ($origin == 'learnpath') {
$em = Database::getManager();
/** @var \Chamilo\CourseBundle\Entity\CStudentPublication $work */
$work = $em->getRepository('ChamiloCourseBundle:CStudentPublication')->find($workId);
/** @var CStudentPublication $work */
$work = $em->getRepository('ChamiloCourseBundle:CStudentPublication')->findOneBy(
['iid' => $workId, 'cId' => $courseInfo['real_id']]
);
if ($work) {
$workId = $work->getId();
}

Loading…
Cancel
Save