Minor - partial merge from 1.11.x

pull/2487/merge
Julio Montoya 8 years ago
parent 62480b4413
commit 1c13c69f26
  1. 149
      main/install/configuration.dist.php
  2. 319
      main/install/install.lib.php
  3. 9
      main/link/link.php
  4. 2
      main/lp/aicc_api.php
  5. 888
      main/lp/learnpath.class.php
  6. 22
      main/lp/learnpathItem.class.php
  7. 27
      main/lp/learnpathList.class.php
  8. 25
      main/lp/lp_add_item.php
  9. 2
      main/lp/lp_admin_view.php
  10. 2
      main/lp/lp_build.php
  11. 14
      main/lp/lp_controller.php
  12. 6
      main/lp/lp_edit.php
  13. 36
      main/lp/lp_edit_item.php
  14. 11
      main/lp/lp_final_item.php
  15. 4
      main/lp/lp_list.php
  16. 34
      main/lp/lp_move_item.php
  17. 8
      main/lp/lp_stats.php
  18. 2
      main/lp/lp_subscribe_users_to_category.php
  19. 12
      main/lp/lp_view.php
  20. 4
      main/lp/lp_view_item.php
  21. 11
      main/lp/openoffice_document.class.php
  22. 493
      main/lp/packaging/assets/api_wrapper.js
  23. 49
      main/lp/scorm.class.php
  24. 70
      main/lp/scorm_api.php
  25. 7
      main/portfolio/add_category.php
  26. 7
      main/portfolio/add_item.php
  27. 7
      main/portfolio/edit_category.php
  28. 9
      main/portfolio/edit_item.php
  29. 4
      main/portfolio/index.php
  30. 97
      main/session/about.php
  31. 6
      main/social/personal_data.php
  32. 33
      main/survey/create_new_survey.php
  33. 17
      main/survey/survey.lib.php
  34. 16
      main/tracking/courseLog.php
  35. 12
      main/tracking/course_log_events.php
  36. 14
      main/tracking/course_log_groups.php
  37. 17
      main/tracking/course_log_resources.php
  38. 19
      main/tracking/course_log_tools.php
  39. 7
      main/tracking/course_session_report.php
  40. 9
      main/tracking/lp_results_by_user.php
  41. 2
      main/tracking/question_course_report.php
  42. 27
      main/tracking/total_time.php
  43. 111
      main/work/work.lib.php
  44. 32
      main/work/work.php

