Browse Source

Minor - partial merge from 1.11.x

Julio Montoya 6 years ago
parent
commit
eb0fcbef70

+ 0 - 5
main/admin/add_sessions_to_usergroup.php

@@ -15,16 +15,11 @@ $data = $usergroup->get($id);
 $usergroup->protectScript($data);
 
 $xajax = new xajax();
-
-//$xajax->debugOn();
 $xajax->registerFunction('search_usergroup_sessions');
 
 // setting the section (for the tabs)
 $this_section = SECTION_PLATFORM_ADMIN;
 
-// setting breadcrumbs
-api_protect_admin_script(true);
-
 // setting breadcrumbs
 $interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('PlatformAdmin')];
 $interbreadcrumb[] = ['url' => 'usergroups.php', 'name' => get_lang('Classes')];

+ 0 - 4
main/admin/course_list.php

@@ -338,8 +338,6 @@ if (isset($_POST['action'])) {
             if (count($course_codes) > 0) {
                 foreach ($course_codes as $course_code) {
                     CourseManager::delete_course($course_code);
-                    $obj_cat = new Category();
-                    $obj_cat->update_category_delete($course_code);
                 }
             }
 
@@ -409,8 +407,6 @@ if (isset($_GET['search']) && $_GET['search'] === 'advanced') {
     $tool_name = get_lang('CourseList');
     if (isset($_GET['delete_course'])) {
         CourseManager::delete_course($_GET['delete_course']);
-        $obj_cat = new Category();
-        $obj_cat->update_category_delete($_GET['delete_course']);
         Display::addFlash(Display::return_message(get_lang('Deleted')));
     }
     // Create a search-box

+ 0 - 1
main/admin/index.php

@@ -305,7 +305,6 @@ if (file_exists($sessionsBlockExtraFile)) {
 if (api_is_platform_admin()) {
     $blocks['sessions']['editable'] = true;
 }
-
 $sessionPath = api_get_path(WEB_CODE_PATH).'session/';
 
 $search_form = ' <form method="GET" class="form-inline" action="'.$sessionPath.'session_list.php">

+ 18 - 26
main/admin/user_list_consent.php

@@ -54,7 +54,8 @@ function prepare_user_sql_query($getCount)
                     u.registration_date AS col10,
                     u.expiration_date AS exp,
                     u.password,
-                    v.field_id
+                    v.field_id,
+                    v.updated_at
                 FROM $user_table u";
     }
 
@@ -246,6 +247,7 @@ function get_user_data($from, $number_of_items, $column, $direction)
             $user[7],
             api_get_local_time($user[9]),
             $user[12],
+            Display::dateToStringAgoAndLongDate($user[13]),
             $user[0],
         ];
     }
@@ -327,18 +329,18 @@ function modify_filter($user_id, $url_params, $row)
         $result .= '&nbsp;&nbsp;';
     }
 
