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

remotes/angel/1.11.x
Yannick Warnier 8 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

@ -194,4 +194,13 @@ border-color: #444;
background: none;
border: 1px solid #D3D3D3;
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>
<h3>Possibly breaking changes</h3>
<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>
<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/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/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/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>

@ -332,15 +332,11 @@ function handleStylesheets()
}
}
// Submit stylesheets.
if (isset($_POST['save'])) {
storeStylesheets();
Display::display_normal_message(get_lang('Saved'));
}
// Current style.
$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) {
$selected = $currentStyle = $styleFromDatabase['selected_value'];
}
@ -349,8 +345,9 @@ function handleStylesheets()
$selected = $currentStyle = Security::remove_XSS($_POST['style']);
}
$dir = api_get_path(SYS_PUBLIC_PATH).'css/themes/' . $selected . '/images/';
$url = api_get_path(WEB_CSS_PATH).'themes/' . $selected . '/images/';
$themeDir = Template::getThemeDir($selected);
$dir = api_get_path(SYS_PUBLIC_PATH).'css/'.$themeDir.'/images/';
$url = api_get_path(WEB_CSS_PATH).'/'.$themeDir.'/images/';
$logoFileName = 'header-logo.png';
$newLogoFileName = 'header-logo-custom' . api_get_current_access_url_id() . '.png';
$webPlatformLogoPath = ChamiloApi::getWebPlatformLogoPath($selected);
@ -498,8 +495,13 @@ function uploadStylesheet($values, $picture)
$style_name = api_preg_replace('/[^A-Za-z0-9]/', '', $values['name_stylesheet']);
$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.'/')) {
mkdir($cssToUpload.$style_name.'/', api_get_permissions_for_new_directories());
}
@ -591,7 +593,12 @@ function uploadStylesheet($values, $picture)
if ($result) {
$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;
@ -687,18 +694,14 @@ function storeStylesheets()
/**
* This function checks if the given style is a recognize style that exists in the css directory as
* a standalone directory.
* @param string Style
* @param string $style
* @return bool True if this style is recognized, false otherwise
*/
function isStyle($style)
{
$dir = CSS_UPLOAD_PATH;
$dirs = scandir($dir);
$style = str_replace(array('/', '\\'), array('', ''), $style); // Avoid slashes or backslashes.
if (in_array($style, $dirs) && is_dir($dir.$style)) {
return true;
}
return false;
$themeList = api_get_themes();
return in_array($style, array_keys($themeList));
}
/**
@ -1012,7 +1015,7 @@ function addEditTemplate()
$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.
$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.
$form->addElement('static', 'file_comment', '', get_lang('TemplateImageComment100x70'));
@ -1025,10 +1028,10 @@ function addEditTemplate()
$result = Database::query($sql);
$row = Database::fetch_array($result);
$defaults['template_id'] = intval($_GET['id']);
$defaults['template_text'] = $row['content'];
$defaults['template_id'] = intval($_GET['id']);
$defaults['template_text'] = $row['content'];
// 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.
$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 ($form->validate()) {
$check = Security::check_token('post');
if ($check) {
// Exporting the values.
@ -1120,7 +1122,7 @@ function addEditTemplate()
displayTemplates();
} else {
$token = Security::get_token();
$form->addElement('hidden','sec_token');
$form->addElement('hidden', 'sec_token');
$form->setConstants(array('sec_token' => $token));
// Display the form.
$form->display();
@ -1638,10 +1640,10 @@ function getAllowedFileTypes()
*/
function setConfigurationSettingsInDatabase($parameters, $accessUrl)
{
$r = api_set_settings_category('Search', 'false', $accessUrl);
api_set_settings_category('Search', 'false', $accessUrl);
// Save the settings.
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
if (api_is_windows_os() == false) {
$list_of_programs = array('pdftotext', 'ps2pdf', 'catdoc', 'html2text', 'unrtf', 'catppt', 'xls2csv');
foreach($list_of_programs as $program) {
$output = [];
$ret_val = null;
@ -1703,7 +1704,8 @@ function showSearchToolsStatusTable()
function generateCSSDownloadLink($style)
{
$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(
$dir,
api_get_path(SYS_CSS_PATH).'themes'
@ -1721,16 +1723,18 @@ function generateCSSDownloadLink($style)
Display::addFlash(Display::return_message(get_lang('FileNotFound'), 'warning'));
}
}
/**
* 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
*/
function isStyleChangeable() {
global $_configuration;
function isStyleChangeable()
{
$changeable = false;
if ($_configuration['access_url'] != 1) {
$urlId = api_get_current_access_url_id();
if ($urlId) {
$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) {
$changeable = true;
}

@ -25,6 +25,12 @@ $_SESSION['this_section'] = $this_section;
// Access restrictions.
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 = array(
'use_session_mode' => 'true',
@ -468,7 +474,6 @@ foreach ($resultcategories as $row) {
$action_array[] = $url;
}
ob_start();
if (!empty($_GET['category'])) {
switch ($_GET['category']) {

@ -811,10 +811,6 @@ class TestCategory
return array();
}
if (!$exercise->specialCategoryOrders) {
return false;
}
$courseId = (int) $courseId;
$table = Database::get_course_table(TABLE_QUIZ_REL_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->display_category_name = 0;
$this->pass_percentage = '';
$this->modelType = 1;
$this->questionSelectionType = EX_Q_SELECTION_ORDERED;
$this->endButton = 0;
@ -122,6 +121,7 @@ class Exercise
*
* @author Olivier Brouckaert
* @param integer $id - exercise Id
* @param bool $parseQuestionList
*
* @return boolean - true if exercise exists, otherwise false
*/
@ -130,7 +130,7 @@ class Exercise
$TBL_EXERCISES = Database::get_course_table(TABLE_QUIZ_TEST);
$table_lp_item = Database::get_course_table(TABLE_LP_ITEM);
$id = intval($id);
$id = (int)$id;
if (empty($this->course_id)) {
return false;
}
@ -167,6 +167,7 @@ class Exercise
$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->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
FROM $table_lp_item
@ -518,7 +519,7 @@ class Exercise
*/
public function setHideQuestionTitle($value)
{
$this->hideQuestionTitle = intval($value);
$this->hideQuestionTitle = (int)$value;
}
/**
@ -534,7 +535,7 @@ class Exercise
*/
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])) {
$value = $value[0];
}
$this->globalCategoryId = intval($value);
$this->globalCategoryId = (int)$value;
}
/**
@ -945,11 +946,13 @@ class Exercise
true,
true
);
$questions_by_category = TestCategory::getQuestionsByCat(
$this->id,
$question_list,
$categoriesAddedInExercise
);
$question_list = $this->pickQuestionsPerCategory(
$categoriesAddedInExercise,
$question_list,
@ -1311,7 +1314,7 @@ class Exercise
*/
public function updateEndButton($value)
{
$this->endButton = intval($value);
$this->endButton = (int)$value;
}
/**
@ -1888,7 +1891,14 @@ class Exercise
'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
$radios_results_disabled = array();
@ -1917,7 +1927,6 @@ class Exercise
array('id' => 'result_disabled_2')
);
$radios_results_disabled[] = $form->createElement(
'radio',
'results_disabled',
@ -2219,7 +2228,6 @@ class Exercise
]
);
$form->addElement('html','</div>');
$form->addElement(
'text',
'pass_percentage',
@ -2376,8 +2384,6 @@ class Exercise
$element = $form->getElement($elementName);
$element->freeze();
}
//$radioCatGroup->freeze();
}
}
@ -2583,7 +2589,6 @@ class Exercise
$this->search_engine_save();
}
}
}
function search_engine_delete()
@ -2886,7 +2891,8 @@ class Exercise
$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;
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 ($questionNum != 1) {
$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
if (!empty($questions_in_media)) {
$questions_in_media = "['".implode("','",$questions_in_media)."']";
$all_button .= '&nbsp;<a href="javascript://" class="'.$class.'" onclick="save_question_list('.$questions_in_media.'); ">'.$label.'</a>';
$all_button[] = Display::button(
'save_question_list',
$label,
[
'type' => 'button',
'class' => $class,
'data-list' => implode(",", $questions_in_media)
]
);
} 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 {
if ($this->review_answers) {
$all_label = get_lang('ReviewQuestions');
@ -2957,9 +2983,13 @@ class Exercise
$class = 'btn btn-warning';
}
$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 .= '&nbsp;' . Display::span(null, ['id' => 'save_all_reponse']);
$html .= $all_button;
$all_button[] = Display::button(
'validate_all',
$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);
break;
case ALL_ON_ONE_PAGE:
$button = '<a href="javascript://" class="btn" onclick="save_now(\''.$questionId.'\', null, true, 1); ">'.get_lang('SaveForNow').'</a>';
$button .= '<span id="save_for_now_'.$questionId.'" class="exercise_save_mini_message"></span>&nbsp;';
$exercise_actions .= Display::div($button, array('class'=>'exercise_save_now_button'));
$button = [
Display::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;
}
if (!empty($questions_in_media)) {
$count_of_questions_inside_media = count($questions_in_media);
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 .= '<span id="save_for_now_'.$questionId.'" class="exercise_save_mini_message"></span>&nbsp;';
$exercise_actions = Display::div($button, array('class'=>'exercise_save_now_button'));
$button = [
Display::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) {

@ -974,6 +974,50 @@ if (!empty($error)) {
$(\'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) {
url = "exercise_submit.php?'.$params.'&num="+question_num;
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) . '\');
}
});
return false;
}
function save_now_all(validate) {
@ -1119,7 +1162,6 @@ if (!empty($error)) {
function validate_all() {
save_now_all("validate");
return false;
}
</script>';
@ -1236,9 +1278,18 @@ if (!empty($error)) {
$exercise_actions .= $objExercise->show_button($questionId, $current_question);
break;
case ALL_ON_ONE_PAGE :
$button = '<a href="javascript://" class="btn btn-info" onclick="save_now(\''.$questionId.'\'); ">'.get_lang('SaveForNow').'</a>';
$button .= '<span id="save_for_now_'.$questionId.'"></span>&nbsp;';
$exercise_actions .= Display::div($button, array('class'=>'exercise_save_now_button'));
$button = [
Display::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;
}

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

@ -469,10 +469,13 @@ if (is_array($forumCategories)) {
$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;
$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="col-md-6">';
$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>';
$html .= '</div>';
@ -488,9 +491,7 @@ if (is_array($forumCategories)) {
'a',
$forum['forum_title'],
[
'href' => 'viewforum.php?' . api_get_cidreq()
. '&gidReq=' . intval($groupid)
. '&forum=' . intval($forum['forum_id']),
'href' => $linkForum ,
'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
// 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;
}

@ -4260,7 +4260,8 @@ function api_get_language_from_type($lang_type)
* @param int $languageId
* @return array
*/
function api_get_language_info($languageId) {
function api_get_language_info($languageId)
{
$language = Database::getManager()
->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.
* 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()
{
static $visual_theme;
if (!isset($visual_theme)) {
$platform_theme = api_get_setting('stylesheets');
// Get style directly from DB
$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.
$visual_theme = $platform_theme;
if (api_get_setting('user_selected_theme') == 'true') {
$user_info = api_get_user_info();
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
* 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
* 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/';
$list = [];
if (is_dir($cssdir)) {
$themes = @scandir($cssdir);
// This configuration value is set by the vchamilo plugin
$virtualTheme = api_get_configuration_value('virtual_css_theme_folder');
$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)) {
if ($themes !== false) {
sort($themes);
$dir = api_get_path(SYS_CSS_PATH).'themes/';
$list = $readCssFolder($dir);
foreach ($themes as & $theme) {
if (substr($theme, 0, 1) == '.') {
continue;
} else {
if (is_dir($cssdir.$theme)) {
$name = ucwords(str_replace('_', ' ', $theme));
$list[$theme] = $name;
}
}
}
}
if (!empty($virtualTheme)) {
$newList = $readCssFolder($dir.'/'.$virtualTheme);
if ($getOnlyThemeFromVirtualInstance) {
return $newList;
}
$list = $list + $newList;
asort($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'
* @param string $username
* @return bool
*/
function api_block_account_captcha($username)
{
@ -7181,10 +7208,12 @@ function api_block_account_captcha($username)
'captcha_blocked_until_date',
api_get_utc_datetime($time)
);
return true;
}
/**
* @param string $username
* @return bool
*/
function api_clean_account_captcha($username)
{
@ -7198,6 +7227,7 @@ function api_clean_account_captcha($username)
'captcha_blocked_until_date',
null
);
return true;
}
/**
@ -7243,7 +7273,8 @@ function api_get_short_text_from_html($in_html, $in_number_char)
* @return string
* @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;
if ($in_double_quote_replace) {
$out_res = str_replace('"', "''", $out_res);
@ -7318,7 +7349,6 @@ function api_can_login_as($loginAsUserId, $userId = null)
}
$userInfo = api_get_user_info($userId);
$isDrh = function() use($loginAsUserId) {
if (api_is_drh()) {
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
* 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
*
* @return bool|mixed

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

@ -1265,6 +1265,11 @@ class CourseHome
*/
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);
$html = '';
if (!empty($navigation_items)) {

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

@ -22,6 +22,7 @@ class Template
* @var string
*/
public $theme = '';
private $themeDir;
/**
* @var string
@ -480,21 +481,42 @@ class Template
$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
*/
private function set_system_parameters()
{
global $_configuration;
$this->theme = api_get_visual_theme();
//Setting app paths/URLs
$this->themeDir = self::getThemeDir($this->theme);
// Setting app paths/URLs
$_p = array(
'web' => api_get_path(WEB_PATH),
'web_relative' => api_get_path(REL_PATH),
'web_course' => api_get_path(WEB_COURSE_PATH),
'web_main' => api_get_path(WEB_CODE_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_img' => api_get_path(WEB_IMG_PATH),
'web_plugin' => api_get_path(WEB_PLUGIN_PATH),
@ -507,10 +529,10 @@ class Template
);
$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(
'software_name' => $_configuration['software_name'],
'system_version' => $_configuration['system_version'],
'software_name' => api_get_configuration_value('software_name'),
'system_version' => api_get_configuration_value('system_version'),
'site_name' => api_get_setting('siteName'),
'institution' => api_get_setting('Institution'),
'date' => api_format_date('now', DATE_FORMAT_LONG),
@ -529,7 +551,6 @@ class Template
{
global $disable_js_and_css_files;
$css = array();
$this->theme = api_get_visual_theme();
if (!empty($this->preview_theme)) {
@ -559,11 +580,7 @@ class Template
if (api_is_global_chat_enabled()) {
$css[] = api_get_path(WEB_LIBRARY_PATH) . 'javascript/chat/css/chat.css';
}
//THEME CSS STYLE
// $css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'responsive.css');
$css_file_to_string = null;
$css_file_to_string = '';
foreach ($css as $file) {
$css_file_to_string .= api_get_css($file);
}
@ -579,8 +596,8 @@ class Template
public function setCSSEditor()
{
$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')) {
$cssEditor = api_get_path(WEB_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).$this->themeDir.'editor.css';
}
$this->assign('cssEditor', $cssEditor);
@ -595,23 +612,22 @@ class Template
{
global $disable_js_and_css_files;
// Base CSS
$css[] = api_get_cdn_path(api_get_path(WEB_CSS_PATH).'base.css');
if ($this->show_learnpath) {
$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')) {
$css[] = api_get_path(WEB_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).$this->themeDir.'learnpath.css';
}
}
if (is_file(api_get_path(SYS_CSS_PATH).'themes/'.$this->theme.'/editor.css')) {
$css[] = api_get_path(WEB_CSS_PATH).'themes/'.$this->theme.'/editor.css';
}else{
if (is_file(api_get_path(SYS_CSS_PATH).$this->themeDir.'editor.css')) {
$css[] = api_get_path(WEB_CSS_PATH).$this->themeDir.'editor.css';
} 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).'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;
foreach ($css as $file) {
@ -642,8 +658,10 @@ class Template
$style_print = '';
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'),
'print');
$style_print = api_get_css(
api_get_cdn_path(api_get_path(WEB_CSS_PATH).$this->theme.'/print.css'),
'print'
);
}
$this->assign('css_style_print', $style_print);
}
@ -801,7 +819,7 @@ class Template
}
$this->assign(
'online_button',
'online_button',
Display::return_icon('statusonline.png', null, [], ICON_SIZE_ATOM)
);
$this->assign(
@ -865,28 +883,29 @@ class Template
$this->assign('text_direction', api_get_text_direction());
$this->assign('section_name', 'section-'.$this_section);
//Defaul root chamilo favicon
$favico = '<link rel="shortcut icon" href="' . api_get_path(WEB_PATH) . 'favicon.ico" type="image/x-icon" />';
// Default root chamilo favicon
$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
$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 (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" />';
if (is_file($favicoThemeUrl.'favicon.ico')) {
$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()) {
$access_url_id = api_get_current_access_url_id();
if ($access_url_id != -1) {
$url_info = api_get_access_url($access_url_id);
$url = api_remove_trailing_slash(preg_replace('/https?:\/\//i', '', $url_info['url']));
$url_info = api_get_access_url($access_url_id);
$url = api_remove_trailing_slash(
preg_replace('/https?:\/\//i', '', $url_info['url'])
);
$clean_url = api_replace_dangerous_char($url);
$clean_url = str_replace('/', '-', $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;
//we create the new dir for the new sites
if (is_file($icon_real_homep.'favicon.ico')) {
$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
$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) {
$rightFloatMenu = '<div class="report">
<a href="https://github.com/chamilo/chamilo-lms/wiki/How-to-report-issues" target="_blank">
'. $iconBug . '
<a href="https://github.com/chamilo/chamilo-lms/wiki/How-to-report-issues" target="_blank">
'.$iconBug.'
</a>
</div>';
</div>';
}
if (api_get_setting('show_link_ticket_notification') == 'true' && $this->user_is_logged_in) {
// 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();
$courseParams = '';
if (!empty($courseInfo)) {
@ -919,7 +948,7 @@ class Template
$url = api_get_path(WEB_CODE_PATH).'ticket/tickets.php?project_id=1&'.$courseParams;
$rightFloatMenu .= '<div class="report">
<a href="'.$url.'" target="_blank">
'. $iconTicket . '
'.$iconTicket.'
</a>
</div>';
}
@ -950,10 +979,10 @@ class Template
//Profile link
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 {
$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 = null;
$message_url = null;
$message_url = null;
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>';
}
$this->assign('message_link', $message_link);
@ -991,8 +1020,15 @@ class Template
$menu = menuArray();
$this->assign('menu', $menu);
// Block Breadcrumb
$breadcrumb = return_breadcrumb($interbreadcrumb, $language_file, $nameTools);
$breadcrumb = '';
// Hide breadcrumb in LP
if ($this->show_learnpath == false) {
$breadcrumb = return_breadcrumb(
$interbreadcrumb,
$language_file,
$nameTools
);
}
$this->assign('breadcrumb', $breadcrumb);
//Extra content

@ -1377,7 +1377,6 @@ class UserManager
public static function get_user_list_by_ids($ids = array(), $active = null, $order = null, $limit = null)
{
if (empty($ids)) {
return array();
}
@ -1419,8 +1418,8 @@ class UserManager
* @todo security filter order by
*/
public static function get_user_list(
$conditions = array(),
$order_by = array(),
$conditions = [],
$order_by = [],
$limit_from = false,
$limit_to = false
) {
@ -1439,9 +1438,10 @@ class UserManager
foreach ($conditions as $field => $value) {
$field = Database::escape_string($field);
$value = Database::escape_string($value);
$sql .= "$field = '$value'";
$sql .= " AND $field = '$value'";
}
}
if (count($order_by) > 0) {
$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;
// Allows to redirect to the session after the inscription in session about
// $_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)
// $_configuration['allow_course_introduction_low_security'] = 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)
// $_configuration['course_introduction_html_strict_filtering'] = true;
// Prevents the duplicate upload in assignments
// $_configuration['assignment_prevent_duplicate_upload'] = false;
// 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 Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Chamilo\CourseBundle\Entity\CLp;
/**
* Class learnpath
@ -4825,27 +4826,31 @@ class learnpath
*/
public function set_expired_on($expired_on)
{
$course_id = api_get_course_int_id();
if ($this->debug > 0) {
error_log('New LP - In learnpath::set_expired_on()', 0);
}
if (!empty($expired_on)) {
$this->expired_on = api_get_utc_datetime($expired_on);
} else {
$this->expired_on = null;
$em = Database::getManager();
/** @var CLp $lp */
$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->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) {
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;
}
@ -4856,24 +4861,30 @@ class learnpath
*/
public function set_publicated_on($publicated_on)
{
$course_id = api_get_course_int_id();
if ($this->debug > 0) {
error_log('New LP - In learnpath::set_expired_on()', 0);
}
if (!empty($publicated_on)) {
$this->publicated_on = api_get_utc_datetime($publicated_on);
} else {
$this->publicated_on = '';
$em = Database::getManager();
/** @var CLp $lp */
$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();
$sql = "UPDATE $lp_table SET
publicated_on = '" . Database::escape_string($this->publicated_on) . "'
WHERE c_id = ".$course_id." AND id = '$lp_id'";
$this->publicated_on = !empty($publicated_on) ? api_get_utc_datetime($publicated_on, false, true) : null;
$lp->setPublicatedOn($this->publicated_on);
$em->persist($lp);
$em->flush();
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;
}
@ -5550,7 +5561,7 @@ class learnpath
$title_cut,
$url,
array(
'class' => 'ajax moved',
'class' => 'ajax moved',
'data-title' => $title_cut
)
);
@ -5567,7 +5578,6 @@ class learnpath
$oddClass = 'row_even';
}
$return_audio .= '<tr id ="lp_item_'.$arrLP[$i]['id'] .'" class="' . $oddClass . '">';
$icon_name = str_replace(' ', '', $arrLP[$i]['item_type']);
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 .= '</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">';
@ -6114,12 +6130,13 @@ class learnpath
$dir = $result['dir'];
if (empty($parentId)) {
$postDir = isset($_POST['dir']) ? $_POST['dir'] : '';
$dir = isset ($_GET['dir']) ? $_GET['dir'] : $postDir; // Please, do not modify this dirname formatting.
$postDir = isset($_POST['dir']) ? $_POST['dir'] : $dir;
$dir = isset($_GET['dir']) ? $_GET['dir'] : $postDir; // Please, do not modify this dirname formatting.
// Please, do not modify this dirname formatting.
if (strstr($dir, '..')) {
$dir = '/';
}
if (!empty($dir[0]) && $dir[0] == '.') {
$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)) {
$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']
@ -6265,21 +6281,22 @@ class learnpath
$course_id = api_get_course_int_id();
$urlAppend = api_get_configuration_value('url_append');
// 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, '..')) {
$dir = '/';
}
if ($dir[0] == '.') {
if (isset($dir[0]) && $dir[0] == '.') {
$dir = substr($dir, 1);
}
if ($dir[0] != '/') {
if (isset($dir[0]) && $dir[0] != '/') {
$dir = '/'.$dir;
}
if ($dir[strlen($dir) - 1] != '/') {
if (isset($dir[strlen($dir) - 1] ) && $dir[strlen($dir) - 1] != '/') {
$dir .= '/';
}
@ -6290,6 +6307,7 @@ class learnpath
}
$table_doc = Database::get_course_table(TABLE_DOCUMENT);
if (isset($_POST['path']) && !empty($_POST['path'])) {
$document_id = intval($_POST['path']);
$sql = "SELECT path FROM " . $table_doc . "
@ -6301,7 +6319,6 @@ class learnpath
if ($fp = @ fopen($file, 'w')) {
$content = str_replace(api_get_path(WEB_COURSE_PATH), $urlAppend.api_get_path(REL_COURSE_PATH), $content);
// Change the path of mp3 to absolute.
// The first regexp deals with :// urls.
$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
title='".Database::escape_string($_POST['title'])."'
WHERE c_id = ".$course_id." AND id = " . $document_id;
Database::query($sql);
}
}
@ -6622,7 +6640,7 @@ class learnpath
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>';
} 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;
@ -7804,7 +7822,6 @@ class learnpath
if (isset($_GET['edit']) && $_GET['edit'] == 'true') {
$return .= Display::return_message('<strong>' . get_lang('Warning') . ' !</strong><br />' . get_lang('WarningEditingDocument'), false);
}
$form = new FormValidator(
'form',
'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') {
$form->addElement('hidden', 'title', $item_title);
@ -11476,17 +11499,6 @@ EOD;
break;
case TOOL_LINK:
$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;
case TOOL_QUIZ:
if (!empty($id)) {

@ -140,7 +140,7 @@ class LearnpathList
}
// Check if visible.
$vis = api_get_item_visibility(
$visibility = api_get_item_visibility(
api_get_course_info($course_code),
'learnpath',
$row->getId(),
@ -149,7 +149,11 @@ class LearnpathList
// If option is not true then don't show invisible LP to user
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) {
continue;
}
@ -166,7 +170,7 @@ class LearnpathList
'lp_maker' => stripslashes($row->getContentMaker()),
'lp_proximity' => $row->getContentLocal(),
'lp_encoding' => api_get_system_encoding(),
'lp_visibility' => $vis,
'lp_visibility' => $visibility,
'lp_published' => $pub,
'lp_prevent_reinit' => $row->getPreventReinit(),
'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->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'));
$defaults = array();
@ -78,8 +83,7 @@ if (!empty($selectedChoices)) {
$formUsers->setDefaults($defaults);
//Building the form for Groups
// Building the form for Groups
$tpl = new Template();
$currentUser = $em->getRepository('ChamiloUserBundle:User')->find(api_get_user_id());
@ -89,30 +93,30 @@ if ($formUsers->validate()) {
// Subscribing 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) {
$categoryUser = new CLpCategoryUser();
$user = UserManager::getRepository()->find($userId);
$categoryUser->setUser($user);
$category->addUser($categoryUser);
$deleteUsers = [];
if ($subscribedUsersInCategory) {
/** @var CLpCategoryUser $user */
foreach ($subscribedUsersInCategory as $user) {
$userId = $user->getUser()->getId();
if (!in_array($userId, $users)) {
$category->removeUsers($user);
}
}
}
$em->merge($category);
$em->flush();
Display::addFlash(Display::return_message(get_lang('Updated')));
foreach ($users as $userId) {
$categoryUser = new CLpCategoryUser();
$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");
exit;
} else {

@ -7,11 +7,13 @@
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
* @param integer 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).
* @return void
* @param integer $survey_id Survey ID (database ID)
* @param boolean $continue Optional. Whether to continue the current
* 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)
{
@ -56,7 +58,8 @@ class SurveyUtil
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @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);
// table definition
$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
* @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 (empty($question_id)) {
return false;
@ -115,7 +124,8 @@ class SurveyUtil
Database::query($sql);
$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);
return true;
}
@ -123,7 +133,7 @@ class SurveyUtil
/**
* 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
* @version February 2007
*/
@ -189,7 +199,7 @@ class SurveyUtil
* This function deals with the action handling
* @param array $survey_data
* @param array $people_filled
* @return void
* @return void
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @version February 2007
*/
@ -280,7 +290,7 @@ class SurveyUtil
* 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.
*
* @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
* @version February 2007 - Updated March 2008
*/
@ -379,9 +389,7 @@ class SurveyUtil
survey_question.question_id = survey_question_option.question_id AND
survey_question_option.c_id = $course_id
WHERE
survey_question.survey_id = '".Database::escape_string(
$_GET['survey_id']
)."' AND
survey_question.survey_id = '".Database::escape_string($_GET['survey_id'])."' AND
survey_question.c_id = $course_id
ORDER BY survey_question.sort, survey_question_option.sort ASC";
$result = Database::query($sql);
@ -1189,7 +1197,7 @@ class SurveyUtil
while ($row = Database::fetch_array($result)) {
// We show the options if
// 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'])) || (
is_array($_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
*
* @param integer Survey ID
* @param integer Question ID
* @return Array Array containing all answers of all users, grouped by user
* @param integer $survey_id Survey ID
* @param integer $question_id Question ID
* @return array Array containing all answers of all users, grouped by user
*
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @version February 2007 - Updated March 2008
@ -1911,8 +1919,14 @@ class SurveyUtil
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @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) {
$check_x = $option_x;
} else {
@ -2040,11 +2054,11 @@ class SurveyUtil
* This function saves all the invitations of course users and additional users in the database
* 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 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.
* The text has to contain a **link** string or this will automatically be added to the end
*
* @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 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
* @return int
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @author Julio Montoya - Adding auto-generated link support
* @version January 2007
@ -2222,8 +2236,12 @@ class SurveyUtil
* $param string $invitation_code - the unique invitation code for the URL
* @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();
$_course = api_get_course_info();
@ -2419,7 +2437,7 @@ class SurveyUtil
{
$course_id = api_get_course_int_id();
// 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
WHERE
@ -2466,7 +2484,12 @@ class SurveyUtil
$parameters['cidReq'] = api_get_course_id();
// 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_header(0, '', false);
$table->set_header(1, get_lang('SurveyName'));
@ -2502,7 +2525,12 @@ class SurveyUtil
}
// 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_header(0, '', false);
$table->set_header(1, get_lang('SurveyName'));
@ -2536,7 +2564,12 @@ class SurveyUtil
}
// 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_header(0, '', false);
$table->set_header(1, get_lang('SurveyName'));
@ -2693,6 +2726,9 @@ class SurveyUtil
return $obj->total_number_of_items;
}
/**
* @return int
*/
public static function get_number_of_surveys_for_coach()
{
$survey_tree = new SurveyTree();
@ -2707,7 +2743,7 @@ class SurveyUtil
* @param int $column
* @param string $direction
* @param bool $isDrh
* @return unknown
* @return array
*
* @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
* @author Julio Montoya <gugli100@gmail.com>, Beeznest - Adding intvals
@ -3244,8 +3280,8 @@ class SurveyUtil
*/
public static function flagSurveyAsAnswered($surveyCode, $courseId)
{
$currenUserId = api_get_user_id();
$flag = sprintf("%s-%s-%d", $courseId, $surveyCode, $currenUserId);
$currentUserId = api_get_user_id();
$flag = sprintf("%s-%s-%d", $courseId, $surveyCode, $currentUserId);
if (!isset($_SESSION['filled_surveys'])) {
$_SESSION['filled_surveys'] = array();
@ -3262,8 +3298,8 @@ class SurveyUtil
*/
public static function isSurveyAnsweredFlagged($surveyCode, $courseId)
{
$currenUserId = api_get_user_id();
$flagToCheck = sprintf("%s-%s-%d", $courseId, $surveyCode, $currenUserId);
$currentUserId = api_get_user_id();
$flagToCheck = sprintf("%s-%s-%d", $courseId, $surveyCode, $currentUserId);
if (!isset($_SESSION['filled_surveys'])) {
return false;
@ -3287,27 +3323,28 @@ class SurveyUtil
/**
* Check if the current survey has answers
*
* @param $surveyId
* @param int $surveyId
* @return boolean return true if the survey has answers, false otherwise
*/
public static function checkIfSurveyHasAnswers($surveyId)
{
$tableSurveyAnswer = Database::get_course_table(TABLE_SURVEY_ANSWER);
$courseId = api_get_course_int_id();
$surveyId = (int)$surveyId;
if (empty($courseId) || empty($surveyId)) {
return false;
}
$sql = "SELECT * FROM $tableSurveyAnswer
WHERE
c_id = $courseId AND
survey_id='".$surveyId."'
survey_id = '".$surveyId."'
ORDER BY answer_id, user ASC";
$result = Database::query($sql);
$response = Database::affected_rows($result);
if ($response > 0) {
return true;
}
return false;
return $response > 0;
}
}

@ -162,11 +162,11 @@
$(document).on('ready', function () {
if (/iPhone|iPod|iPad/.test(navigator.userAgent)) {
$('#wrapper-iframe').css({
'overflow' : 'auto',
'position' : 'relative',
'-webkit-overflow-scrolling': 'touch'
});
document.getElementById('wrapper-iframe')
.setAttribute(
'style',
'width:100%; height:100%; overflow:auto; position:auto; -webkit-overflow-scrolling:touch !important;'
);
}
{% 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);
$course_id = api_get_course_int_id();
$sessionId = api_get_session_id();
if (!empty($work_data['url'])) {
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
$sql = "UPDATE $table SET active = 2
WHERE c_id = $course_id AND filetype = 'folder' AND id = $id";
@ -823,7 +870,7 @@ function deleteDirWork($id)
null,
api_get_user_id(),
api_get_course_int_id(),
api_get_session_id()
$sessionId
);
$link_info = GradebookUtils::isResourceInCourseGradebook(

@ -10,7 +10,7 @@
*/
//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
$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;
//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)
*/
//the plugin title
$plugin_info['title']='Date';
$plugin_info['title'] = 'Date';
//the comments that go with the plugin
$plugin_info['comment']="Multinational date display";
$plugin_info['comment'] = "Multinational date display";
//the plugin version
$plugin_info['version']='1.0';
$plugin_info['version'] = '1.0';
//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' &&
$_user['auth_source'] == CAS_AUTH_SOURCE
) {
$_template['show_message'] = true;
$_template['show_message'] = true;
// the link URL
$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');
//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
$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['VideoConferenceAddedToTheLinkTool'] = "Videoconference added to the link tool";
$strings['GoToTheVideoConference'] = "Go to the videoconference";
$strings['GoToTheVideoConference'] = "Go to the videoconference";
$strings['Records'] = "Recording";
$strings['Meeting'] = "Meeting";
@ -34,7 +34,7 @@ $strings['CopyToLinkTool'] = "Copy to link tool";
$strings['EnterConference'] = "Enter the videoconference";
$strings['RecordList'] = "Recording list";
$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";

@ -16,7 +16,7 @@ $strings['VideoConferenceXCourseX'] = "Vidéoconférence #%s, cours
$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['GoToTheVideoConference'] = "Entrer dans la salle de conférence";
$strings['GoToTheVideoConference'] = "Entrer dans la salle de conférence";
$strings['Records'] = "Enregistrement";
$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['RecordList'] = "Liste des enregistrements";
$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";

@ -16,7 +16,7 @@ $strings['VideoConferenceXCourseX'] = "Videoconferencia #%s, curso %
$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['GoToTheVideoConference'] = "Ir a la videoconferencia";
$strings['GoToTheVideoConference'] = "Ir a la videoconferencia";
$strings['Records'] = "Grabación";
$strings['Meeting'] = "Sala de conferencia";
@ -27,7 +27,7 @@ $strings['CopyToLinkTool'] = "Añadir como enlace del curso";
$strings['EnterConference'] = "Entrar a la videoconferencia";
$strings['RecordList'] = "Lista de grabaciones";
$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";

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

@ -24,13 +24,13 @@
*/
//the plugin title
$plugin_info['title']='PENS';
$plugin_info['title'] = 'PENS';
//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
$plugin_info['location']=array();
$plugin_info['location'] = array();
//the plugin version
$plugin_info['version']='1.1';
$plugin_info['version'] = '1.1';
//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();

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

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

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

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

@ -121,4 +121,8 @@ $strings['ArchiveUrl'] = 'Archive URL';
$strings['HomeUrl'] = 'Home URL';
$strings['UploadUrl'] = 'Upload 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 = '';
$uploadPath = '';
$passwordEncryption = '';
foreach ($virtualSettings as $setting) {
switch ($setting['variable']) {
case 'vchamilo_upload_real_root':
@ -110,7 +109,10 @@ class Virtual
// Instance cannot have multiple urls
$_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;
} else {
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('home_url', $this->_plugin->get_lang('HomeUrl'));
$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'));
/**

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

@ -54,7 +54,7 @@ class TestFreeAnswer extends Basic
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord'],
['Undo', 'Redo', '-', 'SelectAll', 'Find', '-', 'RemoveFormat'],
['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'],
['BulletedList', 'NumberedList', 'HorizontalRule', '-', 'Outdent', 'Indent', 'Blockquote'],

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

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

@ -71,13 +71,14 @@ class ChamiloApi
{
$theme = empty($theme) ? api_get_visual_theme() : $theme;
$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")) {
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)) {
return api_get_path(WEB_CSS_PATH) . $originalLogoPath;

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

Loading…
Cancel
Save