@ -112,6 +112,16 @@ $_configuration['hosting_total_size_limit'] = 0;
* don't need it. These settings are for simple Origin Pull CDNs and are
* experimental. Enable only if you really know what you're doing.
* This might conflict with multiple-access urls.
* Please note that recent browsers forbid the loading of resources from
* a different portal URL then where they are, due to CORS rules.
* To allow for CDN usage with different URLs, you need to specifically
* allow CORS Access-Control-Allow-Origin for your main Chamilo URL.
* This has to be done at the web server level, because Chamilo's PHP code
* doesn't change HTTP headers of all files served from the Chamilo directory.
* To do that on Apache, use
* Header set Access-Control-Allow-Origin "http(s)://main-chamilo-url"
* in Nginx:
* add_header 'Access-Control-Allow-Origin' 'http(s)://main-chamilo-url';.
*/
// Set the following setting to true to start using the CDN
$_configuration['cdn_enable'] = false;
@ -374,7 +384,20 @@ $_configuration['agenda_colors'] = [
*/
// ------
//
// Save some tool titles with HTML editor
// Save some tool titles with HTML editor. Require DB changes:
/*
ALTER TABLE course_category CHANGE name name LONGTEXT NOT NULL;
ALTER TABLE c_course_description CHANGE title title LONGTEXT NOT NULL;
ALTER TABLE c_thematic CHANGE title title LONGTEXT NOT NULL;
ALTER TABLE c_quiz CHANGE title title LONGTEXT NOT NULL;
ALTER TABLE c_lp_category CHANGE name name LONGTEXT NOT NULL;
ALTER TABLE c_glossary CHANGE name name LONGTEXT NOT NULL;
ALTER TABLE c_tool CHANGE name name LONGTEXT NOT NULL;
-- Only with allow_portfolio_tool enabled
ALTER TABLE portfolio CHANGE title title LONGTEXT NOT NULL;
ALTER TABLE portfolio_category CHANGE title title LONGTEXT NOT NULL;
--
*/
// $_configuration['save_titles_as_html'] = false;
// Show the full toolbar set to all CKEditor
//$_configuration['full_ckeditor_toolbar_set'] = false;
@ -440,18 +463,28 @@ $_configuration['agenda_colors'] = [
// X-Frame-Options tells the browser whether you want to allow your site to
// be framed or not. By preventing a browser from framing your site you can
// defend against attacks like clickjacking.
// Recommended value "x-frame-options: SAMEORIGIN".
//$_configuration['security_x_frame_options'] = 'x-frame-options: SAMEORIGIN';
// If defining a URL here, it should define the URL(s) from which your content
// should be visible, not the URLs from which your site accepts content.
// For example, if your main URL (root_web above) is https://11.chamilo.org/,
// then this setting should be: 'ALLOW-FROM https://11.chamilo.org'.
// These headers only apply to pages where Chamilo is responsible of the HTTP
// headers generation (i.e. ".php" files). It does not apply to static files.
// If playing with this feature, make sure you also update your web server
// configuration to add the right headers for static files. See CDN
// configuration documentation above (search for "add_header") for more
// information.
// Recommended (strict) value for this setting, if enabled: "SAMEORIGIN".
//$_configuration['security_x_frame_options'] = 'SAMEORIGIN';
//
// X-XSS-Protection sets the configuration for the cross-site scripting
// filter built into most browsers.
// Recommended value "X-XSS-Protection: 1; mode=block".
//$_configuration['security_xss_protection'] = 'X-XSS-Protection: 1; mode=block';
// Recommended value "1; mode=block".
//$_configuration['security_xss_protection'] = '1; mode=block';
//
// X-Content-Type-Options stops a browser from trying to MIME-sniff the
// content type and forces it to stick with the declared content-type. The only
// valid value for this header is "X-Content-Type-Options: nosniff".
//$_configuration['security_x_content_type_options'] = 'X-Content-Type-Options: nosniff';
// valid value for this header is "nosniff".
//$_configuration['security_x_content_type_options'] = 'nosniff';
//
// Referrer Policy is a new header that allows a site to control how much
// information the browser includes with navigation away from a document
@ -481,6 +514,10 @@ ALTER TABLE c_survey_question ADD is_required TINYINT(1) DEFAULT 0 NOT NULL;
// Hide survey edition tools for all or some surveys.
//Set an asterisk to hide for all, otherwise set an array with the survey codes in which the options will be blocked
//$_configuration['hide_survey_edition'] = ['codes' => []];
// Allows to set the date and time of availability for surveys. Requires DB changes:
// ALTER TABLE c_survey CHANGE avail_from avail_from DATETIME DEFAULT NULL, CHANGE avail_till avail_till DATETIME DEFAULT NULL;
// Requires change the Doctrine type from date to datime in CSurvey::$availFrom and CSurvey::$availTill
//$_configuration['allow_survey_availability_datetime'] = false;
// ------
// Allow career diagram, requires a DB change:
@ -522,6 +559,8 @@ $_configuration['send_all_emails_to'] = [
//$_configuration['hide_search_form_in_session_list'] = false;
// Allow exchange of messages from teachers/bosses about a user.
//$_configuration['private_messages_about_user'] = false;
// Allow the messages to be visible for the students
//$_configuration['private_messages_about_user_visible_to_user'] = false;
// Allow send email notification per exercise
//ALTER TABLE c_quiz ADD COLUMN notifications VARCHAR(255) NULL DEFAULT NULL;
//$_configuration['allow_notification_setting_per_exercise'] = false;
@ -603,7 +642,7 @@ $_configuration['score_grade_model'] = [
//$_configuration['my_courses_list_as_category'] = false;
// ------
// Skills can only visible for admins, teachers (related to a user via a course),
// Skills can only be visible for admins, teachers (related to a user via a course),
// and HRM users (if related to a user).
// $_configuration['allow_private_skills'] = false;
// Additional gradebook dependencies BT#13099
@ -731,6 +770,7 @@ $_configuration['gradebook_badge_sidebar'] = [
// Order sessions
// Requires DB change: ALTER TABLE session ADD COLUMN position INT DEFAULT 0;
// Requires edit Entity Session: src/Chamilo/CoreBundle/Entity/Session.php uncomment "position" variable.
// Requires uncomment the position get and set
//$_configuration['session_list_order'] = false;
// Show skills as a hierarchical table
@ -800,17 +840,17 @@ ALTER TABLE skill_rel_course ADD CONSTRAINT FK_E7CEC7FA613FECDF FOREIGN KEY (ses
/*
CREATE TABLE portfolio (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, c_id INT DEFAULT NULL, session_id INT DEFAULT NULL, category_id INT DEFAULT NULL, title VARCHAR(255) NOT NULL, content LONGTEXT NOT NULL, creation_date DATETIME NOT NULL, update_date DATETIME NOT NULL, is_visible TINYINT(1) DEFAULT '1' NOT NULL, INDEX user (user_id), INDEX course (c_id), INDEX session (session_id), INDEX category (category_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE portfolio_category (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, title VARCHAR(255) NOT NULL, description LONGTEXT DEFAULT NULL, is_visible TINYINT(1) DEFAULT '1' NOT NULL, INDEX user (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED1062A76ED395 FOREIGN KEY (user_id) REFERENCES user (id);
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED106291D79BD3 FOREIGN KEY (c_id) REFERENCES course (id);
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED1062613FECDF FOREIGN KEY (session_id) REFERENCES session (id);
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED106212469DE2 FOREIGN KEY (category_id) REFERENCES portfolio_category (id);
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED1062A76ED395 FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE;
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED106291D79BD3 FOREIGN KEY (c_id) REFERENCES course (id) ON DELETE CASCADE;
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED1062613FECDF FOREIGN KEY (session_id) REFERENCES session (id) ON DELETE CASCADE;
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED106212469DE2 FOREIGN KEY (category_id) REFERENCES portfolio_category (id) ON DELETE SET NULL;
ALTER TABLE portfolio_category ADD CONSTRAINT FK_7AC64359A76ED395 FOREIGN KEY (user_id) REFERENCES user (id);
INSERT INTO settings_current(variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES('course_create_active_tools','portfolio','checkbox','Tools','true','CourseCreateActiveToolsTitle','CourseCreateActiveToolsComment',NULL,'Portfolio', 0);
*/
//$_configuration['allow_portfolio_tool'] = false;
// Disable average and best columns in gradebook see BT#14126
//$_configuration['disable_gradebook_stats'] = false;
// Enable best score column in gradebook. Previously called disable_gradebook_stats
//$_configuration['gradebook_enable_best_score'] = false;
// Allow teachers to access student skills BT#14161 (skills setting must be enabled in the platform)
//$_configuration['allow_teacher_access_student_skills'] = false;
@ -833,15 +873,90 @@ INSERT INTO settings_current(variable, subkey, type, category, selected_value, t
// Enable speed controller in video player
// $_configuration['video_features'] = ['features' => ['speed']];
// Disable token verification when sending a message
// $_configuration['disable_token_in_new_message'] = false;
// My courses session order. Possible field values: "start_date" or "end_date". Order values: "asc" or "desc"
// $_configuration['my_courses_session_order'] = ['field' => 'end_date', 'order' => 'desc'];
// Allow set courses in session in read-only mode. Require DB changes:
/*
INSERT INTO extra_field (extra_field_type, field_type, variable, display_text, visible_to_self, changeable, filter, created_at)
VALUES (2, 13, 'session_courses_read_only_mode', 'Lock Course In Session', 1, 1, 1, NOW());
*/
// $_configuration['session_courses_read_only_mode'] = false;
// Allow SCORM packages when importing a course
// $_configuration['allow_import_scorm_package_in_course_builder'] = false;
// Hide announcement "sent to" label
// $_configuration['hide_announcement_sent_to_users_info'] = false;
// Hide gradebook graph
// $_configuration['gradebook_hide_graph'] = false;
// Hide gradebook "download report in PDF" button
// $_configuration['gradebook_hide_pdf_report_button'] = false;
// Show pending survey link in user menu
// $_configuration['show_pending_survey_in_menu'] = false;
// Show multiple conditions to user during sign up process
// Example with a GDPR condition
/*$_configuration['show_conditions_to_user'] = [
'conditions' => [
[
'variable' => 'gdpr', // internal extra field name
'display_text' => 'GDPRTitle', // checkbox title will be translated with get_lang('GDPRTitle')
'text_area' => 'GDPRTextArea', // this will be translated using get_lang('GDPRTextArea')
],
[
'variable' => 'my_terms',
'display_text' => 'My test conditions',
'text_area' => 'This is a long text area, with lot of terms and conditions ... ',
],
],
];*/
// Hide LP item prerequisite label in the LP view
//$_configuration['hide_accessibility_label_on_lp_item'] = true;
// Round score in exercise category export
//$_configuration['exercise_category_round_score_in_export'] = false;
// Redirect index to url for logged in users
// In this example the index.php will be redirected to user_portal.php for logged in users
//$_configuration['redirect_index_to_url_for_logged_users'] = 'user_portal.php';
// Teachers can CRUD classes
// ALTER TABLE usergroup ADD author_id INT DEFAULT NULL;
//$_configuration['allow_teachers_to_classes'] = false;
// GDPR: European's General Data Protection Rules activation option
// Set to true to automatically enable a new personal data page inside the social network menu
// $_configuration['enable_gdpr'] = false;
// GDPR requires users to be informed of the Data Protection Officer name and contact point
// These can only be defined here for now, but will be moved to web settings in the future.
// Name of the person or organization that is responsible for the treatment of personal info
//$_configuration['data_protection_officer_name'] = '';
// A description of the role of the DP Officer in this context
//$_configuration['data_protection_officer_role'] = '';
// An e-mail address where to contact the data protection officer for queries
//$_configuration['data_protection_officer_email'] = '';
// Validate user login via a webservice, Chamilo will send a "login" and "password" parameters
// to the "myWebServiceFunctionToLogin" function, the result should be "1" if the user have access.
/*$_configuration['webservice_validation'] = [
'options' => [
'wsdl' => 'https://example.com/soap?wsdl',
'check_login_function' => 'myWebServiceFunctionToLogin'
]
];*/
// ------ Custom DB changes (keep this at the end)
// Add user activation by confirmation email
// This option prevents the new user to login in the platform if your account is not confirmed via email
// You need add a new option called "confirmation" to the registration settings
//INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_registration', 'confirmation', 'MailConfirmation');
// ------ (End) Custom DB changes
// You need add a new option called "confirmation" to the registration settings
//INSERT INTO settings_options (variable, value, display_text) VALUES ('allow_registration', 'confirmation', 'MailConfirmation');
// ------ (End) Custom DB changes

@ -19,7 +19,7 @@ use Sonata\PageBundle\Entity\PageManager;
* of older versions before upgrading.
*/
/* CONSTANTS */
/* CONSTANTS */
define('SYSTEM_CONFIG_FILENAME', 'configuration.dist.php');
/**
@ -172,7 +172,15 @@ function checkAccessUrl()
*/
function getPhpSetting($val)
{
return ini_get($val) == '1' ? 'ON' : 'OFF';
$value = ini_get($val);
switch ($val) {
case 'display_errors':
global $originalDisplayErrors;
$value = $originalDisplayErrors;
break;
}
return $value == '1' ? 'ON' : 'OFF';
}
/**
@ -412,19 +420,21 @@ function write_system_config_file($path)
$fp = @fopen($path, 'w');
if (!$fp) {
echo '<strong><font color="red">Your script doesn\'t have write access to the config directory</font></strong><br />
<em>('.str_replace('\\', '/', realpath($path)).')</em><br /><br />
You probably do not have write access on Chamilo root directory,
i.e. you should <em>CHMOD 777</em> or <em>755</em> or <em>775</em>.<br /><br />
Your problems can be related on two possible causes:<br />
<ul>
<li>Permission problems.<br />Try initially with <em>chmod -R 777</em> and increase restrictions gradually.</li>
<li>PHP is running in <a href="http://www.php.net/manual/en/features.safe-mode.php" target="_blank">Safe-Mode</a>. If possible, try to switch it off.</li>
</ul>
<a href="http://forum.chamilo.org/" target="_blank">Read about this problem in Support Forum</a><br /><br />
Please go back to step 5.
<p><input type="submit" name="step5" value="&lt; Back" /></p>
</td></tr></table></form></body></html>';
echo '<strong>
<font color="red">Your script doesn\'t have write access to the config directory</font></strong><br />
<em>('.str_replace('\\', '/', realpath($path)).')</em><br /><br />
You probably do not have write access on Chamilo root directory,
i.e. you should <em>CHMOD 777</em> or <em>755</em> or <em>775</em>.<br /><br />
Your problems can be related on two possible causes:<br />
<ul>
<li>Permission problems.<br />Try initially with <em>chmod -R 777</em> and increase restrictions gradually.</li>
<li>PHP is running in <a href="http://www.php.net/manual/en/features.safe-mode.php" target="_blank">Safe-Mode</a>.
If possible, try to switch it off.</li>
</ul>
<a href="http://forum.chamilo.org/" target="_blank">Read about this problem in Support Forum</a><br /><br />
Please go back to step 5.
<p><input type="submit" name="step5" value="&lt; Back" /></p>
</td></tr></table></form></body></html>';
exit;
}
@ -738,7 +748,7 @@ function display_requirements(
$updatePath = '',
$update_from_version_8 = []
) {
global $_setting;
global $_setting, $originalMemoryLimit;
echo '<div class="RequirementHeading"><h2>'.display_step_sequence().get_lang('Requirements')."</h2></div>";
echo '<div class="RequirementText">';
echo '<strong>'.get_lang('ReadThoroughly').'</strong><br />';
@ -920,7 +930,7 @@ function display_requirements(
<tr>
<td class="requirements-item"><a href="http://www.php.net/manual/en/ini.core.php#ini.memory-limit">Memory Limit</a></td>
<td class="requirements-recommended">'.Display::label('>= '.REQUIRED_MIN_MEMORY_LIMIT.'M', 'success').'</td>
<td class="requirements-value">'.compare_setting_values(ini_get('memory_limit'), REQUIRED_MIN_MEMORY_LIMIT).'</td>
<td class="requirements-value">'.compare_setting_values($originalMemoryLimit, REQUIRED_MIN_MEMORY_LIMIT).'</td>
</tr>
</table>';
echo ' </div>';
@ -933,9 +943,9 @@ function display_requirements(
$course_attempt_name = '__XxTestxX__';
$course_dir = api_get_path(SYS_COURSE_PATH).$course_attempt_name;
$fileToCreate = 'test.html';
//Just in case
@unlink($course_dir.'/test.php');
@unlink($course_dir.'/'.$fileToCreate);
@rmdir($course_dir);
$perms_dir = [0777, 0755, 0775, 0770, 0750, 0700];
@ -958,17 +968,17 @@ function display_requirements(
if ($file_course_test_was_created == true) {
break;
}
$r = @touch($course_dir.'/test.php', $perm);
$r = @touch($course_dir.'/'.$fileToCreate, $perm);
if ($r === true) {
$fil_perm_verified = $perm;
if (check_course_script_interpretation($course_dir, $course_attempt_name, 'test.php')) {
if (checkCourseScriptCreation($course_dir, $course_attempt_name, $fileToCreate)) {
$file_course_test_was_created = true;
}
}
}
}
@unlink($course_dir.'/test.php');
@unlink($course_dir.'/'.$fileToCreate);
@rmdir($course_dir);
$_SESSION['permissions_for_new_directories'] = $_setting['permissions_for_new_directories'] = $dir_perm_verified;
@ -986,7 +996,7 @@ function display_requirements(
$courseTestLabel = Display::label(get_lang('Warning'), 'warning');
$courseTestLabel .= '<br />'.sprintf(
get_lang('InstallWarningCouldNotInterpretPHP'),
api_get_path(WEB_COURSE_PATH).$course_attempt_name.'/test.php'
api_get_path(WEB_COURSE_PATH).$course_attempt_name.'/'.$fileToCreate
);
}
@ -1072,8 +1082,8 @@ function display_requirements(
} else {
$error = false;
// First, attempt to set writing permissions if we don't have them yet
$perm = octdec('0770');
$perm_file = octdec('0770');
$perm = api_get_permissions_for_new_directories();
$perm_file = api_get_permissions_for_new_files();
$notWritable = [];
$checked_writable = api_get_path(SYS_APP_PATH);
@ -1105,6 +1115,7 @@ function display_requirements(
}
// Second, if this fails, report an error
//--> The user would have to adjust the permissions manually
if (count($notWritable) > 0) {
$error = true; ?>
@ -1134,17 +1145,15 @@ function display_requirements(
api_get_path(SYS_PLUGIN_PATH).'skype/',
];
$deprecatedToRemove = [];
foreach ($deprecated as $deprecatedDirectory) {
if (!is_dir($deprecatedDirectory)) {
continue;
}
$deprecatedToRemove[] = $deprecatedDirectory;
}
if (count($deprecatedToRemove) > 0) {
$error = true; ?>
if (count($deprecatedToRemove) > 0) {
?>
<p class="text-danger"><?php echo get_lang('WarningForDeprecatedDirectoriesForUpgrade'); ?></p>
<ul>
<?php foreach ($deprecatedToRemove as $deprecatedDirectory) {
@ -1611,6 +1620,8 @@ function panel($content = null, $title = null, $id = null, $style = null)
* @param string $formFieldName
* @param string $parameterValue
* @param string $displayWhenUpdate
*
* @return string
*/
function display_configuration_parameter(
$installType,
@ -1678,7 +1689,13 @@ function display_configuration_settings_form(
// Parameter 1: administrator's login
$html = '';
$html .= display_configuration_parameter($installType, get_lang('AdminLogin'), 'loginForm', $loginForm, $installType == 'update');
$html .= display_configuration_parameter(
$installType,
get_lang('AdminLogin'),
'loginForm',
$loginForm,
$installType == 'update'
);
// Parameter 2: administrator's password
if ($installType != 'update') {
@ -1687,7 +1704,12 @@ function display_configuration_settings_form(
// Parameters 3 and 4: administrator's names
$html .= display_configuration_parameter($installType, get_lang('AdminFirstName'), 'adminFirstName', $adminFirstName);
$html .= display_configuration_parameter(
$installType,
get_lang('AdminFirstName'),
'adminFirstName',
$adminFirstName
);
$html .= display_configuration_parameter($installType, get_lang('AdminLastName'), 'adminLastName', $adminLastName);
//Parameter 3: administrator's email
@ -1894,8 +1916,6 @@ function get_countries_list_from_array($combo = false)
"Yemen",
"Zambia", "Zimbabwe",
];
$country_select = '';
if ($combo) {
$country_select = '<select class="selectpicker show-tick" id="country" name="country">';
$country_select .= '<option value="">--- '.get_lang('SelectOne').' ---</option>';
@ -1968,24 +1988,24 @@ function compare_setting_values($current_value, $wanted_value)
}
/**
* @param $course_dir
* @param $course_attempt_name
* @param string $course_dir
* @param string $course_attempt_name
* @param string $file
*
* @return bool
*/
function check_course_script_interpretation(
function checkCourseScriptCreation(
$course_dir,
$course_attempt_name,
$file = 'test.php'
$file
) {
$output = false;
//Write in file
$file_name = $course_dir.'/'.$file;
$content = '<?php echo "123"; exit;';
$content = '123';
if (is_writable($file_name)) {
if ($handler = @fopen($file_name, "w")) {
if ($handler = @fopen($file_name, 'w')) {
//write content
if (fwrite($handler, $content)) {
$sock_errno = '';
@ -2126,6 +2146,7 @@ function migrate($chamiloVersion, EntityManager $manager)
{
$debug = true;
$connection = $manager->getConnection();
$config = new \Doctrine\DBAL\Migrations\Configuration\Configuration($connection);
// Table name that will store migrations log (will be created automatically,
@ -2145,7 +2166,9 @@ function migrate($chamiloVersion, EntityManager $manager)
foreach ($versions as $version) {
$version->getMigration()->setEntityManager($manager);
}
$to = null; // if $to == null then schema will be migrated to latest version
echo "<pre>";
try {
// Execute migration!
@ -2165,6 +2188,7 @@ function migrate($chamiloVersion, EntityManager $manager)
$counter++;
}
}
echo "<br>DONE!<br>";
}
@ -2176,6 +2200,7 @@ function migrate($chamiloVersion, EntityManager $manager)
return false;
}
}
echo "</pre>";
return false;
@ -2266,7 +2291,6 @@ function fixIds(EntityManager $em)
if (!empty($sql) && !empty($newId) && !empty($iid)) {
$sql = "UPDATE c_lp_item SET ref = $newId WHERE iid = $iid";
$connection->executeQuery($sql);
}
}
@ -2431,6 +2455,7 @@ function fixIds(EntityManager $em)
$result = $connection->fetchAll($sql);
foreach ($result as $item) {
$courseCode = $item['course_code'];
$categoryId = (int) $item['category_id'];
$sql = "SELECT * FROM course WHERE code = '$courseCode'";
$courseInfo = $connection->fetchAssoc($sql);
@ -2467,7 +2492,7 @@ function fixIds(EntityManager $em)
if (isset($data) && isset($data['iid'])) {
$newId = $data['iid'];
$sql = "UPDATE gradebook_link SET ref_id = $newId
WHERE id = $iid";
WHERE id = $iid AND course_code = '$courseCode' AND category_id = $categoryId ";
$connection->executeQuery($sql);
}
}
@ -2480,9 +2505,7 @@ function fixIds(EntityManager $em)
$sql = "SELECT * FROM groups";
$result = $connection->executeQuery($sql);
$groups = $result->fetchAll();
$oldGroups = [];
if (!empty($groups)) {
foreach ($groups as $group) {
if (empty($group['name'])) {
@ -2741,6 +2764,216 @@ function fixIds(EntityManager $em)
if ($debug) {
error_log('Finish fixId function');
}
fixLpId($connection, true);
}
/**
* @param \Doctrine\DBAL\Connection $connection
* @param $debug
*
* @throws \Doctrine\DBAL\DBALException
*/
function fixLpId($connection, $debug)
{
if ($debug) {
error_log('Fix lp.id lp.iids');
}
$sql = 'SELECT id, title, code FROM course';
$result = $connection->query($sql);
$courses = $result->fetchAll();
$sql = 'SELECT id FROM session';
$result = $connection->query($sql);
$sessions = $result->fetchAll();
$tblCLp = Database::get_course_table(TABLE_LP_MAIN);
$tblCLpItem = Database::get_course_table(TABLE_LP_ITEM);
$toolTable = Database::get_course_table(TABLE_TOOL_LIST);
if (!empty($sessions)) {
$sessions = array_column($sessions, 'id');
$sessions[] = 0;
} else {
$sessions = [0];
}
foreach ($courses as $course) {
$courseId = $course['id'];
$sql = "SELECT * FROM $tblCLp WHERE c_id = $courseId AND iid <> id ORDER by iid";
$result = $connection->query($sql);
if ($debug) {
error_log('-------------');
error_log("Entering Lps in course #$courseId");
error_log($sql);
}
$lpList = $result->fetchAll();
$myOnlyLpList = [];
if (!empty($lpList)) {
foreach ($lpList as $lpInfo) {
$oldId = $lpInfo['id'];
$sql = "SELECT * FROM $tblCLpItem WHERE c_id = $courseId AND lp_id = $oldId ORDER by iid";
$result = $connection->query($sql);
$items = $result->fetchAll();
$lpInfo['lp_list'] = $items;
$myOnlyLpList[] = $lpInfo;
}
}
if (!empty($myOnlyLpList)) {
foreach ($myOnlyLpList as $lpInfo) {
$lpIid = $lpInfo['iid'];
$oldId = $lpInfo['id'];
$items = $lpInfo['lp_list'];
if (empty($items)) {
continue;
}
$itemList = [];
foreach ($items as $subItem) {
$itemList[$subItem['id']] = $subItem['iid'];
}
$variablesToFix = [
'parent_item_id',
'next_item_id',
'prerequisite',
'previous_item_id',
];
foreach ($sessions as $sessionId) {
$correctLink = "lp/lp_controller.php?action=view&lp_id=$lpIid&id_session=$sessionId";
$link = "newscorm/lp_controller.php?action=view&lp_id=$oldId&id_session=$sessionId";
$secondLink = "lp/lp_controller.php?action=view&lp_id=$oldId&id_session=$sessionId";
$sql = "UPDATE $toolTable
SET link = '$correctLink'
WHERE c_id = $courseId AND (link = '$link' OR link ='$secondLink')";
$connection->query($sql);
if ($debug) {
//error_log("Fix wrong c_tool links");
//error_log($sql);
}
}
foreach ($items as $item) {
$itemIid = $item['iid'];
$itemId = $item['id'];
foreach ($variablesToFix as $variable) {
if (!empty($item[$variable]) && isset($itemList[$item[$variable]])) {
$newId = $itemList[$item[$variable]];
$sql = "UPDATE $tblCLpItem SET $variable = $newId
WHERE iid = $itemIid AND c_id = $courseId AND lp_id = $oldId";
$connection->query($sql);
if ($debug) {
//error_log($sql);
}
}
}
if ($item['item_type'] == 'document' && !empty($item['path'])) {
$oldDocumentId = $item['path'];
$sql = "SELECT * FROM c_document WHERE c_id = $courseId AND id = $oldDocumentId";
$result = $connection->query($sql);
$document = $result->fetch();
if (!empty($document)) {
$newDocumentId = $document['iid'];
if (!empty($newDocumentId)) {
$sql = "UPDATE $tblCLpItem SET path = $newDocumentId
WHERE iid = $itemIid AND c_id = $courseId";
$connection->query($sql);
if ($debug) {
//error_log("Fix document: ");
//error_log($sql);
}
}
}
}
// c_lp_view
$sql = "UPDATE c_lp_view SET last_item = $itemIid
WHERE c_id = $courseId AND last_item = $itemId AND lp_id = $oldId";
$connection->query($sql);
// c_lp_item_view
$sql = "UPDATE c_lp_item_view SET lp_item_id = $itemIid
WHERE c_id = $courseId AND lp_item_id = $itemId";
$connection->query($sql);
// Update track_exercises
$sql = "UPDATE track_e_exercises SET orig_lp_item_id = $itemIid
WHERE c_id = $courseId AND orig_lp_id = $oldId AND orig_lp_item_id = $itemId";
$connection->query($sql);
// c_forum_thread
$sql = "UPDATE c_forum_thread SET lp_item_id = $itemIid
WHERE c_id = $courseId AND lp_item_id = $itemId";
$connection->query($sql);
// orig_lp_item_view_id
$sql = "SELECT * FROM c_lp_view
WHERE c_id = $courseId AND lp_id = $oldId";
$result = $connection->query($sql);
$itemViewList = $result->fetchAll();
if ($itemViewList) {
foreach ($itemViewList as $itemView) {
$userId = $itemView['user_id'];
$oldItemViewId = $itemView['id'];
$newItemView = $itemView['iid'];
if (empty($oldItemViewId)) {
continue;
}
$sql = "UPDATE track_e_exercises
SET orig_lp_item_view_id = $newItemView
WHERE
c_id = $courseId AND
orig_lp_id = $oldId AND
orig_lp_item_id = $itemIid AND
orig_lp_item_view_id = $oldItemViewId AND
exe_user_id = $userId
";
$connection->query($sql);
/*$sql = "UPDATE c_lp_item_view
SET lp_view_id = $newItemView
WHERE
lp_view_id = $oldItemViewId AND
c_id = $courseId
";
$connection->query($sql);*/
}
}
$sql = "UPDATE $tblCLpItem SET lp_id = $lpIid
WHERE c_id = $courseId AND lp_id = $oldId AND id = $itemId";
$connection->query($sql);
$sql = "UPDATE $tblCLpItem SET id = iid
WHERE c_id = $courseId AND lp_id = $oldId AND id = $itemId";
$connection->query($sql);
}
$sql = "UPDATE c_lp_view SET lp_id = $lpIid WHERE c_id = $courseId AND lp_id = $oldId";
$connection->query($sql);
$sql = "UPDATE c_forum_forum SET lp_id = $lpIid WHERE c_id = $courseId AND lp_id = $oldId";
$connection->query($sql);
// Update track_exercises.
$sql = "UPDATE track_e_exercises SET orig_lp_id = $lpIid
WHERE c_id = $courseId AND orig_lp_id = $oldId";
$connection->query($sql);
$sql = "UPDATE $tblCLp SET id = iid WHERE c_id = $courseId AND id = $oldId ";
$connection->query($sql);
}
}
}
if ($debug) {
error_log('END Fix lp.id lp.iids');
}
}
/**

@ -82,17 +82,14 @@ if ($action === 'addcategory') {
}
if ($action === 'editlink') {
$nameTools = '';
$nameTools = get_lang('EditLink');
$interbreadcrumb[] = ['url' => 'link.php', 'name' => get_lang('Links')];
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('EditLink')];
}
// Statistics
Event::event_access_tool(TOOL_LINK);
/* Action Handling */
$nameTools = get_lang('Links');
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
$scope = isset($_REQUEST['scope']) ? $_REQUEST['scope'] : null;
$show = isset($_REQUEST['show']) && in_array(trim($_REQUEST['show']), ['all', 'none']) ? $_REQUEST['show'] : '';
@ -224,10 +221,6 @@ switch ($action) {
}
Display::display_header($nameTools, 'Links');
/* Introduction section */
Display::display_introduction_section(TOOL_LINK);
echo $content;
Display::display_footer();

@ -385,7 +385,7 @@ function addListeners(){
}
//assign event handlers to objects
if(lms_lp_type==1 || lms_item_type=='asset'){
logit_lms('Dokeos LP or asset',2);
logit_lms('Chamilo LP or asset',2);
// If this path is a Chamilo learnpath, then start manual save
// when something is loaded in there.
var myelem = document.getElementById('content_id');

File diff suppressed because it is too large Load Diff

@ -112,7 +112,7 @@ class learnpathItem
if (empty($course_id)) {
$course_id = api_get_course_int_id();
} else {
$course_id = intval($course_id);
$course_id = (int) $course_id;
}
$sql = "SELECT * FROM $items_table
WHERE iid = $id";
@ -365,7 +365,7 @@ class learnpathItem
}
$res = 1;
if (!empty($this->attempt_id)) {
$res = intval($this->attempt_id);
$res = (int) $this->attempt_id;
}
if (self::DEBUG > 0) {
error_log(
@ -503,6 +503,7 @@ class learnpathItem
}
$path = $this->get_path();
$type = $this->get_type();
if (empty($path)) {
if ($type == 'dir') {
return '';
@ -1077,23 +1078,24 @@ class learnpathItem
case 'htm':
case 'shtml':
case 'css':
$wanted_attributes = [
$wantedAttributes = [
'src',
'url',
'@import',
'href',
'value',
];
// Parse it for included resources.
$file_content = file_get_contents($abs_path);
$fileContent = file_get_contents($abs_path);
// Get an array of attributes from the HTML source.
$attributes = DocumentManager::parse_HTML_attributes(
$file_content,
$wanted_attributes
$fileContent,
$wantedAttributes
);
// Look at 'src' attributes in this file
foreach ($wanted_attributes as $attr) {
foreach ($wantedAttributes as $attr) {
if (isset($attributes[$attr])) {
// Find which kind of path these are (local or remote).
$sources = $attributes[$attr];
@ -3587,7 +3589,7 @@ class learnpathItem
}
$lp_table = Database::get_course_table(TABLE_LP_MAIN);
$lp_id = intval($this->lp_id);
$lp_id = (int) $this->lp_id;
$sql = "SELECT * FROM $lp_table WHERE iid = $lp_id";
$res = Database::query($sql);
$accumulateScormTime = 'false';
@ -4501,7 +4503,7 @@ class learnpathItem
*/
public function getForumThread($lpCourseId, $lpSessionId = 0)
{
$lpSessionId = intval($lpSessionId);
$lpSessionId = (int) $lpSessionId;
$forumThreadTable = Database::get_course_table(TABLE_FORUM_THREAD);
$itemProperty = Database::get_course_table(TABLE_ITEM_PROPERTY);
@ -4565,7 +4567,7 @@ class learnpathItem
$threadRepo = $em->getRepository('ChamiloCourseBundle:CForumThread');
$forumThread = $threadRepo->findOneBy([
'threadTitle' => "{$this->title} - {$this->db_id}",
'forumId' => intval($currentForumId),
'forumId' => (int) $currentForumId,
]);
if (!$forumThread) {

@ -34,6 +34,7 @@ class LearnpathList
* @param bool $check_publication_dates
* @param int $categoryId
* @param bool $ignoreCategoryFilter
* @param bool $ignoreLpVisibility get the list of LPs for reports
*/
public function __construct(
$user_id,
@ -42,7 +43,8 @@ class LearnpathList
$order_by = null,
$check_publication_dates = false,
$categoryId = null,
$ignoreCategoryFilter = false
$ignoreCategoryFilter = false,
$ignoreLpVisibility = false
) {
$course_info = api_get_course_info($course_code);
@ -90,7 +92,7 @@ class LearnpathList
$categoryFilter = '';
if ($ignoreCategoryFilter == false) {
if (!empty($categoryId)) {
$categoryId = intval($categoryId);
$categoryId = (int) $categoryId;
$categoryFilter = " AND lp.categoryId = $categoryId";
} else {
$categoryFilter = " AND (lp.categoryId = 0 OR lp.categoryId IS NULL) ";
@ -129,11 +131,10 @@ class LearnpathList
)
";
$res2 = Database::query($sql2);
$pub = 'i';
if (Database::num_rows($res2) > 0) {
$row2 = Database::fetch_array($res2);
$pub = $row2['visibility'];
} else {
$pub = 'i';
}
// Check if visible.
@ -145,14 +146,16 @@ 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->getId(),
$user_id,
$course_code
);
if ($lpVisibility === false) {
continue;
if ($ignoreLpVisibility === false) {
if ($showBlockedPrerequisite !== true && !api_is_allowed_to_edit()) {
$lpVisibility = learnpath::is_lp_visible_for_student(
$row->getId(),
$user_id,
$course_code
);
if ($lpVisibility === false) {
continue;
}
}
}

@ -46,30 +46,7 @@ if ($learnPath->get_lp_session_id() != api_get_session_id()) {
exit;
}
$htmlHeadXtra[] = '<script>'.
$learnPath->get_js_dropdown_array()."
function load_cbo(id) {
if (!id) {
return false;
}
var cbo = document.getElementById('previous');
for(var i = cbo.length - 1; i > 0; i--) {
cbo.options[i] = null;
}
var k=0;
for(var i = 1; i <= child_name[id].length; i++){
var option = new Option(child_name[id][i - 1], child_value[id][i - 1]);
option.style.paddingLeft = '40px';
cbo.options[i] = option;
k = i;
}
cbo.options[k].selected = true;
$('#previous').selectpicker('refresh');
}
$htmlHeadXtra[] = '<script>'.$learnPath->get_js_dropdown_array()."
$(function() {
if ($('#previous')) {
if('parent is'+$('#idParent').val()) {

@ -33,6 +33,7 @@ $_course = api_get_course_info();
if ((!$is_allowed_to_edit) || ($isStudentView)) {
error_log('New LP - User not authorized in lp_admin_view.php');
header('location:lp_controller.php?action=view&lp_id='.$learnpath_id);
exit;
}
if (api_is_in_gradebook()) {
@ -61,6 +62,7 @@ if (isset($_REQUEST['updateaudio'])) {
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('BasicOverview')];
}
$htmlHeadXtra[] = '<script>'.$learnPath->get_js_dropdown_array().'</script>';
// Theme calls.
$show_learn_path = true;
$lp_theme_css = $learnPath->get_theme();

@ -44,7 +44,7 @@ if (api_is_in_gradebook()) {
'name' => get_lang('ToolGradebook'),
];
}
$interbreadcrumb[] = ['url' => 'lp_controller.php?action=list?'.api_get_cidreq(), 'name' => get_lang('LearningPaths')];
$interbreadcrumb[] = ['url' => 'lp_controller.php?action=list&'.api_get_cidreq(), 'name' => get_lang('LearningPaths')];
$interbreadcrumb[] = ['url' => '#', "name" => $learnPath->get_name()];
// Theme calls.

@ -199,6 +199,7 @@ if ($refresh == 1) {
}
if ($debug > 0) {
error_log(' $refresh: '.$refresh);
error_log(' $myrefresh: '.$myrefresh);
}
@ -245,6 +246,7 @@ if (!empty($lpObject)) {
}
if ($debug) {
error_log('$lp_found: '.$lp_found);
error_log('$myrefresh_id: '.$myrefresh_id);
}
$course_id = api_get_course_int_id();
@ -342,7 +344,8 @@ if (isset($_SESSION['oLP'])) {
// Reinitialises array used by javascript to update items in the TOC.
}
if (isset($_GET['isStudentView']) && $_GET['isStudentView'] == 'true') {
/*$studentView = api_is_student_view_active();
if ($studentView) {
if (isset($_REQUEST['action']) && !in_array($_REQUEST['action'], ['list', 'view', 'view_category'])) {
if (!empty($_REQUEST['lp_id'])) {
$_REQUEST['action'] = 'view';
@ -358,7 +361,7 @@ if (isset($_GET['isStudentView']) && $_GET['isStudentView'] == 'true') {
$_REQUEST['action'] = 'build';
}
}
}
}*/
$action = !empty($_REQUEST['action']) ? $_REQUEST['action'] : '';
@ -763,6 +766,7 @@ switch ($action) {
$is_success = true;
$url = api_get_self().'?action=add_item&type=step&lp_id='.intval($_SESSION['oLP']->lp_id).'&'.api_get_cidreq();
header('Location: '.$url);
exit;
}
if (isset($_GET['view']) && $_GET['view'] == 'build') {
require 'lp_move_item.php';
@ -826,7 +830,7 @@ switch ($action) {
if (!$lp_found) {
require 'lp_list.php';
} else {
$_SESSION['oLP']->scorm_export();
$_SESSION['oLP']->scormExport();
exit();
}
break;
@ -1318,12 +1322,14 @@ switch ($action) {
$url = api_get_self().'?action=add_item&type=step&lp_id='.intval($_SESSION['oLP']->lp_id)."&".api_get_cidreq();
Display::addFlash(Display::return_message(get_lang('ItemUpdated')));
header('Location: '.$url);
exit;
break;
case 'clear_prerequisites':
$_SESSION['oLP']->clear_prerequisites();
$url = api_get_self().'?action=add_item&type=step&lp_id='.intval($_SESSION['oLP']->lp_id)."&".api_get_cidreq();
Display::addFlash(Display::return_message(get_lang('ItemUpdated')));
header('Location: '.$url);
exit;
break;
case 'toggle_seriousgame':
// activate/deactive seriousgame_mode
@ -1403,6 +1409,7 @@ switch ($action) {
'type' => 'step',
'lp_id' => $_SESSION['oLP']->lp_id,
]));
exit;
break;
case 'report':
@ -1443,6 +1450,7 @@ switch ($action) {
'type' => 'step',
'lp_id' => $_SESSION['oLP']->lp_id,
]));
exit;
break;
case 'add_final_item':
if (!$lp_found) {

@ -76,7 +76,7 @@ $items = learnpath::getCategoryFromCourseIntoSelect(api_get_course_int_id(), tru
$form->addElement('select', 'category_id', get_lang('Category'), $items);
// Hide toc frame
$hide_toc_frame = $form->addElement(
$form->addElement(
'checkbox',
'hide_toc_frame',
null,
@ -142,7 +142,7 @@ $defaults['lp_encoding'] = Security::remove_XSS($learnPath->encoding);
$defaults['lp_name'] = Security::remove_XSS($learnPath->get_name());
$defaults['lp_author'] = Security::remove_XSS($learnPath->get_author());
$defaults['hide_toc_frame'] = $hideTableOfContents;
$defaults['category_id'] = intval($learnPath->getCategoryId());
$defaults['category_id'] = $learnPath->getCategoryId();
$defaults['accumulate_scorm_time'] = $learnPath->getAccumulateScormTime();
$expired_on = $learnPath->expired_on;
@ -241,6 +241,8 @@ if ($enableLpExtraFields) {
</script>';
}
$htmlHeadXtra[] = '<script>'.$learnPath->get_js_dropdown_array()."</sript>";
$defaults['publicated_on'] = !empty($publicated_on) && $publicated_on !== '0000-00-00 00:00:00'
? api_get_local_time($publicated_on)
: null;

@ -21,35 +21,7 @@ api_protect_course_script();
$learnPath = Session::read('oLP');
/* Header and action code */
$htmlHeadXtra[] = '
<script>'.$learnPath->get_js_dropdown_array().
"
function load_cbo(id) {
if (!id) {
return false;
}
var cbo = document.getElementById('previous');
for(var i = cbo.length - 1; i > 0; i--) {
cbo.options[i] = null;
}
var k=0;
for(var i = 1; i <= child_name[id].length; i++){
var option = new Option(child_name[id][i - 1], child_value[id][i - 1]);
option.style.paddingLeft = '20px';
cbo.options[i] = option;
k = i;
}
cbo.options[k].selected = true;
$('#previous').selectpicker('refresh');
}
".
'
$htmlHeadXtra[] = '<script>'.$learnPath->get_js_dropdown_array().'
$(document).on("ready", function() {
CKEDITOR.on("instanceReady", function (e) {
showTemplates("content_lp");
@ -67,7 +39,7 @@ $submit = isset($_POST['submit_button']) ? $_POST['submit_button'] : null;
if (!$is_allowed_to_edit || $isStudentView) {
error_log('New LP - User not authorized in lp_edit_item.php');
header('location:lp_controller.php?action=view&lp_id='.$learnpath_id);
header('location:lp_controller.php?action=view&lp_id='.$learnpath_id.'&'.api_get_cidreq());
exit;
}
// From here on, we are admin because of the previous condition, so don't check anymore.
@ -157,12 +129,12 @@ echo $learnPath->build_action_menu();
echo '<div class="row">';
echo '<div id="lp_sidebar" class="col-md-4">';
$documentId = isset($_GET['path_item']) ? (int) $_GET['path_item'] : 0;
$documentInfo = DocumentManager::get_document_data_by_id($documentId, api_get_course_id());
$documentInfo = DocumentManager::get_document_data_by_id($documentId, api_get_course_id(), false, null, true);
if (empty($documentInfo)) {
// Try with iid
$table = Database::get_course_table(TABLE_DOCUMENT);
$sql = "SELECT path FROM $table
WHERE c_id = $course_id AND iid = $documentId";
WHERE c_id = $course_id AND iid = $documentId AND path NOT LIKE '%_DELETED_%'";
$res_doc = Database::query($sql);
$path_file = Database::result($res_doc, 0, 0);
} else {

@ -47,13 +47,14 @@ if ($checker) {
if (empty($userServiceSale)) {
// Instance a new template : No page tittle, No header, No footer
$tpl = new Template(null, false, false);
$url = api_get_path(WEB_PLUGIN_PATH).'buycourses/src/service_catalog.php';
$content = sprintf(
Display::return_message(
$plugin->get_lang('IfYouWantToGetTheCertificateAndOrSkillsAsociatedToThisCourseYouNeedToBuyTheCertificateServiceYouCanGoToServiceCatalogClickingHere'),
get_lang('IfYouWantToGetTheCertificateAndOrSkillsAsociatedToThisCourseYouNeedToBuyTheCertificateServiceYouCanGoToServiceCatalogClickingHere'),
'normal',
false
),
api_get_path(WEB_PLUGIN_PATH).'buycourses/src/service_catalog.php'
'<a href="'.$url.'">'.$url.'</a>'
);
$tpl->assign('content', $content);
$tpl->display_blank_template();
@ -133,8 +134,8 @@ if ($accessGranted == false) {
if ($link) {
$cat = new Category();
$courseId = CourseManager::get_course_by_category($categoryId);
$show_message = $cat->show_message_resource_delete($courseId);
$catCourseCode = CourseManager::get_course_by_category($categoryId);
$show_message = $cat->show_message_resource_delete($catCourseCode);
if ($show_message == '') {
if (!api_is_allowed_to_edit() && !api_is_excluded_user_type()) {
@ -257,7 +258,7 @@ function generateLPFinalItemTemplateBadgeLinks($userId, $courseId, $sessionId =
<div class='row'>
<div class='col-md-2 col-xs-4'>
<div class='thumbnail'>
<img class='skill-badge-img' src='".$skill->getWebIconPath()."' >
<img class='skill-badge-img' src='".Skill::getWebIconPath($skill)."' >
</div>
</div>
<div class='col-md-8 col-xs-8'>

@ -55,7 +55,7 @@ $sessionId = api_get_session_id();
$subscriptionSettings = learnpath::getSubscriptionSettings();
/* Introduction section (editable by course admins) */
$introductionSection = Display::return_introduction_section(
$introduction = Display::return_introduction_section(
TOOL_LEARNPATH,
[
'CreateDocumentWebDir' => api_get_path(WEB_COURSE_PATH)
@ -936,7 +936,7 @@ $template->assign('is_invitee', api_is_invitee());
$template->assign('actions', $actions);
$template->assign('categories', $categories);
$template->assign('message', $message);
$template->assign('introduction_section', $introductionSection);
$template->assign('introduction', $introduction);
$template->assign('data', $data);
$template->assign('lp_is_shown', $lpIsShown);
$template->assign('filtered_category', $filteredCategoryId);

@ -22,39 +22,14 @@ $learnPath = Session::read('oLP');
/* Header and action code */
$htmlHeadXtra[] = '<script>'.
$learnPath->get_js_dropdown_array().
"
function load_cbo(id) {
if (!id) {
return false;
}
var cbo = document.getElementById('previous');
for(var i = cbo.length - 1; i > 0; i--) {
cbo.options[i] = null;
}
var k=0;
for(var i = 1; i <= child_name[id].length; i++) {
cbo.options[i] = new Option(child_name[id][i - 1], child_value[id][i - 1]);
k=i;
}
cbo.options[k].selected = true;
$('#previous').selectpicker('refresh');
}
".
"\n".
'$().ready(function() {'."\n".
'if ($(\'#previous\')) {'."\n".
'if(\'parent is\'+$(\'#idParent\').val()) {'.
'load_cbo($(\'#idParent\').val());'."\n".
'}}'."\n".
'});</script>'."\n";
'});</script>';
/* Constants and variables */
$is_allowed_to_edit = api_is_allowed_to_edit(null, true);
$isStudentView = isset($_REQUEST['isStudentView']) ? (int) $_REQUEST['isStudentView'] : '';
@ -64,14 +39,11 @@ $submit = isset($_POST['submit_button']) ? $_POST['submit_button'] : '';
/* MAIN CODE */
if ((!$is_allowed_to_edit) || ($isStudentView)) {
header('location:lp_controller.php?action=view&lp_id='.$learnpath_id);
exit;
}
// From here on, we are admin because of the previous condition, so don't check anymore.
$course_id = api_get_course_int_id();
$sql = "SELECT * FROM $tbl_lp WHERE iid = $learnpath_id";
$result = Database::query($sql);
$therow = Database::fetch_array($result);
/*
Course admin section
@ -91,7 +63,7 @@ $interbreadcrumb[] = [
];
$interbreadcrumb[] = [
'url' => api_get_self()."?action=build&lp_id=$learnpath_id&".api_get_cidreq(),
'name' => stripslashes("{$therow['name']}"),
'name' => stripslashes($learnPath->get_name()),
];
$interbreadcrumb[] = [
'url' => api_get_self()."?action=add_item&type=step&lp_id=$learnpath_id&".api_get_cidreq(),

@ -16,16 +16,16 @@ if (!isset($origin)) {
$origin = 'learnpath';
}
$sessionId = isset($_GET['id_session']) ? intval($_GET['id_session']) : api_get_session_id();
$sessionId = isset($_GET['id_session']) ? (int) $_GET['id_session'] : api_get_session_id();
$courseCode = isset($_GET['course']) ? $_GET['course'] : api_get_course_id();
$userId = isset($_GET['student_id']) ? intval($_GET['student_id']) : api_get_user_id();
$userId = isset($_GET['student_id']) ? (int) $_GET['student_id'] : api_get_user_id();
$lpId = isset($_GET['lp_id']) ? $_GET['lp_id'] : null;
$lpItemId = isset($_GET['lp_item_id']) ? $_GET['lp_item_id'] : null;
$extendId = isset($_GET['extend_id']) ? $_GET['extend_id'] : null;
$extendAttemptId = isset($_GET['extend_attempt_id']) ? $_GET['extend_attempt_id'] : null;
$extendedAttempt = isset($_GET['extend_attempt']) ? $_GET['extend_attempt'] : null;
$extendedAll = isset($_GET['extend_all']) ? $_GET['extend_all'] : null;
$export = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
$export = isset($_GET['export']) && $_GET['export'] === 'csv' ? true : false;
$allowExtend = isset($_GET['allow_extend']) ? $_GET['allow_extend'] : 1;
$lpReportType = api_get_setting('lp_show_reduced_report');
@ -53,7 +53,7 @@ $output = Tracking::getLpStats(
// Origin = tracking means that teachers see that info in the Reporting tool
if ($origin != 'tracking') {
Display::display_reduced_header();
$output .= "</body></html>";
$output .= '</body></html>';
}
return $output;

@ -53,6 +53,7 @@ $message = Display::return_message(get_lang('UserLpCategorySubscriptionDescripti
// Building the form for Groups
$form = new FormValidator('lp_edit', 'post', $url);
$form->addElement('hidden', 'group_form', 1);
$form->addLabel('', $message);
// Group list
$groupList = \CourseManager::get_group_list_of_course(
@ -127,6 +128,7 @@ foreach ($subscribedUsersInCategory as $item) {
// Building the form for Users
$formUsers = new FormValidator('lp_edit', 'post', $url);
$formUsers->addElement('hidden', 'user_form', 1);
$formUsers->addLabel('', $message);
$userMultiSelect = $formUsers->addElement(
'advmultiselect',

@ -35,7 +35,7 @@ $show_learnpath = true;
api_protect_course_script();
$lp_id = !empty($_GET['lp_id']) ? intval($_GET['lp_id']) : 0;
$lp_id = !empty($_GET['lp_id']) ? (int) $_GET['lp_id'] : 0;
$sessionId = api_get_session_id();
$course_code = api_get_course_id();
$course_id = api_get_course_int_id();
@ -60,8 +60,8 @@ $visibility = api_get_item_visibility(
$sessionId
);
if (!api_is_allowed_to_edit(false, true, false, false) &&
intval($visibility) == 0
if ($visibility === 0 &&
!api_is_allowed_to_edit(false, true, false, false)
) {
api_not_allowed(true);
}
@ -113,7 +113,7 @@ if (!$is_allowed_to_edit) {
}
}
$platform_theme = api_get_setting('stylesheets'); // Platform's css.
$platform_theme = api_get_setting('stylesheets');
$my_style = $platform_theme;
$ajaxUrl = api_get_path(WEB_AJAX_PATH).'lp.ajax.php?a=get_item_prerequisites&'.api_get_cidreq();
$htmlHeadXtra[] = '<script>
@ -300,9 +300,9 @@ if (!empty($_REQUEST['exeId']) &&
$TBL_TRACK_EXERCICES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$TBL_LP_ITEM_VIEW = Database::get_course_table(TABLE_LP_ITEM_VIEW);
$TBL_LP_ITEM = Database::get_course_table(TABLE_LP_ITEM);
$safe_item_id = intval($_GET['lp_item_id']);
$safe_item_id = (int) $_GET['lp_item_id'];
$safe_id = $lp_id;
$safe_exe_id = intval($_REQUEST['exeId']);
$safe_exe_id = (int) $_REQUEST['exeId'];
if ($safe_id == strval(intval($safe_id)) &&
$safe_item_id == strval(intval($safe_item_id))

@ -48,8 +48,8 @@ if (empty($lp)) {
}
$mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : 'fullpage';
if (isset($lp) && isset($_GET['id'])) {
$lp->current = intval($_GET['id']);
if (isset($_SESSION['oLP']) && isset($_GET['id'])) {
$_SESSION['oLP']->current = intval($_GET['id']);
}
$this_section = SECTION_COURSES;
/* Header and action code */

@ -67,6 +67,9 @@ abstract class OpenofficeDocument extends learnpath
$this->file_path = $this->created_dir.'/'.api_replace_dangerous_char($file['name']);
}
$dirMode = api_get_permissions_for_new_directories();
$fileMode = api_get_permissions_for_new_files();
//var_dump($this->file_name, $this->file_path, $this->base_work_dir, $this->created_dir);
/*
@ -123,9 +126,9 @@ abstract class OpenofficeDocument extends learnpath
// Call to the function implemented by child.
$cmd .= $this->add_command_parameters();
// To allow openoffice to manipulate docs.
@chmod($this->base_work_dir, 0777);
@chmod($this->base_work_dir.$this->created_dir, 0777);
@chmod($this->base_work_dir.$this->file_path, 0777);
@chmod($this->base_work_dir, $dirMode);
@chmod($this->base_work_dir.$this->created_dir, $dirMode);
@chmod($this->base_work_dir.$this->file_path, $fileMode);
$locale = $this->original_locale; // TODO: Improve it because we're not sure this locale is present everywhere.
putenv('LC_ALL='.$locale);
@ -163,7 +166,7 @@ abstract class OpenofficeDocument extends learnpath
foreach ($result['images'] as $image => $img_data) {
$image_path = $this->base_work_dir.$this->created_dir;
@file_put_contents($image_path.'/'.$image, base64_decode($img_data));
@chmod($image_path.'/'.$image, 0777);
@chmod($image_path.'/'.$image, $fileMode);
}
}

@ -6,11 +6,13 @@
* @author Yannick Warnier - inspired by the ADLNet documentation on SCORM content-side API
* @package scorm.js
*/
/**
* Initialisation of the SCORM API section.
* Find the SCO functions (startTimer, computeTime, etc in the second section)
* Find the Chamilo-proper functions (checkAnswers, etc in the third section)
*/
var _debug = true;
var findAPITries = 0;
var _apiHandle = null; //private variable
@ -27,6 +29,8 @@ var _InvalidSetValue = 402;
var _ElementIsReadOnly = 403;
var _ElementIsWriteOnly = 404;
var _IncorrectDataType = 405;
var startTime;
var exitPageStatus;
/**
* Gets the API handle right into the local API object and ensure there is only one.
@ -78,11 +82,12 @@ function getAPI()
}
return MyAPI;
}
/**
* Handles error codes (prints the error if it has a description)
* @return int Error code from LMS's API
*/
function ErrorHandler()
function errorHandler()
{
if (API == null) {
alert("Unable to locate the LMS's API. Cannot determine LMS error code");
@ -96,19 +101,31 @@ function ErrorHandler()
errDescription += "\n";
errDescription += api.LMSGetDiagnostic(null);
}
console.log(errDescription);
addDebug(errDescription);
} else {
var errDescription = API.LMSGetErrorString(errCode);
if (_debug) {
errDescription += "\n";
errDescription += api.LMSGetDiagnostic(null);
}
console.log(errDescription);
addDebug(errDescription);
}
}
return errCode;
}
function addDebug(message) {
if (_debug && window.console) {
console.log(message);
}
}
function addDebugTable(message) {
if (_debug && window.console) {
console.table(message);
}
}
/**
* Calls the LMSInitialize method of the LMS's API object
* @return string The string value of the LMS returned value or false if error (should be "true" otherwise)
@ -119,9 +136,10 @@ function doLMSInitialize()
alert(errMsgLocate + "\nLMSInitialize failed");
return false;
}
var result = API.LMSInitialize("");
if (result.toString() != "true") {
var err = ErrorHandler();
var err = errorHandler();
}
return result.toString();
}
@ -138,7 +156,7 @@ function doLMSFinish()
} else {
var result = API.LMSFinish('');
if (result.toString() != "true") {
var err = ErrorHandler();
var err = errorHandler();
}
}
return result.toString();
@ -152,16 +170,18 @@ function doLMSGetValue(name)
{
if (API == null) {
alert(errMsgLocate + "\nLMSGetValue was not successful.");
return "";
return '';
} else {
var value = API.LMSGetValue(name);
var errCode = API.LMSGetLastError().toString();
if (errCode != _NoError) {
// an error was encountered so display the error description
var errDescription = API.LMSGetErrorString(errCode);
alert("LMSGetValue(" + name + ") failed. \n" + errDescription);
return "";
addDebug("LMSGetValue(" + name + ") failed. \n" + errDescription)
return '';
}
return value.toString();
}
}
@ -179,7 +199,7 @@ function doLMSSetValue(name, value)
} else {
var result = API.LMSSetValue(name, value);
if (result.toString() != "true") {
var err = ErrorHandler();
var err = errorHandler();
}
}
return;
@ -196,7 +216,7 @@ function doLMSCommit()
} else {
var result = API.LMSCommit("");
if (result != "true") {
var err = ErrorHandler();
var err = errorHandler();
}
}
return result.toString();
@ -224,7 +244,7 @@ function doLMSGetErrorString(errorCode)
alert(errMsgLocate + "\nLMSGetErrorString was not successful.");
}
return API.LMSGetErrorString(errorCode).toString();
return API.LMSGetErrorString(errorCode).toString();
}
/**
@ -236,15 +256,9 @@ function doLMSGetDiagnostic(errorCode)
alert(errMsgLocate + "\nLMSGetDiagnostic was not successful.");
}
return API.LMSGetDiagnostic(errorCode).toString();
return API.LMSGetDiagnostic(errorCode).toString();
}
/**
* Second section. The SCO functions are located here (handle time and score messaging to SCORM API)
* Initialisation
*/
var startTime;
var exitPageStatus;
/**
* Initialise page values
*/
@ -379,18 +393,10 @@ function unloadPage(status)
{
if (!exitPageStatus)
{
// doQuit( status );
// doQuit( status );
}
}
/**
* Third section - depending on Chamilo - check answers and set score
*/
var questions = new Array();
var questions_answers = new Array();
var questions_answers_correct = new Array();
var questions_types = new Array();
var questions_score_max = new Array();
var questions_answers_ponderation = new Array();
/**
* Checks the answers on the test formular page
*/
@ -400,13 +406,10 @@ function checkAnswers(interrupted)
var status = 'not attempted';
var scoreMax = 0;
if (_debug) {
console.log('questions_answers_correct:');
console.log(questions_answers_correct);
}
addDebug('Number of questions: '+ questions.length);
for (var i=0; i < questions.length; i++) {
if (questions[i] != undefined && questions[i] != null){
if (questions[i] != undefined && questions[i] != null) {
var idQuestion = questions[i];
var type = questions_types[idQuestion];
var interactionScore = 0;
@ -414,69 +417,45 @@ function checkAnswers(interrupted)
var interactionCorrectResponses = '';
var interactionType = '';
if (_debug) {
console.log('Type: ' +type);
console.log('idQuestion: ' +idQuestion);
console.log('questions_answers: ');
console.log(questions_answers[idQuestion]);
console.log('questions_answers_ponderation: ');
console.log(questions_answers_ponderation[idQuestion]);
console.log('questions_answers_correct: ');
console.log(questions_answers_correct[idQuestion]);
}
if (type == 'mcma') {
interactionType = 'choice';
var myScore = 0;
for(var j=0; j<questions_answers[idQuestion].length;j++) {
var idAnswer = questions_answers[idQuestion][j];
var answer = document.getElementById('question_'+(idQuestion)+'_multiple_'+(idAnswer));
if (answer.checked) {
interactionAnswers += idAnswer+'__|';// changed by isaac flores
myScore += questions_answers_ponderation[idQuestion][idAnswer];
}
}
interactionScore = myScore;
scoreMax += questions_score_max[idQuestion];
if (_debug) {
console.log("Score: "+myScore);
}
} else if (type == 'mcua') {
interactionType = 'choice';
var myScore = 0;
for (var j=0; j<questions_answers[idQuestion].length;j++) {
var idAnswer = questions_answers[idQuestion][j];
var answer = document.getElementById('question_'+(idQuestion)+'_unique_'+(idAnswer));
if (answer.checked) {
interactionAnswers += idAnswer;
if (_debug) {
console.log("idAnswer: "+idAnswer);
console.log("questions_answers_correct: "+questions_answers_correct[idQuestion][idAnswer]);
}
if (questions_answers_correct[idQuestion][idAnswer] == idAnswer) {
if (questions_answers_ponderation[idQuestion][idAnswer]) {
myScore += questions_answers_ponderation[idQuestion][idAnswer];
} else {
myScore++;
}
addDebug('idQuestion: ' +idQuestion + ', Type: ' +type);
addDebug('questions_answers: ');
addDebugTable(questions_answers[idQuestion]);
addDebug('questions_answers_ponderation: ');
addDebugTable(questions_answers_ponderation[idQuestion]);
addDebug('questions_answers_correct: ');
addDebugTable(questions_answers_correct[idQuestion]);
switch (type) {
case 'mcma':
interactionType = 'choice';
var myScore = 0;
for(var j = 0; j< questions_answers[idQuestion].length;j++) {
var idAnswer = questions_answers[idQuestion][j];
var answer = document.getElementById('question_'+(idQuestion)+'_multiple_'+(idAnswer));
if (answer.checked) {
interactionAnswers += idAnswer+'__|';// changed by isaac flores
myScore += questions_answers_ponderation[idQuestion][idAnswer];
}
}
}
if (_debug) {
console.log("Score: "+myScore);
}
interactionScore = myScore;
scoreMax += questions_score_max[idQuestion];
} else if (type == 'tf') {
interactionType = 'true-false';
var myScore = 0;
for (var j = 0; j < questions_answers[idQuestion].length; j++) {
var idAnswer = questions_answers[idQuestion][j];
var answer = document.getElementById('question_' + idQuestion + '_tf_' + (idAnswer));
if (answer.checked.value) {
interactionAnswers += idAnswer;
for (k = 0; k < questions_answers_correct[idQuestion].length; k++) {
if (questions_answers_correct[idQuestion][k] == idAnswer) {
interactionScore = myScore;
scoreMax += questions_score_max[idQuestion];
addDebug("Score: "+myScore);
break;
case 'mcua':
interactionType = 'choice';
var myScore = 0;
for (var j = 0; j<questions_answers[idQuestion].length; j++) {
var idAnswer = questions_answers[idQuestion][j];
var elementId = 'question_'+(idQuestion)+'_unique_'+(idAnswer);
var answer = document.getElementById(elementId);
if (answer.checked) {
addDebug('Element id # "'+ elementId +'" was checked');
interactionAnswers += idAnswer;
addDebug("List of correct answers: "+questions_answers_correct[idQuestion]);
addDebug('Score for this answer: ' + questions_answers_ponderation[idQuestion][idAnswer]);
addDebug("idAnswer: "+idAnswer);
addDebug("Option selected: "+questions_answers_correct[idQuestion][idAnswer]);
if (questions_answers_correct[idQuestion][idAnswer] == 1) {
if (questions_answers_ponderation[idQuestion][idAnswer]) {
myScore += questions_answers_ponderation[idQuestion][idAnswer];
} else {
@ -485,132 +464,166 @@ function checkAnswers(interrupted)
}
}
}
}
if (_debug) {
console.log("Score: "+myScore);
}
interactionScore = myScore;
scoreMax += questions_score_max[idQuestion];
} else if (type == 'fib') {
interactionType = 'fill-in';
var myScore = 0;
for (var j = 0; j < questions_answers[idQuestion].length; j++) {
var idAnswer = questions_answers[idQuestion][j];
var answer = document.getElementById('question_'+(idQuestion)+'_fib_'+(idAnswer));
if (answer.value) {
interactionAnswers += answer.value + '__|';//changed by isaac flores
for (k = 0; k < questions_answers_correct[idQuestion].length; k++) {
if (questions_answers_correct[idQuestion][k] == answer.value) {
if (questions_answers_ponderation[idQuestion][idAnswer]) {
myScore += questions_answers_ponderation[idQuestion][idAnswer];
} else {
myScore++;
addDebug("Score: "+myScore);
interactionScore = myScore;
scoreMax += questions_score_max[idQuestion];
break;
case 'tf':
interactionType = 'true-false';
var myScore = 0;
for (var j = 0; j < questions_answers[idQuestion].length; j++) {
var idAnswer = questions_answers[idQuestion][j];
var answer = document.getElementById('question_' + idQuestion + '_tf_' + (idAnswer));
if (answer.checked.value) {
interactionAnswers += idAnswer;
for (k = 0; k < questions_answers_correct[idQuestion].length; k++) {
if (questions_answers_correct[idQuestion][k] == idAnswer) {
if (questions_answers_ponderation[idQuestion][idAnswer]) {
myScore += questions_answers_ponderation[idQuestion][idAnswer];
} else {
myScore++;
}
}
}
}
}
}
if (_debug) {
console.log("Score: "+myScore);
}
interactionScore = myScore;
scoreMax += questions_score_max[idQuestion];
} else if (type == 'matching') {
interactionType = 'matching';
var myScore = 0;
for (var j = 0; j < questions_answers[idQuestion].length; j++) {
var idAnswer = questions_answers[idQuestion][j];
var answer = document.getElementById('question_' + (idQuestion) + '_matching_' + (idAnswer));
if (answer && answer.value) {
interactionAnswers += answer.value + '__|';//changed by isaac flores
for (k = 0; k < questions_answers_correct[idQuestion].length; k++) {
var left = questions_answers_correct[idQuestion][k][0];
var right = questions_answers_correct[idQuestion][k][1];
if (left == idAnswer && right == answer.value) {
if (questions_answers_ponderation[idQuestion][idAnswer]) {
myScore += questions_answers_ponderation[idQuestion][idAnswer];
} else {
myScore++;
addDebug("Score: "+ myScore);
interactionScore = myScore;
scoreMax += questions_score_max[idQuestion];
break;
case 'fib':
interactionType = 'fill-in';
var myScore = 0;
for (var j = 0; j < questions_answers[idQuestion].length; j++) {
var idAnswer = questions_answers[idQuestion][j];
var answer = document.getElementById('question_'+(idQuestion)+'_fib_'+(idAnswer));
if (answer.value) {
interactionAnswers += answer.value + '__|';//changed by isaac flores
for (k = 0; k < questions_answers_correct[idQuestion].length; k++) {
if (questions_answers_correct[idQuestion][k] == answer.value) {
if (questions_answers_ponderation[idQuestion][idAnswer]) {
myScore += questions_answers_ponderation[idQuestion][idAnswer];
} else {
myScore++;
}
}
}
}
}
}
if (_debug) {
console.log("Score: "+myScore);
}
interactionScore = myScore;
scoreMax += questions_score_max[idQuestion];
} else if (type == 'free') {
//ignore for now as a score cannot be given
interactionType = 'free';
var answer = document.getElementById('question_'+(idQuestion)+'_free');
if (answer && answer.value) {
interactionAnswers += answer.value
}
//interactionScore = questions_score_max[idQuestion];
interactionScore = 0;
scoreMax += questions_score_max[idQuestion];
//interactionAnswers = document.getElementById('question_'+(idQuestion)+'_free').value;
//correct responses work by pattern, see SCORM Runtime Env Doc
//interactionCorrectResponses += questions_answers_correct[idQuestion].toString();
} else if (type == 'hotspot') {
interactionType = 'sequencing';
interactionScore = 0;
//if(question_score && question_score[idQuestion]){
// interactionScore = question_score[idQuestion];
//} //else, 0
//interactionAnswers = document.getElementById('question_'+(idQuestion)+'_free').innerHTML;
//correct responses work by pattern, see SCORM Runtime Env Doc
//for(k=0;k<questions_answers_correct[idQuestion].length;k++)
//{
// interactionCorrectResponses += questions_answers_correct[idQuestion][k].toString()+',';
//}
} else if (type == 'exact') {
interactionType = 'exact';
interactionScore = 0;
var real_answers = new Array();
for (var j = 0; j < questions_answers[idQuestion].length; j++) {
var idAnswer = questions_answers[idQuestion][j];
var answer = document.getElementById('question_' + (idQuestion) + '_exact_' + (idAnswer));
if (answer.checked == true) {
interactionAnswers += idAnswer+', ';
if (questions_answers_correct[idQuestion][idAnswer] != 0) {
real_answers[j] = true;
} else {
real_answers[j] = false;
addDebug("Score: "+myScore);
interactionScore = myScore;
scoreMax += questions_score_max[idQuestion];
break;
case 'matching':
interactionType = 'matching';
var myScore = 0;
addDebug("List of correct answers: ");
console.log(questions_answers_correct[idQuestion]);
for (var j = 0; j < questions_answers[idQuestion].length; j++) {
var idAnswer = questions_answers[idQuestion][j];
var elementId = 'question_' + (idQuestion) + '_matching_' + (idAnswer);
addDebug("---------idAnswer #"+idAnswer+'------------------');
addDebug("Checking element #"+elementId);
var answer = document.getElementById(elementId);
if (answer && answer.value) {
interactionAnswers += answer.value + '__|';//changed by isaac flores
for (k = 0; k < questions_answers_correct[idQuestion].length; k++) {
var left = questions_answers_correct[idQuestion][k][0];
var right = questions_answers_correct[idQuestion][k][1];
addDebug('Left ' + left);
addDebug('Right ' + right);
addDebug('answer.value ' + answer.value);
if (right == idAnswer && left == answer.value) {
addDebug('Score for this answer: ' + questions_answers_ponderation[idQuestion][idAnswer]);
if (questions_answers_ponderation[idQuestion][idAnswer]) {
myScore += questions_answers_ponderation[idQuestion][idAnswer];
} else {
// myScore++;
}
}
}
}
} else {
if (questions_answers_correct[idQuestion][idAnswer] != 0) {
real_answers[j] = false;
addDebug("Partial score: "+myScore);
addDebug("--------- end --- idAnswer #"+idAnswer+'------------------');
}
addDebug("Score: "+myScore);
interactionScore = myScore;
scoreMax += questions_score_max[idQuestion];
break;
case 'free':
//ignore for now as a score cannot be given
interactionType = 'free';
var answer = document.getElementById('question_'+(idQuestion)+'_free');
if (answer && answer.value) {
interactionAnswers += answer.value
}
//interactionScore = questions_score_max[idQuestion];
interactionScore = 0;
scoreMax += questions_score_max[idQuestion];
//interactionAnswers = document.getElementById('question_'+(idQuestion)+'_free').value;
//correct responses work by pattern, see SCORM Runtime Env Doc
//interactionCorrectResponses += questions_answers_correct[idQuestion].toString();
break;
case 'hotspot':
interactionType = 'sequencing';
interactionScore = 0;
//if(question_score && question_score[idQuestion]){
// interactionScore = question_score[idQuestion];
//} //else, 0
//interactionAnswers = document.getElementById('question_'+(idQuestion)+'_free').innerHTML;
//correct responses work by pattern, see SCORM Runtime Env Doc
//for(k=0;k<questions_answers_correct[idQuestion].length;k++)
//{
// interactionCorrectResponses += questions_answers_correct[idQuestion][k].toString()+',';
//}
break;
case 'exact':
interactionType = 'exact';
interactionScore = 0;
var real_answers = new Array();
for (var j = 0; j < questions_answers[idQuestion].length; j++) {
var idAnswer = questions_answers[idQuestion][j];
var answer = document.getElementById('question_' + (idQuestion) + '_exact_' + (idAnswer));
if (answer.checked == true) {
interactionAnswers += idAnswer+', ';
if (questions_answers_correct[idQuestion][idAnswer] != 0) {
real_answers[j] = true;
} else {
real_answers[j] = false;
}
} else {
real_answers[j] = true;
if (questions_answers_correct[idQuestion][idAnswer] != 0) {
real_answers[j] = false;
} else {
real_answers[j] = true;
}
}
}
}
var final_answer = true;
for (var z = 0; z < real_answers.length; z++) {
if (real_answers[z] == false) {
final_answer = false;
var final_answer = true;
for (var z = 0; z < real_answers.length; z++) {
if (real_answers[z] == false) {
final_answer = false;
}
}
interactionScore = 0;
addDebug(real_answers);
if (final_answer) {
//getting only the first score where we save the weight of all the question
interactionScore = questions_answers_ponderation[idQuestion][1];
}
}
interactionScore = 0;
console.log(real_answers);
if (final_answer) {
//getting only the first score where we save the weight of all the question
interactionScore = questions_answers_ponderation[idQuestion][1];
}
if (_debug) {
console.log("Score: "+interactionScore);
}
scoreMax += questions_score_max[idQuestion];
addDebug("Score: "+interactionScore);
scoreMax += questions_score_max[idQuestion];
break;
}
tmpScore += interactionScore;
doLMSSetValue('cmi.interactions.'+idQuestion+'.id', 'Q'+idQuestion);
doLMSSetValue('cmi.interactions.'+idQuestion+'.type', interactionType);
doLMSSetValue('cmi.interactions.'+idQuestion+'.student_response', interactionAnswers);
@ -621,29 +634,81 @@ function checkAnswers(interrupted)
doLMSSetValue('cmi.core.score.max', scoreMax);
doLMSSetValue('cmi.core.score.raw', tmpScore);
//get status
// Get status
var mastery_score = doLMSGetValue('cmi.student_data.mastery_score');
if (mastery_score <= 0) {
mastery_score = (scoreMax * 0.80);
}
if (tmpScore > mastery_score) {
if (tmpScore >= mastery_score) {
status = 'passed';
} else {
status = 'failed';
}
if (_debug) {
console.log('student_score: ' + tmpScore);
console.log('mastery_score: ' + mastery_score);
console.log('cmi.core.score.max: ' + scoreMax);
console.log('cmi.core.lesson_status: ' + status);
}
addDebug('student_score: ' + tmpScore);
addDebug('mastery_score: ' + mastery_score);
addDebug('cmi.core.score.max: ' + scoreMax);
addDebug('cmi.core.lesson_status: ' + status);
doLMSSetValue('cmi.core.lesson_status', status);
if (interrupted && (status != 'completed') && (status != 'passed')) {
doLMSSetValue('cmi.core.exit', 'suspended');
}
return false; //do not submit the form
}
(function($){
//Shuffle all rows, while keeping the first column
//Requires: Shuffle
$.fn.shuffleRows = function(){
return this.each(function(){
var main = $(/table/i.test(this.tagName) ? this.tBodies[0] : this);
var firstElem = [], counter=0;
main.children().each(function(){
firstElem.push(this.firstChild);
});
main.shuffle();
main.children().each(function(){
this.insertBefore(firstElem[counter++], this.firstChild);
});
});
}
/* Shuffle is required */
$.fn.shuffle = function() {
return this.each(function(){
var items = $(this).children();
return (items.length)
? $(this).html($.shuffle(items))
: this;
});
}
$.shuffle = function(arr) {
for(
var j, x, i = arr.length; i;
j = parseInt(Math.random() * i),
x = arr[--i], arr[i] = arr[j], arr[j] = x
);
return arr;
}
})(jQuery);
/*
* Assigns any event handler to any element
* @param object Element on which the event is added
* @param string Name of event
* @param string Function to trigger on event
* @param boolean Capture the event and prevent
*/
function addEvent(elm, evType, fn, useCapture)
{
if (elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;
} else if(elm.attachEvent) {
var r = elm.attachEvent('on' + evType, fn);
return r;
} else {
elm['on' + evType] = fn;
}
}

@ -63,13 +63,8 @@ class scorm extends learnpath
/**
* Possible SCO status: see CAM doc 2.3.2.5.1: passed, completed, browsed, failed, not attempted, incomplete.
*/
/**
* Prerequisites: see CAM doc 2.3.2.5.1 for pseudo-code.
*/
/**
*
* Parses an imsmanifest.xml file and puts everything into the $manifest array.
*
* @param string Path to the imsmanifest.xml file on the system.
@ -289,7 +284,7 @@ class scorm extends learnpath
'$iFrameHolder.html(iFrameTag);',
];
$replace = [
'iFrameTag = \'<a target ="_blank" href="'.$proxyPath.'?type=link&src=\'+ pageSrc + \'">Open website. <img src="'.api_get_path(WEB_CODE_PATH).'img/link-external.png"></a>\'; $iFrameHolder.html(iFrameTag); ',
'iFrameTag = \'<a target ="_blank" href="'.$proxyPath.'?type=link&src=\'+ pageSrc + \'">Open website. <img width="16px" src="'.Display::returnIconPath('link-external.png').'"></a>\'; $iFrameHolder.html(iFrameTag); ',
];
$content = str_replace($find, $replace, $content);
file_put_contents($framePath, $content);
@ -340,15 +335,15 @@ class scorm extends learnpath
$courseInfo = api_get_course_info($courseCode);
$courseId = $courseInfo['real_id'];
$userId = intval($userId);
$userId = (int) $userId;
if (empty($userId)) {
$userId = api_get_user_id();
}
// Get table names.
$new_lp = Database::get_course_table(TABLE_LP_MAIN);
$new_lp_item = Database::get_course_table(TABLE_LP_ITEM);
$userMaxScore = intval($userMaxScore);
$sessionId = empty($sessionId) ? api_get_session_id() : intval($sessionId);
$userMaxScore = (int) $userMaxScore;
$sessionId = empty($sessionId) ? api_get_session_id() : (int) $sessionId;
foreach ($this->organizations as $id => $dummy) {
$oOrganization = &$this->organizations[$id];
// Prepare and execute insert queries:
@ -472,13 +467,12 @@ class scorm extends learnpath
}
$title = Database::escape_string($item['title']);
$title = api_utf8_decode($title);
$max_score = (int) $item['max_score'];
$max_score = intval($item['max_score']);
if ($max_score == 0 || is_null($max_score) || $max_score == '') {
if ($max_score === 0) {
// If max score is not set The use_max_score parameter
// is check in order to use 100 (chamilo style) or '' (strict scorm)
$max_score = "NULL";
$max_score = 'NULL';
if ($userMaxScore) {
$max_score = 100;
}
@ -547,11 +541,12 @@ class scorm extends learnpath
$courseid = api_get_course_id();
$ic_slide->addCourseId($courseid);
$ic_slide->addToolId(TOOL_LEARNPATH);
// TODO: Unify with other lp types.
$xapian_data = [
SE_COURSE_ID => $courseid,
SE_TOOL_ID => TOOL_LEARNPATH,
SE_DATA => ['lp_id' => $lp_id, 'lp_item' => $previous, 'document_id' => ''], // TODO: Unify with other lp types.
SE_USER => (int) api_get_user_id(),
SE_DATA => ['lp_id' => $lp_id, 'lp_item' => $previous, 'document_id' => ''],
SE_USER => api_get_user_id(),
];
$ic_slide->xapian_data = serialize($xapian_data);
$di->addChunk($ic_slide);
@ -607,7 +602,9 @@ class scorm extends learnpath
$lpToCheck = null
) {
if ($this->debug > 0) {
error_log('In scorm::import_package('.print_r($zip_file_info, true).',"'.$current_dir.'") method', 0);
error_log(
'In scorm::import_package('.print_r($zip_file_info, true).',"'.$current_dir.'") method'
);
}
$courseInfo = empty($courseInfo) ? api_get_course_info() : $courseInfo;
@ -646,8 +643,6 @@ class scorm extends learnpath
// Check the zip content (real size and file extension).
$zipContentArray = $zipFile->listContent();
$package_type = '';
$at_root = false;
$manifest = '';
$manifest_list = [];
// The following loop should be stopped as soon as we found the right imsmanifest.xml (how to recognize it?).
$realFileSize = 0;
@ -656,9 +651,7 @@ class scorm extends learnpath
$file = $thisContent['filename'];
$this->set_error_msg("File $file contains a PHP script");
} elseif (stristr($thisContent['filename'], 'imsmanifest.xml')) {
//error_log('Found imsmanifest at '.$thisContent['filename'], 0);
if ($thisContent['filename'] == basename($thisContent['filename'])) {
$at_root = true;
} else {
if ($this->debug > 2) {
error_log("New LP - subdir is now ".$this->subdir);
@ -666,7 +659,6 @@ class scorm extends learnpath
}
$package_type = 'scorm';
$manifest_list[] = $thisContent['filename'];
$manifest = $thisContent['filename']; //just the relative directory inside scorm/
}
$realFileSize += $thisContent['size'];
}
@ -684,13 +676,10 @@ class scorm extends learnpath
$this->subdir .= '/'.dirname($shortest_path); // Do not concatenate because already done above.
$manifest = $shortest_path;
if ($this->debug > 1) {
error_log('New LP - Package type is now '.$package_type);
if ($this->debug) {
error_log("New LP - Package type is now: '$package_type'");
}
if ($package_type == '') {
if ($this->debug > 1) {
error_log('New LP - Package type is empty');
}
Display::addFlash(
Display::return_message(get_lang('NotScormContent'))
);
@ -728,7 +717,6 @@ class scorm extends learnpath
}
/* Uncompressing phase */
/*
We need to process each individual file in the zip archive to
- add it to the database
@ -770,11 +758,6 @@ class scorm extends learnpath
}
while ($file = readdir($dir)) {
if ($file != '.' && $file != '..') {
$filetype = 'file';
if (is_dir($course_sys_dir.$new_dir.$file)) {
$filetype = 'folder';
}
// TODO: RENAMING FILES CAN BE VERY DANGEROUS SCORM-WISE, avoid that as much as possible!
//$safe_file = api_replace_dangerous_char($file, 'strict');
$find_str = ['\\', '.php', '.phtml'];

@ -385,7 +385,7 @@ function Initialize() {
* @return string All return values must be string (see SCORM)
*/
function LMSGetValue(param) {
olms.G_LastError = G_NoError ;
olms.G_LastError = G_NoError;
olms.G_LastErrorMessage = 'No error';
var result='';
@ -394,14 +394,13 @@ function LMSGetValue(param) {
if (param == 'cmi.core.score.raw') {
return '';
}
olms.G_LastError = G_NotInitialized;
olms.G_LastError = G_NotInitialized;
olms.G_LastErrorMessage = G_NotInitializedMessage;
logit_scorm('LMSGetValue('+param+') on item id '+olms.lms_item_id+':<br />=> Error '+ G_NotInitialized + ' ' +G_NotInitializedMessage, 0);
return '';
}
//Chamilo does not support these SCO object properties
// Chamilo does not support these SCO object properties
if (param == 'cmi.student_preference.text' ||
param == 'cmi.student_preference.language' ||
param == 'cmi.student_preference.speed' ||
@ -410,8 +409,8 @@ function LMSGetValue(param) {
param == 'cmi.student_data.time_limit_action' ||
param == 'cmi.comments' ||
param == 'cmi.comments_from_lms' ||
/* The following properties were part of SCORM 1.0 or never implemented at all
but seem to react badly to Captivate content producer when not defined */
/* The following properties were part of SCORM 1.0 or never implemented at all
but seem to react badly to Captivate content producer when not defined */
param == 'cmi.student_demographics._children' ||
param == 'cmi.student_demographics.city' ||
param == 'cmi.student_demographics.class' ||
@ -429,7 +428,7 @@ function LMSGetValue(param) {
// the value is not supported
olms.G_LastError = G_NotImplementedError ;
olms.G_LastErrorString = G_NotImplementedErrorMessage;
logit_scorm("LMSGetValue ('"+param+"') Error '"+G_NotImplementedErrorMessage+"'",1);
logit_scorm("LMSGetValue ('"+param+"') Error '"+G_NotImplementedErrorMessage+"'",1);
result = '';
return result;
}
@ -449,7 +448,7 @@ function LMSGetValue(param) {
} else {
result='';
}
} else if(param == 'cmi.core.exit'){
} else if(param == 'cmi.core.exit') {
// ---- cmi.core.exit
result='';
olms.G_LastError = G_ElementIsWriteOnly;
@ -458,8 +457,8 @@ function LMSGetValue(param) {
olms.G_LastError = G_ElementIsWriteOnly;
} else if(param == 'cmi.core.lesson_status'){
// ---- cmi.core.lesson_status
if(olms.lesson_status != '') {
result=olms.lesson_status;
if (olms.lesson_status != '') {
result = olms.lesson_status;
} else {
//result='not attempted';
}
@ -637,18 +636,17 @@ function LMSSetValue(param, val) {
olms.commit = true; //value has changed, need to re-commit
olms.G_LastError = G_NoError ;
olms.G_LastErrorMessage = 'No error';
return_value = 'false';
if ( param == "cmi.core.score.raw" ) {
if (param == "cmi.core.score.raw") {
olms.score= val;
olms.updatable_vars_list['cmi.core.score.raw']=true;
return_value='true';
} else if ( param == "cmi.core.score.max" ) {
} else if ( param == "cmi.core.score.max") {
olms.max = val;
olms.updatable_vars_list['cmi.core.score.max']=true;
return_value='true';
} else if ( param == "cmi.core.score.min" ) {
} else if ( param == "cmi.core.score.min") {
olms.min = val;
olms.updatable_vars_list['cmi.core.score.min']=true;
return_value='true';
@ -681,9 +679,9 @@ function LMSSetValue(param, val) {
success_status = val;
olms.updatable_vars_list['cmi.success_status']=true;
return_value='true'; //1.3
} else if ( param == "cmi.suspend_data" ) {
} else if ( param == "cmi.suspend_data") {
olms.suspend_data = val;
olms.updatable_vars_list['cmi.suspend_data']=true;
olms.updatable_vars_list['cmi.suspend_data'] = true;
return_value='true';
} else if ( param == "cmi.core.exit" ) {
olms.lms_item_core_exit = val;
@ -797,11 +795,11 @@ function LMSSetValue(param, val) {
if(olms.item_objectives[obj_id]==null) {
olms.item_objectives[obj_id] = ['','','','',''];
}
if( req_type == "id" ) {
//olms.item_objectives[obj_id][0] = val.substring(51,57);
olms.item_objectives[obj_id][0] = val;
logit_scorm("Objective "+obj_id+"'s id updated",2);
return_value = 'true';
if (req_type == "id") {
//olms.item_objectives[obj_id][0] = val.substring(51,57);
olms.item_objectives[obj_id][0] = val;
logit_scorm("Objective "+obj_id+"'s id updated",2);
return_value = 'true';
} else if ( req_type == "score" ) {
if (myres[3] == '._children'){
return_value = '';
@ -819,18 +817,18 @@ function LMSSetValue(param, val) {
olms.item_objectives[obj_id][4] = val;
logit_scorm("Objective "+obj_id+"'s score min updated",2);
return_value = 'true';
} else{
} else {
return_value = '';
olms.G_LastError = G_NotImplementedError;
olms.G_LastErrorString = 'Not implemented yet';
}
} else if ( req_type == "status" ) {
olms.item_objectives[obj_id][1] = val;
logit_scorm("Objective "+obj_id+"'s status updated",2);
return_value = 'true';
olms.item_objectives[obj_id][1] = val;
logit_scorm("Objective "+obj_id+"'s status updated",2);
return_value = 'true';
} else {
olms.G_LastError = G_NotImplementedError;
olms.G_LastErrorString = 'Not implemented yet';
olms.G_LastError = G_NotImplementedError;
olms.G_LastErrorString = 'Not implemented yet';
}
}
}
@ -863,13 +861,11 @@ function savedata(item_id) {
logit_lms('function savedata(' + item_id + ')', 3);
// Status is NOT modified here see the lp_ajax_save_item.php file
if (olms.lesson_status != '') {
olms.updatable_vars_list['cmi.core.lesson_status'] = true;
}
old_item_id = olms.info_lms_item[0];
var item_to_save = olms.lms_item_id;
logit_lms('item_to_save (original value): ' + item_to_save, 3);
@ -982,8 +978,9 @@ function Finish(val) {
* @return string Error code
*/
function LMSGetLastError() {
logit_scorm('LMSGetLastError()',1);
return(olms.G_LastError.toString());
var error = olms.G_LastError.toString();
logit_scorm('LMSGetLastError() returned: ' + error, 1);
return error;
}
/**
@ -1244,7 +1241,7 @@ function log_in_log(message, priority) {
*/
function logit_lms(message, priority){
if (scorm_logs) {
log_in_log("LMS: " + message + ' (# lms_item_id = '+olms.lms_item_id+')', priority);
log_in_log("LMS: " + message + ' (#lms_item_id = '+olms.lms_item_id+')', priority);
}
return false;
}
@ -1421,7 +1418,7 @@ function reinit_updatable_vars_list() {
olms.updatable_vars_list[olms.scorm_variables[i]]=false;
}
}
olms.lesson_status='';
olms.lesson_status = 'not attempted';
}
/**
@ -1894,9 +1891,7 @@ function xajax_save_item_scorm(
params += '&userNavigatesAway='+userNavigatesAway;
params += '&statusSignalReceived='+statusSignalReceived;
var my_scorm_values = new Array();
my_scorm_values = process_scorm_values();
for (k=0; k < my_scorm_values.length; k++) {
if (my_scorm_values[k]=='cmi.core.session_time') {
params += '&t='+olms.session_time;
@ -1928,7 +1923,6 @@ function xajax_save_item_scorm(
if (is_interactions == 'true') {
interact_string = '';
temp = '';
for (i in olms.interactions) {
interact_string += '&interact['+i+']=';
interact_temp = '[';
@ -2298,7 +2292,7 @@ function attach_glossary_into_scorm(type) {
var randLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
var uniqid = randLetter + Date.now();
var openerId = uniqid +'_opener';
var link = '<a id="'+openerId+'" class="generated" href="#">Open website <img src="<?php echo Display::returnIconPath('link-external.png'); ?>"/></a>';
var link = '<a id="'+openerId+'" class="generated" href="#">Open website <img width="16px" src="<?php echo Display::returnIconPath('link-external.png'); ?>"/></a>';
var embed = $(this);
var height = embed.attr('height');
var width = embed.attr('width');
@ -2363,7 +2357,7 @@ function attach_glossary_into_scorm(type) {
src = url+'&type=link&src='+src;
src = src.replace('https', 'http');
$(this).attr('href', src);
var myAnchor = $('<a><img src="<?php echo Display::returnIconPath('link-external.png'); ?>"/></a>').attr("href", src).attr('target', '_blank').attr('class', 'generated');
var myAnchor = $('<a><img width="16px" src="<?php echo Display::returnIconPath('link-external.png'); ?>"/></a>').attr("href", src).attr('target', '_blank').attr('class', 'generated');
$(this).after(myAnchor);
$(this).after('-');
}

@ -4,7 +4,12 @@
use Chamilo\CoreBundle\Entity\PortfolioCategory;
$form = new FormValidator('add_category', 'post', "$baseUrl&action=add_category");
$form->addText('title', get_lang('Title'));
if (api_get_configuration_value('save_titles_as_html')) {
$form->addHtmlEditor('title', get_lang('Title'), true, false, ['ToolbarSet' => 'NotebookStudent']);
} else {
$form->addText('title', get_lang('Title'));
$form->applyFilter('title', 'trim');
}
$form->addHtmlEditor('description', get_lang('Description'), false, false, ['ToolbarSet' => 'Minimal']);
$form->addButtonCreate(get_lang('Create'));

@ -10,7 +10,12 @@ $categories = $em
]);
$form = new FormValidator('add_portfolio', 'post', $baseUrl.'action=add_item');
$form->addText('title', get_lang('Title'));
if (api_get_configuration_value('save_titles_as_html')) {
$form->addHtmlEditor('title', get_lang('Title'), true, false, ['ToolbarSet' => 'NotebookStudent']);
} else {
$form->addText('title', get_lang('Title'));
$form->applyFilter('title', 'trim');
}
$form->addHtmlEditor('content', get_lang('Content'), true, false, ['ToolbarSet' => 'NotebookStudent']);
$form->addSelectFromCollection('category', get_lang('Category'), $categories, [], true);
$form->addButtonCreate(get_lang('Create'));

@ -2,7 +2,12 @@
/* For licensing terms, see /license.txt */
$form = new FormValidator('edit_category', 'post', $baseUrl."action=edit_category&id={$category->getId()}");
$form->addText('title', get_lang('Title'));
if (api_get_configuration_value('save_titles_as_html')) {
$form->addHtmlEditor('title', get_lang('Title'), true, false, ['ToolbarSet' => 'NotebookStudent']);
} else {
$form->addText('title', get_lang('Title'));
$form->applyFilter('title', 'trim');
}
$form->addHtmlEditor('description', get_lang('Description'), false, false, ['ToolbarSet' => 'Minimal']);
$form->addButtonUpdate(get_lang('Update'));
$form->setDefaults([

@ -8,7 +8,12 @@ $categories = $em
]);
$form = new FormValidator('edit_portfolio', 'post', $baseUrl."action=edit_item&id={$item->getId()}");
$form->addText('title', get_lang('Title'));
if (api_get_configuration_value('save_titles_as_html')) {
$form->addHtmlEditor('title', get_lang('Title'), true, false, ['ToolbarSet' => 'NotebookStudent']);
} else {
$form->addText('title', get_lang('Title'));
$form->applyFilter('title', 'trim');
}
$form->addHtmlEditor('content', get_lang('Content'), true, false, ['ToolbarSet' => 'NotebookStudent']);
$form->addSelectFromCollection('category', get_lang('Category'), $categories, [], true, '__toString');
$form->addButtonUpdate(get_lang('Update'));
@ -34,7 +39,7 @@ if ($form->validate()) {
$em->flush();
Display::addFlash(
Display::return_message(get_lang('Updated'), 'success')
Display::return_message(get_lang('ItemUpdated'), 'success')
);
header("Location: $baseUrl");

@ -133,7 +133,7 @@ switch ($action) {
$em->flush();
Display::addFlash(
Display::return_message(get_lang('PortfolioItemDeleted'), 'success')
Display::return_message(get_lang('CategoryDeleted'), 'success')
);
header("Location: $baseUrl");
@ -201,7 +201,7 @@ switch ($action) {
$em->flush();
Display::addFlash(
Display::return_message(get_lang('PortfolioItemDeleted'), 'success')
Display::return_message(get_lang('ItemDeleted'), 'success')
);
header("Location: $baseUrl");

@ -1,12 +1,13 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\ExtraField;
use Chamilo\CoreBundle\Repository\SequenceRepository;
use Chamilo\CoreBundle\Entity\SequenceResource;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CourseBundle\Entity\CCourseDescription;
use Chamilo\UserBundle\Repository\UserRepository;
use Chamilo\UserBundle\Entity\User;
use ChamiloSession as Session;
/**
* Session about page
@ -25,16 +26,19 @@ $sessionId = isset($_GET['session_id']) ? (int) $_GET['session_id'] : 0;
$em = Database::getManager();
/** @var Session $session */
$session = $em->find('ChamiloCoreBundle:Session', $sessionId);
if (!$session) {
api_not_allowed(true);
}
$htmlHeadXtra[] = api_get_asset('readmore-js/readmore.js');
$courses = [];
$sessionCourses = $em->getRepository('ChamiloCoreBundle:Session')->getCoursesOrderedByPosition($session);
$fieldsRepo = $em->getRepository('ChamiloCoreBundle:ExtraField');
$fieldTagsRepo = $em->getRepository('ChamiloCoreBundle:ExtraFieldRelTag');
$userRepo = UserManager::getRepository();
/** @var SequenceRepository $sequenceResourceRepo */
$sequenceResourceRepo = $em->getRepository('ChamiloCoreBundle:SequenceResource');
$tagField = $fieldsRepo->findOneBy([
@ -46,6 +50,7 @@ $courseValues = new ExtraFieldValue('course');
$userValues = new ExtraFieldValue('user');
$sessionValues = new ExtraFieldValue('session');
/** @var Course $sessionCourse */
foreach ($sessionCourses as $sessionCourse) {
$courseTags = [];
@ -75,46 +80,48 @@ foreach ($sessionCourses as $sessionCourse) {
$coachesData[] = $coachData;
}
$courseDescriptionTools = $em->getRepository('ChamiloCourseBundle:CCourseDescription')
->findBy(
[
'cId' => $sessionCourse->getId(),
'sessionId' => 0,
],
[
'id' => 'DESC',
'descriptionType' => 'ASC',
]
);
$courseDescription = $courseObjectives = $courseTopics = $courseMethodology = $courseMaterial = $courseResources = $courseAssessment = '';
$cd = new CourseDescription();
$cd->set_course_id($sessionCourse->getId());
$cd->set_session_id($session->getId());
$descriptionsData = $cd->get_description_data();
$courseDescription = [];
$courseObjectives = [];
$courseTopics = [];
$courseMethodology = [];
$courseMaterial = [];
$courseResources = [];
$courseAssessment = [];
$courseCustom = [];
foreach ($courseDescriptionTools as $descriptionTool) {
switch ($descriptionTool->getDescriptionType()) {
case CCourseDescription::TYPE_DESCRIPTION:
$courseDescription = $descriptionTool;
break;
case CCourseDescription::TYPE_OBJECTIVES:
$courseObjectives = $descriptionTool;
break;
case CCourseDescription::TYPE_TOPICS:
$courseTopics = $descriptionTool;
break;
case CCourseDescription::TYPE_METHODOLOGY:
$courseMethodology = $descriptionTool;
break;
case CCourseDescription::TYPE_COURSE_MATERIAL:
$courseMaterial = $descriptionTool;
break;
case CCourseDescription::TYPE_RESOURCES:
$courseResources = $descriptionTool;
break;
case CCourseDescription::TYPE_ASSESSMENT:
$courseAssessment = $descriptionTool;
break;
case CCourseDescription::TYPE_CUSTOM:
$courseCustom[] = $descriptionTool;
break;
if (!empty($descriptionsData['descriptions'])) {
foreach ($descriptionsData['descriptions'] as $descriptionInfo) {
switch ($descriptionInfo['description_type']) {
case CCourseDescription::TYPE_DESCRIPTION:
$courseDescription[] = $descriptionInfo;
break;
case CCourseDescription::TYPE_OBJECTIVES:
$courseObjectives[] = $descriptionInfo;
break;
case CCourseDescription::TYPE_TOPICS:
$courseTopics[] = $descriptionInfo;
break;
case CCourseDescription::TYPE_METHODOLOGY:
$courseMethodology[] = $descriptionInfo;
break;
case CCourseDescription::TYPE_COURSE_MATERIAL:
$courseMaterial[] = $descriptionInfo;
break;
case CCourseDescription::TYPE_RESOURCES:
$courseResources[] = $descriptionInfo;
break;
case CCourseDescription::TYPE_ASSESSMENT:
$courseAssessment[] = $descriptionInfo;
break;
case CCourseDescription::TYPE_CUSTOM:
$courseCustom[] = $descriptionInfo;
break;
}
}
}
@ -206,8 +213,8 @@ if ($checker) {
BuyCoursesPlugin::PRODUCT_TYPE_SESSION
);
if ($sessionIsPremium) {
Session::write('SessionIsPremium', true);
Session::write('sessionId', $sessionId);
ChamiloSession::write('SessionIsPremium', true);
ChamiloSession::write('sessionId', $sessionId);
}
}
@ -216,7 +223,9 @@ $redirectToSession = $redirectToSession ? '?s='.$sessionId : false;
$coursesInThisSession = SessionManager::get_course_list_by_session_id($sessionId);
$coursesCount = count($coursesInThisSession);
$redirectToSession = $coursesCount == 1 && $redirectToSession ? $redirectToSession.'&cr='.array_values($coursesInThisSession)[0]['directory'] : $redirectToSession;
$redirectToSession = $coursesCount == 1 && $redirectToSession
? ($redirectToSession.'&cr='.array_values($coursesInThisSession)[0]['directory'])
: $redirectToSession;
$template->assign('redirect_to_session', $redirectToSession);
$template->assign('courses', $courses);

@ -100,7 +100,7 @@ switch ($action) {
UserManager::createDataPrivacyExtraFields();
// Remove delete agreement if it was sent:
UserManager::update_extra_field_value(
/*UserManager::update_extra_field_value(
$userId,
'request_for_legal_agreement_consent_removal',
''
@ -110,7 +110,7 @@ switch ($action) {
$userId,
'request_for_legal_agreement_consent_removal_justification',
''
);
);*/
UserManager::update_extra_field_value(
$userId,
@ -181,7 +181,7 @@ switch ($action) {
$userInfo
);
$url = api_get_path(WEB_CODE_PATH).'admin/';
$url = api_get_path(WEB_CODE_PATH).'admin/user_list_consent.php';
$link = Display::url($url, $url);
$subject = get_lang('RequestForLegalConsentRemoval');
$content = sprintf(

@ -18,6 +18,8 @@ require_once __DIR__.'/../inc/global.inc.php';
$this_section = SECTION_COURSES;
$allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
// Database table definitions
$table_survey = Database::get_course_table(TABLE_SURVEY);
$table_user = Database::get_main_table(TABLE_MAIN_USER);
@ -72,6 +74,13 @@ if ($_GET['action'] == 'edit' && isset($survey_id) && is_numeric($survey_id)) {
$defaults['survey_id'] = $survey_id;
$defaults['anonymous'] = $survey_data['anonymous'];
if ($allowSurveyAvailabilityDatetime) {
$defaults['avail_from'] = api_get_local_time($defaults['avail_from'], null, 'UTC');
$defaults['avail_till'] = api_get_local_time($defaults['avail_till'], null, 'UTC');
$defaults['start_date'] = $defaults['avail_from'];
$defaults['end_date'] = $defaults['avail_till'];
}
$link_info = GradebookUtils::isResourceInCourseGradebook(
$course_id,
$gradebook_link_type,
@ -93,9 +102,15 @@ if ($_GET['action'] == 'edit' && isset($survey_id) && is_numeric($survey_id)) {
}
} else {
$defaults['survey_language'] = $_course['language'];
$defaults['start_date'] = date('Y-m-d', api_strtotime(api_get_local_time()));
$defaults['start_date'] = date(
$allowSurveyAvailabilityDatetime ? 'Y-m-d 00:00:00' : 'Y-m-d',
api_strtotime(api_get_local_time())
);
$startdateandxdays = time() + 864000; // today + 10 days
$defaults['end_date'] = date('Y-m-d', $startdateandxdays);
$defaults['end_date'] = date(
$allowSurveyAvailabilityDatetime ? 'Y-m-d 23:59:59' : 'Y-m-d',
$startdateandxdays
);
//$defaults['survey_share']['survey_share'] = 0;
//$form_share_value = 1;
$defaults['anonymous'] = 0;
@ -149,8 +164,14 @@ $form->addElement(
// Pass the language of the survey in the form
$form->addElement('hidden', 'survey_language');
$form->addElement('date_picker', 'start_date', get_lang('StartDate'));
$form->addElement('date_picker', 'end_date', get_lang('EndDate'));
if ($allowSurveyAvailabilityDatetime) {
$form->addDateTimePicker('start_date', get_lang('StartDate'));
$form->addDateTimePicker('end_date', get_lang('EndDate'));
} else {
$form->addElement('date_picker', 'start_date', get_lang('StartDate'));
$form->addElement('date_picker', 'end_date', get_lang('EndDate'));
}
$form->addElement('checkbox', 'anonymous', null, get_lang('Anonymous'));
$visibleResults = [
@ -298,8 +319,8 @@ if ($_GET['action'] == 'add') {
$form->addRule('survey_code', '', 'maxlength', 20);
}
$form->addRule('survey_title', get_lang('ThisFieldIsRequired'), 'required');
$form->addRule('start_date', get_lang('InvalidDate'), 'date');
$form->addRule('end_date', get_lang('InvalidDate'), 'date');
$form->addRule('start_date', get_lang('InvalidDate'), $allowSurveyAvailabilityDatetime ? 'datetime' : 'date');
$form->addRule('end_date', get_lang('InvalidDate'), $allowSurveyAvailabilityDatetime ? 'datetime' : 'date');
$form->addRule(
['start_date', 'end_date'],
get_lang('StartDateShouldBeBeforeEndDate'),

@ -218,6 +218,7 @@ class SurveyManager
*/
public static function store_survey($values)
{
$allowSurveyAvailabilityDatetime = api_get_configuration_value('allow_survey_availability_datetime');
$_user = api_get_user_info();
$course_id = api_get_course_int_id();
$session_id = api_get_session_id();
@ -338,8 +339,12 @@ class SurveyManager
'subtitle' => $values['survey_subtitle'],
'author' => $_user['user_id'],
'lang' => $values['survey_language'],
'avail_from' => $values['start_date'],
'avail_till' => $values['end_date'],
'avail_from' => $allowSurveyAvailabilityDatetime
? api_get_utc_datetime($values['start_date'].':00')
: $values['start_date'],
'avail_till' => $allowSurveyAvailabilityDatetime
? api_get_utc_datetime($values['end_date'].':59')
: $values['end_date'],
'is_shared' => $shared_survey_id,
'template' => 'template',
'intro' => $values['survey_introduction'],
@ -444,8 +449,12 @@ class SurveyManager
'subtitle' => $values['survey_subtitle'],
'author' => $_user['user_id'],
'lang' => $values['survey_language'],
'avail_from' => $values['start_date'],
'avail_till' => $values['end_date'],
'avail_from' => $allowSurveyAvailabilityDatetime
? api_get_utc_datetime($values['start_date'].':00')
: $values['start_date'],
'avail_till' => $allowSurveyAvailabilityDatetime
? api_get_utc_datetime($values['end_date'].':59')
: $values['end_date'],
'is_shared' => $shared_survey_id,
'template' => 'template',
'intro' => $values['survey_introduction'],

@ -16,24 +16,16 @@ $from = isset($_GET['from']) ? $_GET['from'] : null;
// Starting the output buffering when we are exporting the information.
$export_csv = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
$session_id = isset($_REQUEST['id_session']) ? intval($_REQUEST['id_session']) : 0;
$session_id = isset($_REQUEST['id_session']) ? (int) $_REQUEST['id_session'] : 0;
$this_section = SECTION_COURSES;
if ($from == 'myspace') {
$from_myspace = true;
$this_section = "session_my_space";
} else {
$this_section = SECTION_COURSES;
$this_section = 'session_my_space';
}
// Access restrictions.
$is_allowedToTrack =
api_is_platform_admin() ||
SessionManager::user_is_general_coach(api_get_user_id(), $session_id) ||
api_is_allowed_to_create_course() ||
api_is_session_admin() ||
api_is_drh() ||
api_is_course_tutor() ||
api_is_course_admin();
$is_allowedToTrack = Tracking::isAllowToTrack($session_id);
if (!$is_allowedToTrack) {
api_not_allowed(true);

@ -7,9 +7,12 @@
require_once __DIR__.'/../inc/global.inc.php';
$this_section = SECTION_COURSES;
$course_id = api_get_course_int_id();
$course_code = api_get_course_id();
$sessionId = api_get_session_id();
// Access restrictions.
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() ||
api_is_session_admin() || api_is_drh() || api_is_course_tutor();
$is_allowedToTrack = Tracking::isAllowToTrack($sessionId);
if (!$is_allowedToTrack) {
api_not_allowed(true);
@ -18,11 +21,6 @@ if (!$is_allowedToTrack) {
// Starting the output buffering when we are exporting the information.
$export_csv = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
$exportXls = isset($_GET['export']) && $_GET['export'] == 'xls' ? true : false;
$course_id = api_get_course_int_id();
$course_code = api_get_course_id();
$sessionId = api_get_session_id();
$keyword = isset($_GET['keyword']) ? Security::remove_XSS($_GET['keyword']) : '';
// jqgrid will use this URL to do the selects

@ -6,26 +6,24 @@ require_once __DIR__.'/../inc/global.inc.php';
$from_myspace = false;
$from = isset($_GET['from']) ? $_GET['from'] : null;
$course_id = api_get_course_int_id();
$course_code = api_get_course_id();
$sessionId = api_get_session_id();
$this_section = SECTION_COURSES;
if ($from == 'myspace') {
$from_myspace = true;
$this_section = "session_my_space";
} else {
$this_section = SECTION_COURSES;
}
// Access restrictions.
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() ||
api_is_session_admin() || api_is_drh() || api_is_course_tutor();
$is_allowedToTrack = Tracking::isAllowToTrack($sessionId);
if (!$is_allowedToTrack) {
api_not_allowed(true);
exit;
}
$course_id = api_get_course_int_id();
$course_code = api_get_course_id();
$sessionId = api_get_session_id();
// jqgrid will use this URL to do the selects
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_group_reporting&course_id='.$course_id.'&session_id='.$sessionId;

@ -10,26 +10,23 @@ $current_course_tool = TOOL_TRACKING;
$from_myspace = false;
$from = isset($_GET['from']) ? $_GET['from'] : null;
$export_csv = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
$exportXls = isset($_GET['export']) && $_GET['export'] == 'xls' ? true : false;
$session_id = intval($_REQUEST['id_session']);
$this_section = SECTION_COURSES;
if ($from == 'myspace') {
$from_myspace = true;
$this_section = "session_my_space";
} else {
$this_section = SECTION_COURSES;
$this_section = 'session_my_space';
}
// Access restrictions.
$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() ||
api_is_session_admin() || api_is_drh() || api_is_course_tutor();
$is_allowedToTrack = Tracking::isAllowToTrack($session_id);
if (!$is_allowedToTrack) {
api_not_allowed(true);
}
// Starting the output buffering when we are exporting the information.
$export_csv = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
$exportXls = isset($_GET['export']) && $_GET['export'] == 'xls' ? true : false;
$session_id = intval($_REQUEST['id_session']);
if ($export_csv || $exportXls) {
$csvData = TrackingCourseLog::get_item_resources_data(0, 0, '', '');
array_walk(

@ -14,17 +14,14 @@ $groupId = isset($_REQUEST['gidReq']) ? intval($_REQUEST['gidReq']) : 0;
$from_myspace = false;
$from = isset($_GET['from']) ? $_GET['from'] : null;
$this_section = SECTION_COURSES;
if ($from == 'myspace') {
$from_myspace = true;
$this_section = "session_my_space";
} else {
$this_section = SECTION_COURSES;
$this_section = 'session_my_space';
}
// Access restrictions.
$is_allowedToTrack = api_is_platform_admin(true, true) ||
api_is_allowed_to_create_course() ||
api_is_course_tutor();
$is_allowedToTrack = Tracking::isAllowToTrack($session_id);
if (!$is_allowedToTrack) {
api_not_allowed(true);
@ -71,7 +68,7 @@ if (isset($_GET['origin']) && $_GET['origin'] == 'resume_session') {
];
}
$view = (isset($_REQUEST['view']) ? $_REQUEST['view'] : '');
$view = isset($_REQUEST['view']) ? $_REQUEST['view'] : '';
$nameTools = get_lang('Tracking');
// Display the header.
@ -98,16 +95,13 @@ if (empty($session_id)) {
);
}
$nbStudents = count($a_students);
$student_ids = array_keys($a_students);
$studentCount = count($student_ids);
/* MAIN CODE */
echo '<div class="actions">';
echo TrackingCourseLog::actionsLeft('courses', api_get_session_id());
echo '<span style="float:right; padding-top:0px;">';
echo '<a href="javascript: void(0);" onclick="javascript: window.print();">'.
Display::return_icon('printer.png', get_lang('Print'), '', ICON_SIZE_MEDIUM).'</a>';
@ -152,11 +146,12 @@ if ($lpReporting) {
$session_id
);
}
$lp_avg_progress = null;
if ($studentCount > 0) {
$lp_avg_progress = $lp_avg_progress / $studentCount;
} else {
$lp_avg_progress = null;
}
// Separated presentation logic.
if (is_null($lp_avg_progress)) {
$lp_avg_progress = '0%';

@ -9,9 +9,9 @@
$cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
$this_section = "session_my_space";
$is_allowedToTrack = $is_courseAdmin || $is_platformAdmin || $is_session_general_coach || $is_sessionAdmin;
$session_id = isset($_GET['session_id']) ? intval($_GET['session_id']) : null;
$this_section = 'session_my_space';
$is_allowedToTrack = Tracking::isAllowToTrack($session_id);
if (!$is_allowedToTrack) {
api_not_allowed(true);
@ -28,7 +28,6 @@ if (api_is_platform_admin()) {
}
$global = true;
$session_id = isset($_GET['session_id']) ? intval($_GET['session_id']) : null;
if (empty($session_id)) {
$session_id = 1;
}

@ -12,12 +12,10 @@ require_once __DIR__.'/../inc/global.inc.php';
$this_section = SECTION_TRACKING;
$is_allowedToTrack = $is_courseAdmin || $is_platformAdmin || $is_session_general_coach || $is_sessionAdmin;
$is_allowedToTrack = Tracking::isAllowToTrack(api_get_session_id());
if (!$is_allowedToTrack) {
Display :: display_header(null);
api_not_allowed();
Display :: display_footer();
api_not_allowed(true);
}
$export_to_csv = false;
@ -25,10 +23,9 @@ if (isset($_GET['export'])) {
$export_to_csv = true;
}
$global = false;
if (api_is_platform_admin()) {
$global = true;
} else {
$global = false;
}
if ($global) {

@ -11,7 +11,7 @@ require_once __DIR__.'/../inc/global.inc.php';
$this_section = 'session_my_space';
$allow = api_is_platform_admin(true) || api_is_course_admin() || $is_session_general_coach;
$allow = Tracking::isAllowToTrack(api_get_session_id());
if (!$allow) {
api_not_allowed(true);

@ -18,22 +18,14 @@ $from = isset($_GET['from']) ? $_GET['from'] : null;
$export_csv = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
$session_id = isset($_REQUEST['id_session']) ? intval($_REQUEST['id_session']) : 0;
$this_section = SECTION_COURSES;
if ($from == 'myspace') {
$from_myspace = true;
$this_section = "session_my_space";
} else {
$this_section = SECTION_COURSES;
$this_section = 'session_my_space';
}
// Access restrictions.
$is_allowedToTrack =
api_is_platform_admin() ||
SessionManager::user_is_general_coach(api_get_user_id(), $session_id) ||
api_is_allowed_to_create_course() ||
api_is_session_admin() ||
api_is_drh() ||
api_is_course_tutor() ||
api_is_course_admin();
$is_allowedToTrack = Tracking::isAllowToTrack($session_id);
if (!$is_allowedToTrack) {
api_not_allowed(true);
@ -44,7 +36,8 @@ if (!$is_allowedToTrack) {
if (api_is_drh()) {
// Blocking course for drh
if (api_drh_can_access_all_session_content()) {
// If the drh has been configured to be allowed to see all session content, give him access to the session courses
// If the drh has been configured to be allowed to see all session content,
// give him access to the session courses
$coursesFromSession = SessionManager::getAllCoursesFollowedByUser(
api_get_user_id(),
null
@ -320,11 +313,17 @@ if (count($a_students) > 0) {
$headers['login'] = get_lang('Login');
$table->set_header(4, get_lang('TrainingTime').'&nbsp;'.
Display::return_icon('info3.gif', get_lang('CourseTimeInfo'), ['align' => 'absmiddle', 'hspace' => '3px']), false, ['style' => 'width:110px;']);
Display::return_icon('info3.gif', get_lang('CourseTimeInfo'), ['align' => 'absmiddle', 'hspace' => '3px']),
false,
['style' => 'width:110px;']
);
$headers['training_time'] = get_lang('TrainingTime');
$table->set_header(5, get_lang('TotalLPTime').'&nbsp;'.
Display::return_icon('info3.gif', get_lang('TotalLPTime'), ['align' => 'absmiddle', 'hspace' => '3px']), false, ['style' => 'width:110px;']);
Display::return_icon('info3.gif', get_lang('TotalLPTime'), ['align' => 'absmiddle', 'hspace' => '3px']),
false,
['style' => 'width:110px;']
);
$headers['total_time_lp'] = get_lang('TotalLPTime');
$table->set_header(6, get_lang('FirstLoginInCourse'), false);

@ -56,17 +56,7 @@ function displayWorkActionLinks($id, $action, $isTutor)
}
}
if (api_is_allowed_to_edit(null, true) && $origin != 'learnpath') {
if (empty($id)) {
// Options
$output .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=settings">';
$output .= Display::return_icon(
'settings.png',
get_lang('EditToolOptions'),
'',
ICON_SIZE_MEDIUM
).'</a>';
}
if (api_is_allowed_to_edit(null, true) && $origin != 'learnpath' && $action == 'list') {
$output .= '<a id="open-view-list" href="#">'.
Display::return_icon(
'listwork.png',
@ -84,45 +74,6 @@ function displayWorkActionLinks($id, $action, $isTutor)
}
}
/**
* Returns a form displaying all options for this tool.
* These are
* - make all files visible / invisible
* - set the default visibility of uploaded files.
*
* @param $defaults
*
* @return string The HTML form
*/
function settingsForm($defaults)
{
$allowed = api_is_allowed_to_edit(null, true);
if (!$allowed) {
return;
}
$url = api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq().'&action=settings';
$form = new FormValidator('edit_settings', 'post', $url);
$form->addElement('hidden', 'changeProperties', 1);
$form->addElement('header', get_lang('EditToolOptions'));
$group = [
$form->createElement('radio', 'show_score', null, get_lang('NewVisible'), 0),
$form->createElement('radio', 'show_score', null, get_lang('NewUnvisible'), 1),
];
$form->addGroup($group, '', get_lang('DefaultUpload'));
$group = [
$form->createElement('radio', 'student_delete_own_publication', null, get_lang('Yes'), 1),
$form->createElement('radio', 'student_delete_own_publication', null, get_lang('No'), 0),
];
$form->addGroup($group, '', get_lang('StudentAllowedToDeleteOwnPublication'));
$form->addButtonSave(get_lang('Save'));
$form->setDefaults($defaults);
return $form->returnForm();
}
/**
* @param string $path
* @param int $courseId
@ -4721,64 +4672,6 @@ function getUploadDocumentType()
];
}
/**
* @param array $courseInfo
* @param bool $showScore
* @param bool $studentDeleteOwnPublication
*
* @return bool
*/
function updateSettings($courseInfo, $showScore, $studentDeleteOwnPublication)
{
$showScore = (int) $showScore;
$courseId = api_get_course_int_id();
$main_course_table = Database::get_main_table(TABLE_MAIN_COURSE);
$table_course_setting = Database::get_course_table(TOOL_COURSE_SETTING);
if (empty($courseId)) {
return false;
}
$query = "UPDATE $main_course_table
SET show_score = '$showScore'
WHERE id = $courseId";
Database::query($query);
/**
* Course data are cached in session so we need to update both the database
* and the session data.
*/
$courseInfo['show_score'] = $showScore;
Session::write('_course', $courseInfo);
// changing the tool setting: is a student allowed to delete his/her own document
// counting the number of occurrences of this setting (if 0 => add, if 1 => update)
$query = "SELECT * FROM $table_course_setting
WHERE
c_id = $courseId AND
variable = 'student_delete_own_publication'";
$result = Database::query($query);
$number_of_setting = Database::num_rows($result);
if ($number_of_setting == 1) {
$query = "UPDATE $table_course_setting SET
value = '".Database::escape_string($studentDeleteOwnPublication)."'
WHERE variable = 'student_delete_own_publication' AND c_id = $courseId";
Database::query($query);
} else {
$params = [
'c_id' => $courseId,
'variable' => 'student_delete_own_publication',
'value' => $studentDeleteOwnPublication,
'category' => 'work',
];
Database::insert($table_course_setting, $params);
}
return true;
}
/**
* @param int $item_id
* @param array $course_info
@ -5347,7 +5240,7 @@ function exportAllStudentWorkFromPublication(
$expiresOn = null;
if (!empty($assignment) && isset($assignment['expires_on'])) {
$content .= '<br /><strong>'.get_lang('ExpirationDate').'</strong>: '.api_get_local_time($assignment['expires_on']);
$content .= '<br /><strong>'.get_lang('PostedExpirationDate').'</strong>: '.api_get_local_time($assignment['expires_on']);
$expiresOn = api_get_local_time($assignment['expires_on']);
}

@ -90,7 +90,7 @@ if (!empty($groupId)) {
} else {
if ($origin != 'learnpath') {
if (isset($_GET['id']) &&
!empty($_GET['id']) || $display_upload_form || $action == 'settings' || $action == 'create_dir'
!empty($_GET['id']) || $display_upload_form || $action == 'create_dir'
) {
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq(),
@ -110,9 +110,7 @@ if (!empty($groupId)) {
if ($action == 'upload_form') {
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('UploadADocument')];
}
if ($action == 'settings') {
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('EditToolOptions')];
}
if ($action == 'create_dir') {
$interbreadcrumb[] = ['url' => '#', 'name' => get_lang('CreateAssignment')];
}
@ -145,32 +143,6 @@ $content = null;
// For teachers
switch ($action) {
case 'settings':
//if posts
if ($is_allowed_to_edit && !empty($_POST['changeProperties'])) {
updateSettings(
$courseInfo,
$_POST['show_score'],
$_POST['student_delete_own_publication']
);
Display::addFlash(Display::return_message(get_lang('Saved'), 'success'));
header('Location: '.$currentUrl);
exit;
}
if (!$is_allowed_to_edit) {
api_not_allowed(true);
}
$studentDeleteOwnPublication = api_get_course_setting('student_delete_own_publication') == 1 ? 1 : 0;
/* Display of tool options */
$content = settingsForm(
[
'show_score' => $courseInfo['show_score'],
'student_delete_own_publication' => $studentDeleteOwnPublication,
]
);
break;
case 'add':
case 'create_dir':
if (!($is_allowed_to_edit || $isTutor)) {

Loading…
Cancel
Save