Merge branch '1.11.x' of github.com:chamilo/chamilo-lms into 1791

pull/2487/head
Yannick Warnier 9 years ago
commit dbd384b72e
  1. 9
      app/Resources/public/css/themes/silver_line/default.css
  2. 9
      documentation/changelog.html
  3. 70
      main/admin/settings.lib.php
  4. 7
      main/admin/settings.php
  5. 4
      main/exercise/TestCategory.php
  6. 1
      main/exercise/answer.class.php
  7. 104
      main/exercise/exercise.class.php
  8. 61
      main/exercise/exercise_submit.php
  9. 3
      main/exercise/question_list_admin.inc.php
  10. 9
      main/forum/index.php
  11. 2
      main/inc/introductionSection.inc.php
  12. 88
      main/inc/lib/api.lib.php
  13. 50
      main/inc/lib/course.lib.php
  14. 5
      main/inc/lib/course_home.lib.php
  15. 3
      main/inc/lib/myspace.lib.php
  16. 126
      main/inc/lib/template.lib.php
  17. 8
      main/inc/lib/usermanager.lib.php
  18. 5
      main/install/configuration.dist.php
  19. 112
      main/lp/learnpath.class.php
  20. 10
      main/lp/learnpathList.class.php
  21. 50
      main/lp/lp_subscribe_users_to_category.php
  22. 123
      main/survey/surveyUtil.class.php
  23. 10
      main/template/default/learnpath/view.tpl
  24. 483
      main/wiki/wiki.inc.php
  25. 49
      main/work/work.lib.php
  26. 4
      plugin/add_cas_login_button/plugin.php
  27. 8
      plugin/date/plugin.php
  28. 2
      plugin/ext_auth_chamilo_logout_button_behaviour/index.php
  29. 4
      plugin/follow_buttons/plugin.php
  30. 4
      plugin/openmeetings/lang/english.php
  31. 4
      plugin/openmeetings/lang/french.php
  32. 4
      plugin/openmeetings/lang/spanish.php
  33. 2
      plugin/openmeetings/lib/openmeetings_api.php
  34. 10
      plugin/pens/plugin.php
  35. 2
      plugin/share_buttons/plugin.php
  36. 4
      plugin/show_user_info/index.php
  37. 2
      plugin/show_user_info/lang/english.php
  38. 1
      plugin/vchamilo/install.php
  39. 4
      plugin/vchamilo/lang/english.php
  40. 6
      plugin/vchamilo/lib/Virtual.php
  41. 8
      plugin/vchamilo/views/editinstance_form.php
  42. 2
      src/Chamilo/CoreBundle/Component/Editor/CkEditor/Toolbar/Minimal.php
  43. 2
      src/Chamilo/CoreBundle/Component/Editor/CkEditor/Toolbar/TestFreeAnswer.php
  44. 10
      src/Chamilo/CoreBundle/Component/Editor/CkEditor/Toolbar/TestQuestionDescription.php
  45. 4
      src/Chamilo/CoreBundle/Component/Editor/CkEditor/Toolbar/UniqueAnswerImage.php
  46. 5
      src/Chamilo/CoreBundle/Component/Utils/ChamiloApi.php
  47. 5
      src/Chamilo/CourseBundle/Component/CourseCopy/CourseRestorer.php

@ -195,3 +195,12 @@ border-color: #444;
border: 1px solid #D3D3D3; border: 1px solid #D3D3D3;
box-shadow: none; box-shadow: none;
} }
.navbar-nav .open .dropdown-menu .user-header,
.navbar-nav .open .dropdown-menu .user-header a,
.navbar-nav .open .dropdown-menu .user-body a{
color: #FFF;
}
.navbar-nav .dropdown .dropdown-toggle
{
margin-top: 0;
}

@ -69,7 +69,12 @@
</ul> </ul>
<h3>Possibly breaking changes</h3> <h3>Possibly breaking changes</h3>
<ul> <ul>
<li>As Chamilo becomes more popular, we are facing new security-based challenges that come as consequences of the simplicity that we offer our users. As such, in this version of Chamilo, the administrator *must* enable a configuration setting as follows in order <b>to authorize teachers and students to use iframes</b> (embedding things from outside) inside the online text areas in their courses and personal spaces. to enable those, edit the app/config/configuration.php file and paste the following just after the last setting: <pre>$_configuration['allow_course_introduction_low_security'] = true;</pre></li> <li>As Chamilo becomes more popular, we are facing new security-based challenges that come as consequences of the simplicity
that we offer our users. As such, in this version of Chamilo, the administrator *must* enable a configuration setting as follows
in order <b>to authorize teachers and students to use iframes</b> (embedding things from outside) inside the online text areas in their courses and personal spaces.
To enable those, edit the app/config/configuration.php file and paste the following just after the last setting:
<pre>$_configuration['course_introduction_html_strict_filtering'] = false;</pre>
</li>
</ul> </ul>
<h3>Notable new Features</h3> <h3>Notable new Features</h3>
@ -83,7 +88,7 @@
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/e6faa0ee9f5ed69e715cf81f29e7b48a9cb1067b">e6faa0ee</a>) Add hide_main_navigation_menu setting.</li> <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/e6faa0ee9f5ed69e715cf81f29e7b48a9cb1067b">e6faa0ee</a>) Add hide_main_navigation_menu setting.</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/62083f65953eee0ffea5a7375e9258c7ae308396">62083f65</a> - <a href="https://task.beeznest.com/issues/11019">BT#11019</a> - <a href="https://github.com/chamilo/chamilo-lms/commit/0204752ed1c39a9f91c0a946377d1d4a5c057548">0204752e</a>) Add configuration "certificate_pdf_orientation"</li> <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/62083f65953eee0ffea5a7375e9258c7ae308396">62083f65</a> - <a href="https://task.beeznest.com/issues/11019">BT#11019</a> - <a href="https://github.com/chamilo/chamilo-lms/commit/0204752ed1c39a9f91c0a946377d1d4a5c057548">0204752e</a>) Add configuration "certificate_pdf_orientation"</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ffb966dbc2aafe0982c9c8b428cb2121234e2fb8">ffb966db</a> - <a href="https://support.chamilo.org/issues/12302">CT#12302</a>) Add setting "update_users_email_to_dummy_except_admins"</li> <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/ffb966dbc2aafe0982c9c8b428cb2121234e2fb8">ffb966db</a> - <a href="https://support.chamilo.org/issues/12302">CT#12302</a>) Add setting "update_users_email_to_dummy_except_admins"</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/5c5795fdfeff259aaa41e9282c6abed19b994711">5c5795fd</a> - <a href="https://task.beeznest.com/issues/12244">BT#12244</a>) Add configuration setting allow_course_introduction_low_security to allow course introduction html in low security for removeXSS</li> <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/5c5795fdfeff259aaa41e9282c6abed19b994711">5c5795fd</a> - <a href="https://task.beeznest.com/issues/12244">BT#12244</a>) Add configuration setting "course_introduction_html_strict_filtering" to allow course introduction html in low security for removeXSS</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/3a04f0d3812ed3e41a18e185cbf49e33193986ba">3a04f0d3</a>) Add setting "personal_agenda_show_all_session_events"</li> <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/3a04f0d3812ed3e41a18e185cbf49e33193986ba">3a04f0d3</a>) Add setting "personal_agenda_show_all_session_events"</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/632923da80723ac1a506614e39bc1982b2b177ee">632923da</a>) Add differentiation of sessions options based on limit_session_admin_role setting in admin homepage</li> <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/632923da80723ac1a506614e39bc1982b2b177ee">632923da</a>) Add differentiation of sessions options based on limit_session_admin_role setting in admin homepage</li>
<li>(<a href="https://github.com/chamilo/chamilo-lms/commit/bfdf62f0f2dfa1ad4c23d3cbfb6bbaf3b74dee97">bfdf62f0</a> - <a href="https://task.beeznest.com/issues/12162">BT#12162</a>) Learning paths: Add configuration setting show_prerequisite_as_blocked to show all prerequisites in gray</li> <li>(<a href="https://github.com/chamilo/chamilo-lms/commit/bfdf62f0f2dfa1ad4c23d3cbfb6bbaf3b74dee97">bfdf62f0</a> - <a href="https://task.beeznest.com/issues/12162">BT#12162</a>) Learning paths: Add configuration setting show_prerequisite_as_blocked to show all prerequisites in gray</li>

@ -332,15 +332,11 @@ function handleStylesheets()
} }
} }
// Submit stylesheets.
if (isset($_POST['save'])) {
storeStylesheets();
Display::display_normal_message(get_lang('Saved'));
}
// Current style. // Current style.
$selected = $currentStyle = api_get_setting('stylesheets'); $selected = $currentStyle = api_get_setting('stylesheets');
$styleFromDatabase = api_get_settings_params_simple(['variable = ?' => 'stylesheets']); $styleFromDatabase = api_get_settings_params_simple(
['variable = ? AND access_url = ?' => ['stylesheets', api_get_current_access_url_id()]]
);
if ($styleFromDatabase) { if ($styleFromDatabase) {
$selected = $currentStyle = $styleFromDatabase['selected_value']; $selected = $currentStyle = $styleFromDatabase['selected_value'];
} }
@ -349,8 +345,9 @@ function handleStylesheets()
$selected = $currentStyle = Security::remove_XSS($_POST['style']); $selected = $currentStyle = Security::remove_XSS($_POST['style']);
} }
$dir = api_get_path(SYS_PUBLIC_PATH).'css/themes/' . $selected . '/images/'; $themeDir = Template::getThemeDir($selected);
$url = api_get_path(WEB_CSS_PATH).'themes/' . $selected . '/images/'; $dir = api_get_path(SYS_PUBLIC_PATH).'css/'.$themeDir.'/images/';
$url = api_get_path(WEB_CSS_PATH).'/'.$themeDir.'/images/';
$logoFileName = 'header-logo.png'; $logoFileName = 'header-logo.png';
$newLogoFileName = 'header-logo-custom' . api_get_current_access_url_id() . '.png'; $newLogoFileName = 'header-logo-custom' . api_get_current_access_url_id() . '.png';
$webPlatformLogoPath = ChamiloApi::getWebPlatformLogoPath($selected); $webPlatformLogoPath = ChamiloApi::getWebPlatformLogoPath($selected);
@ -498,8 +495,13 @@ function uploadStylesheet($values, $picture)
$style_name = api_preg_replace('/[^A-Za-z0-9]/', '', $values['name_stylesheet']); $style_name = api_preg_replace('/[^A-Za-z0-9]/', '', $values['name_stylesheet']);
$cssToUpload = CSS_UPLOAD_PATH; $cssToUpload = CSS_UPLOAD_PATH;
// Create the folder if needed. // Check if a virtual instance vchamilo is used
$virtualInstanceTheme = api_get_configuration_value('virtual_css_theme_folder');
if (!empty($virtualInstanceTheme)) {
$cssToUpload = $cssToUpload.$virtualInstanceTheme.'/';
}
// Create the folder if needed.
if (!is_dir($cssToUpload.$style_name.'/')) { if (!is_dir($cssToUpload.$style_name.'/')) {
mkdir($cssToUpload.$style_name.'/', api_get_permissions_for_new_directories()); mkdir($cssToUpload.$style_name.'/', api_get_permissions_for_new_directories());
} }
@ -591,7 +593,12 @@ function uploadStylesheet($values, $picture)
if ($result) { if ($result) {
$fs = new Filesystem(); $fs = new Filesystem();
$fs->mirror($cssToUpload, api_get_path(SYS_PATH).'web/css/themes/'); $fs->mirror(
CSS_UPLOAD_PATH,
api_get_path(SYS_PATH).'web/css/themes/',
null,
['override' => true]
);
} }
return $result; return $result;
@ -687,18 +694,14 @@ function storeStylesheets()
/** /**
* This function checks if the given style is a recognize style that exists in the css directory as * This function checks if the given style is a recognize style that exists in the css directory as
* a standalone directory. * a standalone directory.
* @param string Style * @param string $style
* @return bool True if this style is recognized, false otherwise * @return bool True if this style is recognized, false otherwise
*/ */
function isStyle($style) function isStyle($style)
{ {
$dir = CSS_UPLOAD_PATH; $themeList = api_get_themes();
$dirs = scandir($dir);
$style = str_replace(array('/', '\\'), array('', ''), $style); // Avoid slashes or backslashes. return in_array($style, array_keys($themeList));
if (in_array($style, $dirs) && is_dir($dir.$style)) {
return true;
}
return false;
} }
/** /**
@ -1012,7 +1015,7 @@ function addEditTemplate()
$form->addElement('html_editor', 'template_text', get_lang('Text'), null, array('ToolbarSet' => 'AdminTemplates', 'Width' => '100%', 'Height' => '400')); $form->addElement('html_editor', 'template_text', get_lang('Text'), null, array('ToolbarSet' => 'AdminTemplates', 'Width' => '100%', 'Height' => '400'));
// Setting the form elements: the form to upload an image to be used with the template. // Setting the form elements: the form to upload an image to be used with the template.
$form->addElement('file','template_image',get_lang('Image'),''); $form->addElement('file', 'template_image', get_lang('Image'), '');
// Setting the form elements: a little bit information about the template image. // Setting the form elements: a little bit information about the template image.
$form->addElement('static', 'file_comment', '', get_lang('TemplateImageComment100x70')); $form->addElement('static', 'file_comment', '', get_lang('TemplateImageComment100x70'));
@ -1025,10 +1028,10 @@ function addEditTemplate()
$result = Database::query($sql); $result = Database::query($sql);
$row = Database::fetch_array($result); $row = Database::fetch_array($result);
$defaults['template_id'] = intval($_GET['id']); $defaults['template_id'] = intval($_GET['id']);
$defaults['template_text'] = $row['content']; $defaults['template_text'] = $row['content'];
// Forcing get_lang(). // Forcing get_lang().
$defaults['title'] = get_lang($row['title']); $defaults['title'] = get_lang($row['title']);
// Adding an extra field: a hidden field with the id of the template we are editing. // Adding an extra field: a hidden field with the id of the template we are editing.
$form->addElement('hidden', 'template_id'); $form->addElement('hidden', 'template_id');
@ -1055,7 +1058,6 @@ function addEditTemplate()
// if the form validates (complies to all rules) we save the information, else we display the form again (with error message if needed) // if the form validates (complies to all rules) we save the information, else we display the form again (with error message if needed)
if ($form->validate()) { if ($form->validate()) {
$check = Security::check_token('post'); $check = Security::check_token('post');
if ($check) { if ($check) {
// Exporting the values. // Exporting the values.
@ -1120,7 +1122,7 @@ function addEditTemplate()
displayTemplates(); displayTemplates();
} else { } else {
$token = Security::get_token(); $token = Security::get_token();
$form->addElement('hidden','sec_token'); $form->addElement('hidden', 'sec_token');
$form->setConstants(array('sec_token' => $token)); $form->setConstants(array('sec_token' => $token));
// Display the form. // Display the form.
$form->display(); $form->display();
@ -1638,10 +1640,10 @@ function getAllowedFileTypes()
*/ */
function setConfigurationSettingsInDatabase($parameters, $accessUrl) function setConfigurationSettingsInDatabase($parameters, $accessUrl)
{ {
$r = api_set_settings_category('Search', 'false', $accessUrl); api_set_settings_category('Search', 'false', $accessUrl);
// Save the settings. // Save the settings.
foreach ($parameters as $key => $value) { foreach ($parameters as $key => $value) {
$result = api_set_setting($key, $value, null, null); api_set_setting($key, $value, null, null);
} }
} }
@ -1667,7 +1669,6 @@ function showSearchToolsStatusTable()
//@todo windows support //@todo windows support
if (api_is_windows_os() == false) { if (api_is_windows_os() == false) {
$list_of_programs = array('pdftotext', 'ps2pdf', 'catdoc', 'html2text', 'unrtf', 'catppt', 'xls2csv'); $list_of_programs = array('pdftotext', 'ps2pdf', 'catdoc', 'html2text', 'unrtf', 'catppt', 'xls2csv');
foreach($list_of_programs as $program) { foreach($list_of_programs as $program) {
$output = []; $output = [];
$ret_val = null; $ret_val = null;
@ -1703,7 +1704,8 @@ function showSearchToolsStatusTable()
function generateCSSDownloadLink($style) function generateCSSDownloadLink($style)
{ {
$arch = api_get_path(SYS_ARCHIVE_PATH).$style.'.zip'; $arch = api_get_path(SYS_ARCHIVE_PATH).$style.'.zip';
$dir = api_get_path(SYS_CSS_PATH).'themes/'.$style; $themeDir = Template::getThemeDir($style);
$dir = api_get_path(SYS_CSS_PATH).$themeDir;
$check = Security::check_abs_path( $check = Security::check_abs_path(
$dir, $dir,
api_get_path(SYS_CSS_PATH).'themes' api_get_path(SYS_CSS_PATH).'themes'
@ -1721,16 +1723,18 @@ function generateCSSDownloadLink($style)
Display::addFlash(Display::return_message(get_lang('FileNotFound'), 'warning')); Display::addFlash(Display::return_message(get_lang('FileNotFound'), 'warning'));
} }
} }
/** /**
* Helper function to tell if the style is changeable in the current URL * Helper function to tell if the style is changeable in the current URL
* @return bool $changeable Whether the style can be changed in this URL or not * @return bool $changeable Whether the style can be changed in this URL or not
*/ */
function isStyleChangeable() { function isStyleChangeable()
global $_configuration; {
$changeable = false; $changeable = false;
if ($_configuration['access_url'] != 1) { $urlId = api_get_current_access_url_id();
if ($urlId) {
$style_info = api_get_settings('stylesheets', '', 1, 0); $style_info = api_get_settings('stylesheets', '', 1, 0);
$url_info = api_get_access_url($_configuration['access_url']); $url_info = api_get_access_url($urlId);
if ($style_info[0]['access_url_changeable'] == 1 && $url_info['active'] == 1) { if ($style_info[0]['access_url_changeable'] == 1 && $url_info['active'] == 1) {
$changeable = true; $changeable = true;
} }

@ -25,6 +25,12 @@ $_SESSION['this_section'] = $this_section;
// Access restrictions. // Access restrictions.
api_protect_admin_script(); api_protect_admin_script();
// Submit stylesheets.
if (isset($_POST['save']) && isset($_GET['category']) && $_GET['category'] === 'Stylesheets') {
storeStylesheets();
Display::addFlash(Display::return_message(get_lang('Saved')));
}
// Settings to avoid // Settings to avoid
$settings_to_avoid = array( $settings_to_avoid = array(
'use_session_mode' => 'true', 'use_session_mode' => 'true',
@ -468,7 +474,6 @@ foreach ($resultcategories as $row) {
$action_array[] = $url; $action_array[] = $url;
} }
ob_start(); ob_start();
if (!empty($_GET['category'])) { if (!empty($_GET['category'])) {
switch ($_GET['category']) { switch ($_GET['category']) {

@ -811,10 +811,6 @@ class TestCategory
return array(); return array();
} }
if (!$exercise->specialCategoryOrders) {
return false;
}
$courseId = (int) $courseId; $courseId = (int) $courseId;
$table = Database::get_course_table(TABLE_QUIZ_REL_CATEGORY); $table = Database::get_course_table(TABLE_QUIZ_REL_CATEGORY);
$categoryTable = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY); $categoryTable = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);

@ -944,7 +944,6 @@ class Answer
} }
} }
} }
} }
} }