-    $result .= ' <a href="'.api_get_self().'?action=anonymize&user_id='.$user_id.'&'.$url_params.'&sec_token='.$token.'"  onclick="javascript:if(!confirm('."'".addslashes(
-            api_htmlentities(get_lang('ConfirmYourChoice'))
-        )."'".')) return false;">'.
-        Display::return_icon(
-            'anonymous.png',
-            get_lang('Anonymize'),
-            [],
-            ICON_SIZE_SMALL
-        ).
-        '</a>';
-
     if ($user_id != api_get_user_id()) {
+        $result .= ' <a href="'.api_get_self().'?action=anonymize&user_id='.$user_id.'&'.$url_params.'&sec_token='.$token.'"  onclick="javascript:if(!confirm('."'".addslashes(
+                api_htmlentities(get_lang('ConfirmYourChoice'))
+            )."'".')) return false;">'.
+            Display::return_icon(
+                'anonymous.png',
+                get_lang('Anonymize'),
+                [],
+                ICON_SIZE_SMALL
+            ).
+            '</a>';
+
         $result .= ' <a href="'.api_get_self().'?action=delete_user&user_id='.$user_id.'&'.$url_params.'&sec_token='.$token.'"  onclick="javascript:if(!confirm('."'".addslashes(
             api_htmlentities(get_lang('ConfirmYourChoice'))
         )."'".')) return false;">'.
@@ -463,18 +465,7 @@ if (!empty($action)) {
     if ($check) {
         switch ($action) {
             case 'delete_terms':
-                $extraFieldValue = new ExtraFieldValue('user');
-                $value = $extraFieldValue->get_values_by_handler_and_field_variable(
-                    $_GET['user_id'],
-                    'legal_accept'
-                );
-                $result = $extraFieldValue->delete($value['id']);
-
-                $value = $extraFieldValue->get_values_by_handler_and_field_variable(
-                    $_GET['user_id'],
-                    'request_for_legal_agreement_consent_removal'
-                );
-                $result = $extraFieldValue->delete($value['id']);
+                UserManager::cleanUserRequestsOfRemoval($_GET['user_id']);
 
                 Display::addFlash(Display::return_message(get_lang('Deleted')));
                 header('Location: '.api_get_self());
@@ -624,14 +615,15 @@ $table->set_header(7, get_lang('Profile'));
 $table->set_header(8, get_lang('Active'), true, 'width="15px"');
 $table->set_header(9, get_lang('RegistrationDate'), true, 'width="90px"');
 $table->set_header(10, get_lang('RequestType'), true, 'width="15px"');
-$table->set_header(11, get_lang('Action'), false, 'width="220px"');
+$table->set_header(11, get_lang('RequestDate'), true, 'width="15px"');
+$table->set_header(12, get_lang('Action'), false, 'width="220px"');
 
 $table->set_column_filter(3, 'user_filter');
 $table->set_column_filter(4, 'user_filter');
 $table->set_column_filter(6, 'email_filter');
 $table->set_column_filter(7, 'status_filter');
 $table->set_column_filter(8, 'active_filter');
-$table->set_column_filter(11, 'modify_filter');
+$table->set_column_filter(12, 'modify_filter');
 $table->set_column_filter(10, 'requestTypeFilter');
 
 // Only show empty actions bar if delete users has been blocked

+ 0 - 11
main/admin/usergroups.php

@@ -16,17 +16,6 @@ $usergroup->protectScript();
 // Add the JS needed to use the jqgrid
 $htmlHeadXtra[] = api_get_jqgrid_js();
 
-$interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('PlatformAdmin')];
-$action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : null;
-if ($action == 'add') {
-    $interbreadcrumb[] = ['url' => 'usergroups.php', 'name' => get_lang('Classes')];
-    $interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Add')];
-} elseif ($action == 'edit') {
-    $interbreadcrumb[] = ['url' => 'usergroups.php', 'name' => get_lang('Classes')];
-    $interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Edit')];
-} else {
-    $interbreadcrumb[] = ['url' => '#', 'name' => get_lang('Classes')];
-}
 // setting breadcrumbs
 $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : '';
 $userGroupId = isset($_GET['id']) ? (int) $_GET['id'] : 0;

+ 3 - 2
main/auth/courses_controller.php

@@ -166,7 +166,7 @@ class CoursesController
         $data['content'] = $content;
         $data['error'] = $error;
         $data['catalogShowCoursesSessions'] = 0;
-        $showCoursesSessions = intval('catalog_show_courses_sessions');
+        $showCoursesSessions = (int) api_get_setting('catalog_show_courses_sessions');
         if ($showCoursesSessions > 0) {
             $data['catalogShowCoursesSessions'] = $showCoursesSessions;
         }
@@ -930,7 +930,8 @@ class CoursesController
                 $actions = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$session->getId();
             }
 
-            $isThisSessionOnSale = $session->getBuyCoursePluginPrice();
+            $plugin = \BuyCoursesPlugin::create();
+            $isThisSessionOnSale = $plugin->getBuyCoursePluginPrice($session);
 
             $sessionsBlock = [
                 'id' => $session->getId(),

+ 83 - 12
main/auth/inscription.php

@@ -37,10 +37,12 @@ if ($gMapsPlugin->get('enable_api') === 'true') {
     $htmlHeadXtra[] = '<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?sensor=true&key='.$key.'" ></script>';
 }
 
+$extraFieldsLoaded = false;
 $htmlHeadXtra[] = api_get_password_checker_js('#username', '#pass1');
 // User is not allowed if Terms and Conditions are disabled and
 // registration is disabled too.
-$isNotAllowedHere = api_get_setting('allow_terms_conditions') === 'false' && api_get_setting('allow_registration') === 'false';
+$isNotAllowedHere = api_get_setting('allow_terms_conditions') === 'false' &&
+    api_get_setting('allow_registration') === 'false';
 
 if ($isNotAllowedHere) {
     api_not_allowed(true, get_lang('RegistrationDisabled'));
@@ -54,9 +56,33 @@ if (!empty($_SESSION['user_language_choice'])) {
     $user_selected_language = api_get_setting('platformLanguage');
 }
 
+$extraConditions = api_get_configuration_value('show_conditions_to_user');
+
+if ($extraConditions && isset($extraConditions['conditions'])) {
+    // Create user extra fields for the conditions
+    $userExtraField = new ExtraField('user');
+    $extraConditions = $extraConditions['conditions'];
+    foreach ($extraConditions as $condition) {
+        $exists = $userExtraField->get_handler_field_info_by_field_variable($condition['variable']);
+        if ($exists == false) {
+            $params = [
+                'field_type' => ExtraField::FIELD_TYPE_CHECKBOX,
+                'variable' => $condition['variable'],
+                'display_text' => $condition['display_text'],
+                'default_value' => '',
+                'visible_to_self' => true,
+                'visible_to_others' => false,
+                'changeable' => true,
+                'filter' => false,
+            ];
+            $userExtraField->save($params);
+        }
+    }
+}
+
 $form = new FormValidator('registration');
 $user_already_registered_show_terms = false;
-if (api_get_setting('allow_terms_conditions') == 'true') {
+if (api_get_setting('allow_terms_conditions') === 'true') {
     $user_already_registered_show_terms = isset($_SESSION['term_and_condition']['user_id']);
 }
 
@@ -83,7 +109,9 @@ if (!empty($course_code_redirect)) {
     Session::write('exercise_redirect', $exercise_redirect);
 }
 
-if ($user_already_registered_show_terms === false && api_get_setting('allow_registration') === 'true') {
+if ($user_already_registered_show_terms === false &&
+    api_get_setting('allow_registration') !== 'false'
+) {
     // STUDENT/TEACHER
     if (api_get_setting('allow_registration_as_teacher') != 'false') {
         if (in_array('status', $allowedFields)) {
@@ -310,9 +338,10 @@ if ($user_already_registered_show_terms === false && api_get_setting('allow_regi
         in_array('extra_fields', $allowedFields)
     ) {
         $extraField = new ExtraField('user');
-        $extraFieldList = isset($allowedFields['extra_fields']) && is_array(
-            $allowedFields['extra_fields']
-        ) ? $allowedFields['extra_fields'] : [];
+        $extraFieldList = [];
+        if (isset($allowedFields['extra_fields']) && is_array($allowedFields['extra_fields'])) {
+            $extraFieldList = $allowedFields['extra_fields'];
+        }
         $returnParams = $extraField->addElements(
             $form,
             0,
@@ -321,6 +350,7 @@ if ($user_already_registered_show_terms === false && api_get_setting('allow_regi
             false,
             $extraFieldList
         );
+        $extraFieldsLoaded = true;
     }
 
     // CAPTCHA
@@ -475,7 +505,7 @@ if (!empty($_GET['openid_msg']) && $_GET['openid_msg'] == 'idnotfound') {
 
 $showTerms = false;
 // Terms and conditions
-if (api_get_setting('allow_terms_conditions') == 'true' && $user_already_registered_show_terms) {
+if (api_get_setting('allow_terms_conditions') === 'true' && $user_already_registered_show_terms) {
     if (!api_is_platform_admin()) {
         if (api_get_setting('show_terms_if_profile_completed') === 'true') {
             $userInfo = api_get_user_info();
@@ -517,7 +547,7 @@ if (api_get_setting('allow_terms_conditions') == 'true' && $user_already_registe
                 'TermsAndConditions'
             ).'</a>'
         );
-        $form->addRule('legal_accept', get_lang('ThisFieldIsRequired'), 'required');
+        $form->addRule('legal_accept', get_lang('WeNeedYouToAcceptOurTreatmentOfYourData'), 'required');
     } else {
         $preview = LegalManager::show_last_condition($term_preview);
         $form->addElement('label', null, $preview);
@@ -555,7 +585,16 @@ if ($allowDoubleValidation && $showTerms == false) {
     $form->addHtml('</div>');
     $formContainsSendButton = true;
 } else {
-    if (api_get_setting('allow_registration') === 'true' || $user_already_registered_show_terms || $showTerms) {
+    // In normal cases (without double validation), we check if the
+    // registration is allowed in any way or if the user is already registered
+    // but needs to confirm terms. If not, send not allowed message
+    if (
+        api_get_setting('allow_registration') === 'approval' ||
+        api_get_setting('allow_registration') === 'true' ||
+        api_get_setting('allow_registration') === 'confirmation' ||
+        $user_already_registered_show_terms ||
+        $showTerms
+    ) {
         $form->addButtonNext(get_lang('RegisterUser'));
         $formContainsSendButton = true;
     }
@@ -569,6 +608,31 @@ if (!$formContainsSendButton) {
 $course_code_redirect = Session::read('course_redirect');
 $sessionToRedirect = Session::read('session_redirect');
 
+if ($extraConditions && $extraFieldsLoaded) {
+    // Set conditions as "required" and also change the labels
+    foreach ($extraConditions as $condition) {
+        /** @var HTML_QuickForm_group $element */
+        $element = $form->getElement('extra_'.$condition['variable']);
+        if ($element) {
+            $children = $element->getElements();
+            /** @var HTML_QuickForm_checkbox $child */
+            foreach ($children as $child) {
+                $child->setText(get_lang($condition['display_text']));
+            }
+            $form->setRequired($element);
+            if (!empty($condition['text_area'])) {
+                $element->setLabel(
+                    [
+                        '',
+                        //'<textarea rows="5" disabled cols="100%">'.get_lang($condition['text_area']).'</textarea>',
+                        '<div class="form-control" disabled=disabled style="height: 100px; overflow: auto;">'.get_lang($condition['text_area']).'</div>',
+                    ]
+                );
+            }
+        }
+    }
+}
+
 if ($form->validate()) {
     $values = $form->getSubmitValues(1);
     // Make *sure* the login isn't too long
@@ -584,7 +648,7 @@ if ($form->validate()) {
         $values['official_code'] = api_strtoupper($values['username']);
     }
 
-    if (api_get_setting('login_is_email') == 'true') {
+    if (api_get_setting('login_is_email') === 'true') {
         $values['username'] = $values['email'];
     }
 
@@ -824,11 +888,18 @@ if ($form->validate()) {
             $cond_array = explode(':', $values['legal_accept_type']);
             if (!empty($cond_array[0]) && !empty($cond_array[1])) {
                 $time = time();
-                $condition_to_save = intval($cond_array[0]).':'.intval($cond_array[1]).':'.$time;
+                $conditionToSave = (int) $cond_array[0].':'.(int) $cond_array[1].':'.$time;
                 UserManager::update_extra_field_value(
                     $user_id,
                     'legal_accept',
-                    $condition_to_save
+                    $conditionToSave
+                );
+
+                Event::addEvent(
+                    LOG_TERM_CONDITION_ACCEPTED,
+                    LOG_USER_OBJECT,
+                    api_get_user_info($user_id),
+                    api_get_utc_datetime()
                 );
 
                 $bossList = UserManager::getStudentBossList($user_id);

+ 20 - 6
main/auth/my_progress.php

@@ -10,7 +10,6 @@ $cidReset = true;
 require_once __DIR__.'/../inc/global.inc.php';
 
 $this_section = SECTION_TRACKING;
-
 $nameTools = get_lang('MyProgress');
 
 api_block_anonymous_users();
@@ -23,23 +22,29 @@ $(function() {
         autoPlayPause: 2000
     })
 });
-
 </script>";
 
+$pluginCalendar = api_get_plugin_setting('learning_calendar', 'enabled') === 'true';
+
+if ($pluginCalendar) {
+    $plugin = LearningCalendarPlugin::create();
+    $plugin->setJavaScript($htmlHeadXtra);
+}
+
 if (api_get_configuration_value('block_my_progress_page')) {
     api_not_allowed(true);
 }
 
 $user_id = api_get_user_id();
-$course_user_list = CourseManager::get_courses_list_by_user_id($user_id);
+$courseUserList = CourseManager::get_courses_list_by_user_id($user_id);
 $dates = $issues = '';
-$sessionId = isset($_GET['session_id']) ? intval($_GET['session_id']) : 0;
+$sessionId = isset($_GET['session_id']) ? (int) $_GET['session_id'] : 0;
 $courseCode = isset($_GET['course']) ? Security::remove_XSS($_GET['course']) : null;
 
-if (!empty($course_user_list)) {
+if (!empty($courseUserList)) {
     $items = MySpace::get_connections_from_course_list(
         $user_id,
-        $course_user_list
+        $courseUserList
     );
     $first = null;
     $last = null;
@@ -94,6 +99,15 @@ if (!empty($dates)) {
     $content .= '</div></div>';
 }
 
+if (api_get_configuration_value('private_messages_about_user_visible_to_user') === true) {
+    $allowMessages = api_get_configuration_value('private_messages_about_user');
+    if ($allowMessages === true) {
+        // Messages
+        $content .= Display::page_subheader2(get_lang('Messages'));
+        $content .= MessageManager::getMessagesAboutUserToString(api_get_user_info());
+    }
+}
+
 $message = null;
 if (empty($content)) {
     $message = Display::return_message(get_lang('NoDataAvailable'), 'warning');

+ 12 - 80
main/auth/profile.php

@@ -23,9 +23,7 @@ if (api_get_setting('allow_social_tool') == 'true') {
 
 $_SESSION['this_section'] = $this_section;
 
-if (!(isset($_user['user_id']) && $_user['user_id']) ||
-    api_is_anonymous($_user['user_id'], true)
-) {
+if (!(isset($_user['user_id']) && $_user['user_id']) || api_is_anonymous($_user['user_id'], true)) {
     api_not_allowed(true);
 }
 
@@ -363,87 +361,20 @@ if (is_profile_editable()) {
 } else {
     $form->freeze();
 }
-$form->setDefaults($user_data);
-
-/**
- * Is user auth_source is platform ?
- *
- * @return bool if auth_source is platform
- */
-function is_platform_authentication()
-{
-    $tab_user_info = api_get_user_info();
-
-    return $tab_user_info['auth_source'] == PLATFORM_AUTH_SOURCE;
-}
-
-/**
- * Can a user edit his/her profile?
- *
- * @return bool Editability of the profile
- */
-function is_profile_editable()
-{
-    if (isset($GLOBALS['profileIsEditable'])) {
-        return (bool) $GLOBALS['profileIsEditable'];
-    }
-
-    return true;
-}
-
-/*
-    PRODUCTIONS FUNCTIONS
-*/
 
-/**
- * Upload a submitted user production.
- *
- * @param $user_id User id
- *
- * @return The filename of the new production or FALSE if the upload has failed
- */
-function upload_user_production($user_id)
-{
-    $production_repository = UserManager::getUserPathById($user_id, 'system');
 
-    if (!file_exists($production_repository)) {
-        @mkdir($production_repository, api_get_permissions_for_new_directories(), true);
-    }
-    $filename = api_replace_dangerous_char($_FILES['production']['name']);
-    $filename = disable_dangerous_file($filename);
-
-    if (filter_extension($filename)) {
-        if (@move_uploaded_file($_FILES['production']['tmp_name'], $production_repository.$filename)) {
-            return $filename;
+$extraConditions = api_get_configuration_value('show_conditions_to_user');
+if ($extraConditions && isset($extraConditions['conditions'])) {
+    $extraConditions = $extraConditions['conditions'];
+    foreach ($extraConditions as $condition) {
+        $element = $form->getElement('extra_'.$condition['variable']);
+        if ($element) {
+            $element->freeze();
         }
     }
-
-    return false; // this should be returned if anything went wrong with the upload
 }
 
-/**
- * Check current user's current password.
- *
- * @param    char    email
- *
- * @return bool true o false
- *
- * @uses \Gets user ID from global variable
- */
-function check_user_email($email)
-{
-    $user_id = api_get_user_id();
-    if ($user_id != strval(intval($user_id)) || empty($email)) {
-        return false;
-    }
-    $table_user = Database::get_main_table(TABLE_MAIN_USER);
-    $email = Database::escape_string($email);
-    $sql = "SELECT * FROM $table_user
-            WHERE user_id='".$user_id."' AND email='".$email."'";
-    $result = Database::query($sql);
-
-    return Database::num_rows($result) != 0;
-}
+$form->setDefaults($user_data);
 
 $filtered_extension = false;
 
@@ -542,7 +473,7 @@ if ($form->validate()) {
         }
     } elseif (!empty($user_data['remove_picture'])) {
         // remove existing picture if asked
-        UserManager::delete_user_picture(api_get_user_id());
+        UserManager::deleteUserPicture(api_get_user_id());
         $user_data['picture_uri'] = '';
     }
 
@@ -719,6 +650,7 @@ if ($form->validate()) {
     Session::write('_user', $userInfo);
 
     if ($hook) {
+        $hook->setEventData(['user' => $user]);
         $hook->notifyUpdateUser(HOOK_EVENT_TYPE_POST);
     }
 
@@ -782,7 +714,7 @@ if (api_get_setting('allow_social_tool') === 'true') {
     $normalImage = UserManager::getUserPicture(api_get_user_id(), USER_IMAGE_SIZE_ORIGINAL);
 
     $imageToShow = '<div id="image-message-container">';
-    $imageToShow .= '<a class="expand-image" href="'.$bigImage.'" /><img src="'.$normalImage.'"></a>';
+    $imageToShow .= '<a class="expand-image pull-right" href="'.$bigImage.'" /><img src="'.$normalImage.'"></a>';
     $imageToShow .= '</div>';
 
     $content = $imageToShow.$form->returnForm();

+ 2 - 4
main/auth/unsubscribe_account.php

@@ -28,10 +28,8 @@ if ($form->validate()) {
     if ($result) {
         $message = Display::return_message(
             sprintf(
-                get_lang(
-                    'UnsubscribeFromPlatformSuccess',
-                    $user_info['username']
-                )
+                get_lang('UnsubscribeFromPlatformSuccess'),
+                $user_info['username']
             )
         );
         $content = null;

+ 27 - 2
main/auth/user_mail_confirmation.php

@@ -19,8 +19,33 @@ if ($user) {
     Database::getManager()->persist($user);
     Database::getManager()->flush();
 
-    Display::addFlash(Display::return_message(get_lang('UserConfirmedNowYouCanLogInThePlatform'), 'success'));
-    header('Location: '.api_get_path(WEB_PATH));
+    // See where to redirect the user to, if any redirection has been set
+    $url = api_get_path(WEB_PATH);
+
+    if (!empty($_GET['c'])) {
+        $courseCode = Security::remove_XSS($_GET['c']);
+    }
+    if (!empty($_GET['s'])) {
+        $sessionId = (int) $_GET['s'];
+    }
+
+    // Get URL to a course, to a session, or an empty string
+    $courseUrl = api_get_course_url($courseCode, $sessionId);
+    if (!empty($courseUrl)) {
+        $url = $courseUrl;
+    }
+
+    Event::addEvent(
+        LOG_USER_CONFIRMED_EMAIL,
+        LOG_USER_OBJECT,
+        api_get_user_info($user->getId()),
+        api_get_utc_datetime()
+    );
+
+    Display::addFlash(
+        Display::return_message(get_lang('UserConfirmedNowYouCanLogInThePlatform'), 'success')
+    );
+    header('Location: '.$url);
     exit;
 } else {
     Display::addFlash(

+ 2 - 1
main/badge/criteria.php

@@ -11,6 +11,7 @@
 require_once __DIR__.'/../inc/global.inc.php';
 
 $entityManager = Database::getManager();
+/** @var \Chamilo\CoreBundle\Entity\Skill $skill */
 $skill = $entityManager->find('ChamiloCoreBundle:Skill', $_GET['id']);
 
 if (!$skill) {
@@ -27,7 +28,7 @@ $skillInfo = [
     'short_code' => $skill->getShortCode(),
     'description' => $skill->getDescription(),
     'criteria' => $skill->getCriteria(),
-    'badge_image' => $skill->getWebIconPath(),
+    'badge_image' => Skill::getWebIconPath($skill),
 ];
 
 $template = new Template();

+ 6 - 8
main/badge/issued.php

@@ -3,6 +3,7 @@
 
 use Chamilo\CoreBundle\Entity\SkillRelUser;
 use Chamilo\CoreBundle\Entity\SkillRelUserComment;
+use SkillRelUser as SkillRelUserManager;
 
 /**
  * Show information about the issued badge.
@@ -63,7 +64,7 @@ $skillInfo = [
     'short_code' => $skill->getShortCode(),
     'description' => $skill->getDescription(),
     'criteria' => $skill->getCriteria(),
-    'badge_image' => $skill->getWebIconPath(),
+    'badge_image' => Skill::getWebIconPath($skill),
     'courses' => [],
 ];
 
@@ -102,12 +103,12 @@ $skillIssueInfo = [
     'user_id' => $skillIssue->getUser()->getId(),
     'user_complete_name' => $skillIssue->getUser()->getCompleteName(),
     'skill_id' => $skillIssue->getSkill()->getId(),
-    'skill_badge_image' => $skillIssue->getSkill()->getWebIconPath(),
+    'skill_badge_image' => Skill::getWebIconPath($skillIssue->getSkill()),
     'skill_name' => $skillIssue->getSkill()->getName(),
     'skill_short_code' => $skillIssue->getSkill()->getShortCode(),
     'skill_description' => $skillIssue->getSkill()->getDescription(),
     'skill_criteria' => $skillIssue->getSkill()->getCriteria(),
-    'badge_assertion' => $skillIssue->getAssertionUrl(),
+    'badge_assertion' => SkillRelUserManager::getAssertionUrl($skillIssue),
     'comments' => [],
     'feedback_average' => $skillIssue->getAverage(),
 ];
@@ -120,7 +121,6 @@ $skillId = $skillIssueInfo['skill_id'];
 /** @var SkillRelUserComment $comment */
 foreach ($skillIssueComments as $comment) {
     $commentDate = api_get_local_time($comment->getFeedbackDateTime());
-
     $skillIssueInfo['comments'][] = [
         'text' => $comment->getFeedbackText(),
         'value' => $comment->getFeedbackValue(),
@@ -157,7 +157,6 @@ if (!$profile) {
 
 if ($profile) {
     $profileId = $profile->getId();
-
     $levels = $skillLevelRepo->findBy([
         'profile' => $profileId,
     ]);
@@ -168,7 +167,6 @@ if ($profile) {
     }
 
     ksort($profileLevels); // Sort the array by Position.
-
     foreach ($profileLevels as $profileLevel) {
         $profileId = key($profileLevel);
         $acquiredLevel[$profileId] = $profileLevel[$profileId];
@@ -193,7 +191,7 @@ if ($showLevels && $allowToEdit) {
         $entityManager->flush();
         Display::addFlash(Display::return_message(get_lang('Saved')));
 
-        header("Location: ".$skillIssue->getIssueUrl());
+        header('Location: '.SkillRelUserManager::getIssueUrl($skillIssue));
         exit;
     }
 }
@@ -226,7 +224,7 @@ if ($form->validate() && $allowComment && $allowToEdit) {
     $entityManager->flush();
     Display::addFlash(Display::return_message(get_lang('Added')));
 
-    header("Location: ".$skillIssue->getIssueUrl());
+    header('Location: '.SkillRelUserManager::getIssueUrl($skillIssue));
     exit;
 }
 

+ 14 - 11
main/badge/issued_all.php

@@ -4,6 +4,7 @@
 use Chamilo\CoreBundle\Entity\SkillRelUser;
 use Chamilo\CoreBundle\Entity\SkillRelUserComment;
 use Chamilo\UserBundle\Entity\User;
+use SkillRelUser as SkillRelUserManager;
 
 /**
  * Show information about all issued badges with same skill by user.
@@ -14,8 +15,8 @@ use Chamilo\UserBundle\Entity\User;
  */
 require_once __DIR__.'/../inc/global.inc.php';
 
-$userId = isset($_GET['user']) ? intval($_GET['user']) : 0;
-$skillId = isset($_GET['skill']) ? intval($_GET['skill']) : 0;
+$userId = isset($_GET['user']) ? (int) $_GET['user'] : 0;
+$skillId = isset($_GET['skill']) ? (int) $_GET['skill'] : 0;
 
 if (!$userId || !$skillId) {
     api_not_allowed(true);
@@ -26,7 +27,6 @@ Skill::isAllowed($userId);
 $em = Database::getManager();
 $user = api_get_user_entity($userId);
 $skill = $em->find('ChamiloCoreBundle:Skill', $skillId);
-
 $currentUserId = api_get_user_id();
 
 if (!$user || !$skill) {
@@ -58,7 +58,7 @@ $skillInfo = [
     'short_code' => $skill->getShortCode(),
     'description' => $skill->getDescription(),
     'criteria' => $skill->getCriteria(),
-    'badge_image' => $skill->getWebIconPath(),
+    'badge_image' => Skill::getWebIconPath($skill),
     'courses' => [],
 ];
 
@@ -80,18 +80,21 @@ foreach ($userSkills as $index => $skillIssue) {
         'datetime' => api_format_date($skillIssueDate, DATE_TIME_FORMAT_SHORT),
         'acquired_level' => $currentSkillLevel,
         'argumentation_author_id' => $skillIssue->getArgumentationAuthorId(),
-        'argumentation_author_name' => api_get_person_name($argumentationAuthor['firstname'], $argumentationAuthor['lastname']),
+        'argumentation_author_name' => api_get_person_name(
+            $argumentationAuthor['firstname'],
+            $argumentationAuthor['lastname']
+        ),
         'argumentation' => $skillIssue->getArgumentation(),
         'source_name' => $skillIssue->getSourceName(),
         'user_id' => $skillIssue->getUser()->getId(),
         'user_complete_name' => $skillIssue->getUser()->getCompleteName(),
         'skill_id' => $skillIssue->getSkill()->getId(),
-        'skill_badge_image' => $skillIssue->getSkill()->getWebIconPath(),
+        'skill_badge_image' => Skill::getWebIconPath($skillIssue->getSkill()),
         'skill_name' => $skillIssue->getSkill()->getName(),
         'skill_short_code' => $skillIssue->getSkill()->getShortCode(),
         'skill_description' => $skillIssue->getSkill()->getDescription(),
         'skill_criteria' => $skillIssue->getSkill()->getCriteria(),
-        'badge_assertion' => $skillIssue->getAssertionUrl(),
+        'badge_assertion' => SkillRelUserManager::getAssertionUrl($skillIssue),
         'comments' => [],
         'feedback_average' => $skillIssue->getAverage(),
     ];
@@ -156,7 +159,7 @@ foreach ($userSkills as $index => $skillIssue) {
     $formAcquiredLevel = new FormValidator(
         'acquired_level'.$skillIssue->getId(),
         'post',
-        $skillIssue->getIssueUrlAll()
+        SkillRelUserManager::getIssueUrlAll($skillIssue)
     );
     $formAcquiredLevel->addSelect('acquired_level', get_lang('AcquiredLevel'), $acquiredLevel);
     $formAcquiredLevel->addHidden('user', $skillIssue->getUser()->getId());
@@ -172,14 +175,14 @@ foreach ($userSkills as $index => $skillIssue) {
         $em->persist($skillIssue);
         $em->flush();
 
-        header("Location: ".$skillIssue->getIssueUrlAll());
+        header('Location: '.SkillRelUserManager::getIssueUrlAll($skillIssue));
         exit;
     }
 
     $form = new FormValidator(
         'comment'.$skillIssue->getId(),
         'post',
-        $skillIssue->getIssueUrlAll()
+        SkillRelUserManager::getIssueUrlAll($skillIssue)
     );
     $form->addTextarea('comment', get_lang('NewComment'), ['rows' => 4]);
     $form->applyFilter('comment', 'trim');
@@ -207,7 +210,7 @@ foreach ($userSkills as $index => $skillIssue) {
         $em->persist($skillUserComment);
         $em->flush();
 
-        header("Location: ".$skillIssue->getIssueUrlAll());
+        header('Location: '.SkillRelUserManager::getIssueUrlAll($skillIssue));
         exit;
     }
 

+ 2 - 6
main/calendar/agenda.php

@@ -114,13 +114,11 @@ if ($allowToEdit) {
 
                 $sendEmail = isset($values['add_announcement']) ? true : false;
                 $allDay = isset($values['all_day']) ? 'true' : 'false';
-
                 $sendAttachment = isset($_FILES) && !empty($_FILES) ? true : false;
                 $attachmentList = $sendAttachment ? $_FILES : null;
                 $attachmentCommentList = isset($values['legend']) ? $values['legend'] : null;
                 $comment = isset($values['comment']) ? $values['comment'] : null;
                 $usersToSend = isset($values['users_to_send']) ? $values['users_to_send'] : '';
-
                 $startDate = $values['date_range_start'];
                 $endDate = $values['date_range_end'];
 
@@ -185,12 +183,10 @@ if ($allowToEdit) {
 
                 $sendAttachment = isset($_FILES) && !empty($_FILES) ? true : false;
                 $attachmentList = $sendAttachment ? $_FILES : null;
-                $attachmentCommentList = isset($values['legend']) ? $values['legend'] : null;
-
-                $comment = isset($values['comment']) ? $values['comment'] : null;
+                $attachmentCommentList = isset($values['legend']) ? $values['legend'] : '';
+                $comment = isset($values['comment']) ? $values['comment'] : '';
 
                 // This is a sub event. Delete the current and create another BT#7803
-
                 if (!empty($event['parent_event_id'])) {
                     $agenda->deleteEvent($eventId);
 

+ 8 - 6
main/calendar/agenda_list.php

@@ -6,17 +6,19 @@
  */
 require_once __DIR__.'/../inc/global.inc.php';
 
+$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
+
 $interbreadcrumb[] = [
-    'url' => api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php',
+    'url' => api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?type='.Security::remove_XSS($type),
     'name' => get_lang('Agenda'),
 ];
 
 $currentCourseId = api_get_course_int_id();
-$currentGroupdId = api_get_group_id();
+$groupId = api_get_group_id();
 
-if (!empty($currentGroupdId)) {
-    $groupProperties = GroupManager::get_group_properties($currentGroupdId);
-    $currentGroupdId = $groupProperties['iid'];
+if (!empty($groupId)) {
+    $groupProperties = GroupManager::get_group_properties($groupId);
+    $groupId = $groupProperties['iid'];
     $interbreadcrumb[] = [
         "url" => api_get_path(WEB_CODE_PATH)."group/group.php?".api_get_cidreq(),
         "name" => get_lang('Groups'),
@@ -33,7 +35,7 @@ $events = $agenda->getEvents(
     null,
     null,
     $currentCourseId,
-    $currentGroupdId,
+    $groupId,
     null,
     'array'
 );

+ 17 - 1
main/course_description/course_description_controller.php

@@ -52,13 +52,29 @@ class CourseDescriptionController
             $data['descriptions'] = [$data['descriptions']];
         }
 
-        foreach ($data['descriptions'] as $description) {
+        // Prepare confirmation code for item deletion
+        global $htmlHeadXtra;
+        $htmlHeadXtra[] = "<script>
+        function confirmation(name) {
+            if (confirm(\" ".trim(get_lang('AreYouSureToDeleteJS'))." \"+name+\"?\")) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+        </script>";
+
+        foreach ($data['descriptions'] as $id => $description) {
             if (!empty($description['content'])
                 && strpos($description['content'], '<iframe') !== false
                 && $browser['name'] == 'Chrome'
             ) {
                 header("X-XSS-Protection: 0");
             }
+            // Add an escape version for the JS code of delete confirmation
+            if ($description) {
+                $data['descriptions'][$id]['title_js'] = addslashes($description['title']);
+            }
         }
         $actions = null;
         $actionLeft = null;

+ 15 - 19
main/course_description/resources/js/main.js

@@ -1,44 +1,40 @@
+function Proxy() {
+}
 
-function Proxy() {};
-
-Proxy.prototype.root = function(){
+Proxy.prototype.root = function () {
     return www + '/main/inc/ajax/course_description.ajax.php';
 }
 
-Proxy.prototype.post = function(data, f){    
-    if(typeof(sec_token)!=='undefined'){  
+Proxy.prototype.post = function (data, f) {
+    if (typeof(sec_token) !== 'undefined') {
         data.sec_token = sec_token;
     }
     $.post(this.root(), data, f, 'json');
 }
 
-
 var CourseDescription = new Proxy();
 
-CourseDescription.del = function(c_id, id, f)
-{
+CourseDescription.del = function (c_id, id, f) {
     var data = {
-        c_id: c_id, 
-        id: id, 
+        c_id: c_id,
+        id: id,
         action: 'delete'
     };
     this.post(data, f);
 };
 
-CourseDescription.delete_by_course = function(c_id, session_id, f)
-{
+CourseDescription.delete_by_course = function (c_id, session_id, f) {
     var data = {
-        c_id: c_id, 
-        session_id: session_id, 
+        c_id: c_id,
+        session_id: session_id,
         action: 'delete_by_course'
     };
     this.post(data, f);
 };
 
-
 var message = {};
 
-message.update = function(data){
-    text = typeof(data)=='string' ? data : data.message;
-    $('#messages').html(text)
-}
+message.update = function (data) {
+    text = typeof(data) == 'string' ? data : data.message;
+    $('#messages').html(text);
+}

+ 1 - 1
main/course_home/course_home.php

@@ -60,7 +60,7 @@ $(document).ready(function(){
 
 		$.ajax({
 			contentType: "application/x-www-form-urlencoded",
-			beforeSend: function(objeto) {
+			beforeSend: function(myObject) {
 				$(".normal-message").show();
 				$("#id_confirmation_message").hide();
 			},

+ 0 - 2
main/course_info/delete_course.php

@@ -28,8 +28,6 @@ $tool_name = get_lang('DelCourse');
 
 if (isset($_GET['delete']) && $_GET['delete'] === 'yes') {
     CourseManager::delete_course($_course['sysCode']);
-    $obj_cat = new Category();
-    $obj_cat->update_category_delete($_course['sysCode']);
 
     // DELETE CONFIRMATION MESSAGE
     Session::erase('_cid');

+ 198 - 253
main/course_info/infocours.php

@@ -7,11 +7,11 @@
  *
  * See ./inc/conf/course_info.conf.php for settings
  *
- * @todo Take those config settings into account in this script
+ * @todo    Take those config settings into account in this script
  *
- * @author Patrick Cool <patrick.cool@UGent.be>
- * @author Roan Embrechts, refactoring and improved course visibility|subscribe|unsubscribe options
- * @author Julio Montoya <gugli100@gmail.com> Jquery support + lots of fixes
+ * @author  Patrick Cool <patrick.cool@UGent.be>
+ * @author  Roan Embrechts, refactoring and improved course visibility|subscribe|unsubscribe options
+ * @author  Julio Montoya <gugli100@gmail.com> Jquery support + lots of fixes
  *
  * @package chamilo.course_info
  */
@@ -28,7 +28,7 @@ define('MODULE_HELP_NAME', 'Settings');
 define('COURSE_CHANGE_PROPERTIES', 'COURSE_CHANGE_PROPERTIES');
 
 $currentCourseRepository = $_course['path'];
-$is_allowedToEdit = $is_courseAdmin || $is_platformAdmin;
+$is_allowedToEdit = api_is_course_admin() || api_is_platform_admin();
 $course_code = api_get_course_id();
 $courseId = api_get_course_int_id();
 
@@ -52,9 +52,7 @@ if (api_get_setting('pdf_export_watermark_by_course') == 'true') {
     }
 }
 
-$categories = CourseCategory::getCategoriesCanBeAddedInCourse(
-    $_course['categoryCode']
-);
+$categories = CourseCategory::getCategoriesCanBeAddedInCourse($_course['categoryCode']);
 
 // Build the form
 $form = new FormValidator(
@@ -119,7 +117,7 @@ $group = [
     $form->createElement('radio', 'show_course_in_user_language', null, get_lang('No'), 2),
 ];
 
-$form->addGroup($group, '', [get_lang("ShowCourseInUserLanguage")]);
+$form->addGroup($group, '', [get_lang('ShowCourseInUserLanguage')]);
 
 $form->addText('department_name', get_lang('Department'), false);
 $form->applyFilter('department_name', 'html_filter');
@@ -128,6 +126,30 @@ $form->applyFilter('department_name', 'trim');
 $form->addText('department_url', get_lang('DepartmentUrl'), false);
 $form->applyFilter('department_url', 'html_filter');
 
+// Extra fields
+$extra_field = new ExtraField('course');
+
+$extraFieldAdminPermissions = false;
+$showOnlyTheseFields = ['tags', 'video_url', 'course_hours_duration'];
+$extra = $extra_field->addElements(
+    $form,
+    $courseId,
+    [],
+    false,
+    false,
+    $showOnlyTheseFields,
+    [],
+    false
+);
+
+//Tags ExtraField
+$htmlHeadXtra[] = '
+<script>
+$(function() {
+    '.$extra['jquery_ready_content'].'
+});
+</script>';
+
 // Picture
 $form->addFile(
     'picture',
@@ -171,7 +193,7 @@ if (api_get_setting('allow_course_theme') == 'true') {
         null,
         ['id' => 'course_theme_id']
     );
-    $form->addGroup($group, '', [get_lang("Stylesheets")]);
+    $form->addGroup($group, '', [get_lang('Stylesheets')]);
 }
 
 $form->addElement('label', get_lang('DocumentQuota'), format_file_size(DocumentManager::get_course_quota()));
@@ -193,34 +215,11 @@ $form->addHtml('
 $form->addHtml('</div>');
 
 // COURSE ACCESS
-$form->addHtml('<div class="panel panel-default">');
-$form->addHtml('
-    <div class="panel-heading" role="tab" id="heading-course-access">
-        <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
-               href="#collapse-course-access" aria-expanded="false" aria-controls="collapse-course-access">
-');
-$form->addElement(
-    'html',
-    Display::return_icon('course.png', get_lang('CourseAccess')).' '.get_lang('CourseAccess')
-);
-$form->addHtml('
-            </a>
-        </h4>
-    </div>
-');
-
-$form->addHtml('
-    <div id="collapse-course-access" class="panel-collapse collapse" role="tabpanel"
-         aria-labelledby="heading-course-access">
-        <div class="panel-body">
-');
-
 $group = [];
 $group[] = $form->createElement(
     'radio',
     'visibility',
-    get_lang("CourseAccess"),
+    get_lang('CourseAccess'),
     get_lang('OpenToTheWorld'),
     COURSE_VISIBILITY_OPEN_WORLD
 );
@@ -239,6 +238,7 @@ $group[] = $form->createElement(
     get_lang('CourseVisibilityClosed'),
     COURSE_VISIBILITY_CLOSED
 );
+
 // The "hidden" visibility is only available to portal admins
 if (api_is_platform_admin()) {
     $group[] = $form->createElement(
@@ -249,79 +249,86 @@ if (api_is_platform_admin()) {
         COURSE_VISIBILITY_HIDDEN
     );
 }
-$form->addGroup($group, '', [get_lang("CourseAccess"), get_lang("CourseAccessConfigTip")]);
+
+$groupElement = $form->addGroup(
+    $group,
+    '',
+    [get_lang('CourseAccess'), get_lang('CourseAccessConfigTip')],
+    null,
+    null,
+    true
+);
 
 $url = api_get_path(WEB_CODE_PATH)."auth/inscription.php?c=$course_code&e=1";
 $url = Display::url($url, $url);
-$form->addElement('label', get_lang('DirectLink'), sprintf(get_lang('CourseSettingsRegisterDirectLink'), $url));
+$label = $form->addLabel(get_lang('DirectLink'), sprintf(get_lang('CourseSettingsRegisterDirectLink'), $url), true);
 
-$group = [];
-$group[] = $form->createElement('radio', 'subscribe', get_lang('Subscription'), get_lang('Allowed'), 1);
-$group[] = $form->createElement('radio', 'subscribe', null, get_lang('Denied'), 0);
-$form->addGroup($group, '', [get_lang("Subscription")]);
+$group2 = [];
+$group2[] = $form->createElement('radio', 'subscribe', get_lang('Subscription'), get_lang('Allowed'), 1);
+$group2[] = $form->createElement('radio', 'subscribe', null, get_lang('Denied'), 0);
 
-$group = [];
-$group[] = $form->createElement(
+$myButton = $form->addButtonSave(get_lang('SaveSettings'), 'submit_save', true);
+
+$group3[] = $form->createElement(
     'radio',
     'unsubscribe',
     get_lang('Unsubscription'),
     get_lang('AllowedToUnsubscribe'),
     1
 );
-$group[] = $form->createElement('radio', 'unsubscribe', null, get_lang('NotAllowedToUnsubscribe'), 0);
-$form->addGroup($group, '', [get_lang("Unsubscription")]);
-
-$form->addText('course_registration_password', get_lang('CourseRegistrationPassword'), false, ['size' => '60']);
+$group3[] = $form->createElement('radio', 'unsubscribe', null, get_lang('NotAllowedToUnsubscribe'), 0);
+
+$text = $form->createElement(
+    'text',
+    'course_registration_password',
+    get_lang('CourseRegistrationPassword'),
+    false,
+    ['size' => '60']
+);
 
-$form->addElement(
+$checkBoxActiveLegal = $form->createElement(
     'checkbox',
     'activate_legal',
     [null, get_lang('ShowALegalNoticeWhenEnteringTheCourse')],
     get_lang('ActivateLegal')
 );
-$form->addElement('textarea', 'legal', get_lang('CourseLegalAgreement'), ['rows' => 8]);
-$form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
-
-$form->addHtml('
-        </div>
-    </div>
-');
-$form->addHtml('</div>');
+$textAreaLegal = $form->createElement('textarea', 'legal', get_lang('CourseLegalAgreement'), ['rows' => 8]);
+
+$elements = [
+    $groupElement,
+    $label,
+    get_lang('Subscription') => $group2,
+    get_lang('Unsubscription') => $group3,
+    $text,
+    $checkBoxActiveLegal,
+    $textAreaLegal,
+    $myButton,
+];
 
-// Documents
-$form->addHtml('<div class="panel panel-default">');
-$form->addHtml('
-    <div class="panel-heading" role="tab" id="heading-documents">
-        <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
-               href="#collapse-documents" aria-expanded="false" aria-controls="collapse-documents">
-');
-$form->addHtml(
-    Display::return_icon('folder.png', get_lang('Documents')).' '.get_lang('Documents')
+$form->addPanelOption(
+    'course-access',
+    Display::return_icon('course.png', get_lang('CourseAccess')).' '.get_lang('CourseAccess'),
+    $elements
 );
-$form->addHtml('
-                </a>
-            </h4>
-        </div>
-    ');
-$form->addHtml('
-    <div id="collapse-documents" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-documents">
-        <div class="panel-body">
-');
 
+// Documents
+$globalGroup = [];
 if (api_get_setting('documents_default_visibility_defined_in_course') == 'true') {
     $group = [
         $form->createElement('radio', 'documents_default_visibility', null, get_lang('Visible'), 'visible'),
         $form->createElement('radio', 'documents_default_visibility', null, get_lang('Invisible'), 'invisible'),
     ];
-    $form->addGroup($group, '', [get_lang('DocumentsDefaultVisibility')]);
+    $globalGroup[get_lang('DocumentsDefaultVisibility')] = $group;
 }
 
 $group = [
     $form->createElement('radio', 'show_system_folders', null, get_lang('Yes'), 1),
     $form->createElement('radio', 'show_system_folders', null, get_lang('No'), 2),
 ];
-$form->addGroup($group, '', [get_lang('ShowSystemFolders')]);
+
+$globalGroup[get_lang('ShowSystemFolders')] = $group;
+
+$myButton = $form->addButtonSave(get_lang('SaveSettings'), 'submit_save', true);
 
 $group = [];
 $group[] = $form->createElement(
@@ -332,14 +339,15 @@ $group[] = $form->createElement(
     1
 );
 $group[] = $form->createElement('radio', 'enable_document_auto_launch', null, get_lang('Deactivate'), 0);
-$form->addGroup($group, '', [get_lang('DocumentAutoLaunch')]);
+$globalGroup[get_lang('DocumentAutoLaunch')] = $group;
 
-$form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
-$form->addHtml('
-        </div>
-    </div>
-');
-$form->addHtml('</div>');
+$globalGroup[] = $myButton;
+
+$form->addPanelOption(
+    'documents',
+    Display::return_icon('folder.png', get_lang('Documents')).' '.get_lang('Documents'),
+    $globalGroup
+);
 
 // EMAIL NOTIFICATIONS
 $form->addHtml('<div class="panel panel-default">');
@@ -498,26 +506,6 @@ $form->addHtml('
 ');
 $form->addHtml('</div>');
 
-// USER RIGHTS
-$form->addHtml('<div class="panel panel-default">');
-$form->addHtml('
-    <div class="panel-heading" role="tab" id="heading-user-right">
-        <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
-               href="#collapse-user-right" aria-expanded="false" aria-controls="collapse-user-right">
-');
-$form->addHtml(
-    Display::return_icon('user.png', get_lang('UserRights')).' '.get_lang('UserRights')
-);
-$form->addHtml('
-            </a>
-        </h4>
-    </div>
-');
-$form->addHtml('
-    <div id="collapse-user-right" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-user-right">
-        <div class="panel-body">
-');
 
 $group = [];
 $group[] = $form->createElement(
@@ -528,80 +516,64 @@ $group[] = $form->createElement(
     1
 );
 $group[] = $form->createElement('radio', 'allow_user_edit_agenda', null, get_lang('AllowUserEditAgendaDeactivate'), 0);
-$form->addGroup($group, '', [get_lang("AllowUserEditAgenda")]);
 
-$group = [];
-$group[] = $form->createElement(
+$group2 = [];
+$group2[] = $form->createElement(
     'radio',
     'allow_user_edit_announcement',
     get_lang('AllowUserEditAnnouncement'),
     get_lang('AllowUserEditAnnouncementActivate'),
     1
 );
-$group[] = $form->createElement(
+$group2[] = $form->createElement(
     'radio',
     'allow_user_edit_announcement',
     null,
     get_lang('AllowUserEditAnnouncementDeactivate'),
     0
 );
-$form->addGroup($group, '', [get_lang("AllowUserEditAnnouncement")]);
 
-$group = [];
-$group[] = $form->createElement(
+$group3 = [];
+$group3[] = $form->createElement(
     'radio',
     'allow_user_image_forum',
     get_lang('AllowUserImageForum'),
     get_lang('AllowUserImageForumActivate'),
     1
 );
-$group[] = $form->createElement('radio', 'allow_user_image_forum', null, get_lang('AllowUserImageForumDeactivate'), 0);
-$form->addGroup($group, '', [get_lang("AllowUserImageForum")]);
+$group3[] = $form->createElement('radio', 'allow_user_image_forum', null, get_lang('AllowUserImageForumDeactivate'), 0);
 
-$group = [];
-$group[] = $form->createElement(
+$group4 = [];
+$group4[] = $form->createElement(
     'radio',
     'allow_user_view_user_list',
     get_lang('AllowUserViewUserList'),
     get_lang('AllowUserViewUserListActivate'),
     1
 );
-$group[] = $form->createElement(
+$group4[] = $form->createElement(
     'radio',
     'allow_user_view_user_list',
     null,
     get_lang('AllowUserViewUserListDeactivate'),
     0
 );
-$form->addGroup($group, '', [get_lang("AllowUserViewUserList")]);
-$form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
-$form->addHtml('
-        </div>
-    </div>
-');
-$form->addHtml('</div>');
-
+$myButton = $form->addButtonSave(get_lang('SaveSettings'), 'submit_save', true);
+
+$globalGroup = [
+    get_lang('AllowUserEditAgenda') => $group,
+    get_lang('AllowUserEditAnnouncement') => $group2,
+    get_lang('AllowUserImageForum') => $group3,
+    get_lang('AllowUserViewUserList') => $group4,
+    '' => $myButton,
+];
 // CHAT SETTINGS
-$form->addHtml('<div class="panel panel-default">');
-$form->addHtml('
-    <div class="panel-heading" role="tab" id="heading-chat-settings">
-        <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
-               href="#collapse-chat-settings" aria-expanded="false" aria-controls="collapse-chat-settings">
-');
-$form->addHtml(
-    Display::return_icon('chat.png', get_lang('ConfigChat'), '', ICON_SIZE_SMALL).' '.get_lang('ConfigChat')
+$form->addPanelOption(
+    'users',
+    Display::return_icon('user.png', get_lang('UserRights')).' '.get_lang('UserRights'),
+    $globalGroup
 );
-$form->addHtml('
-            </a>
-        </h4>
-    </div>
-');
-$form->addHtml('
-    <div id="collapse-chat-settings" class="panel-collapse collapse" role="tabpanel"
-         aria-labelledby="heading-chat-settings">
-        <div class="panel-body">
-');
+
 
 $group = [];
 $group[] = $form->createElement(
@@ -612,14 +584,18 @@ $group[] = $form->createElement(
     1
 );
 $group[] = $form->createElement('radio', 'allow_open_chat_window', null, get_lang('AllowOpenChatWindowDeactivate'), 0);
-$form->addGroup($group, '', [get_lang("AllowOpenchatWindow")]);
-$form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
+$myButton = $form->addButtonSave(get_lang('SaveSettings'), 'submit_save', true);
 
-$form->addHtml('
-        </div>
-    </div>
-');
-$form->addHtml('</div>');
+$globalGroup = [
+    get_lang('AllowOpenchatWindow') => $group,
+    '' => $myButton,
+];
+
+$form->addPanelOption(
+    'chat',
+    Display::return_icon('chat.png', get_lang('ConfigChat'), '', ICON_SIZE_SMALL).' '.get_lang('ConfigChat'),
+    $globalGroup
+);
 
 // LEARNING PATH
 $form->addHtml('<div class="panel panel-default">');
@@ -809,32 +785,6 @@ if (api_get_configuration_value('allow_exercise_auto_launch')) {
     $form->addHtml('</div>');
 }
 
-// THEMATIC ADVANCE SETTINGS
-$form->addHtml('<div class="panel panel-default">');
-$form->addHtml('
-    <div class="panel-heading" role="tab" id="heading-advance-settings">
-        <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion"
-               href="#collapse-advance-settings" aria-expanded="false" aria-controls="collapse-advance-settings">
-');
-$form->addHtml(
-    Display::return_icon(
-        'course_progress.png',
-        get_lang('ThematicAdvanceConfiguration')
-    )
-    .' '
-    .get_lang('ThematicAdvanceConfiguration')
-);
-$form->addHtml('
-            </a>
-        </h4>
-    </div>
-');
-$form->addHtml('
-    <div id="collapse-advance-settings" class="panel-collapse collapse" role="tabpanel"
-         aria-labelledby="heading-advance-settings">
-        <div class="panel-body">
-');
 
 $group = [];
 $group[] = $form->createElement(
@@ -865,37 +815,26 @@ $group[] = $form->createElement(
     get_lang('DoNotDisplayAnyAdvance'),
     0
 );
-$form->addGroup($group, '', [get_lang("InfoAboutAdvanceInsideHomeCourse")]);
-$form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
-$form->addHtml('
-        </div>
-    </div>
-');
-$form->addHtml('</div>');
+$myButton = $form->addButtonSave(get_lang('SaveSettings'), 'submit_save', true);
 
+$globalGroup = [
+    get_lang('InfoAboutAdvanceInsideHomeCourse') => $group,
+    '' => $myButton,
+];
 // Certificate settings
-if (api_get_setting('allow_public_certificates') == 'true') {
-    $form->addHtml('<div class="panel panel-default">');
-    $form->addHtml('
-        <div class="panel-heading" role="tab" id="heading-certificate-settings">
-            <h4 class="panel-title">
-                <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" aria-expanded="false"
-                   href="#collapse-certificate-settings" aria-controls="collapse-certificate-settings">
-    ');
-    $form->addHtml(
-        Display::return_icon('certificate.png', get_lang('Certificates')).' '.get_lang('Certificates')
-    );
-    $form->addHtml('
-                </a>
-            </h4>
-        </div>
-    ');
-    $form->addHtml('
-        <div id="collapse-certificate-settings" class="panel-collapse collapse" role="tabpanel"
-             aria-labelledby="heading-certificate-settings">
-            <div class="panel-body">
-    ');
+$form->addPanelOption(
+    'thematic',
+    Display::return_icon(
+        'course_progress.png',
+        get_lang('ThematicAdvanceConfiguration')
+    )
+    .' '
+    .get_lang('ThematicAdvanceConfiguration'),
+    $globalGroup
+);
 
+// Certificate settings
+if (api_get_setting('allow_public_certificates') === 'true') {
     $group = [];
     $group[] = $form->createElement(
         'radio',
@@ -905,47 +844,60 @@ if (api_get_setting('allow_public_certificates') == 'true') {
         1
     );
     $group[] = $form->createElement('radio', 'allow_public_certificates', null, get_lang('No'), 0);
-    $form->addGroup($group, '', [get_lang('AllowPublicCertificates')]);
-    $form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
-    $form->addHtml('
-            </div>
-        </div>
-    ');
-    $form->addHtml('</div>');
+    $myButton = $form->addButtonSave(get_lang('SaveSettings'), 'submit_save', true);
+
+    $globalGroup = [
+        get_lang('AllowPublicCertificates') => $group,
+        '' => $myButton,
+    ];
+
+    $form->addPanelOption(
+        'certificate',
+        Display::return_icon('certificate.png', get_lang('Certificates')).' '.get_lang('Certificates'),
+        $globalGroup
+    );
 }
 
-// Forum settings
-$form->addHtml('<div class="panel panel-default">');
-$form->addHtml('
-    <div class="panel-heading" role="tab" id="heading-forum-settings">
-        <h4 class="panel-title">
-            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-forum-settings" aria-expanded="false" aria-controls="collapse-forum-settings">
-');
-$form->addHtml(
-    Display::return_icon('forum.png', get_lang('Forum')).' '.get_lang('Forum')
-);
-$form->addHtml('
-            </a>
-        </h4>
-    </div>
-');
-$form->addHtml('
-    <div id="collapse-forum-settings" class="panel-collapse collapse" role="tabpanel"
-         aria-labelledby="heading-forum-settings">
-        <div class="panel-body">
-');
 
 $group = [
     $form->createElement('radio', 'enable_forum_auto_launch', null, get_lang('RedirectToForumList'), 1),
     $form->createElement('radio', 'enable_forum_auto_launch', null, get_lang('Disabled'), 2),
 ];
-$form->addGroup($group, '', [get_lang('EnableForumAutoLaunch')]);
-$form->addButtonSave(get_lang('SaveSettings'), 'submit_save');
-$form->addHtml('
-        </div>
-    </div>
-');
-$form->addHtml('</div>');
+$myButton = $form->addButtonSave(get_lang('SaveSettings'), 'submit_save', true);
+
+$globalGroup = [
+    get_lang('EnableForumAutoLaunch') => $group,
+    '' => $myButton,
+];
+
+$form->addPanelOption(
+    'forum',
+    Display::return_icon('forum.png', get_lang('Forum')).' '.get_lang('Forum'),
+    $globalGroup
+);
+
+// Student publication
+$group = [
+    $form->createElement('radio', 'show_score', null, get_lang('NewVisible'), 0),
+    $form->createElement('radio', 'show_score', null, get_lang('NewUnvisible'), 1),
+];
+$group2 = [
+    $form->createElement('radio', 'student_delete_own_publication', null, get_lang('Yes'), 1),
+    $form->createElement('radio', 'student_delete_own_publication', null, get_lang('No'), 0),
+];
+$myButton = $form->addButtonSave(get_lang('SaveSettings'), 'submit_save', true);
+
+$globalGroup = [
+    get_lang('DefaultUpload') => $group,
+    get_lang('StudentAllowedToDeleteOwnPublication') => $group2,
+    '' => $myButton,
+];
+
+$form->addPanelOption(
+    'student-publication',
+    Display::return_icon('work.png', get_lang('StudentPublications')).' '.get_lang('StudentPublications'),
+    $globalGroup
+);
 
 // Plugin course settings
 $appPlugin = new AppPlugin();
@@ -969,6 +921,7 @@ $values['unsubscribe'] = $_course['unsubscribe'];
 $values['course_registration_password'] = $all_course_information['registration_code'];
 $values['legal'] = $all_course_information['legal'];
 $values['activate_legal'] = $all_course_information['activate_legal'];
+$values['show_score'] = $all_course_information['show_score'];
 
 $courseSettings = CourseManager::getCourseSettingVariables($appPlugin);
 
@@ -978,6 +931,10 @@ foreach ($courseSettings as $setting) {
         $values[$setting] = $result;
     }
 }
+// make sure new settings have a clear default value
+if (!isset($values['student_delete_own_publication'])) {
+    $values['student_delete_own_publication'] = 0;
+}
 $form->setDefaults($values);
 
 // Validate form
@@ -1042,22 +999,6 @@ if ($form->validate() && is_settings_editable()) {
         unset($updateValues['pdf_export_watermark_path']);
     }
 
-    // Variables that will be saved in the TABLE_MAIN_COURSE table
-    $update_in_course_table = [
-        'title',
-        'course_language',
-        'category_code',
-        'department_name',
-        'department_url',
-        'visibility',
-        'subscribe',
-        'unsubscribe',
-        'tutor_name',
-        'course_registration_password',
-        'legal',
-        'activate_legal',
-    ];
-
     $activeLegal = isset($updateValues['activate_legal']) ? $updateValues['activate_legal'] : 0;
     $table_course = Database::get_main_table(TABLE_MAIN_COURSE);
 
@@ -1073,6 +1014,7 @@ if ($form->validate() && is_settings_editable()) {
         'legal' => $updateValues['legal'],
         'activate_legal' => $activeLegal,
         'registration_code' => $updateValues['course_registration_password'],
+        'show_score' => $updateValues['show_score'],
     ];
     Database::update($table_course, $params, ['id = ?' => $courseId]);
 
@@ -1086,6 +1028,9 @@ if ($form->validate() && is_settings_editable()) {
             api_get_course_int_id()
         );
     }
+    // update the extra fields
+    $courseFieldValue = new ExtraFieldValue('course');
+    $courseFieldValue->saveFieldValues($updateValues);
 
     $appPlugin->saveCourseSettingsHook($updateValues);
     $courseParams = api_get_cidreq();

+ 2 - 2
main/course_progress/index.php

@@ -116,7 +116,7 @@ $htmlHeadXtra[] = '<script>
 function datetime_by_attendance(attendance_id, thematic_advance_id) {
 	$.ajax({
 		contentType: "application/x-www-form-urlencoded",
-		beforeSend: function(objeto) {},
+		beforeSend: function(myObject) {},
 		type: "GET",
 		url: "'.api_get_path(WEB_AJAX_PATH).'thematic.ajax.php?a=get_datetime_by_attendance",
 		data: "attendance_id="+attendance_id+"&thematic_advance_id="+thematic_advance_id,
@@ -132,7 +132,7 @@ function datetime_by_attendance(attendance_id, thematic_advance_id) {
 function update_done_thematic_advance(selected_value) {
 	$.ajax({
 		contentType: "application/x-www-form-urlencoded",
-		beforeSend: function(objeto) {},
+		beforeSend: function(myObject) {},
 		type: "GET",
 		url: "'.api_get_path(WEB_AJAX_PATH).'thematic.ajax.php?a=update_done_thematic_advance",
 		data: "thematic_advance_id="+selected_value,

+ 6 - 11
main/coursecopy/copy_course.php

@@ -20,12 +20,7 @@ if (!api_is_allowed_to_edit()) {
     api_not_allowed(true);
 }
 
-// Remove memory and time limits as much as possible as this might be a long process...
-if (function_exists('ini_set')) {
-    api_set_memory_limit('256M');
-    ini_set('max_execution_time', 1800);
-    //ini_set('post_max_size', "512M");
-}
+api_set_more_memory_and_time_limits();
 
 // Breadcrumbs
 $interbreadcrumb[] = [
@@ -40,17 +35,17 @@ $this_section = SECTION_COURSES;
 Display::display_header(get_lang('CopyCourse'));
 echo Display::page_header(get_lang('CopyCourse'));
 
-/* MAIN CODE */
+$action = isset($_POST['action']) ? $_POST['action'] : '';
 
 // If a CourseSelectForm is posted or we should copy all resources, then copy them
 if (Security::check_token('post') && (
-    (isset($_POST['action']) && $_POST['action'] == 'course_select_form') ||
-    (isset($_POST['copy_option']) && $_POST['copy_option'] == 'full_copy')
+    ($action === 'course_select_form') ||
+    (isset($_POST['copy_option']) && $_POST['copy_option'] === 'full_copy')
     )
 ) {
     // Clear token
     Security::clear_token();
-    if (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
+    if ($action === 'course_select_form') {
         $course = CourseSelectForm::get_posted_course('copy_course');
     } else {
         $cb = new CourseBuilder();
@@ -68,7 +63,7 @@ if (Security::check_token('post') && (
     );
 } elseif (Security::check_token('post') && (
         isset($_POST['copy_option']) &&
-        $_POST['copy_option'] == 'select_items'
+        $_POST['copy_option'] === 'select_items'
     )
 ) {
     // Clear token

+ 6 - 13
main/coursecopy/copy_course_session.php

@@ -9,7 +9,7 @@ use ChamiloSession as Session;
 /**
  * Copy resources from one course in a session to another one.
  *
- * @author Christian Fasanando <christian.fasanando@dokeos.com>
+ * @author Christian Fasanando
  * @author Julio Montoya <gugli100@gmail.com> Lots of bug fixes/improvements
  *
  * @package chamilo.backup
@@ -20,6 +20,7 @@ $current_course_tool = TOOL_COURSE_MAINTENANCE;
 
 api_protect_global_admin_script();
 api_protect_limit_for_session_admin();
+api_set_more_memory_and_time_limits();
 
 $xajax = new xajax();
 $xajax->registerFunction('search_courses');
@@ -28,12 +29,7 @@ if (!api_is_allowed_to_edit() && !api_is_session_admin()) {
     api_not_allowed(true);
 }
 
-// Remove memory and time limits as much as possible as this might be a long process...
-if (function_exists('ini_set')) {
-    api_set_memory_limit('256M');
-    ini_set('max_execution_time', 1800);
-}
-
+$action = isset($_POST['action']) ? $_POST['action'] : '';
 $this_section = SECTION_PLATFORM_ADMIN;
 
 $nameTools = get_lang('CopyCourse');
@@ -167,7 +163,7 @@ function search_courses($id_session, $type)
     $return = null;
 
     if (!empty($type)) {
-        $id_session = intval($id_session);
+        $id_session = (int) $id_session;
         if ($type == 'origin') {
             $course_list = SessionManager::get_course_list_by_session_id($id_session);
             $temp_course_list = [];
@@ -283,10 +279,7 @@ if (isset($_POST['copy_only_session_items']) && $_POST['copy_only_session_items'
 
 /*  MAIN CODE  */
 if (Security::check_token('post') && (
-        (
-            isset($_POST['action']) &&
-            $_POST['action'] == 'course_select_form'
-        ) || (
+        ($action === 'course_select_form') || (
             isset($_POST['copy_option']) &&
             $_POST['copy_option'] == 'full_copy'
         )
@@ -295,7 +288,7 @@ if (Security::check_token('post') && (
     // Clear token
     Security::clear_token();
     $destination_course = $origin_course = $destination_session = $origin_session = '';
-    if (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
+    if ($action === 'course_select_form') {
         $destination_course = $_POST['destination_course'];
         $origin_course = $_POST['origin_course'];
         $destination_session = $_POST['destination_session'];

+ 8 - 15
main/coursecopy/copy_course_session_selected.php

@@ -9,7 +9,7 @@ use ChamiloSession as Session;
 /**
  * Copy resources from one course in a session to another one.
  *
- * @author Christian Fasanando <christian.fasanando@dokeos.com>
+ * @author Christian Fasanando 
  * @author Julio Montoya <gugli100@gmail.com> Lots of bug fixes/improvements
  * @author Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com> Code conventions
  *
@@ -20,6 +20,7 @@ require_once __DIR__.'/../inc/global.inc.php';
 $current_course_tool = TOOL_COURSE_MAINTENANCE;
 
 api_protect_course_script(true, true);
+api_set_more_memory_and_time_limits();
 
 $xajax = new xajax();
 $xajax->registerFunction('searchCourses');
@@ -32,6 +33,8 @@ if (!api_is_coach()) {
     api_not_allowed(true);
 }
 
+$action = isset($_POST['action']) ? $_POST['action'] : '';
+
 $courseId = api_get_course_int_id();
 $courseInfo = api_get_course_info_by_id($courseId);
 $courseCode = $courseInfo['code'];
@@ -41,12 +44,6 @@ if (empty($courseCode) || empty($sessionId)) {
     api_not_allowed(true);
 }
 
-// Remove memory and time limits as much as possible as this might be a long process...
-if (function_exists('ini_set')) {
-    ini_set('memory_limit', '256M');
-    ini_set('max_execution_time', 1800);
-}
-
 $this_section = SECTION_COURSES;
 $nameTools = get_lang('CopyCourse');
 $returnLink = api_get_path(WEB_CODE_PATH).'course_info/maintenance_coach.php?'.api_get_cidreq();
@@ -62,7 +59,6 @@ $tbl_session_rel_course_rel_user = Database::get_main_table(
 $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
 $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
 
-/* FUNCTIONS */
 /**
  * @param string $name
  */
@@ -132,8 +128,7 @@ function displayForm()
             get_lang('CopyCourseFromSessionToSessionExplanation')
     );
 
-    $html .= '<form name="formulaire" method="post" action="'.api_get_self(
-        ).'?'.api_get_cidreq().'" >';
+    $html .= '<form name="formulaire" method="post" action="'.api_get_self().'?'.api_get_cidreq().'" >';
     $html .= '<table border="0" cellpadding="5" cellspacing="0" width="100%">';
 
     // Source
@@ -203,7 +198,7 @@ function searchCourses($idSession, $type)
     $courseCode = api_get_course_id();
 
     if (!empty($type)) {
-        $idSession = intval($idSession);
+        $idSession = (int) $idSession;
         $courseList = SessionManager::get_course_list_by_session_id($idSession);
 
         $return .= '<select id="destination" name="SessionCoursesListDestination[]" style="width:380px;" >';
@@ -240,8 +235,6 @@ function searchCourses($idSession, $type)
 
 $xajax->processRequests();
 
-/* HTML head extra */
-
 $htmlHeadXtra[] = $xajax->getJavascript(
     api_get_path(WEB_LIBRARY_PATH).'xajax/'
 );
@@ -287,14 +280,14 @@ Display::display_header($nameTools);
 
 /* MAIN CODE */
 
-if ((isset($_POST['action']) && $_POST['action'] == 'course_select_form') ||
+if (($action === 'course_select_form') ||
     (isset($_POST['copy_option']) && $_POST['copy_option'] == 'full_copy')
 ) {
     $destinationCourse = $destinationSession = '';
     $originCourse = api_get_course_id();
     $originSession = api_get_session_id();
 
-    if (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
+    if ($action === 'course_select_form') {
         $destinationCourse = $_POST['destination_course'];
         $destinationSession = $_POST['destination_session'];
         $course = CourseSelectForm::get_posted_course(

+ 59 - 73
main/coursecopy/create_backup.php

@@ -17,18 +17,13 @@ $current_course_tool = TOOL_COURSE_MAINTENANCE;
 
 api_protect_course_script(true);
 
-api_check_archive_dir();
-
 // Check access rights (only teachers are allowed here)
 if (!api_is_allowed_to_edit()) {
     api_not_allowed(true);
 }
 
-// Remove memory and time limits as much as possible as this might be a long process...
-if (function_exists('ini_set')) {
-    api_set_memory_limit('256M');
-    ini_set('max_execution_time', 1800);
-}
+api_check_archive_dir();
+api_set_more_memory_and_time_limits();
 
 // Section for the tabs
 $this_section = SECTION_COURSES;
@@ -45,87 +40,78 @@ Display::display_header($nameTools);
 
 // Display the tool title
 echo Display::page_header($nameTools);
+$action = isset($_POST['action']) ? $_POST['action'] : '';
+$backupOption = isset($_POST['backup_option']) ? $_POST['backup_option'] : '';
 
-if (Security::check_token('post') && (
-        (
-            isset($_POST['action']) &&
-            $_POST['action'] == 'course_select_form'
-        ) || (
-            isset($_POST['backup_option']) &&
-            $_POST['backup_option'] == 'full_backup'
-        )
-    )
+if (Security::check_token('post') &&
+    ($action === 'course_select_form' || $backupOption === 'full_backup')
 ) {
     // Clear token
     Security::clear_token();
 
-    if (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
-        $course = CourseSelectForm::get_posted_course();
+    if ($action === 'course_select_form') {
+        $cb = new CourseBuilder('partial');
+        $course = $cb->build(0, null, false, array_keys($_POST['resource']), $_POST['resource']);
+        $course = CourseSelectForm::get_posted_course(null, 0, '', $course);
     } else {
-        $cb = new CourseBuilder();
+        $cb = new CourseBuilder('complete');
         $course = $cb->build();
     }
-
-    $zip_file = CourseArchiver::createBackup($course);
+    $zipFile = CourseArchiver::createBackup($course);
     echo Display::return_message(get_lang('BackupCreated'), 'confirm');
-    echo '<br />
-        <a class="btn btn-primary btn-large" 
-        href="'.api_get_path(WEB_CODE_PATH).'course_info/download.php?archive='.$zip_file.'&'.api_get_cidreq().'">
-    '.get_lang('Download').'</a>';
-} elseif (Security::check_token('post') && (
-        isset($_POST['backup_option']) &&
-        $_POST['backup_option'] == 'select_items'
-    )
-) {
+    echo '<br />';
+    echo Display::url(
+        get_lang('Download'),
+        api_get_path(WEB_CODE_PATH).'course_info/download.php?archive='.$zipFile.'&'.api_get_cidreq(),
+        ['class' => 'btn btn-primary btn-large']
+    );
+} elseif (Security::check_token('post') && $backupOption === 'select_items') {
     // Clear token
     Security::clear_token();
-
     $cb = new CourseBuilder('partial');
     $course = $cb->build();
-    // Add token to Course select form
-    $hiddenFields['sec_token'] = Security::get_token();
-    CourseSelectForm::display_form($course, $hiddenFields);
-} else {
-    $cb = new CourseBuilder();
-    $course = $cb->build();
-    if (!$course->has_resources()) {
-        echo get_lang('NoResourcesToBackup');
+    if ($course->has_resources()) {
+        // Add token to Course select form
+        $hiddenFields['sec_token'] = Security::get_token();
+        CourseSelectForm::display_form($course, $hiddenFields, false, true);
     } else {
-        $form = new FormValidator(
-            'create_backup_form',
-            'post',
-            api_get_self().'?'.api_get_cidreq()
-        );
-        $form->addElement('header', get_lang('SelectOptionForBackup'));
-        $form->addElement('radio', 'backup_option', '', get_lang('CreateFullBackup'), 'full_backup');
-        $form->addElement('radio', 'backup_option', '', get_lang('LetMeSelectItems'), 'select_items');
-        $form->addButtonSave(get_lang('CreateBackup'));
-        $form->addProgress();
-        // When progress bar appears we have to hide the title "Please select a backup-option".
-        $form->updateAttributes(
-            [
-                'onsubmit' => str_replace(
-                    'javascript: ',
-                    'javascript: page_title = getElementById(\'page_title\'); if (page_title) { setTimeout(\'page_title.style.display = \\\'none\\\';\', 2000); } ',
-                    $form->getAttribute('onsubmit')
-                ),
-            ]
-        );
-        $values['backup_option'] = 'full_backup';
-        $form->setDefaults($values);
-
-        // Add Security token
-        $token = Security::get_token();
-        $form->addElement('hidden', 'sec_token');
-        $form->setConstants(['sec_token' => $token]);
-        echo '<div class="row">';
-        echo '<div class="col-md-12">';
-        echo '<div class="tool-backup">';
-        $form->display();
-        echo '</div>';
-        echo '</div>';
-        echo '</div>';
+        echo Display::return_message(get_lang('NoResourcesToBackup'), 'warning');
     }
+} else {
+    $form = new FormValidator(
+        'create_backup_form',
+        'post',
+        api_get_self().'?'.api_get_cidreq()
+    );
+    $form->addElement('header', get_lang('SelectOptionForBackup'));
+    $form->addElement('radio', 'backup_option', '', get_lang('CreateFullBackup'), 'full_backup');
+    $form->addElement('radio', 'backup_option', '', get_lang('LetMeSelectItems'), 'select_items');
+    $form->addButtonSave(get_lang('CreateBackup'));
+    $form->addProgress();
+    // When progress bar appears we have to hide the title "Please select a backup-option".
+    $form->updateAttributes(
+        [
+            'onsubmit' => str_replace(
+                'javascript: ',
+                'javascript: page_title = getElementById(\'page_title\'); if (page_title) { setTimeout(\'page_title.style.display = \\\'none\\\';\', 2000); } ',
+                $form->getAttribute('onsubmit')
+            ),
+        ]
+    );
+    $values['backup_option'] = 'full_backup';
+    $form->setDefaults($values);
+
+    // Add Security token
+    $token = Security::get_token();
+    $form->addElement('hidden', 'sec_token');
+    $form->setConstants(['sec_token' => $token]);
+    echo '<div class="row">';
+    echo '<div class="col-md-12">';
+    echo '<div class="tool-backup">';
+    $form->display();
+    echo '</div>';
+    echo '</div>';
+    echo '</div>';
 }
 
 Display::display_footer();

+ 26 - 40
main/coursecopy/import_backup.php

@@ -4,6 +4,7 @@
 use Chamilo\CourseBundle\Component\CourseCopy\CourseArchiver;
 use Chamilo\CourseBundle\Component\CourseCopy\CourseRestorer;
 use Chamilo\CourseBundle\Component\CourseCopy\CourseSelectForm;
+use ChamiloSession as Session;
 
 /**
  * Import a backup.
@@ -22,11 +23,7 @@ if (!api_is_allowed_to_edit()) {
     api_not_allowed(true);
 }
 
-// Remove memory and time limits as much as possible as this might be a long process...
-if (function_exists('ini_set')) {
-    api_set_memory_limit('256M');
-    ini_set('max_execution_time', 1800);
-}
+api_set_more_memory_and_time_limits();
 
 // Section for the tabs
 $this_section = SECTION_COURSES;
@@ -44,45 +41,34 @@ Display::display_header($nameTools);
 // Display the tool title
 echo Display::page_header($nameTools);
 
+$action = isset($_POST['action']) ? $_POST['action'] : '';
+$importOption = isset($_POST['import_option']) ? $_POST['import_option'] : '';
+
 /* MAIN CODE */
 $filename = '';
-if (Security::check_token('post') && (
-        (
-            isset($_POST['action']) &&
-            $_POST['action'] == 'course_select_form'
-        ) || (
-            isset($_POST['import_option']) &&
-            $_POST['import_option'] == 'full_backup'
-        )
-    )
-) {
+if (Security::check_token('post') && ($action === 'course_select_form' || $importOption === 'full_backup')) {
     // Clear token
     Security::clear_token();
 
     $error = false;
-    if (isset($_POST['action']) &&
-        $_POST['action'] == 'course_select_form'
-    ) {
+    if ($action === 'course_select_form') {
         // Partial backup here we recover the documents posted
-        // This gets $_POST['course']. Beware that when using Suhosin,
-        // the post.max_value_length limit might get in the way of the
-        // restoration of a course with many items. A value of 1,000,000 bytes
-        // might be too short.
-        $course = CourseSelectForm::get_posted_course();
+        $filename = Session::read('backup_file');
+        $course = CourseArchiver::readCourse($filename, false);
+        $course = CourseSelectForm::get_posted_course(null, null, null, $course);
     } else {
-        if ($_POST['backup_type'] == 'server') {
+        if ($_POST['backup_type'] === 'server') {
             $filename = $_POST['backup_server'];
             $delete_file = false;
         } else {
             if ($_FILES['backup']['error'] == 0) {
-                $filename = CourseArchiver::importUploadedFile(
-                    $_FILES['backup']['tmp_name']
-                );
+                $filename = CourseArchiver::importUploadedFile($_FILES['backup']['tmp_name']);
                 if ($filename === false) {
                     $error = true;
                 } else {
-                    $delete_file = true;
+                    $delete_file = false;
                 }
+                Session::write('backup_file', $filename);
             } else {
                 $error = true;
             }
@@ -99,7 +85,8 @@ if (Security::check_token('post') && (
         $cr->set_file_option($_POST['same_file_name_option']);
         $cr->restore();
         echo Display::return_message(get_lang('ImportFinished'));
-        echo '<a class="btn btn-default" href="'.api_get_path(WEB_COURSE_PATH).api_get_course_path().'/index.php">'.get_lang('CourseHomepage').'</a>';
+        echo '<a class="btn btn-default" href="'.api_get_path(WEB_COURSE_PATH).api_get_course_path().'/index.php">'.
+            get_lang('CourseHomepage').'</a>';
     } else {
         if (!$error) {
             echo Display::return_message(get_lang('NoResourcesInBackupFile'), 'warning');
@@ -118,24 +105,21 @@ if (Security::check_token('post') && (
         }
     }
     CourseArchiver::cleanBackupDir();
-} elseif (Security::check_token('post') && (
-        isset($_POST['import_option']) &&
-        $_POST['import_option'] == 'select_items'
-    )
-) {
+} elseif (Security::check_token('post') && $importOption === 'select_items') {
     // Clear token
     Security::clear_token();
 
-    if ($_POST['backup_type'] == 'server') {
+    if ($_POST['backup_type'] === 'server') {
         $filename = $_POST['backup_server'];
         $delete_file = false;
     } else {
         $filename = CourseArchiver::importUploadedFile($_FILES['backup']['tmp_name']);
-        $delete_file = true;
+        $delete_file = false;
+        Session::write('backup_file', $filename);
     }
     $course = CourseArchiver::readCourse($filename, $delete_file);
 
-    if ($course->has_resources() && ($filename !== false)) {
+    if ($course->has_resources() && $filename !== false) {
         $hiddenFields['same_file_name_option'] = $_POST['same_file_name_option'];
         // Add token to Course select form
         $hiddenFields['sec_token'] = Security::get_token();
@@ -149,9 +133,7 @@ if (Security::check_token('post') && (
     }
 } else {
     $user = api_get_user_info();
-    $backups = CourseArchiver::getAvailableBackups(
-        $is_platformAdmin ? null : $user['user_id']
-    );
+    $backups = CourseArchiver::getAvailableBackups($is_platformAdmin ? null : $user['user_id']);
     $backups_available = count($backups) > 0;
 
     $form = new FormValidator(
@@ -285,4 +267,8 @@ if (Security::check_token('post') && (
     $form->display();
 }
 
+if (!isset($_POST['action'])) {
+    Session::erase('backup_file');
+}
+
 Display::display_footer();

+ 1 - 5
main/coursecopy/import_moodle.php

@@ -18,11 +18,7 @@ if (!api_is_allowed_to_edit()) {
     api_not_allowed(true);
 }
 
-// Remove memory and time limits as much as possible as this might be a long process...
-if (function_exists('ini_set')) {
-    api_set_memory_limit('256M');
-    ini_set('max_execution_time', 1800);
-}
+api_set_more_memory_and_time_limits();
 
 // Section for the tabs
 $this_section = SECTION_COURSES;

+ 6 - 7
main/coursecopy/recycle_course.php

@@ -36,10 +36,10 @@ Display::display_header($nameTools);
 
 // Display the tool title
 echo Display::page_header($nameTools);
+$action = isset($_POST['action']) ? $_POST['action'] : '';
 
 if (Security::check_token('post') && (
-        isset($_POST['action']) &&
-        $_POST['action'] == 'course_select_form' ||
+        $action === 'course_select_form' ||
         (
             isset($_POST['recycle_option']) &&
             $_POST['recycle_option'] == 'full_backup'
@@ -48,17 +48,16 @@ if (Security::check_token('post') && (
 ) {
     // Clear token
     Security::clear_token();
-
-    if (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
+    if (isset($_POST['action']) && $_POST['action'] === 'course_select_form') {
         $course = CourseSelectForm::get_posted_course();
     } else {
         $cb = new CourseBuilder();
         $course = $cb->build();
     }
     $recycle_type = '';
-    if (isset($_POST['recycle_option']) && $_POST['recycle_option'] == 'full_backup') {
+    if (isset($_POST['recycle_option']) && $_POST['recycle_option'] === 'full_backup') {
         $recycle_type = 'full_backup';
-    } elseif (isset($_POST['action']) && $_POST['action'] == 'course_select_form') {
+    } elseif (isset($_POST['action']) && $_POST['action'] === 'course_select_form') {
         $recycle_type = 'select_items';
     }
     $cr = new CourseRecycler($course);
@@ -66,7 +65,7 @@ if (Security::check_token('post') && (
     echo Display::return_message(get_lang('RecycleFinished'), 'confirm');
 } elseif (Security::check_token('post') && (
         isset($_POST['recycle_option']) &&
-        $_POST['recycle_option'] == 'select_items'
+        $_POST['recycle_option'] === 'select_items'
     )
 ) {
     // Clear token