Browse Source

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

Alex Ruben 7 years ago
parent
commit
9763696a9c

+ 4 - 2
app/Migrations/Schema/V111/Version20161028123400.php

@@ -34,8 +34,10 @@ class Version20161028123400 extends AbstractMigrationChamilo
         $table = $schema->getTable('personal_agenda');
         if ($table->hasIndex('id')) {
             $this->addSql('ALTER TABLE personal_agenda modify id INT NOT NULL');
-            $this->addSql('ALTER TABLE personal_agenda DROP index id');
-            $this->addSql('ALTER TABLE personal_agenda DROP PRIMARY KEY');
+            $table->dropIndex('id');
+            if ($table->hasPrimaryKey()) {
+                $table->dropPrimaryKey();
+            }
             $this->addSql('ALTER TABLE personal_agenda CHANGE id id INT AUTO_INCREMENT NOT NULL PRIMARY KEY');
         }
     }

+ 3 - 5
main/admin/skill_badge_create.php

@@ -89,11 +89,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
     exit;
 }
 
-$interbreadcrumb = [
-    [
-        'url' => api_get_path(WEB_CODE_PATH).'admin/index.php',
-        'name' => get_lang('Administration'),
-    ],
+$interbreadcrumb[] = [
+    'url' => api_get_path(WEB_CODE_PATH).'admin/index.php',
+    'name' => get_lang('Administration'),
 ];
 $interbreadcrumb[] = ['url' => 'skill_list.php', 'name' => get_lang('ManageSkills')];
 

+ 16 - 21
main/exercise/exercise.class.php

@@ -5869,19 +5869,22 @@ class Exercise
     }
 
     /**
-     * @param array  $user_data  result of api_get_user_info()
-     * @param string $start_date
-     * @param null   $duration
-     * @param string $ip         Optional. The user IP
+     * @param array $user_data         result of api_get_user_info()
+     * @param array $trackExerciseInfo result of get_stat_track_exercise_info
      *
      * @return string
      */