@ -101,7 +101,6 @@ class Exercise
$this->text_when_finished = ''; $this->text_when_finished = '';
$this->display_category_name = 0; $this->display_category_name = 0;
$this->pass_percentage = ''; $this->pass_percentage = '';
$this->modelType = 1; $this->modelType = 1;
$this->questionSelectionType = EX_Q_SELECTION_ORDERED; $this->questionSelectionType = EX_Q_SELECTION_ORDERED;
$this->endButton = 0; $this->endButton = 0;
@ -122,6 +121,7 @@ class Exercise
* *
* @author Olivier Brouckaert * @author Olivier Brouckaert
* @param integer $id - exercise Id * @param integer $id - exercise Id
* @param bool $parseQuestionList
* *
* @return boolean - true if exercise exists, otherwise false * @return boolean - true if exercise exists, otherwise false
*/ */
@ -130,7 +130,7 @@ class Exercise
$TBL_EXERCISES = Database::get_course_table(TABLE_QUIZ_TEST); $TBL_EXERCISES = Database::get_course_table(TABLE_QUIZ_TEST);
$table_lp_item = Database::get_course_table(TABLE_LP_ITEM); $table_lp_item = Database::get_course_table(TABLE_LP_ITEM);
$id = intval($id); $id = (int)$id;
if (empty($this->course_id)) { if (empty($this->course_id)) {
return false; return false;
} }
@ -167,6 +167,7 @@ class Exercise
$this->review_answers = (isset($object->review_answers) && $object->review_answers == 1) ? true : false; $this->review_answers = (isset($object->review_answers) && $object->review_answers == 1) ? true : false;
$this->globalCategoryId = isset($object->global_category_id) ? $object->global_category_id : null; $this->globalCategoryId = isset($object->global_category_id) ? $object->global_category_id : null;
$this->questionSelectionType = isset($object->question_selection_type) ? $object->question_selection_type : null; $this->questionSelectionType = isset($object->question_selection_type) ? $object->question_selection_type : null;
$this->hideQuestionTitle = isset($object->hide_question_title) ? (int)$object->hide_question_title : 0;
$sql = "SELECT lp_id, max_score $sql = "SELECT lp_id, max_score
FROM $table_lp_item FROM $table_lp_item
@ -518,7 +519,7 @@ class Exercise
*/ */
public function setHideQuestionTitle($value) public function setHideQuestionTitle($value)
{ {
$this->hideQuestionTitle = intval($value); $this->hideQuestionTitle = (int)$value;
} }
/** /**
@ -534,7 +535,7 @@ class Exercise
*/ */
public function setScoreTypeModel($value) public function setScoreTypeModel($value)
{ {
$this->scoreTypeModel = intval($value); $this->scoreTypeModel = (int)$value;
} }
/** /**
@ -553,7 +554,7 @@ class Exercise
if (is_array($value) && isset($value[0])) { if (is_array($value) && isset($value[0])) {
$value = $value[0]; $value = $value[0];
} }
$this->globalCategoryId = intval($value); $this->globalCategoryId = (int)$value;
} }
/** /**
@ -945,11 +946,13 @@ class Exercise
true, true,
true true
); );
$questions_by_category = TestCategory::getQuestionsByCat( $questions_by_category = TestCategory::getQuestionsByCat(
$this->id, $this->id,
$question_list, $question_list,
$categoriesAddedInExercise $categoriesAddedInExercise
); );
$question_list = $this->pickQuestionsPerCategory( $question_list = $this->pickQuestionsPerCategory(
$categoriesAddedInExercise, $categoriesAddedInExercise,
$question_list, $question_list,
@ -1311,7 +1314,7 @@ class Exercise
*/ */
public function updateEndButton($value) public function updateEndButton($value)
{ {
$this->endButton = intval($value); $this->endButton = (int)$value;
} }
/** /**
@ -1888,7 +1891,14 @@ class Exercise
'2', '2',
array('id' => 'exerciseType_2') array('id' => 'exerciseType_2')
); );
$form->addGroup($radios_feedback, null, array(get_lang('FeedbackType'),get_lang('FeedbackDisplayOptions'))); $form->addGroup(
$radios_feedback,
null,
array(
get_lang('FeedbackType'),
get_lang('FeedbackDisplayOptions'),
)
);
// Type of results display on the final page // Type of results display on the final page
$radios_results_disabled = array(); $radios_results_disabled = array();
@ -1917,7 +1927,6 @@ class Exercise
array('id' => 'result_disabled_2') array('id' => 'result_disabled_2')
); );
$radios_results_disabled[] = $form->createElement( $radios_results_disabled[] = $form->createElement(
'radio', 'radio',
'results_disabled', 'results_disabled',
@ -2219,7 +2228,6 @@ class Exercise
] ]
); );
$form->addElement('html','</div>'); $form->addElement('html','</div>');
$form->addElement( $form->addElement(
'text', 'text',
'pass_percentage', 'pass_percentage',
@ -2376,8 +2384,6 @@ class Exercise
$element = $form->getElement($elementName); $element = $form->getElement($elementName);
$element->freeze(); $element->freeze();
} }
//$radioCatGroup->freeze();
} }
} }
@ -2583,7 +2589,6 @@ class Exercise
$this->search_engine_save(); $this->search_engine_save();
} }
} }
} }
function search_engine_delete() function search_engine_delete()
@ -2886,7 +2891,8 @@ class Exercise
$nbrQuestions = $this->get_count_question_list(); $nbrQuestions = $this->get_count_question_list();
$all_button = $html = $label = ''; $all_button = [];
$html = $label = '';
$hotspot_get = isset($_POST['hotspot']) ? Security::remove_XSS($_POST['hotspot']):null; $hotspot_get = isset($_POST['hotspot']) ? Security::remove_XSS($_POST['hotspot']):null;
if ($this->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT && $this->type == ONE_PER_PAGE) { if ($this->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT && $this->type == ONE_PER_PAGE) {
@ -2935,19 +2941,39 @@ class Exercise
if ($this->type == ONE_PER_PAGE) { if ($this->type == ONE_PER_PAGE) {
if ($questionNum != 1) { if ($questionNum != 1) {
$prev_question = $questionNum - 2; $prev_question = $questionNum - 2;
$all_button .= '<a href="javascript://" class="btn btn-default" onclick="previous_question_and_save('.$prev_question.', '.$question_id.' ); ">'.get_lang('PreviousQuestion').'</a>'; $all_button[] = Display::button(
'previous_question_and_save',
get_lang('PreviousQuestion'),
[
'type' => 'button',
'class' => 'btn btn-default',
'data-prev' => $prev_question,
'data-question' => $question_id
]
);
} }
//Next question //Next question
if (!empty($questions_in_media)) { if (!empty($questions_in_media)) {
$questions_in_media = "['".implode("','",$questions_in_media)."']"; $all_button[] = Display::button(
$all_button .= '&nbsp;<a href="javascript://" class="'.$class.'" onclick="save_question_list('.$questions_in_media.'); ">'.$label.'</a>'; 'save_question_list',
$label,
[
'type' => 'button',
'class' => $class,
'data-list' => implode(",", $questions_in_media)
]
);
} else { } else {
$all_button .= '&nbsp;<a href="javascript://" class="'.$class.'" onclick="save_now('.$question_id.', \'\', \''.$currentAnswer.'\'); ">'.$label.'</a>'; $all_button[] = Display::button(
'save_now',
$label,
['type' => 'button', 'class' => $class, 'data-question' => $question_id]
);
} }
$all_button .= '<span id="save_for_now_'.$question_id.'" class="exercise_save_mini_message"></span>&nbsp;'; $all_button[] = '<span id="save_for_now_'.$question_id.'" class="exercise_save_mini_message"></span>&nbsp;';
$html .= $all_button; $html .= implode(PHP_EOL, $all_button);
} else { } else {
if ($this->review_answers) { if ($this->review_answers) {
$all_label = get_lang('ReviewQuestions'); $all_label = get_lang('ReviewQuestions');
@ -2957,9 +2983,13 @@ class Exercise
$class = 'btn btn-warning'; $class = 'btn btn-warning';
} }
$class .= ' question-validate-btn'; // used to select it with jquery $class .= ' question-validate-btn'; // used to select it with jquery
$all_button = '&nbsp;<a href="javascript://" class="'.$class.'" onclick="validate_all(); ">'.$all_label.'</a>'; $all_button[] = Display::button(
$all_button .= '&nbsp;' . Display::span(null, ['id' => 'save_all_reponse']); 'validate_all',
$html .= $all_button; $all_label,
['type' => 'button', 'class' => $class]
);
$all_button[] = '&nbsp;' . Display::span(null, ['id' => 'save_all_reponse']);
$html .= implode(PHP_EOL, $all_button);
} }
} }
} }
@ -6934,18 +6964,36 @@ class Exercise
$exercise_actions .= $this->show_button($questionId, $current_question, null, $remindList); $exercise_actions .= $this->show_button($questionId, $current_question, null, $remindList);
break; break;
case ALL_ON_ONE_PAGE: case ALL_ON_ONE_PAGE:
$button = '<a href="javascript://" class="btn" onclick="save_now(\''.$questionId.'\', null, true, 1); ">'.get_lang('SaveForNow').'</a>'; $button = [
$button .= '<span id="save_for_now_'.$questionId.'" class="exercise_save_mini_message"></span>&nbsp;'; Display::button(
$exercise_actions .= Display::div($button, array('class'=>'exercise_save_now_button')); 'save_now',
get_lang('SaveForNow'),
['type' => 'button', 'class' => 'btn btn-primary', 'data-question' => $questionId]
),
'<span id="save_for_now_'.$questionId.'" class="exercise_save_mini_message"></span>'
];
$exercise_actions .= Display::div(
implode(PHP_EOL, $button),
array('class'=>'exercise_save_now_button')
);
break; break;
} }
if (!empty($questions_in_media)) { if (!empty($questions_in_media)) {
$count_of_questions_inside_media = count($questions_in_media); $count_of_questions_inside_media = count($questions_in_media);
if ($count_of_questions_inside_media > 1) { if ($count_of_questions_inside_media > 1) {
$button = '<a href="javascript://" class="btn" onclick="save_now(\''.$questionId.'\', false, false, 0); ">'.get_lang('SaveForNow').'</a>'; $button = [
$button .= '<span id="save_for_now_'.$questionId.'" class="exercise_save_mini_message"></span>&nbsp;'; Display::button(
$exercise_actions = Display::div($button, array('class'=>'exercise_save_now_button')); 'save_now',
get_lang('SaveForNow'),
['type' => 'button', 'class' => 'btn btn-primary', 'data-question' => $questionId]
),
'<span id="save_for_now_'.$questionId.'" class="exercise_save_mini_message"></span>&nbsp;'
];
$exercise_actions = Display::div(
implode(PHP_EOL, $button),
array('class'=>'exercise_save_now_button')
);
} }
if ($last_question_in_media && $this->type == ONE_PER_PAGE) { if ($last_question_in_media && $this->type == ONE_PER_PAGE) {

@ -974,6 +974,50 @@ if (!empty($error)) {
$(\'form#exercise_form\').prepend($(\'#exercise-description\')); $(\'form#exercise_form\').prepend($(\'#exercise-description\'));
}); });
$(document).on(\'ready\', function () {
$(\'button[name="previous_question_and_save"]\').on(\'click\', function (e) {
e.preventDefault();
e.stopPropagation();
var
$this = $(this),
previousId = parseInt($this.data(\'prev\')) || 0,
questionId = parseInt($this.data(\'question\')) || 0;
previous_question_and_save(previousId, questionId);
});
$(\'button[name="save_question_list"\').on(\'click\', function (e) {
e.preventDefault();
e.stopPropagation();
var
$this = $(this),
questionList = $this.data(\'list\').split(",");
save_question_list(questionList);
});
$(\'button[name="save_now"]\').on(\'click\', function (e) {
e.preventDefault();
e.stopPropagation();
var
$this = $(this),
questionId = parseInt($this.data(\'question\')) || 0,
urlExtra = $this.data(\'url\') || null;
save_now(questionId, urlExtra);
});
$(\'button[name="validate_all"]\').on(\'click\', function (e) {
e.preventDefault();
e.stopPropagation();
validate_all();
});
});
function previous_question(question_num) { function previous_question(question_num) {
url = "exercise_submit.php?'.$params.'&num="+question_num; url = "exercise_submit.php?'.$params.'&num="+question_num;
window.location = url; window.location = url;
@ -1064,7 +1108,6 @@ if (!empty($error)) {
$("#save_for_now_"+question_id).html(\'' . Display::return_icon('error.png', get_lang('Error'), array(), ICON_SIZE_SMALL) . '\'); $("#save_for_now_"+question_id).html(\'' . Display::return_icon('error.png', get_lang('Error'), array(), ICON_SIZE_SMALL) . '\');
} }
}); });
return false;
} }
function save_now_all(validate) { function save_now_all(validate) {
@ -1119,7 +1162,6 @@ if (!empty($error)) {
function validate_all() { function validate_all() {
save_now_all("validate"); save_now_all("validate");
return false;
} }
</script>'; </script>';
@ -1236,9 +1278,18 @@ if (!empty($error)) {
$exercise_actions .= $objExercise->show_button($questionId, $current_question); $exercise_actions .= $objExercise->show_button($questionId, $current_question);
break; break;
case ALL_ON_ONE_PAGE : case ALL_ON_ONE_PAGE :
$button = '<a href="javascript://" class="btn btn-info" onclick="save_now(\''.$questionId.'\'); ">'.get_lang('SaveForNow').'</a>'; $button = [
$button .= '<span id="save_for_now_'.$questionId.'"></span>&nbsp;'; Display::button(
$exercise_actions .= Display::div($button, array('class'=>'exercise_save_now_button')); 'save_now',
get_lang('SaveForNow'),
['type' => 'button', 'class' => 'btn btn-info', 'data-question' => $questionId]
),
'<span id="save_for_now_'.$questionId.'"></span>&nbsp;'
];
$exercise_actions .= Display::div(
implode(PHP_EOL, $button),
array('class'=>'exercise_save_now_button')
);
break; break;
} }

@ -192,10 +192,7 @@ if (!$inATest) {
//$questionList = $objExercise->getQuestionListWithMediasUncompressed(); //$questionList = $objExercise->getQuestionListWithMediasUncompressed();
// Show all questions no matter the category settings. // Show all questions no matter the category settings.
$tempCategoryOrder = isset($objExercise->specialCategoryOrders) ? $objExercise->specialCategoryOrders : false;
$objExercise->specialCategoryOrders = false;
$questionList = $objExercise->selectQuestionList(true, true); $questionList = $objExercise->selectQuestionList(true, true);
$objExercise->specialCategoryOrders = $tempCategoryOrder;
// Style for columns // Style for columns
$styleQuestion = "question"; $styleQuestion = "question";

@ -469,10 +469,13 @@ if (is_array($forumCategories)) {
$number_threads = isset($forum['number_of_threads']) ? (int) $forum['number_of_threads'] : 0; $number_threads = isset($forum['number_of_threads']) ? (int) $forum['number_of_threads'] : 0;
$number_posts = isset($forum['number_of_posts']) ? $forum['number_of_posts'] : 0; $number_posts = isset($forum['number_of_posts']) ? $forum['number_of_posts'] : 0;
$linkForum = api_get_path(WEB_CODE_PATH).'forum/viewforum.php?'.api_get_cidreq().'&gidReq='.$groupid.'&forum='.$forum['forum_id'];
$html .= '<div class="row">'; $html .= '<div class="row">';
$html .= '<div class="col-md-6">'; $html .= '<div class="col-md-6">';
$html .= '<div class="col-md-3">'; $html .= '<div class="col-md-3">';
$html .= '<div class="number-post">'.$forum_image.'<p>'.$number_threads.' ' . get_lang('ForumThreads') . '</p>' $html .= '<div class="number-post">'.Display::url($forum_image, $linkForum);
$html .= '<p>'.$number_threads.' ' . get_lang('ForumThreads') . '</p>'
. '</div>'; . '</div>';
$html .= '</div>'; $html .= '</div>';
@ -488,9 +491,7 @@ if (is_array($forumCategories)) {
'a', 'a',
$forum['forum_title'], $forum['forum_title'],
[ [
'href' => 'viewforum.php?' . api_get_cidreq() 'href' => $linkForum ,
. '&gidReq=' . intval($groupid)
. '&forum=' . intval($forum['forum_id']),
'class' => empty($forum['visibility']) ? 'text-muted' : null 'class' => empty($forum['visibility']) ? 'text-muted' : null
] ]
); );

@ -168,7 +168,7 @@ $userStatus = COURSEMANAGER;
// Allows to do a remove_XSS in course introduction with user status COURSEMANAGERLOWSECURITY // Allows to do a remove_XSS in course introduction with user status COURSEMANAGERLOWSECURITY
// in order to accept all embed type videos (like vimeo, wistia, etc) - see BT#12244 // in order to accept all embed type videos (like vimeo, wistia, etc) - see BT#12244
if (api_get_configuration_value('allow_course_introduction_low_security')) { if (api_get_configuration_value('course_introduction_html_strict_filtering')) {
$userStatus = COURSEMANAGERLOWSECURITY; $userStatus = COURSEMANAGERLOWSECURITY;
} }

@ -4260,7 +4260,8 @@ function api_get_language_from_type($lang_type)
* @param int $languageId * @param int $languageId
* @return array * @return array
*/ */
function api_get_language_info($languageId) { function api_get_language_info($languageId)
{
$language = Database::getManager() $language = Database::getManager()
->find('ChamiloCoreBundle:Language', intval($languageId)); ->find('ChamiloCoreBundle:Language', intval($languageId));
@ -4282,18 +4283,29 @@ function api_get_language_info($languageId) {
/** /**
* Returns the name of the visual (CSS) theme to be applied on the current page. * Returns the name of the visual (CSS) theme to be applied on the current page.
* The returned name depends on the platform, course or user -wide settings. * The returned name depends on the platform, course or user -wide settings.
* @return string The visual theme's name, it is the name of a folder inside .../chamilo/main/css/ * @return string The visual theme's name, it is the name of a folder inside web/css/themes
*/ */
function api_get_visual_theme() function api_get_visual_theme()
{ {
static $visual_theme; static $visual_theme;
if (!isset($visual_theme)) { if (!isset($visual_theme)) {
// Get style directly from DB
$platform_theme = api_get_setting('stylesheets'); $styleFromDatabase = api_get_settings_params_simple(
[
'variable = ? AND access_url = ?' => [
'stylesheets',
api_get_current_access_url_id(),
],
]
);
if ($styleFromDatabase) {
$platform_theme = $styleFromDatabase['selected_value'];
} else {
$platform_theme = api_get_setting('stylesheets');
}
// Platform's theme. // Platform's theme.
$visual_theme = $platform_theme; $visual_theme = $platform_theme;
if (api_get_setting('user_selected_theme') == 'true') { if (api_get_setting('user_selected_theme') == 'true') {
$user_info = api_get_user_info(); $user_info = api_get_user_info();
if (isset($user_info['theme'])) { if (isset($user_info['theme'])) {
@ -4348,32 +4360,46 @@ function api_get_visual_theme()
/** /**
* Returns a list of CSS themes currently available in the CSS folder * Returns a list of CSS themes currently available in the CSS folder
* The folder must have a default.css file
* @param bool $getOnlyThemeFromVirtualInstance Used by the vchamilo plugin
* @return array List of themes directories from the css folder * @return array List of themes directories from the css folder
* Note: Directory names (names of themes) in the file system should contain ASCII-characters only. * Note: Directory names (names of themes) in the file system should contain ASCII-characters only.
*/ */
function api_get_themes() function api_get_themes($getOnlyThemeFromVirtualInstance = false)
{ {
$cssdir = api_get_path(SYS_CSS_PATH) . 'themes/'; // This configuration value is set by the vchamilo plugin
$list = []; $virtualTheme = api_get_configuration_value('virtual_css_theme_folder');
if (is_dir($cssdir)) {
$themes = @scandir($cssdir); $readCssFolder = function ($dir) use ($virtualTheme) {
$finder = new \Symfony\Component\Finder\Finder();
$themes = $finder->directories()->in($dir)->depth(0)->sortByName();
$list = [];
/** @var Symfony\Component\Finder\SplFileInfo $theme */
foreach ($themes as $theme) {
$folder = $theme->getFilename();
// A theme folder is consider if there's a default.css file
if (!file_exists($theme->getPathname().'/default.css')) {
continue;
}
$name = ucwords(str_replace('_', ' ', $folder));
if ($folder == $virtualTheme) {
continue;
}
$list[$folder] = $name;
}
return $list;
};
if (is_array($themes)) { $dir = api_get_path(SYS_CSS_PATH).'themes/';
if ($themes !== false) { $list = $readCssFolder($dir);
sort($themes);
foreach ($themes as & $theme) { if (!empty($virtualTheme)) {
if (substr($theme, 0, 1) == '.') { $newList = $readCssFolder($dir.'/'.$virtualTheme);
continue; if ($getOnlyThemeFromVirtualInstance) {
} else { return $newList;
if (is_dir($cssdir.$theme)) {
$name = ucwords(str_replace('_', ' ', $theme));
$list[$theme] = $name;
}
}
}
}
} }
$list = $list + $newList;
asort($list);
} }
return $list; return $list;
@ -7165,8 +7191,9 @@ function api_get_password_checker_js($usernameInputId, $passwordInputId)
} }
/** /**
* @param string $username
* create an user extra field called 'captcha_blocked_until_date' * create an user extra field called 'captcha_blocked_until_date'
* @param string $username
* @return bool
*/ */
function api_block_account_captcha($username) function api_block_account_captcha($username)
{ {
@ -7181,10 +7208,12 @@ function api_block_account_captcha($username)
'captcha_blocked_until_date', 'captcha_blocked_until_date',
api_get_utc_datetime($time) api_get_utc_datetime($time)
); );
return true;
} }
/** /**
* @param string $username * @param string $username
* @return bool
*/ */
function api_clean_account_captcha($username) function api_clean_account_captcha($username)
{ {
@ -7198,6 +7227,7 @@ function api_clean_account_captcha($username)
'captcha_blocked_until_date', 'captcha_blocked_until_date',
null null
); );
return true;
} }
/** /**
@ -7243,7 +7273,8 @@ function api_get_short_text_from_html($in_html, $in_number_char)
* @return string * @return string
* @author hubert borderiou * @author hubert borderiou
*/ */
function api_remove_tags_with_space($in_html, $in_double_quote_replace = true) { function api_remove_tags_with_space($in_html, $in_double_quote_replace = true)
{
$out_res = $in_html; $out_res = $in_html;
if ($in_double_quote_replace) { if ($in_double_quote_replace) {
$out_res = str_replace('"', "''", $out_res); $out_res = str_replace('"', "''", $out_res);
@ -7318,7 +7349,6 @@ function api_can_login_as($loginAsUserId, $userId = null)
} }
$userInfo = api_get_user_info($userId); $userInfo = api_get_user_info($userId);
$isDrh = function() use($loginAsUserId) { $isDrh = function() use($loginAsUserId) {
if (api_is_drh()) { if (api_is_drh()) {
if (api_drh_can_access_all_session_content()) { if (api_drh_can_access_all_session_content()) {
@ -7466,6 +7496,10 @@ function api_warn_hosting_contact($limitName)
/** /**
* Gets value of a variable from app/config/configuration.php * Gets value of a variable from app/config/configuration.php
* Variables that are not set in the configuration.php file but set elsewhere:
* - virtual_css_theme_folder (vchamilo plugin)
* - access_url (global.inc.php)
*
* @param string $variable * @param string $variable
* *
* @return bool|mixed * @return bool|mixed

@ -3259,27 +3259,27 @@ class CourseManager
$direction = null, $direction = null,
$getCount = false, $getCount = false,
$keyword = null, $keyword = null,
$sessionId = null, $sessionId = 0,
$showAllAssignedCourses = false $showAllAssignedCourses = false
) { ) {
// Database Table Definitions // Database Table Definitions
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE); $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
$tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
$tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
$sessionId = intval($sessionId); $sessionId = (int)$sessionId;
$user_id = intval($user_id); $user_id = (int)$user_id;
$select = "SELECT DISTINCT *, c.id as real_id "; $select = "SELECT DISTINCT *, c.id as real_id ";
if ($getCount) { if ($getCount) {
$select = "SELECT COUNT(DISTINCT c.id) as count"; $select = "SELECT COUNT(DISTINCT c.id) as count";
} }
$whereConditions = null; $whereConditions = '';
switch ($status) { switch ($status) {
case COURSEMANAGER: case COURSEMANAGER:
$whereConditions .= " AND cru.user_id = '$user_id'"; $whereConditions .= " AND cru.user_id = '$user_id'";
if (!$showAllAssignedCourses) { if (!$showAllAssignedCourses) {
$whereConditions .= " AND status = " . COURSEMANAGER; $whereConditions .= " AND cru.status = " . COURSEMANAGER;
} else { } else {
$whereConditions .= " AND relation_type = " . COURSE_RELATION_TYPE_COURSE_MANAGER; $whereConditions .= " AND relation_type = " . COURSE_RELATION_TYPE_COURSE_MANAGER;
} }
@ -3287,7 +3287,7 @@ class CourseManager
case DRH: case DRH:
$whereConditions .= " AND $whereConditions .= " AND
cru.user_id = '$user_id' AND cru.user_id = '$user_id' AND
status = " . DRH . " AND cru.status = " . DRH . " AND
relation_type = '" . COURSE_RELATION_TYPE_RRHH . "' relation_type = '" . COURSE_RELATION_TYPE_RRHH . "'
"; ";
break; break;
@ -3303,27 +3303,35 @@ class CourseManager
$extraInnerJoin = null; $extraInnerJoin = null;
if (!empty($sessionId)) { if (!empty($sessionId)) {
if (!empty($sessionId)) { if ($status == COURSEMANAGER) {
$courseList = SessionManager::get_course_list_by_session_id( // Teacher of course or teacher inside session
$sessionId $whereConditions = " AND (cru.status = " . COURSEMANAGER." OR srcru.status = 2) ";
); }
if (!empty($courseList)) { $courseList = SessionManager::get_course_list_by_session_id(
$courseListToString = implode("','", array_keys($courseList)); $sessionId
$whereConditions .= " AND c.id IN ('" . $courseListToString . "')"; );
} if (!empty($courseList)) {
$tableSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE); $courseListToString = implode("','", array_keys($courseList));
$orderBy = ' ORDER BY position'; $whereConditions .= " AND c.id IN ('" . $courseListToString . "')";
$extraInnerJoin = " INNER JOIN $tableSessionRelCourse src
ON (c.id = src.c_id AND session_id = $sessionId) ";
} }
$tableSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
$tableSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
$orderBy = ' ORDER BY position';
$extraInnerJoin = " INNER JOIN $tableSessionRelCourse src
ON (c.id = src.c_id AND src.session_id = $sessionId)
INNER JOIN $tableSessionRelCourseRelUser srcru
ON (src.session_id = srcru.session_id AND srcru.c_id = src.c_id)
";
} }
$whereConditions .= $keywordCondition; $whereConditions .= $keywordCondition;
$sql = "$select $sql = "$select
FROM $tbl_course c FROM $tbl_course c
INNER JOIN $tbl_course_rel_user cru ON (cru.c_id = c.id) INNER JOIN $tbl_course_rel_user cru
INNER JOIN $tbl_course_rel_access_url a ON (a.c_id = c.id) ON (cru.c_id = c.id)
$extraInnerJoin INNER JOIN $tbl_course_rel_access_url a
ON (a.c_id = c.id)
$extraInnerJoin
WHERE WHERE
access_url_id = " . api_get_current_access_url_id() . " access_url_id = " . api_get_current_access_url_id() . "
$whereConditions $whereConditions

@ -1265,6 +1265,11 @@ class CourseHome
*/ */
public static function show_navigation_tool_shortcuts($orientation = SHORTCUTS_HORIZONTAL) public static function show_navigation_tool_shortcuts($orientation = SHORTCUTS_HORIZONTAL)
{ {
$origin = api_get_origin();
if ($origin === 'learnpath') {
return '';
}
$navigation_items = self::get_navigation_items(false); $navigation_items = self::get_navigation_items(false);
$html = ''; $html = '';
if (!empty($navigation_items)) { if (!empty($navigation_items)) {

@ -1869,7 +1869,6 @@ class MySpace
*/ */
public static function get_user_data_tracking_overview($from, $numberItems, $column, $direction) public static function get_user_data_tracking_overview($from, $numberItems, $column, $direction)
{ {
$conditions = [];
$isWestern = api_is_western_name_order(); $isWestern = api_is_western_name_order();
switch ($column) { switch ($column) {
case '0': case '0':
@ -1892,7 +1891,7 @@ class MySpace
$order = [ $order = [
"$column $direction" "$column $direction"
]; ];
$userList = UserManager::get_user_list($conditions, $order, $from, $numberItems); $userList = UserManager::get_user_list([], $order, $from, $numberItems);
$return = []; $return = [];
foreach ($userList as $user) { foreach ($userList as $user) {
$firstPosition = $user['lastname']; $firstPosition = $user['lastname'];

@ -22,6 +22,7 @@ class Template
* @var string * @var string
*/ */
public $theme = ''; public $theme = '';
private $themeDir;
/** /**
* @var string * @var string
@ -480,21 +481,42 @@ class Template
$this->assign('_u', $user_info); $this->assign('_u', $user_info);
} }
/**
* Get theme dir
* @param string $theme
* @return string
*/
public static function getThemeDir($theme)
{
$themeDir = 'themes/'.$theme.'/';
$virtualTheme = api_get_configuration_value('virtual_css_theme_folder');
if (!empty($virtualTheme)) {
$virtualThemeList = api_get_themes(true);
$isVirtualTheme = in_array($theme, array_keys($virtualThemeList));
if ($isVirtualTheme) {
$themeDir = 'themes/'.$virtualTheme.'/'.$theme.'/';
}
}
return $themeDir;
}
/** /**
* Set system parameters * Set system parameters
*/ */
private function set_system_parameters() private function set_system_parameters()
{ {
global $_configuration;
$this->theme = api_get_visual_theme(); $this->theme = api_get_visual_theme();
//Setting app paths/URLs $this->themeDir = self::getThemeDir($this->theme);
// Setting app paths/URLs
$_p = array( $_p = array(
'web' => api_get_path(WEB_PATH), 'web' => api_get_path(WEB_PATH),
'web_relative' => api_get_path(REL_PATH), 'web_relative' => api_get_path(REL_PATH),
'web_course' => api_get_path(WEB_COURSE_PATH), 'web_course' => api_get_path(WEB_COURSE_PATH),
'web_main' => api_get_path(WEB_CODE_PATH), 'web_main' => api_get_path(WEB_CODE_PATH),
'web_css' => api_get_path(WEB_CSS_PATH), 'web_css' => api_get_path(WEB_CSS_PATH),
'web_css_theme' => api_get_path(WEB_CSS_PATH) . 'themes/' . $this->theme . '/', 'web_css_theme' => api_get_path(WEB_CSS_PATH) . $this->themeDir,
'web_ajax' => api_get_path(WEB_AJAX_PATH), 'web_ajax' => api_get_path(WEB_AJAX_PATH),
'web_img' => api_get_path(WEB_IMG_PATH), 'web_img' => api_get_path(WEB_IMG_PATH),
'web_plugin' => api_get_path(WEB_PLUGIN_PATH), 'web_plugin' => api_get_path(WEB_PLUGIN_PATH),
@ -507,10 +529,10 @@ class Template
); );
$this->assign('_p', $_p); $this->assign('_p', $_p);
//Here we can add system parameters that can be use in any template // Here we can add system parameters that can be use in any template
$_s = array( $_s = array(
'software_name' => $_configuration['software_name'], 'software_name' => api_get_configuration_value('software_name'),
'system_version' => $_configuration['system_version'], 'system_version' => api_get_configuration_value('system_version'),
'site_name' => api_get_setting('siteName'), 'site_name' => api_get_setting('siteName'),
'institution' => api_get_setting('Institution'), 'institution' => api_get_setting('Institution'),
'date' => api_format_date('now', DATE_FORMAT_LONG), 'date' => api_format_date('now', DATE_FORMAT_LONG),
@ -529,7 +551,6 @@ class Template
{ {
global $disable_js_and_css_files; global $disable_js_and_css_files;
$css = array(); $css = array();
$this->theme = api_get_visual_theme(); $this->theme = api_get_visual_theme();
if (!empty($this->preview_theme)) { if (!empty($this->preview_theme)) {
@ -559,11 +580,7 @@ class Template
if (api_is_global_chat_enabled()) { if (api_is_global_chat_enabled()) {
$css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/chat/css/chat.css'; $css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/chat/css/chat.css';
} }
$css_file_to_string = '';
//THEME CSS STYLE
// $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'responsive.css');
$css_file_to_string = null;
foreach ($css as $file) { foreach ($css as $file) {
$css_file_to_string .= api_get_css($file); $css_file_to_string .= api_get_css($file);
} }
@ -579,8 +596,8 @@ class Template
public function setCSSEditor() public function setCSSEditor()
{ {
$cssEditor = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'editor.css'); $cssEditor = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'editor.css');
if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/editor.css')) { if (is_file(api_get_path(SYS_CSS_PATH).$this->themeDir.'editor.css')) {
$cssEditor = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/editor.css'; $cssEditor = api_get_path(WEB_CSS_PATH).$this->themeDir.'editor.css';
} }
$this->assign('cssEditor', $cssEditor); $this->assign('cssEditor', $cssEditor);
@ -595,23 +612,22 @@ class Template
{ {
global $disable_js_and_css_files; global $disable_js_and_css_files;
// Base CSS // Base CSS
$css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'base.css'); $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'base.css');
if ($this->show_learnpath) { if ($this->show_learnpath) {
$css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'scorm.css'); $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'scorm.css');
if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/learnpath.css')) { if (is_file(api_get_path(SYS_CSS_PATH).$this->themeDir.'learnpath.css')) {
$css[] = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/learnpath.css'; $css[] = api_get_path(WEB_CSS_PATH).$this->themeDir.'learnpath.css';
} }
} }
if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/editor.css')) { if (is_file(api_get_path(SYS_CSS_PATH).$this->themeDir.'editor.css')) {
$css[] = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/editor.css'; $css[] = api_get_path(WEB_CSS_PATH).$this->themeDir.'editor.css';
}else{ } else {
$css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'editor.css'); $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'editor.css');
} }
$css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/default.css'); $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).$this->themeDir.'default.css');
$css_file_to_string = null; $css_file_to_string = null;
foreach ($css as $file) { foreach ($css as $file) {
@ -642,8 +658,10 @@ class Template
$style_print = ''; $style_print = '';
if (is_readable(api_get_path(SYS_CSS_PATH).$this->theme.'/print.css')) { if (is_readable(api_get_path(SYS_CSS_PATH).$this->theme.'/print.css')) {
$style_print = api_get_css(api_get_cdn_path(api_get_path(WEB_CSS_PATH) . $this->theme . '/print.css'), $style_print = api_get_css(
'print'); api_get_cdn_path(api_get_path(WEB_CSS_PATH).$this->theme.'/print.css'),
'print'
);
} }
$this->assign('css_style_print', $style_print); $this->assign('css_style_print', $style_print);
} }
@ -801,7 +819,7 @@ class Template
} }
$this->assign( $this->assign(
'online_button', 'online_button',
Display::return_icon('statusonline.png', null, [], ICON_SIZE_ATOM) Display::return_icon('statusonline.png', null, [], ICON_SIZE_ATOM)
); );
$this->assign( $this->assign(
@ -865,28 +883,29 @@ class Template
$this->assign('text_direction', api_get_text_direction()); $this->assign('text_direction', api_get_text_direction());
$this->assign('section_name', 'section-'.$this_section); $this->assign('section_name', 'section-'.$this_section);
//Defaul root chamilo favicon // Default root chamilo favicon
$favico = '<link rel="shortcut icon" href="' . api_get_path(WEB_PATH) . 'favicon.ico" type="image/x-icon" />'; $favico = '<link rel="shortcut icon" href="'.api_get_path(WEB_PATH).'favicon.ico" type="image/x-icon" />';
//Added to verify if in the current Chamilo Theme exist a favicon //Added to verify if in the current Chamilo Theme exist a favicon
$favicoThemeUrl = api_get_path(SYS_CSS_PATH) . 'themes/' . $this->theme . '/images/'; $favicoThemeUrl = api_get_path(SYS_CSS_PATH).$this->themeDir.'images/';
//If exist pick the current chamilo theme favicon //If exist pick the current chamilo theme favicon
if (is_file($favicoThemeUrl . 'favicon.ico')) { if (is_file($favicoThemeUrl.'favicon.ico')) {
$favico = '<link rel="shortcut icon" href="' . api_get_path(WEB_CSS_PATH). 'themes/' . $this->theme . '/images/favicon.ico" type="image/x-icon" />'; $favico = '<link rel="shortcut icon" href="'.api_get_path(WEB_CSS_PATH).$this->themeDir.'images/favicon.ico" type="image/x-icon" />';
} }
if (api_is_multiple_url_enabled()) { if (api_is_multiple_url_enabled()) {
$access_url_id = api_get_current_access_url_id(); $access_url_id = api_get_current_access_url_id();
if ($access_url_id != -1) { if ($access_url_id != -1) {
$url_info = api_get_access_url($access_url_id); $url_info = api_get_access_url($access_url_id);
$url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $url_info['url'])); $url = api_remove_trailing_slash(
preg_replace('/https?:\/\//i', '', $url_info['url'])
);
$clean_url = api_replace_dangerous_char($url); $clean_url = api_replace_dangerous_char($url);
$clean_url = str_replace('/', '-', $clean_url); $clean_url = str_replace('/', '-', $clean_url);
$clean_url .= '/'; $clean_url .= '/';
$homep = api_get_path(REL_PATH).'home/'.$clean_url; //homep for Home Path $homep = api_get_path(REL_PATH).'home/'.$clean_url; //homep for Home Path
$icon_real_homep = api_get_path(SYS_APP_PATH).'home/'.$clean_url; $icon_real_homep = api_get_path(SYS_APP_PATH).'home/'.$clean_url;
//we create the new dir for the new sites //we create the new dir for the new sites
if (is_file($icon_real_homep.'favicon.ico')) { if (is_file($icon_real_homep.'favicon.ico')) {
$favico = '<link rel="shortcut icon" href="'.$homep.'favicon.ico" type="image/x-icon" />'; $favico = '<link rel="shortcut icon" href="'.$homep.'favicon.ico" type="image/x-icon" />';
@ -899,18 +918,28 @@ class Template
//@todo move this in the template //@todo move this in the template
$rightFloatMenu = ''; $rightFloatMenu = '';
$iconBug = Display::return_icon('bug.png', get_lang('ReportABug'), [], ICON_SIZE_LARGE); $iconBug = Display::return_icon(
'bug.png',
get_lang('ReportABug'),
[],
ICON_SIZE_LARGE
);
if (api_get_setting('show_link_bug_notification') == 'true' && $this->user_is_logged_in) { if (api_get_setting('show_link_bug_notification') == 'true' && $this->user_is_logged_in) {
$rightFloatMenu = '<div class="report"> $rightFloatMenu = '<div class="report">
<a href="https://github.com/chamilo/chamilo-lms/wiki/How-to-report-issues" target="_blank"> <a href="https://github.com/chamilo/chamilo-lms/wiki/How-to-report-issues" target="_blank">
'. $iconBug . ' '.$iconBug.'
</a> </a>
</div>'; </div>';
} }
if (api_get_setting('show_link_ticket_notification') == 'true' && $this->user_is_logged_in) { if (api_get_setting('show_link_ticket_notification') == 'true' && $this->user_is_logged_in) {
// by default is project_id = 1 // by default is project_id = 1
$iconTicket = Display::return_icon('bug.png', get_lang('Ticket'), [], ICON_SIZE_LARGE); $iconTicket = Display::return_icon(
'bug.png',
get_lang('Ticket'),
[],
ICON_SIZE_LARGE
);
$courseInfo = api_get_course_info(); $courseInfo = api_get_course_info();
$courseParams = ''; $courseParams = '';
if (!empty($courseInfo)) { if (!empty($courseInfo)) {
@ -919,7 +948,7 @@ class Template
$url = api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id=1&'.$courseParams; $url = api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id=1&'.$courseParams;
$rightFloatMenu .= '<div class="report"> $rightFloatMenu .= '<div class="report">
<a href="'.$url.'" target="_blank"> <a href="'.$url.'" target="_blank">
'. $iconTicket . ' '.$iconTicket.'
</a> </a>
</div>'; </div>';
} }
@ -950,10 +979,10 @@ class Template
//Profile link //Profile link
if (api_get_setting('allow_social_tool') == 'true') { if (api_get_setting('allow_social_tool') == 'true') {
$profile_url = api_get_path(WEB_CODE_PATH).'social/home.php'; $profile_url = api_get_path(WEB_CODE_PATH).'social/home.php';
} else { } else {
$profile_url = api_get_path(WEB_CODE_PATH).'auth/profile.php'; $profile_url = api_get_path(WEB_CODE_PATH).'auth/profile.php';
} }
@ -961,9 +990,9 @@ class Template
//Message link //Message link
$message_link = null; $message_link = null;
$message_url = null; $message_url = null;
if (api_get_setting('allow_message_tool') == 'true') { if (api_get_setting('allow_message_tool') == 'true') {
$message_url = api_get_path(WEB_CODE_PATH).'messages/inbox.php'; $message_url = api_get_path(WEB_CODE_PATH).'messages/inbox.php';
$message_link = '<a href="'.api_get_path(WEB_CODE_PATH).'messages/inbox.php">'.get_lang('Inbox').'</a>'; $message_link = '<a href="'.api_get_path(WEB_CODE_PATH).'messages/inbox.php">'.get_lang('Inbox').'</a>';
} }
$this->assign('message_link', $message_link); $this->assign('message_link', $message_link);
@ -991,8 +1020,15 @@ class Template
$menu = menuArray(); $menu = menuArray();
$this->assign('menu', $menu); $this->assign('menu', $menu);
// Block Breadcrumb $breadcrumb = '';
$breadcrumb = return_breadcrumb($interbreadcrumb, $language_file, $nameTools); // Hide breadcrumb in LP
if ($this->show_learnpath == false) {
$breadcrumb = return_breadcrumb(
$interbreadcrumb,
$language_file,
$nameTools
);
}
$this->assign('breadcrumb', $breadcrumb); $this->assign('breadcrumb', $breadcrumb);
//Extra content //Extra content

@ -1377,7 +1377,6 @@ class UserManager
public static function get_user_list_by_ids($ids = array(), $active = null, $order = null, $limit = null) public static function get_user_list_by_ids($ids = array(), $active = null, $order = null, $limit = null)
{ {
if (empty($ids)) { if (empty($ids)) {
return array(); return array();
} }
@ -1419,8 +1418,8 @@ class UserManager
* @todo security filter order by * @todo security filter order by
*/ */
public static function get_user_list( public static function get_user_list(
$conditions = array(), $conditions = [],
$order_by = array(), $order_by = [],
$limit_from = false, $limit_from = false,
$limit_to = false $limit_to = false
) { ) {
@ -1439,9 +1438,10 @@ class UserManager
foreach ($conditions as $field => $value) { foreach ($conditions as $field => $value) {
$field = Database::escape_string($field); $field = Database::escape_string($field);
$value = Database::escape_string($value); $value = Database::escape_string($value);
$sql .= "$field = '$value'"; $sql .= " AND $field = '$value'";
} }
} }
if (count($order_by) > 0) { if (count($order_by) > 0) {
$sql .= ' ORDER BY '.Database::escape_string(implode(',', $order_by), null, false); $sql .= ' ORDER BY '.Database::escape_string(implode(',', $order_by), null, false);
} }

@ -282,8 +282,9 @@ $_configuration['system_stable'] = NEW_VERSION_STABLE;
//$_configuration['personal_agenda_show_all_session_events'] = false; //$_configuration['personal_agenda_show_all_session_events'] = false;
// Allows to redirect to the session after the inscription in session about // Allows to redirect to the session after the inscription in session about
// $_configuration['allow_redirect_to_session_after_inscription_about'] = false; // $_configuration['allow_redirect_to_session_after_inscription_about'] = false;
// Allows to do a remove_XSS in course introduction with user status COURSEMANAGERLOWSECURITY in order to accept all embed type videos (like vimeo, wistia, etc) // Allows to do a remove_XSS in course introduction with user status COURSEMANAGERLOWSECURITY
// $_configuration['allow_course_introduction_low_security'] = false; // in order to accept all embed type videos (like vimeo, wistia, etc)
// $_configuration['course_introduction_html_strict_filtering'] = true;
// Prevents the duplicate upload in assignments // Prevents the duplicate upload in assignments
// $_configuration['assignment_prevent_duplicate_upload'] = false; // $_configuration['assignment_prevent_duplicate_upload'] = false;
// Set ConsideredWorkingTime work extra field variable from main/admin/extra_fields.php?type=work // Set ConsideredWorkingTime work extra field variable from main/admin/extra_fields.php?type=work

@ -8,6 +8,7 @@ use Chamilo\CourseBundle\Component\CourseCopy\CourseRestorer;
use Gedmo\Sortable\Entity\Repository\SortableRepository; use Gedmo\Sortable\Entity\Repository\SortableRepository;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder; use Symfony\Component\Finder\Finder;
use Chamilo\CourseBundle\Entity\CLp;
/** /**
* Class learnpath * Class learnpath
@ -4825,27 +4826,31 @@ class learnpath
*/ */
public function set_expired_on($expired_on) public function set_expired_on($expired_on)
{ {
$course_id = api_get_course_int_id();
if ($this->debug > 0) { if ($this->debug > 0) {
error_log('New LP - In learnpath::set_expired_on()', 0); error_log('New LP - In learnpath::set_expired_on()', 0);
} }
if (!empty($expired_on)) { $em = Database::getManager();
$this->expired_on = api_get_utc_datetime($expired_on); /** @var CLp $lp */
} else { $lp = $em
$this->expired_on = null; ->getRepository('ChamiloCourseBundle:CLp')
->findOneBy(['id' => $this->get_id(), 'cId' => api_get_course_int_id()]);
if (!$lp) {
return false;
} }
$lp_table = Database::get_course_table(TABLE_LP_MAIN);
$lp_id = $this->get_id(); $this->expired_on = !empty($expired_on) ? api_get_utc_datetime($expired_on, false, true) : null;
$lp->setExpiredOn($this->expired_on);
$em->persist($lp);
$em->flush();
if ($this->debug > 2) { if ($this->debug > 2) {
error_log('New LP - lp updated with new expired_on : ' . $this->expired_on, 0); error_log('New LP - lp updated with new expired_on : '.$this->expired_on, 0);
} }
$params = [
'expired_on' => $this->expired_on,
];
Database::update($lp_table, $params, ['c_id = ? AND id = ?' => [$course_id, $lp_id]]);
return true; return true;
} }
@ -4856,24 +4861,30 @@ class learnpath
*/ */
public function set_publicated_on($publicated_on) public function set_publicated_on($publicated_on)
{ {
$course_id = api_get_course_int_id();
if ($this->debug > 0) { if ($this->debug > 0) {
error_log('New LP - In learnpath::set_expired_on()', 0); error_log('New LP - In learnpath::set_expired_on()', 0);
} }
if (!empty($publicated_on)) {
$this->publicated_on = api_get_utc_datetime($publicated_on); $em = Database::getManager();
} else { /** @var CLp $lp */
$this->publicated_on = ''; $lp = $em
->getRepository('ChamiloCourseBundle:CLp')
->findOneBy(['id' => $this->get_id(), 'cId' => api_get_course_int_id()]);
if (!$lp) {
return false;
} }
$lp_table = Database::get_course_table(TABLE_LP_MAIN);
$lp_id = $this->get_id(); $this->publicated_on = !empty($publicated_on) ? api_get_utc_datetime($publicated_on, false, true) : null;
$sql = "UPDATE $lp_table SET
publicated_on = '" . Database::escape_string($this->publicated_on) . "' $lp->setPublicatedOn($this->publicated_on);
WHERE c_id = ".$course_id." AND id = '$lp_id'";
$em->persist($lp);
$em->flush();
if ($this->debug > 2) { if ($this->debug > 2) {
error_log('New LP - lp updated with new publicated_on : ' . $this->publicated_on, 0); error_log('New LP - lp updated with new publicated_on : '.$this->publicated_on, 0);
} }
Database::query($sql);
return true; return true;
} }
@ -5550,7 +5561,7 @@ class learnpath
$title_cut, $title_cut,
$url, $url,
array( array(
'class' => 'ajax moved', 'class' => 'ajax moved',
'data-title' => $title_cut 'data-title' => $title_cut
) )
); );
@ -5567,7 +5578,6 @@ class learnpath
$oddClass = 'row_even'; $oddClass = 'row_even';
} }
$return_audio .= '<tr id ="lp_item_'.$arrLP[$i]['id'] .'" class="' . $oddClass . '">'; $return_audio .= '<tr id ="lp_item_'.$arrLP[$i]['id'] .'" class="' . $oddClass . '">';
$icon_name = str_replace(' ', '', $arrLP[$i]['item_type']); $icon_name = str_replace(' ', '', $arrLP[$i]['item_type']);
if (file_exists('../img/lp_' . $icon_name . '.png')) { if (file_exists('../img/lp_' . $icon_name . '.png')) {
@ -5664,6 +5674,12 @@ class learnpath
$edit_icon .= Display::return_icon('edit.png', get_lang('LearnpathEditModule'), array(), ICON_SIZE_TINY); $edit_icon .= Display::return_icon('edit.png', get_lang('LearnpathEditModule'), array(), ICON_SIZE_TINY);
$edit_icon .= '</a>'; $edit_icon .= '</a>';
} }
} else {
if ($arrLP[$i]['item_type'] == TOOL_LP_FINAL_ITEM) {
$edit_icon .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=edit_item&id=' . $arrLP[$i]['id'] . '&lp_id=' . $this->lp_id.'" class="btn btn-default">';
$edit_icon .= Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_TINY);
$edit_icon .= '</a>';
}
} }
$delete_icon .= ' <a href="'.api_get_self().'?'.api_get_cidreq().'&action=delete_item&id=' . $arrLP[$i]['id'] . '&lp_id=' . $this->lp_id . '" onclick="return confirmation(\'' . addslashes($title) . '\');" class="btn btn-default">'; $delete_icon .= ' <a href="'.api_get_self().'?'.api_get_cidreq().'&action=delete_item&id=' . $arrLP[$i]['id'] . '&lp_id=' . $this->lp_id . '" onclick="return confirmation(\'' . addslashes($title) . '\');" class="btn btn-default">';
@ -6114,12 +6130,13 @@ class learnpath
$dir = $result['dir']; $dir = $result['dir'];
if (empty($parentId)) { if (empty($parentId)) {
$postDir = isset($_POST['dir']) ? $_POST['dir'] : ''; $postDir = isset($_POST['dir']) ? $_POST['dir'] : $dir;
$dir = isset ($_GET['dir']) ? $_GET['dir'] : $postDir; // Please, do not modify this dirname formatting. $dir = isset($_GET['dir']) ? $_GET['dir'] : $postDir; // Please, do not modify this dirname formatting.
// Please, do not modify this dirname formatting. // Please, do not modify this dirname formatting.
if (strstr($dir, '..')) { if (strstr($dir, '..')) {
$dir = '/'; $dir = '/';
} }
if (!empty($dir[0]) && $dir[0] == '.') { if (!empty($dir[0]) && $dir[0] == '.') {
$dir = substr($dir, 1); $dir = substr($dir, 1);
} }
@ -6136,11 +6153,10 @@ class learnpath
} }
} }
$filepath = api_get_path(SYS_COURSE_PATH) . $courseInfo['path'] . '/document'.$dir; $filepath = api_get_path(SYS_COURSE_PATH) . $courseInfo['path'] . '/document/'.$dir;
if (!is_dir($filepath)) { if (!is_dir($filepath)) {
$dir = '/'; $dir = '/';
$filepath = api_get_path(SYS_COURSE_PATH) . $courseInfo['path'] . '/document'.$dir; $filepath = api_get_path(SYS_COURSE_PATH) . $courseInfo['path'] . '/document/'.$dir;
} }
// stripslashes() before calling api_replace_dangerous_char() because $_POST['title'] // stripslashes() before calling api_replace_dangerous_char() because $_POST['title']
@ -6265,21 +6281,22 @@ class learnpath
$course_id = api_get_course_int_id(); $course_id = api_get_course_int_id();
$urlAppend = api_get_configuration_value('url_append'); $urlAppend = api_get_configuration_value('url_append');
// Please, do not modify this dirname formatting. // Please, do not modify this dirname formatting.
$dir = isset($_GET['dir']) ? $_GET['dir'] : $_POST['dir']; $postDir = isset($_POST['dir']) ? $_POST['dir'] : '';
$dir = isset($_GET['dir']) ? $_GET['dir'] : $postDir;
if (strstr($dir, '..')) { if (strstr($dir, '..')) {
$dir = '/'; $dir = '/';
} }
if ($dir[0] == '.') { if (isset($dir[0]) && $dir[0] == '.') {
$dir = substr($dir, 1); $dir = substr($dir, 1);
} }
if ($dir[0] != '/') { if (isset($dir[0]) && $dir[0] != '/') {
$dir = '/'.$dir; $dir = '/'.$dir;
} }
if ($dir[strlen($dir) - 1] != '/') { if (isset($dir[strlen($dir) - 1] ) && $dir[strlen($dir) - 1] != '/') {
$dir .= '/'; $dir .= '/';
} }
@ -6290,6 +6307,7 @@ class learnpath
} }
$table_doc = Database::get_course_table(TABLE_DOCUMENT); $table_doc = Database::get_course_table(TABLE_DOCUMENT);
if (isset($_POST['path']) && !empty($_POST['path'])) { if (isset($_POST['path']) && !empty($_POST['path'])) {
$document_id = intval($_POST['path']); $document_id = intval($_POST['path']);
$sql = "SELECT path FROM " . $table_doc . " $sql = "SELECT path FROM " . $table_doc . "
@ -6301,7 +6319,6 @@ class learnpath
if ($fp = @ fopen($file, 'w')) { if ($fp = @ fopen($file, 'w')) {
$content = str_replace(api_get_path(WEB_COURSE_PATH), $urlAppend.api_get_path(REL_COURSE_PATH), $content); $content = str_replace(api_get_path(WEB_COURSE_PATH), $urlAppend.api_get_path(REL_COURSE_PATH), $content);
// Change the path of mp3 to absolute. // Change the path of mp3 to absolute.
// The first regexp deals with :// urls. // The first regexp deals with :// urls.
$content = preg_replace("|(flashvars=\"file=)([^:/]+)/|", "$1" . api_get_path(REL_COURSE_PATH) . $_course['path'] . '/document/', $content); $content = preg_replace("|(flashvars=\"file=)([^:/]+)/|", "$1" . api_get_path(REL_COURSE_PATH) . $_course['path'] . '/document/', $content);
@ -6313,6 +6330,7 @@ class learnpath
$sql = "UPDATE " . $table_doc ." SET $sql = "UPDATE " . $table_doc ." SET
title='".Database::escape_string($_POST['title'])."' title='".Database::escape_string($_POST['title'])."'
WHERE c_id = ".$course_id." AND id = " . $document_id; WHERE c_id = ".$course_id." AND id = " . $document_id;
Database::query($sql); Database::query($sql);
} }
} }
@ -6622,7 +6640,7 @@ class learnpath
if ($iframe) { if ($iframe) {
$return .= '<iframe id="learnpath_preview_frame" frameborder="0" height="400" width="100%" scrolling="auto" src="' . api_get_path(WEB_COURSE_PATH) . $_course['path'] . '/document' . str_replace('%2F', '/', urlencode($row_doc['path'])) . '?' . api_get_cidreq() . '"></iframe>'; $return .= '<iframe id="learnpath_preview_frame" frameborder="0" height="400" width="100%" scrolling="auto" src="' . api_get_path(WEB_COURSE_PATH) . $_course['path'] . '/document' . str_replace('%2F', '/', urlencode($row_doc['path'])) . '?' . api_get_cidreq() . '"></iframe>';
} else { } else {
$return .= file_get_contents(api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document' . $row_doc['path']); $return .= file_get_contents(api_get_path(SYS_COURSE_PATH) . $_course['path'] . '/document/' . $row_doc['path']);
} }
return $return; return $return;
@ -7804,7 +7822,6 @@ class learnpath
if (isset($_GET['edit']) && $_GET['edit'] == 'true') { if (isset($_GET['edit']) && $_GET['edit'] == 'true') {
$return .= Display::return_message('<strong>' . get_lang('Warning') . ' !</strong><br />' . get_lang('WarningEditingDocument'), false); $return .= Display::return_message('<strong>' . get_lang('Warning') . ' !</strong><br />' . get_lang('WarningEditingDocument'), false);
} }
$form = new FormValidator( $form = new FormValidator(
'form', 'form',
'POST', 'POST',
@ -8058,6 +8075,12 @@ class learnpath
} }
} }
} }
if (isset($extra_info['item_type'] ) &&
$extra_info['item_type'] == TOOL_LP_FINAL_ITEM
) {
$parent_select->freeze();
$position->freeze();
}
if ($action == 'move') { if ($action == 'move') {
$form->addElement('hidden', 'title', $item_title); $form->addElement('hidden', 'title', $item_title);
@ -11476,17 +11499,6 @@ EOD;
break; break;
case TOOL_LINK: case TOOL_LINK:
$link .= $main_dir_path.'link/link_goto.php?'.api_get_cidreq().'&link_id='.$id; $link .= $main_dir_path.'link/link_goto.php?'.api_get_cidreq().'&link_id='.$id;
/*$TABLETOOLLINK = Database::get_course_table(TABLE_LINK);
$result = Database::query("SELECT * FROM $TABLETOOLLINK WHERE c_id = $course_id AND id=$id");
$myrow = Database::fetch_array($result);
$thelink = $myrow["url"];
$link = Display::url(
Display::return_icon('preview_view.png', get_lang('Preview')),
api_get_path(WEB_CODE_PATH).'link/link_goto.php?'.api_get_cidreq().'&link_id='.$key,
['target' => '_blank']
);
$link .= $thelink;*/
break; break;
case TOOL_QUIZ: case TOOL_QUIZ:
if (!empty($id)) { if (!empty($id)) {

@ -140,7 +140,7 @@ class LearnpathList
} }
// Check if visible. // Check if visible.
$vis = api_get_item_visibility( $visibility = api_get_item_visibility(
api_get_course_info($course_code), api_get_course_info($course_code),
'learnpath', 'learnpath',
$row->getId(), $row->getId(),
@ -149,7 +149,11 @@ class LearnpathList
// If option is not true then don't show invisible LP to user // If option is not true then don't show invisible LP to user
if ($showBlockedPrerequisite !== true && !api_is_allowed_to_edit()) { if ($showBlockedPrerequisite !== true && !api_is_allowed_to_edit()) {
$lpVisibility = learnpath::is_lp_visible_for_student($row->getIid(), $user_id); $lpVisibility = learnpath::is_lp_visible_for_student(
$row->getId(),
$user_id,
$course_code
);
if ($lpVisibility === false) { if ($lpVisibility === false) {
continue; continue;
} }
@ -166,7 +170,7 @@ class LearnpathList
'lp_maker' => stripslashes($row->getContentMaker()), 'lp_maker' => stripslashes($row->getContentMaker()),
'lp_proximity' => $row->getContentLocal(), 'lp_proximity' => $row->getContentLocal(),
'lp_encoding' => api_get_system_encoding(), 'lp_encoding' => api_get_system_encoding(),
'lp_visibility' => $vis, 'lp_visibility' => $visibility,
'lp_published' => $pub, 'lp_published' => $pub,
'lp_prevent_reinit' => $row->getPreventReinit(), 'lp_prevent_reinit' => $row->getPreventReinit(),
'seriousgame_mode' => $row->getSeriousgameMode(), 'seriousgame_mode' => $row->getSeriousgameMode(),

@ -67,7 +67,12 @@ $url = api_get_self().'?'.api_get_cidreq().'&action=add_users_to_category&id='.$
$formUsers = new \FormValidator('lp_edit', 'post', $url); $formUsers = new \FormValidator('lp_edit', 'post', $url);
$formUsers->addElement('hidden', 'user_form', 1); $formUsers->addElement('hidden', 'user_form', 1);
$userMultiSelect = $formUsers->addElement('advmultiselect', 'users', get_lang('Users'), $choices); $userMultiSelect = $formUsers->addElement(
'advmultiselect',
'users',
get_lang('Users'),
$choices
);
$formUsers->addButtonSave(get_lang('Save')); $formUsers->addButtonSave(get_lang('Save'));
$defaults = array(); $defaults = array();
@ -78,8 +83,7 @@ if (!empty($selectedChoices)) {
$formUsers->setDefaults($defaults); $formUsers->setDefaults($defaults);
//Building the form for Groups // Building the form for Groups
$tpl = new Template(); $tpl = new Template();
$currentUser = $em->getRepository('ChamiloUserBundle:User')->find(api_get_user_id()); $currentUser = $em->getRepository('ChamiloUserBundle:User')->find(api_get_user_id());
@ -89,30 +93,30 @@ if ($formUsers->validate()) {
// Subscribing users // Subscribing users
$users = isset($values['users']) ? $values['users'] : []; $users = isset($values['users']) ? $values['users'] : [];
if (!empty($users)) {
$deleteUsers = [];
if ($subscribedUsersInCategory) {
/** @var CLpCategoryUser $user */
foreach ($subscribedUsersInCategory as $user) {
$userId = $user->getUser()->getId();
if (!in_array($userId, $users)) {
$category->removeUsers($user);
}
}
}
foreach ($users as $userId) { $deleteUsers = [];
$categoryUser = new CLpCategoryUser(); if ($subscribedUsersInCategory) {
$user = UserManager::getRepository()->find($userId); /** @var CLpCategoryUser $user */
$categoryUser->setUser($user); foreach ($subscribedUsersInCategory as $user) {
$category->addUser($categoryUser); $userId = $user->getUser()->getId();
if (!in_array($userId, $users)) {
$category->removeUsers($user);
}
} }
}
$em->merge($category); foreach ($users as $userId) {
$em->flush(); $categoryUser = new CLpCategoryUser();
Display::addFlash(Display::return_message(get_lang('Updated'))); $user = UserManager::getRepository()->find($userId);
$categoryUser->setUser($user);
$category->addUser($categoryUser);
} }
$em->merge($category);
$em->flush();
Display::addFlash(Display::return_message(get_lang('Updated')));
header("Location: $url"); header("Location: $url");
exit; exit;
} else { } else {

@ -7,11 +7,13 @@
class SurveyUtil class SurveyUtil
{ {
/** /**
* Checks whether the given survey has a pagebreak question as the first or the last question. * Checks whether the given survey has a pagebreak question as the first
* or the last question.
* If so, break the current process, displaying an error message * If so, break the current process, displaying an error message
* @param integer Survey ID (database ID) * @param integer $survey_id Survey ID (database ID)
* @param boolean Optional. Whether to continue the current process or exit when breaking condition found. Defaults to true (do not break). * @param boolean $continue Optional. Whether to continue the current
* @return void * process or exit when breaking condition found. Defaults to true (do not break).
* @return void
*/ */
public static function check_first_last_question($survey_id, $continue = true) public static function check_first_last_question($survey_id, $continue = true)
{ {
@ -56,7 +58,8 @@ class SurveyUtil
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @version January 2007 * @version January 2007
*/ */
public static function remove_answer($user, $survey_id, $question_id, $course_id) { public static function remove_answer($user, $survey_id, $question_id, $course_id)
{
$course_id = intval($course_id); $course_id = intval($course_id);
// table definition // table definition
$table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER); $table_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
@ -83,8 +86,14 @@ class SurveyUtil
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @version January 2007 * @version January 2007
*/ */
public static function store_answer($user, $survey_id, $question_id, $option_id, $option_value, $survey_data) public static function store_answer(
{ $user,
$survey_id,
$question_id,
$option_id,
$option_value,
$survey_data
) {
// If the question_id is empty, don't store an answer // If the question_id is empty, don't store an answer
if (empty($question_id)) { if (empty($question_id)) {
return false; return false;
@ -115,7 +124,8 @@ class SurveyUtil
Database::query($sql); Database::query($sql);
$insertId = Database::insert_id(); $insertId = Database::insert_id();
$sql = "UPDATE $table_survey_answer SET answer_id = $insertId WHERE iid = $insertId"; $sql = "UPDATE $table_survey_answer SET answer_id = $insertId
WHERE iid = $insertId";
Database::query($sql); Database::query($sql);
return true; return true;
} }
@ -123,7 +133,7 @@ class SurveyUtil
/** /**
* This function checks the parameters that are used in this page * This function checks the parameters that are used in this page
* *
* @return string The header, an error and the footer if any parameter fails, else it returns true * @return string $people_filled The header, an error and the footer if any parameter fails, else it returns true
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @version February 2007 * @version February 2007
*/ */
@ -189,7 +199,7 @@ class SurveyUtil
* This function deals with the action handling * This function deals with the action handling
* @param array $survey_data * @param array $survey_data
* @param array $people_filled * @param array $people_filled
* @return void * @return void
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @version February 2007 * @version February 2007
*/ */
@ -280,7 +290,7 @@ class SurveyUtil
* than a one-page display of all the questions * than a one-page display of all the questions
* of the survey that is filled with the answers of the person who filled the survey. * of the survey that is filled with the answers of the person who filled the survey.
* *
* @return string html code of the one-page survey with the answers of the selected user * @return string html code of the one-page survey with the answers of the selected user
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @version February 2007 - Updated March 2008 * @version February 2007 - Updated March 2008
*/ */
@ -379,9 +389,7 @@ class SurveyUtil
survey_question.question_id = survey_question_option.question_id AND survey_question.question_id = survey_question_option.question_id AND
survey_question_option.c_id = $course_id survey_question_option.c_id = $course_id
WHERE WHERE
survey_question.survey_id = '".Database::escape_string( survey_question.survey_id = '".Database::escape_string($_GET['survey_id'])."' AND
$_GET['survey_id']
)."' AND
survey_question.c_id = $course_id survey_question.c_id = $course_id
ORDER BY survey_question.sort, survey_question_option.sort ASC"; ORDER BY survey_question.sort, survey_question_option.sort ASC";
$result = Database::query($sql); $result = Database::query($sql);
@ -1189,7 +1197,7 @@ class SurveyUtil
while ($row = Database::fetch_array($result)) { while ($row = Database::fetch_array($result)) {
// We show the options if // We show the options if
// 1. there is no question filter and the export button has not been clicked // 1. there is no question filter and the export button has not been clicked
// 2. there is a quesiton filter but the question is selected for display // 2. there is a question filter but the question is selected for display
if (!(isset($_POST['submit_question_filter'])) || ( if (!(isset($_POST['submit_question_filter'])) || (
is_array($_POST['questions_filter']) && is_array($_POST['questions_filter']) &&
in_array($row['question_id'], $_POST['questions_filter'])) in_array($row['question_id'], $_POST['questions_filter']))
@ -1870,9 +1878,9 @@ class SurveyUtil
/** /**
* Get all the answers of a question grouped by user * Get all the answers of a question grouped by user
* *
* @param integer Survey ID * @param integer $survey_id Survey ID
* @param integer Question ID * @param integer $question_id Question ID
* @return Array Array containing all answers of all users, grouped by user * @return array Array containing all answers of all users, grouped by user
* *
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @version February 2007 - Updated March 2008 * @version February 2007 - Updated March 2008
@ -1911,8 +1919,14 @@ class SurveyUtil
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @version February 2007 * @version February 2007
*/ */
public static function comparative_check($answers_x, $answers_y, $option_x, $option_y, $value_x = 0, $value_y = 0) public static function comparative_check(
{ $answers_x,
$answers_y,
$option_x,
$option_y,
$value_x = 0,
$value_y = 0
) {
if ($value_x == 0) { if ($value_x == 0) {
$check_x = $option_x; $check_x = $option_x;
} else { } else {
@ -2040,11 +2054,11 @@ class SurveyUtil
* This function saves all the invitations of course users and additional users in the database * This function saves all the invitations of course users and additional users in the database
* and sends the invitations by email * and sends the invitations by email
* *
* @param array Users array can be both a list of course uids AND a list of additional emailaddresses * @param array Users array can be both a list of course uids AND a list of additional emailaddresses
* @param string Title of the invitation, used as the title of the mail * @param string Title of the invitation, used as the title of the mail
* @param string Text of the invitation, used as the text of the mail. * @param string Text of the invitation, used as the text of the mail.
* The text has to contain a **link** string or this will automatically be added to the end * The text has to contain a **link** string or this will automatically be added to the end
* * @return int
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @author Julio Montoya - Adding auto-generated link support * @author Julio Montoya - Adding auto-generated link support
* @version January 2007 * @version January 2007
@ -2222,8 +2236,12 @@ class SurveyUtil
* $param string $invitation_code - the unique invitation code for the URL * $param string $invitation_code - the unique invitation code for the URL
* @return void * @return void
*/ */
public static function send_invitation_mail($invitedUser, $invitation_code, $invitation_title, $invitation_text) public static function send_invitation_mail(
{ $invitedUser,
$invitation_code,
$invitation_title,
$invitation_text
) {
$_user = api_get_user_info(); $_user = api_get_user_info();
$_course = api_get_course_info(); $_course = api_get_course_info();
@ -2419,7 +2437,7 @@ class SurveyUtil
{ {
$course_id = api_get_course_int_id(); $course_id = api_get_course_int_id();
// Database table definition // Database table definition
$table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION); $table_survey_invitation = Database::get_course_table(TABLE_SURVEY_INVITATION);
$sql = "SELECT * FROM $table_survey_invitation $sql = "SELECT * FROM $table_survey_invitation
WHERE WHERE
@ -2466,7 +2484,12 @@ class SurveyUtil
$parameters['cidReq'] = api_get_course_id(); $parameters['cidReq'] = api_get_course_id();
// Create a sortable table with survey-data // Create a sortable table with survey-data
$table = new SortableTable('surveys', 'get_number_of_surveys', 'get_survey_data_drh', 2); $table = new SortableTable(
'surveys',
'get_number_of_surveys',
'get_survey_data_drh',
2
);
$table->set_additional_parameters($parameters); $table->set_additional_parameters($parameters);
$table->set_header(0, '', false); $table->set_header(0, '', false);
$table->set_header(1, get_lang('SurveyName')); $table->set_header(1, get_lang('SurveyName'));
@ -2502,7 +2525,12 @@ class SurveyUtil
} }
// Create a sortable table with survey-data // Create a sortable table with survey-data
$table = new SortableTable('surveys', 'get_number_of_surveys', 'get_survey_data', 2); $table = new SortableTable(
'surveys',
'get_number_of_surveys',
'get_survey_data',
2
);
$table->set_additional_parameters($parameters); $table->set_additional_parameters($parameters);
$table->set_header(0, '', false); $table->set_header(0, '', false);
$table->set_header(1, get_lang('SurveyName')); $table->set_header(1, get_lang('SurveyName'));
@ -2536,7 +2564,12 @@ class SurveyUtil
} }
// Create a sortable table with survey-data // Create a sortable table with survey-data
$table = new SortableTable('surveys_coach', 'get_number_of_surveys_for_coach', 'get_survey_data_for_coach', 2); $table = new SortableTable(
'surveys_coach',
'get_number_of_surveys_for_coach',
'get_survey_data_for_coach',
2
);
$table->set_additional_parameters($parameters); $table->set_additional_parameters($parameters);
$table->set_header(0, '', false); $table->set_header(0, '', false);
$table->set_header(1, get_lang('SurveyName')); $table->set_header(1, get_lang('SurveyName'));
@ -2693,6 +2726,9 @@ class SurveyUtil
return $obj->total_number_of_items; return $obj->total_number_of_items;
} }
/**
* @return int
*/
public static function get_number_of_surveys_for_coach() public static function get_number_of_surveys_for_coach()
{ {
$survey_tree = new SurveyTree(); $survey_tree = new SurveyTree();
@ -2707,7 +2743,7 @@ class SurveyUtil
* @param int $column * @param int $column
* @param string $direction * @param string $direction
* @param bool $isDrh * @param bool $isDrh
* @return unknown * @return array
* *
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @author Julio Montoya <gugli100@gmail.com>, Beeznest - Adding intvals * @author Julio Montoya <gugli100@gmail.com>, Beeznest - Adding intvals
@ -3244,8 +3280,8 @@ class SurveyUtil
*/ */
public static function flagSurveyAsAnswered($surveyCode, $courseId) public static function flagSurveyAsAnswered($surveyCode, $courseId)
{ {
$currenUserId = api_get_user_id(); $currentUserId = api_get_user_id();
$flag = sprintf("%s-%s-%d", $courseId, $surveyCode, $currenUserId); $flag = sprintf("%s-%s-%d", $courseId, $surveyCode, $currentUserId);
if (!isset($_SESSION['filled_surveys'])) { if (!isset($_SESSION['filled_surveys'])) {
$_SESSION['filled_surveys'] = array(); $_SESSION['filled_surveys'] = array();
@ -3262,8 +3298,8 @@ class SurveyUtil
*/ */
public static function isSurveyAnsweredFlagged($surveyCode, $courseId) public static function isSurveyAnsweredFlagged($surveyCode, $courseId)
{ {
$currenUserId = api_get_user_id(); $currentUserId = api_get_user_id();
$flagToCheck = sprintf("%s-%s-%d", $courseId, $surveyCode, $currenUserId); $flagToCheck = sprintf("%s-%s-%d", $courseId, $surveyCode, $currentUserId);
if (!isset($_SESSION['filled_surveys'])) { if (!isset($_SESSION['filled_surveys'])) {
return false; return false;
@ -3287,27 +3323,28 @@ class SurveyUtil
/** /**
* Check if the current survey has answers * Check if the current survey has answers
* *
* @param $surveyId * @param int $surveyId
* @return boolean return true if the survey has answers, false otherwise * @return boolean return true if the survey has answers, false otherwise
*/ */
public static function checkIfSurveyHasAnswers($surveyId) public static function checkIfSurveyHasAnswers($surveyId)
{ {
$tableSurveyAnswer = Database::get_course_table(TABLE_SURVEY_ANSWER); $tableSurveyAnswer = Database::get_course_table(TABLE_SURVEY_ANSWER);
$courseId = api_get_course_int_id(); $courseId = api_get_course_int_id();
$surveyId = (int)$surveyId;
if (empty($courseId) || empty($surveyId)) {
return false;
}
$sql = "SELECT * FROM $tableSurveyAnswer $sql = "SELECT * FROM $tableSurveyAnswer
WHERE WHERE
c_id = $courseId AND c_id = $courseId AND
survey_id='".$surveyId."' survey_id = '".$surveyId."'
ORDER BY answer_id, user ASC"; ORDER BY answer_id, user ASC";
$result = Database::query($sql); $result = Database::query($sql);
$response = Database::affected_rows($result); $response = Database::affected_rows($result);
if ($response > 0) { return $response > 0;
return true;
}
return false;
} }
} }

@ -162,11 +162,11 @@
$(document).on('ready', function () { $(document).on('ready', function () {
if (/iPhone|iPod|iPad/.test(navigator.userAgent)) { if (/iPhone|iPod|iPad/.test(navigator.userAgent)) {
$('#wrapper-iframe').css({ document.getElementById('wrapper-iframe')
'overflow' : 'auto', .setAttribute(
'position' : 'relative', 'style',
'-webkit-overflow-scrolling': 'touch' 'width:100%; height:100%; overflow:auto; position:auto; -webkit-overflow-scrolling:touch !important;'
}); );
} }
{% if lp_mode == 'embedframe' %} {% if lp_mode == 'embedframe' %}

File diff suppressed because it is too large Load Diff

@ -774,9 +774,56 @@ function deleteDirWork($id)
$t_agenda = Database::get_course_table(TABLE_AGENDA); $t_agenda = Database::get_course_table(TABLE_AGENDA);
$course_id = api_get_course_int_id(); $course_id = api_get_course_int_id();
$sessionId = api_get_session_id();
if (!empty($work_data['url'])) { if (!empty($work_data['url'])) {
if ($check) { if ($check) {
$consideredWorkingTime = api_get_configuration_value('considered_working_time');
if (!empty($consideredWorkingTime)) {
$fieldValue = new ExtraFieldValue('work');
$resultExtra = $fieldValue->getAllValuesForAnItem(
$work_data['id'],
true
);
$workingTime = null;
foreach ($resultExtra as $field) {
$field = $field['value'];
if ($consideredWorkingTime == $field->getField()->getVariable()) {
$workingTime = $field->getValue();
break;
}
}
$courseUsers = CourseManager::get_user_list_from_course_code($_course['code'], $sessionId);
if (!empty($workingTime)) {
foreach ($courseUsers as $user) {
$userWorks = get_work_user_list(
0,
100,
null,
null,
$work_data['id'],
null,
$user['user_id'],
false,
$course_id,
$sessionId
);
if (count($userWorks) != 1) {
continue;
}
Event::eventRemoveVirtualCourseTime($course_id, $user['user_id'], $sessionId, $workingTime);
}
}
}
// Deleting all contents inside the folder // Deleting all contents inside the folder
$sql = "UPDATE $table SET active = 2 $sql = "UPDATE $table SET active = 2
WHERE c_id = $course_id AND filetype = 'folder' AND id = $id"; WHERE c_id = $course_id AND filetype = 'folder' AND id = $id";
@ -823,7 +870,7 @@ function deleteDirWork($id)
null, null,
api_get_user_id(), api_get_user_id(),
api_get_course_int_id(), api_get_course_int_id(),
api_get_session_id() $sessionId
); );
$link_info = GradebookUtils::isResourceInCourseGradebook( $link_info = GradebookUtils::isResourceInCourseGradebook(

@ -10,7 +10,7 @@
*/ */
//the plugin title //the plugin title
$plugin_info['title'] = 'Add a button to login using CAS'; $plugin_info['title'] = 'Add a button to login using CAS';
//the comments that go with the plugin //the comments that go with the plugin
$plugin_info['comment'] = "If CAS is activated, this plugin add a text and a button on the login page to login with CAS. Configure plugin to add title, comment and logo."; $plugin_info['comment'] = "If CAS is activated, this plugin add a text and a button on the login page to login with CAS. Configure plugin to add title, comment and logo.";
@ -38,4 +38,4 @@ $form->setDefaults($defaults);
$plugin_info['settings_form'] = $form; $plugin_info['settings_form'] = $form;
//set the templates that are going to be used //set the templates that are going to be used
$plugin_info['templates'] = array('template.tpl'); $plugin_info['templates'] = array('template.tpl');

@ -9,10 +9,10 @@
* Plugin details (must be present) * Plugin details (must be present)
*/ */
//the plugin title //the plugin title
$plugin_info['title']='Date'; $plugin_info['title'] = 'Date';
//the comments that go with the plugin //the comments that go with the plugin
$plugin_info['comment']="Multinational date display"; $plugin_info['comment'] = "Multinational date display";
//the plugin version //the plugin version
$plugin_info['version']='1.0'; $plugin_info['version'] = '1.0';
//the plugin author //the plugin author
$plugin_info['author']='Yannick Warnier'; $plugin_info['author'] = 'Yannick Warnier';

@ -7,7 +7,7 @@ if (!api_is_anonymous() &&
api_get_setting('cas_activate') == 'true' && api_get_setting('cas_activate') == 'true' &&
$_user['auth_source'] == CAS_AUTH_SOURCE $_user['auth_source'] == CAS_AUTH_SOURCE
) { ) {
$_template['show_message'] = true; $_template['show_message'] = true;
// the link URL // the link URL
$link_url = "#"; $link_url = "#";
if (!empty($plugin_info['settings']['ext_auth_chamilo_logout_button_behaviour_eaclbb_form_link_url'])) { if (!empty($plugin_info['settings']['ext_auth_chamilo_logout_button_behaviour_eaclbb_form_link_url'])) {

@ -23,7 +23,7 @@ $plugin_info['author'] = 'Julio Montoya';
$plugin_info['templates'] = array('template.tpl'); $plugin_info['templates'] = array('template.tpl');
//For bigger icons change this value to addthis_32x32_style //For bigger icons change this value to addthis_32x32_style
$plugin_info['icon_class'] = ''; $plugin_info['icon_class'] = '';
//To use vertical alignment change this value to //To use vertical alignment change this value to
$plugin_info['position'] = 'addthis_default_style'; //addthis_vertical_style $plugin_info['position'] = 'addthis_default_style'; //addthis_vertical_style

@ -23,7 +23,7 @@ $strings['VideoConferenceXCourseX'] = "Videoconference #%s course %s
$strings['VideoConferenceAddedToTheCalendar'] = "Videoconference added to the calendar"; $strings['VideoConferenceAddedToTheCalendar'] = "Videoconference added to the calendar";
$strings['VideoConferenceAddedToTheLinkTool'] = "Videoconference added to the link tool"; $strings['VideoConferenceAddedToTheLinkTool'] = "Videoconference added to the link tool";
$strings['GoToTheVideoConference'] = "Go to the videoconference"; $strings['GoToTheVideoConference'] = "Go to the videoconference";
$strings['Records'] = "Recording"; $strings['Records'] = "Recording";
$strings['Meeting'] = "Meeting"; $strings['Meeting'] = "Meeting";
@ -34,7 +34,7 @@ $strings['CopyToLinkTool'] = "Copy to link tool";
$strings['EnterConference'] = "Enter the videoconference"; $strings['EnterConference'] = "Enter the videoconference";
$strings['RecordList'] = "Recording list"; $strings['RecordList'] = "Recording list";
$strings['ServerIsNotRunning'] = "Videoconference server is not running"; $strings['ServerIsNotRunning'] = "Videoconference server is not running";
$strings['ServerIsNotConfigured'] = "Videoconference server is not configured"; $strings['ServerIsNotConfigured'] = "Videoconference server is not configured";
$strings['XUsersOnLine'] = "%s user(s) online"; $strings['XUsersOnLine'] = "%s user(s) online";

@ -16,7 +16,7 @@ $strings['VideoConferenceXCourseX'] = "Vidéoconférence #%s, cours
$strings['VideoConferenceAddedToTheCalendar'] = "Vidéoconférence ajoutée au calendrier"; $strings['VideoConferenceAddedToTheCalendar'] = "Vidéoconférence ajoutée au calendrier";
$strings['VideoConferenceAddedToTheLinkTool'] = "Vidéoconférence ajoutée comme lien. Vous pouvez éditer et publier le lien sur la page principale du cours depuis l'outil liens."; $strings['VideoConferenceAddedToTheLinkTool'] = "Vidéoconférence ajoutée comme lien. Vous pouvez éditer et publier le lien sur la page principale du cours depuis l'outil liens.";
$strings['GoToTheVideoConference'] = "Entrer dans la salle de conférence"; $strings['GoToTheVideoConference'] = "Entrer dans la salle de conférence";
$strings['Records'] = "Enregistrement"; $strings['Records'] = "Enregistrement";
$strings['Meeting'] = "Salle de conférence"; $strings['Meeting'] = "Salle de conférence";
@ -27,7 +27,7 @@ $strings['CopyToLinkTool'] = "Ajouter comme lien du cours";
$strings['EnterConference'] = "Entrer dans la salle de conférence"; $strings['EnterConference'] = "Entrer dans la salle de conférence";
$strings['RecordList'] = "Liste des enregistrements"; $strings['RecordList'] = "Liste des enregistrements";
$strings['ServerIsNotRunning'] = "Le serveur de vidéoconférence ne fonctionne pas"; $strings['ServerIsNotRunning'] = "Le serveur de vidéoconférence ne fonctionne pas";
$strings['ServerIsNotConfigured'] = "Le serveur de vidéoconférence n'est pas configuré correctement"; $strings['ServerIsNotConfigured'] = "Le serveur de vidéoconférence n'est pas configuré correctement";
$strings['XUsersOnLine'] = "%s utilisateurs dans la salle"; $strings['XUsersOnLine'] = "%s utilisateurs dans la salle";

@ -16,7 +16,7 @@ $strings['VideoConferenceXCourseX'] = "Videoconferencia #%s, curso %
$strings['VideoConferenceAddedToTheCalendar'] = "Videoconferencia añadida al calendario"; $strings['VideoConferenceAddedToTheCalendar'] = "Videoconferencia añadida al calendario";
$strings['VideoConferenceAddedToTheLinkTool'] = "Videoconferencia añadida como enlace. Puede editar y publicar el enlace en la página principal del curso desde la herramienta de enlace."; $strings['VideoConferenceAddedToTheLinkTool'] = "Videoconferencia añadida como enlace. Puede editar y publicar el enlace en la página principal del curso desde la herramienta de enlace.";
$strings['GoToTheVideoConference'] = "Ir a la videoconferencia"; $strings['GoToTheVideoConference'] = "Ir a la videoconferencia";
$strings['Records'] = "Grabación"; $strings['Records'] = "Grabación";
$strings['Meeting'] = "Sala de conferencia"; $strings['Meeting'] = "Sala de conferencia";
@ -27,7 +27,7 @@ $strings['CopyToLinkTool'] = "Añadir como enlace del curso";
$strings['EnterConference'] = "Entrar a la videoconferencia"; $strings['EnterConference'] = "Entrar a la videoconferencia";
$strings['RecordList'] = "Lista de grabaciones"; $strings['RecordList'] = "Lista de grabaciones";
$strings['ServerIsNotRunning'] = "El servidor de videoconferencia no está funcionando"; $strings['ServerIsNotRunning'] = "El servidor de videoconferencia no está funcionando";
$strings['ServerIsNotConfigured'] = "El servidor de videoconferencia no está configurado correctamente"; $strings['ServerIsNotConfigured'] = "El servidor de videoconferencia no está configurado correctamente";
$strings['XUsersOnLine'] = "%s usuario(s) en la sala"; $strings['XUsersOnLine'] = "%s usuario(s) en la sala";

@ -19,6 +19,6 @@ class OpenMeetingsAPI
{ {
$this->_user = CONFIG_OPENMEETINGS_USER; $this->_user = CONFIG_OPENMEETINGS_USER;
$this->_pass = CONFIG_OPENMEETINGS_PASS; $this->_pass = CONFIG_OPENMEETINGS_PASS;
$this->_serverBaseUrl = CONFIG_OPENMEETINGS_SERVER_URL; $this->_serverBaseUrl = CONFIG_OPENMEETINGS_SERVER_URL;
} }
} }

@ -24,13 +24,13 @@
*/ */
//the plugin title //the plugin title
$plugin_info['title']='PENS'; $plugin_info['title'] = 'PENS';
//the comments that go with the plugin //the comments that go with the plugin
$plugin_info['comment']="PENS implementation for Chamilo"; $plugin_info['comment'] = "PENS implementation for Chamilo";
//the locations where this plugin can be shown //the locations where this plugin can be shown
$plugin_info['location']=array(); $plugin_info['location'] = array();
//the plugin version //the plugin version
$plugin_info['version']='1.1'; $plugin_info['version'] = '1.1';
//the plugin author //the plugin author
$plugin_info['author']='Guillaume Viguier-Just, Yannick Warnier'; $plugin_info['author'] = 'Guillaume Viguier-Just, Yannick Warnier';
$plugin_info = PENSPlugin::create()->get_info(); $plugin_info = PENSPlugin::create()->get_info();

@ -17,4 +17,4 @@ $plugin_info['version'] = '1.0';
// The plugin author. // The plugin author.
$plugin_info['author'] = 'Julio Montoya'; $plugin_info['author'] = 'Julio Montoya';
// For bigger icons change this value to addthis_32x32_style // For bigger icons change this value to addthis_32x32_style
$plugin_info['icon_class'] = ''; $plugin_info['icon_class'] = '';

@ -1,9 +1,9 @@
<?php <?php
// A user must be logged in. // A user must be logged in.
$_template['show_message'] = false; $_template['show_message'] = false;
if (!api_is_anonymous()) { if (!api_is_anonymous()) {
$_template['show_message'] = true; $_template['show_message'] = true;
// Getting the current user id. // Getting the current user id.
$user_id = api_get_user_id(); $user_id = api_get_user_id();

@ -1,3 +1,3 @@
<?php <?php
$strings['WelcomeToChamiloUserX'] = "Welcome to Chamilo %s!"; $strings['WelcomeToChamiloUserX'] = "Welcome to Chamilo %s!";

@ -42,6 +42,7 @@ $sql = "
home_url varchar(255), home_url varchar(255),
upload_url varchar(255), upload_url varchar(255),
course_url varchar(255), course_url varchar(255),
css_theme_folder varchar(255),
PRIMARY KEY (id) PRIMARY KEY (id)
) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; ) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
"; ";

@ -121,4 +121,8 @@ $strings['ArchiveUrl'] = 'Archive URL';
$strings['HomeUrl'] = 'Home URL'; $strings['HomeUrl'] = 'Home URL';
$strings['UploadUrl'] = 'Upload URL'; $strings['UploadUrl'] = 'Upload URL';
$strings['CourseUrl'] = 'Course URL'; $strings['CourseUrl'] = 'Course URL';
$strings['ThemeFolder'] = 'Theme folder';
$strings['ThemeFolderExplanation'] = 'Theme folder should be located inside the web/css/themes/ folder';

@ -55,7 +55,6 @@ class Virtual
$archivePath = ''; $archivePath = '';
$uploadPath = ''; $uploadPath = '';
$passwordEncryption = ''; $passwordEncryption = '';
foreach ($virtualSettings as $setting) { foreach ($virtualSettings as $setting) {
switch ($setting['variable']) { switch ($setting['variable']) {
case 'vchamilo_upload_real_root': case 'vchamilo_upload_real_root':
@ -110,7 +109,10 @@ class Virtual
// Instance cannot have multiple urls // Instance cannot have multiple urls
$_configuration['multiple_access_urls'] = false; $_configuration['multiple_access_urls'] = false;
$_configuration['virtual_css_theme_folder'] = '';
if (isset($data['css_theme_folder']) && !empty($data['css_theme_folder'])) {
$_configuration['virtual_css_theme_folder'] = $data['css_theme_folder'];
}
$virtualChamilo = $data; $virtualChamilo = $data;
} else { } else {
exit("This portal is disabled. Please contact your administrator"); exit("This portal is disabled. Please contact your administrator");

@ -418,6 +418,14 @@ class InstanceForm extends ChamiloForm
$form->addText('archive_url', $this->_plugin->get_lang('ArchiveUrl')); $form->addText('archive_url', $this->_plugin->get_lang('ArchiveUrl'));
$form->addText('home_url', $this->_plugin->get_lang('HomeUrl')); $form->addText('home_url', $this->_plugin->get_lang('HomeUrl'));
$form->addText('upload_url', $this->_plugin->get_lang('UploadUrl')); $form->addText('upload_url', $this->_plugin->get_lang('UploadUrl'));
$form->addText(
'css_theme_folder',
[
$this->_plugin->get_lang('ThemeFolder'),
$this->_plugin->get_lang('ThemeFolderExplanation'),
],
false
);
//$form->addText('course_url', $this->_plugin->get_lang('CourseUrl')); //$form->addText('course_url', $this->_plugin->get_lang('CourseUrl'));
/** /**

@ -34,7 +34,7 @@ class Minimal extends Basic
], ],
[ [
'name' => 'links', 'name' => 'links',
'items' => [ 'Link', 'Unlink', 'Anchor'] 'items' => ['Link', 'Unlink', 'Anchor']
] ]
]; ];

@ -54,7 +54,7 @@ class TestFreeAnswer extends Basic
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord'], ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord'],
['Undo', 'Redo', '-', 'SelectAll', 'Find', '-', 'RemoveFormat'], ['Undo', 'Redo', '-', 'SelectAll', 'Find', '-', 'RemoveFormat'],
['Link', 'Unlink', 'Anchor', 'Glossary'], ['Link', 'Unlink', 'Anchor', 'Glossary'],
['Image', 'Mapping', 'Video', 'Oembed', 'Youtube', 'Flash', 'Audio', 'leaflet', 'Smiley', 'SpecialChar', 'Asciimath',], ['Image', 'Mapping', 'Video', 'Oembed', 'Youtube', 'Flash', 'Audio', 'leaflet', 'Smiley', 'SpecialChar', 'Asciimath', ],
'/', '/',
['Table', '-', 'CreateDiv'], ['Table', '-', 'CreateDiv'],
['BulletedList', 'NumberedList', 'HorizontalRule', '-', 'Outdent', 'Indent', 'Blockquote'], ['BulletedList', 'NumberedList', 'HorizontalRule', '-', 'Outdent', 'Indent', 'Blockquote'],

@ -16,13 +16,13 @@ class TestQuestionDescription extends Basic
public function getConfig() public function getConfig()
{ {
$config['toolbarGroups'] = array( $config['toolbarGroups'] = array(
array('name' => 'document', 'groups' =>array('document', 'doctools')), array('name' => 'document', 'groups' =>array('document', 'doctools')),
array('name' => 'clipboard', 'groups' =>array('clipboard', 'undo')), array('name' => 'clipboard', 'groups' =>array('clipboard', 'undo')),
array('name' => 'editing', 'groups' =>array('clipboard', 'undo')), array('name' => 'editing', 'groups' =>array('clipboard', 'undo')),
//array('name' => 'forms', 'groups' =>array('clipboard', 'undo', )), //array('name' => 'forms', 'groups' =>array('clipboard', 'undo', )),
'/', '/',
array('name' => 'basicstyles', 'groups' =>array('basicstyles', 'cleanup')), array('name' => 'basicstyles', 'groups' =>array('basicstyles', 'cleanup')),
array('name' => 'paragraph', 'groups' =>array('list', 'indent', 'blocks', 'align')), array('name' => 'paragraph', 'groups' =>array('list', 'indent', 'blocks', 'align')),
array('name' => 'links'), array('name' => 'links'),
array('name' => 'insert'), array('name' => 'insert'),
'/', '/',

@ -18,8 +18,8 @@ class UniqueAnswerImage extends Basic
{ {
$config['toolbarGroups'] = array( $config['toolbarGroups'] = array(
'/', '/',
array('name' => 'basicstyles', 'groups' =>array('basicstyles', 'cleanup', )), array('name' => 'basicstyles', 'groups' =>array('basicstyles', 'cleanup',)),
array('name' => 'paragraph', 'groups' =>array('list', 'indent', 'blocks', 'align' )), array('name' => 'paragraph', 'groups' =>array('list', 'indent', 'blocks', 'align')),
array('name' => 'links'), array('name' => 'links'),
array('name' => 'insert'), array('name' => 'insert'),
'/', '/',

@ -71,13 +71,14 @@ class ChamiloApi
{ {
$theme = empty($theme) ? api_get_visual_theme() : $theme; $theme = empty($theme) ? api_get_visual_theme() : $theme;
$accessUrlId = api_get_current_access_url_id(); $accessUrlId = api_get_current_access_url_id();
$customLogoPath = "themes/$theme/images/header-logo-custom$accessUrlId.png"; $themeDir = \Template::getThemeDir($theme);
$customLogoPath = "$themeDir/images/header-logo-custom$accessUrlId.png";
if (file_exists(api_get_path(SYS_PUBLIC_PATH) . "css/$customLogoPath")) { if (file_exists(api_get_path(SYS_PUBLIC_PATH) . "css/$customLogoPath")) {
return api_get_path(WEB_CSS_PATH) . $customLogoPath; return api_get_path(WEB_CSS_PATH) . $customLogoPath;
} }
$originalLogoPath = "themes/$theme/images/header-logo.png"; $originalLogoPath = "$themeDir/images/header-logo.png";
if (file_exists(api_get_path(SYS_CSS_PATH) . $originalLogoPath)) { if (file_exists(api_get_path(SYS_CSS_PATH) . $originalLogoPath)) {
return api_get_path(WEB_CSS_PATH) . $originalLogoPath; return api_get_path(WEB_CSS_PATH) . $originalLogoPath;

@ -1681,10 +1681,10 @@ class CourseRestorer
foreach ($resources[RESOURCE_QUIZ] as $id => $quiz) { foreach ($resources[RESOURCE_QUIZ] as $id => $quiz) {
if (isset($quiz->obj)) { if (isset($quiz->obj)) {
//For new imports // For new imports
$quiz = $quiz->obj; $quiz = $quiz->obj;
} else { } else {
//For backward compatibility // For backward compatibility
$quiz->obj = $quiz; $quiz->obj = $quiz;
} }
@ -1746,6 +1746,7 @@ class CourseRestorer
'end_time' => $quiz->end_time, 'end_time' => $quiz->end_time,
'save_correct_answers' => 0, 'save_correct_answers' => 0,
'display_category_name' => 0, 'display_category_name' => 0,
'hide_question_title' => isset($quiz->hide_question_title) ? $quiz->hide_question_title : 0,
); );
if ($respect_base_content) { if ($respect_base_content) {

Loading…
Cancel
Save