-    public function show_exercise_result_header(
+    public function showExerciseResultHeader(
         $user_data,
-        $start_date = null,
-        $duration = null,
-        $ip = null
+        $trackExerciseInfo
     ) {
+        $start_date = null;
+        if (isset($trackExerciseInfo['start_date'])) {
+            $start_date = api_convert_and_format_date($trackExerciseInfo['start_date']);
+        }
+        $duration = isset($trackExerciseInfo['duration_formatted']) ? $trackExerciseInfo['duration_formatted'] : null;
+        $ip = isset($trackExerciseInfo['user_ip']) ? $trackExerciseInfo['user_ip'] : null;
+
         $array = [];
         if (!empty($user_data)) {
             $array[] = [
@@ -5958,6 +5961,7 @@ class Exercise
      * @param int     Whether the results are show to the user (0) or not (1)
      * @param int     Maximum number of attempts (0 if no limit)
      * @param int     Feedback type
+     * @param int $propagateNegative
      *
      * @todo this was function was added due the import exercise via CSV
      *
@@ -6630,21 +6634,12 @@ class Exercise
         $new_array = [];
         if (Database::num_rows($result) > 0) {
             $new_array = Database::fetch_array($result, 'ASSOC');
-            $new_array['duration'] = null;
             $start_date = api_get_utc_datetime($new_array['start_date'], true);
             $end_date = api_get_utc_datetime($new_array['exe_date'], true);
-
-            if (!empty($start_date) && !empty($end_date)) {
-                $start_date = api_strtotime($start_date, 'UTC');
-                $end_date = api_strtotime($end_date, 'UTC');
-                if ($start_date && $end_date) {
-                    $mytime = $end_date - $start_date;
-                    $new_learnpath_item = new learnpathItem(null);
-                    $time_attemp = $new_learnpath_item->get_scorm_time('js', $mytime);
-                    $h = get_lang('h');
-                    $time_attemp = str_replace('NaN', '00'.$h.'00\'00"', $time_attemp);
-                    $new_array['duration'] = $time_attemp;
-                }
+            $new_array['duration_formatted'] = '';
+            if (!empty($new_array['exe_duration']) && !empty($start_date) && !empty($end_date)) {
+                $time = api_format_time($new_array['exe_duration'], 'js');
+                $new_array['duration_formatted'] = $time;
             }
         }
 

+ 2 - 6
main/exercise/exercise_show.php

@@ -35,7 +35,6 @@ if (empty($track_exercise_info)) {
 }
 
 $exercise_id = $track_exercise_info['id'];
-$exercise_date = $track_exercise_info['start_date'];
 $student_id = $track_exercise_info['exe_user_id'];
 $learnpath_id = $track_exercise_info['orig_lp_id'];
 $learnpath_item_id = $track_exercise_info['orig_lp_item_id'];
@@ -123,7 +122,6 @@ if (empty($objExercise)) {
     $objExercise->read($exercise_id);
 }
 $feedback_type = $objExercise->feedback_type;
-
 //Only users can see their own results
 if (!$is_allowedToEdit) {
     if ($student_id != $currentUserId) {
@@ -293,11 +291,9 @@ if ($action == 'export') {
 $user_info = api_get_user_info($student_id);
 if ($show_results || $show_only_total_score || $showTotalScoreAndUserChoicesInLastAttempt) {
     // Shows exercise header
-    echo $objExercise->show_exercise_result_header(
+    echo $objExercise->showExerciseResultHeader(
         $user_info,
-        api_convert_and_format_date($exercise_date),
-        null,
-        $track_exercise_info['user_ip']
+        $track_exercise_info
     );
 }
 

+ 0 - 6
main/exercise/upload_exercise.php

@@ -546,13 +546,7 @@ function lp_upload_quiz_action_handling()
         if (!empty($lpObject)) {
             $oLP = unserialize($lpObject);
             if (is_object($oLP)) {
-                if ($debug > 0) {
-                    error_log('New LP - oLP is object', 0);
-                }
                 if ((empty($oLP->cc)) || $oLP->cc != api_get_course_id()) {
-                    if ($debug > 0) {
-                        error_log('New LP - Course has changed, discard lp object', 0);
-                    }
                     $oLP = null;
                     Session::erase('oLP');
                     Session::erase('lpobject');

+ 0 - 1
main/inc/lib/TicketManager.php

@@ -705,7 +705,6 @@ class TicketManager
      * @param $message_id
      *
      * @return bool
-     *
      */
     public static function saveMessageAttachmentFile(
         $file_attach,

+ 12 - 9
main/inc/lib/api.lib.php

@@ -279,15 +279,17 @@ define('USERNAME_PURIFIER_SHALLOW', '/\s/');
 define('IS_WINDOWS_OS', api_is_windows_os());
 
 // Checks for installed optional php-extensions.
-define('INTL_INSTALLED', function_exists('intl_get_error_code')); // intl extension (from PECL), it is installed by default as of PHP 5.3.0
-define('ICONV_INSTALLED', function_exists('iconv')); // iconv extension, for PHP5 on Windows it is installed by default.
+// intl extension (from PECL), it is installed by default as of PHP 5.3.0.
+define('INTL_INSTALLED', function_exists('intl_get_error_code'));
+// iconv extension, for PHP5 on Windows it is installed by default.
+define('ICONV_INSTALLED', function_exists('iconv'));
 define('MBSTRING_INSTALLED', function_exists('mb_strlen')); // mbstring extension.
 
-// Patterns for processing paths.                                   // Examples:
+// Patterns for processing paths. Examples.
 define('REPEATED_SLASHES_PURIFIER', '/\/{2,}/'); // $path = preg_replace(REPEATED_SLASHES_PURIFIER, '/', $path);
 define('VALID_WEB_PATH', '/https?:\/\/[^\/]*(\/.*)?/i'); // $is_valid_path = preg_match(VALID_WEB_PATH, $path);
-define('VALID_WEB_SERVER_BASE', '/https?:\/\/[^\/]*/i'); // $new_path = preg_replace(VALID_WEB_SERVER_BASE, $new_base, $path);
-
+// $new_path = preg_replace(VALID_WEB_SERVER_BASE, $new_base, $path);
+define('VALID_WEB_SERVER_BASE', '/https?:\/\/[^\/]*/i');
 // Constants for api_get_path() and api_get_path_type(), etc. - registered path types.
 // basic (leaf elements)
 define('REL_CODE_PATH', 'REL_CODE_PATH');
@@ -737,9 +739,10 @@ function api_get_path($path = '', $configuration = [])
                             : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST']
                                 : (isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR']
                                     : 'localhost')));
-                    if (isset($_SERVER['SERVER_PORT']) && !strpos($server_name, ':')
-                        && (($server_protocol == 'http'
-                                && $_SERVER['SERVER_PORT'] != 80) || ($server_protocol == 'https' && $_SERVER['SERVER_PORT'] != 443))
+                    if (isset($_SERVER['SERVER_PORT']) &&
+                        !strpos($server_name, ':') &&
+                        (($server_protocol == 'http' && $_SERVER['SERVER_PORT'] != 80) ||
+                        ($server_protocol == 'https' && $_SERVER['SERVER_PORT'] != 443))
                     ) {
                         $server_name .= ":".$_SERVER['SERVER_PORT'];
                     }
@@ -754,7 +757,7 @@ function api_get_path($path = '', $configuration = [])
     if (isset($configuration['multiple_access_urls']) &&
         $configuration['multiple_access_urls']
     ) {
-        // To avoid that the api_get_access_url() function fails since global.inc.php also calls the main_api.lib.php
+        // To avoid that the api_get_access_url() function fails since global.inc.php also calls the api.lib.php.
         if (isset($configuration['access_url']) && !empty($configuration['access_url'])) {
             // We look into the DB the function api_get_access_url
             $urlInfo = api_get_access_url($configuration['access_url']);

+ 7 - 7
main/inc/lib/exercise.lib.php

@@ -1369,6 +1369,11 @@ HOTSPOT;
 
             $res_fb_type = Database::query($sql);
             $result = Database::fetch_array($res_fb_type, 'ASSOC');
+            $result['duration_formatted'] = '';
+            if (!empty($result['exe_duration'])) {
+                $time = api_format_time($result['exe_duration'], 'js');
+                $result['duration_formatted'] = $time;
+            }
         }
 
         return $result;
@@ -4118,14 +4123,9 @@ EOT;
                 $user_info = api_get_user_info($exercise_stat_info['exe_user_id']);
                 if ($user_info) {
                     // Shows exercise header
-                    echo $objExercise->show_exercise_result_header(
+                    echo $objExercise->showExerciseResultHeader(
                         $user_info,
-                        api_convert_and_format_date(
-                            $exercise_stat_info['start_date'],
-                            DATE_TIME_FORMAT_LONG
-                        ),
-                        $exercise_stat_info['duration'],
-                        $exercise_stat_info['user_ip']
+                        $exercise_stat_info
                     );
                 }
             }

+ 1 - 0
main/inc/lib/import.lib.php

@@ -71,6 +71,7 @@ class Import
 
     /**
      * @param string $filename
+     *
      * @return array
      */
     public static function xlsToArray($filename)

+ 8 - 8
main/inc/lib/message.lib.php

@@ -505,15 +505,15 @@ class MessageManager
     }
 
     /**
-     * @param int $receiver_user_id
-     * @param int $subject
+     * @param int    $receiver_user_id
+     * @param int    $subject
      * @param string $message
-     * @param int $sender_id
-     * @param bool $sendCopyToDrhUsers send copy to related DRH users
-     * @param bool $directMessage
-     * @param array $smsParameters
-     * @param bool $uploadFiles Do not upload files using the MessageManager class
-     * @param array $attachmentList
+     * @param int    $sender_id
+     * @param bool   $sendCopyToDrhUsers send copy to related DRH users
+     * @param bool   $directMessage
+     * @param array  $smsParameters
+     * @param bool   $uploadFiles        Do not upload files using the MessageManager class
+     * @param array  $attachmentList
      *
      * @return bool
      */

+ 1 - 1
main/inc/lib/pear/HTML/QuickForm/select.php

@@ -53,7 +53,7 @@ class HTML_QuickForm_select extends HTML_QuickForm_element
      * @since     1.0
      * @access    private
      */
-    protected $_values;
+    protected $_values = [];
 
     /**
      * Class constructor

+ 1 - 1
main/inc/lib/skill.lib.php

@@ -1543,7 +1543,7 @@ class Skill extends Model
                         'id' => '1',
                         'name' => get_lang('Root'),
                         'parent_id' => '0',
-                        'status' => 1
+                        'status' => 1,
                     ];
                     $skillInfo = $this->getSkillInfo($skill_id);
 

+ 8 - 10
main/inc/lib/tracking.lib.php

@@ -1009,12 +1009,9 @@ class Tracking
                                         $my_exo_exe_id = $row_attempts['exe_exo_id'];
                                         $mktime_start_date = api_strtotime($row_attempts['start_date'], 'UTC');
                                         $mktime_exe_date = api_strtotime($row_attempts['exe_date'], 'UTC');
+                                        $time_attemp = ' - ';
                                         if ($mktime_start_date && $mktime_exe_date) {
-                                            $mytime = ((int) $mktime_exe_date - (int) $mktime_start_date);
-                                            $time_attemp = learnpathItem::getScormTimeFromParameter('js', $mytime);
-                                            $time_attemp = str_replace('NaN', '00'.$h.'00\'00"', $time_attemp);
-                                        } else {
-                                            $time_attemp = ' - ';
+                                            $time_attemp = api_format_time($row_attempts['exe_duration'], 'js');
                                         }
                                         if (!$is_allowed_to_edit && $result_disabled_ext_all) {
                                             $view_score = Display::return_icon(
@@ -6560,15 +6557,16 @@ class Tracking
     /**
      * Get the HTML code for show a block with the achieved user skill on course/session.
      *
-     * @param int $userId
-     * @param int $courseId  optional
-     * @param int $sessionId optional
+     * @param int  $userId
+     * @param int  $courseId
+     * @param int  $sessionId
+     * @param bool $forceView forces the view of the skills, not checking for deeper access
      *
      * @return string
      */
-    public static function displayUserSkills($userId, $courseId = 0, $sessionId = 0)
+    public static function displayUserSkills($userId, $courseId = 0, $sessionId = 0, $forceView = false)
     {
-        if (Skill::isAllowed($userId, false) === false) {
+        if (Skill::isAllowed($userId, false) === false && $forceView == false) {
             return '';
         }
         $skillManager = new Skill();

+ 11 - 8
main/install/configuration.dist.php

@@ -788,13 +788,6 @@ ALTER TABLE skill_rel_course ADD CONSTRAINT FK_E7CEC7FA613FECDF FOREIGN KEY (ses
 // affect privacy protection.
 //$_configuration['allow_user_message_tracking'] = false;
 
-// ------ Custom DB changes
-// 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
-
 // Add a portfolio tool (duplicating the Notebook tool). Requires DB changes:
 /*
 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;
@@ -808,5 +801,15 @@ INSERT INTO settings_current(variable, subkey, type, category, selected_value, t
 */
 //$_configuration['allow_portfolio_tool'] = false;
 
-// Disable average and best columns in gradebook see BT#
+// Disable average and best columns in gradebook see BT#14126
 //$_configuration['disable_gradebook_stats'] = false;
+
+// Allow teachers to access student skills BT#14161 (skills setting must be enabled in the platform)
+//$_configuration['allow_teacher_access_student_skills'] = false;
+
+// ------ 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

+ 196 - 0
main/install/install.lib.php

@@ -1641,6 +1641,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,
@@ -2783,6 +2785,198 @@ 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');
+    } else {
+        $sessions = [0];
+    }
+
+    foreach ($courses as $course) {
+        $courseId = $course['id'];
+        $sql = "SELECT * FROM $tblCLp WHERE c_id = $courseId AND iid <> id";
+        $result = $connection->query($sql);
+        if ($debug) {
+            error_log('-------------');
+            error_log("Entering Lps in course #$courseId");
+            error_log($sql);
+        }
+        $lpList = $result->fetchAll();
+        if (!empty($lpList)) {
+            foreach ($lpList as $lpInfo) {
+                $lpIid = $lpInfo['iid'];
+                $oldId = $lpInfo['id'];
+
+                if ($lpIid == $oldId) {
+                    // Do nothing
+                    continue;
+                }
+                $sql = "SELECT * FROM $tblCLpItem WHERE c_id = $courseId AND lp_id = $oldId";
+
+                $result = $connection->query($sql);
+                $items = $result->fetchAll();
+                $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 $tblCLpItem SET lp_id = $lpIid 
+                        WHERE iid = $itemIid AND c_id = $courseId AND lp_id = $oldId";
+                    $connection->query($sql);
+
+                    $sql = "UPDATE $tblCLpItem SET id = iid 
+                        WHERE c_id = $courseId AND lp_id = $oldId";
+                    $connection->query($sql);
+                }
+
+                $sql = "UPDATE $tblCLp SET id = iid WHERE c_id = $courseId AND iid = $lpIid";
+                $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);
+            }
+        }
+    }
+
+    if ($debug) {
+        error_log('----- END - fixIds');
+    }
 }
 
 /**
@@ -3272,6 +3466,8 @@ function migrateSwitch($fromVersion, $manager, $processFiles = true)
             );
 
             if ($result) {
+                fixLpId($connection, true);
+
                 error_log('Migrations files were executed ('.date('Y-m-d H:i:s').')');
 
                 fixPostGroupIds($connection);

File diff suppressed because it is too large
+ 205 - 99
main/lp/learnpath.class.php


+ 12 - 15
main/lp/learnpathItem.class.php

@@ -3912,27 +3912,24 @@ class learnpathItem
                 } else {
                     // For all other content types...
                     if ($this->type == 'quiz') {
+                        if ($debug) {
+                            error_log("item is quiz:");
+                        }
                         $my_status = ' ';
                         $total_time = ' ';
                         if (!empty($_REQUEST['exeId'])) {
                             $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
-
-                            $safe_exe_id = intval($_REQUEST['exeId']);
-                            $sql = "SELECT start_date, exe_date
+                            $exeId = (int) $_REQUEST['exeId'];
+                            $sql = "SELECT exe_duration
                                     FROM $table
-                                    WHERE exe_id = $safe_exe_id";
+                                    WHERE exe_id = $exeId";
+                            if ($debug) {
+                                error_log($sql);
+                            }
                             $res = Database::query($sql);
-                            $row_dates = Database::fetch_array($res);
-
-                            $time_start_date = convert_sql_date(
-                                $row_dates['start_date']
-                            );
-                            $time_exe_date = convert_sql_date(
-                                $row_dates['exe_date']
-                            );
-                            $mytime = ((int) $time_exe_date - (int) $time_start_date);
-                            $mytime = $this->fixAbusiveTime($mytime);
-                            $total_time = " total_time = ".$mytime.", ";
+                            $exeRow = Database::fetch_array($res);
+                            $duration = $exeRow['exe_duration'];
+                            $total_time = " total_time = ".$duration.", ";
                             if ($debug) {
                                 error_log("quiz: $total_time");
                             }

+ 0 - 1
main/lp/lp_ajax_start_timer.php

@@ -6,5 +6,4 @@
  *
  * @author Yannick Warnier <ywarnier@beeznest.org>
  */
-
 echo time();

+ 3 - 6
main/lp/lp_view.php

@@ -276,16 +276,13 @@ if (!empty($_REQUEST['exeId']) &&
     if ($safe_id == strval(intval($safe_id)) &&
         $safe_item_id == strval(intval($safe_item_id))
     ) {
-        $sql = 'SELECT start_date, exe_date, exe_result, exe_weighting, exe_exo_id
+        $sql = 'SELECT start_date, exe_date, exe_result, exe_weighting, exe_exo_id, exe_duration
                 FROM '.$TBL_TRACK_EXERCICES.'
                 WHERE exe_id = '.$safe_exe_id;
         $res = Database::query($sql);
         $row_dates = Database::fetch_array($res);
 
-        $time_start_date = api_strtotime($row_dates['start_date'], 'UTC');
-        $time_exe_date = api_strtotime($row_dates['exe_date'], 'UTC');
-
-        $mytime = (int) $time_exe_date - (int) $time_start_date;
+        $duration = (int) $row_dates['exe_duration'];
         $score = (float) $row_dates['exe_result'];
         $max_score = (float) $row_dates['exe_weighting'];
 
@@ -326,7 +323,7 @@ if (!empty($_REQUEST['exeId']) &&
             $sql = "UPDATE $TBL_LP_ITEM_VIEW SET
                         status = '$status',
                         score = $score,
-                        total_time = $mytime
+                        total_time = $duration
                     WHERE iid = $lp_item_view_id";
             if ($debug) {
                 error_log($sql);

+ 20 - 8
main/mySpace/myStudents.php

@@ -893,13 +893,13 @@ if (empty($details)) {
                     $progress = Tracking::get_avg_student_progress(
                         $user_info['user_id'],
                         $courseCodeItem,
-                        null,
+                        [],
                         $sId
                     );
                     $score = Tracking:: get_avg_student_score(
                         $user_info['user_id'],
                         $courseCodeItem,
-                        null,
+                        [],
                         $sId
                     );
                     $progress = empty($progress) ? '0%' : $progress.'%';
@@ -1603,12 +1603,24 @@ if (empty($details)) {
     </div>
 <?php
 } //end details
-echo Tracking::displayUserSkills(
-    $user_info['user_id'],
-    $courseInfo ? $courseInfo['real_id'] : 0,
-    $sessionId
-);
 
+$allowAll = api_get_configuration_value('allow_teacher_access_student_skills');
+if ($allowAll) {
+    // Show all skills
+    echo Tracking::displayUserSkills(
+        $user_info['user_id'],
+        0,
+        0,
+        true
+    );
+} else {
+    // Default behaviour - Show all skills depending the course and session id
+    echo Tracking::displayUserSkills(
+        $user_info['user_id'],
+        $courseInfo ? $courseInfo['real_id'] : 0,
+        $sessionId
+    );
+}
 if ($allowMessages === true) {
     // Messages
     echo Display::page_subheader2(get_lang('Messages'));
@@ -1658,7 +1670,7 @@ if ($allowMessages === true) {
     $form = new FormValidator(
         'messages',
         'post',
-        api_get_self().'?action=send_message&student='.$student_id
+        $currentUrl.'&action=send_message'
     );
     $form->addHtml('<div id="compose_message" style="display:none;">');
     $form->addText('subject', get_lang('Subject'));

+ 1 - 0
main/survey/surveyUtil.class.php

@@ -2832,6 +2832,7 @@ class SurveyUtil
      * @throws \Doctrine\ORM\ORMException
      * @throws \Doctrine\ORM\OptimisticLockException
      * @throws \Doctrine\ORM\TransactionRequiredException
+     *
      * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
      *
      * @return string html code that are the actions that can be performed on any survey

+ 4 - 1
plugin/resubscription/src/HookResubscription.php

@@ -100,7 +100,10 @@ class HookResubscription extends HookObserver implements HookResubscribeObserver
                     $endDate = $userSessionCourses[$currentSessionCourse['c_id']];
                     $resubscriptionDate = gmdate($limitDateFormat, strtotime($endDate." +$resubscriptionOffset"));
                     $icon = Display::return_icon('students.gif', get_lang('Student'));
-                    $canResubscribeFrom = sprintf(get_plugin_lang('CanResubscribeFromX', 'resubscription'), $resubscriptionDate);
+                    $canResubscribeFrom = sprintf(
+                        get_plugin_lang('CanResubscribeFromX', 'resubscription'),
+                        $resubscriptionDate
+                    );
                     throw new Exception(Display::label($icon.' '.$canResubscribeFrom, "info"));
                 }
             }

+ 1 - 1
plugin/test2pdf/lang/spanish.php

@@ -6,7 +6,7 @@ $strings['enable_plugin'] = "Activar plugin";
 $strings['ViewExercises'] = "Ver ejercicios";
 $strings['NoExercise'] = "Sin ejercicios creados en el curso";
 $strings['Exercise'] = "Ejercicio";
-$strings['DownloadOnlyQuestion'] = "Descargar cuestiones";
+$strings['DownloadOnlyQuestion'] = "Descargar preguntas";
 $strings['DownloadOnlyAnswer'] = "Descargar respuestas";
 $strings['DownloadAll'] = "Descargar todo";
 $strings['PluginDisabledFromAdminPanel'] = "La herramienta está deshabilitada desde la administración";

+ 14 - 18
plugin/test2pdf/src/test2pdf.lib.php

@@ -5,7 +5,6 @@
  *
  * @package chamilo.plugin.test2pdf
  */
-
 $letters = [
     'a',
     'b',
@@ -38,18 +37,19 @@ $letters = [
 /**
  * List exercises.
  *
- * @param int $courseId Course ID
+ * @param int $courseId  Course ID
  * @param int $sessionId Session ID
  *
  * @throws Exception
  *
  * @return array Results (list of exercise details)
  */
-
 function showExerciseCourse($courseId, $sessionId = 0)
 {
     $tableQuiz = Database::get_course_table(TABLE_QUIZ_TEST);
     $tableLpItem = Database::get_course_table(TABLE_LP_ITEM);
+    $courseId = (int) $courseId;
+    $sessionId = (int) $sessionId;
     $conditionSession = api_get_session_condition($sessionId, true, true, 'a.session_id');
     $sql = "SELECT a.* 
             FROM $tableQuiz a 
@@ -59,9 +59,6 @@ function showExerciseCourse($courseId, $sessionId = 0)
             $conditionSession
             ORDER BY a.title ASC;";
     $res = Database::query($sql);
-    if (!$res) {
-        die("Error Database $tableQuiz");
-    }
     $aux = [];
     while ($row = Database::fetch_assoc($res)) {
         $aux[] = $row;
@@ -79,12 +76,11 @@ function showExerciseCourse($courseId, $sessionId = 0)
  */
 function getInfoQuiz($courseId, $id)
 {
+    $courseId = (int) $courseId;
+    $id = (int) $id;
     $tableQuiz = Database::get_course_table(TABLE_QUIZ_TEST);
     $sql = "SELECT * FROM $tableQuiz WHERE c_id = $courseId AND iid = $id";
     $res = Database::query($sql);
-    if (!$res) {
-        die("Error Database $tableQuiz");
-    }
     $row = Database::fetch_assoc($res);
 
     return $row;
@@ -99,6 +95,10 @@ function getInfoQuiz($courseId, $id)
  */
 function getQuestions($courseId, $quizId, $sessionId = 0)
 {
+    $courseId = (int) $courseId;
+    $quizId = (int) $quizId;
+    $sessionId = (int) $sessionId;
+
     $tableQuizQuestion = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
     $tableQuestion = Database::get_course_table(TABLE_QUIZ_QUESTION);
     $tableQuiz = Database::get_course_table(TABLE_QUIZ_TEST);
@@ -113,13 +113,11 @@ function getQuestions($courseId, $quizId, $sessionId = 0)
             $conditionSession 
             ORDER BY question_order ASC;";
     $res = Database::query($sql);
-    if (!$res) {
-        die("Error Database $tableQuizQuestion");
-    }
     $aux = [];
     while ($row = Database::fetch_assoc($res)) {
         $aux[] = $row['question_id'];
     }
+
     return $aux;
 }
 
@@ -132,15 +130,14 @@ function getQuestions($courseId, $quizId, $sessionId = 0)
  */
 function getInfoQuestion($courseId, $id)
 {
+    $courseId = (int) $courseId;
+    $id = (int) $id;
     $tableQuestion = Database::get_course_table(TABLE_QUIZ_QUESTION);
     $sql = "SELECT * FROM $tableQuestion 
             WHERE c_id = $courseId 
             AND iid = $id
             AND (type IN (1, 2, 9, 10, 11, 12, 14))";
     $res = Database::query($sql);
-    if (!$res) {
-        die("Error Database $tableQuestion");
-    }
     $row = Database::fetch_assoc($res);
 
     return $row;
@@ -155,14 +152,13 @@ function getInfoQuestion($courseId, $id)
  */
 function getAnswers($courseId, $id)
 {
+    $courseId = (int) $courseId;
+    $id = (int) $id;
     $tableQuizAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER);
     $sql = "SELECT * FROM $tableQuizAnswer
     	    WHERE c_id = $courseId AND question_id = $id
     	    ORDER BY position ASC;";
     $res = Database::query($sql);
-    if (!$res) {
-        die("Error Database $tableQuizAnswer");
-    }
     $aux = [];
     while ($row = Database::fetch_assoc($res)) {
         $aux[] = $row;

+ 1 - 1
plugin/test2pdf/src/test2pdf_plugin.class.php

@@ -55,7 +55,7 @@ class Test2pdfPlugin extends Plugin
      */
     public function uninstall()
     {
-        //Deleting course settings
+        // Deleting course settings.
         $this->uninstall_course_fields_in_all_courses($this->course_settings);
         $this->manageTab(false);
     }

+ 0 - 3
plugin/test2pdf/src/view-pdf.php

@@ -5,9 +5,6 @@
  *
  * @package chamilo.plugin.test2pdf
  */
-/**
- * Initialization.
- */
 require_once '../config.php';
 api_protect_course_script(true);
 

+ 1 - 1
tests/scripts/fix_lp_id_to_iid.php

@@ -30,7 +30,7 @@ foreach ($courses as $course) {
         }
     }
     $courseId = $course['id'];
-    $sql = "SELECT * FROM $tblCLp WHERE c_id = $courseId";
+    $sql = "SELECT * FROM $tblCLp WHERE c_id = $courseId AND iid <> id";
     echo 'Select all lps';
     var_dump($sql);
     $result = Database::query($sql);

+ 1 - 1
tests/scripts/fix_restored_learnpaths.php

@@ -1,7 +1,7 @@
 <?php
 /* For licensing terms, see /license.txt */
 
-//exit;
+exit;
 
 use Chamilo\CourseBundle\Entity\CLp;
 use Doctrine\ORM\Query\Expr\Join;

Some files were not shown because too many files changed in this diff