Przeglądaj źródła

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

jmontoyaa 7 lat temu
rodzic
commit
aa18681848

+ 13 - 1
app/Resources/public/css/scorm.css

@@ -302,6 +302,8 @@ See https://support.chamilo.org/issues/6976
     height: 100%;
     margin: 0;
     overflow: hidden;
+    position: absolute;
+    width: 100%;
 }
 #learning_path_left_zone,
 #learning_path_right_zone {
@@ -313,9 +315,13 @@ See https://support.chamilo.org/issues/6976
     position: absolute;
     right: 0;
     top: 0;
-    transition-property: left width;
+    transition-property: left, width;
     transition-duration: 0.5s;
 }
+#learning_path_right_zone #wrapper-iframe {
+    height: 100%;
+    width: 100%;
+}
 #learning_path_left_zone .lp-view-zone-container,
 #learning_path_right_zone .lp-view-zone-container {
     bottom: 0;
@@ -339,6 +345,9 @@ See https://support.chamilo.org/issues/6976
     left: 100%;
     width: 100%;
 }
+#learning_path_right_zone.no-right-col {
+    left: 0;
+}
 #learning_path_right_zone .lp-view-tabs .tab-content {
     bottom: 5px;
     left: 5px;
@@ -435,6 +444,9 @@ See https://support.chamilo.org/issues/6976
         left: 250px;
         width: calc(100% - 250px);
     }
+    #learning_path_right_zone.no-right-col {
+        width: 100%;
+    }
     #learning_path_main.lp-view-include-breadcrumb #learning_path_left_zone,
     #learning_path_main.lp-view-include-breadcrumb #learning_path_right_zone {
         top: 0;

+ 5 - 8
app/Resources/public/css/themes/kiddy/default.css

@@ -91,14 +91,7 @@ background: linear-gradient(to bottom, #fc8a00 0%,#ff6e00 100%);
 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fc8a00', endColorstr='#ff6e00',GradientType=0 );
 }
 .navbar-default .navbar-nav > li > .dropdown-menu {
-  background: #01a1ff;
-background: -moz-linear-gradient(top, #01a1ff 0%, #0266ef 100%);
-background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#01a1ff), color-stop(100%,#0266ef));
-background: -webkit-linear-gradient(top, #01a1ff 0%,#0266ef 100%);
-background: -o-linear-gradient(top, #01a1ff 0%,#0266ef 100%);
-background: -ms-linear-gradient(top, #01a1ff 0%,#0266ef 100%);
-background: linear-gradient(to bottom, #01a1ff 0%,#0266ef 100%);
-filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#01a1ff', endColorstr='#0266ef',GradientType=0 );
+  background: #FFFFFF;
 }
 .navbar-default .navbar-nav > li > .dropdown-menu > li > a {
   color: #ffffff;
@@ -236,19 +229,23 @@ footer.bgfooter a:hover{
     background-image: url(images/user.png);
     background-position: 10px center;
     background-repeat: no-repeat;
+    padding-left: 40px;
 }
 #skill_block .panel-heading{
     background-image: url(images/star.png);
     background-position: 10px center;
     background-repeat: no-repeat;
+    padding-left: 40px;
 }
 #course_block .panel-heading{
     background-image: url(images/book.png);
     background-position: 10px center;
     background-repeat: no-repeat;
+    padding-left: 40px;
 }
 #help_block .panel-heading{
     background-image: url(images/rocket.png);
     background-position: 10px center;
     background-repeat: no-repeat;
+    padding-left: 40px;
 }

+ 1 - 0
documentation/credits.html

@@ -112,6 +112,7 @@ Note: this list of credits is relatively discontinued. We now prefer the list of
     <li>Dokeos (2004-2009)
     <ul>
       <li>Thomas De Praetere (thomas.depraetere@dokeos.com) - Creator of Claroline (2000) and later Dokeos (2004)</li>
+      <li>Yannick Warnier (ywarnier@beeznest.org) - Developer (2004-2005) and Technical lead (2006-2009)</li>
       <li>Arnaud Ligot (arnaud@cblue.be) - also independently, through CBlue (2010-2011)</li>
       <li>Noel Dieschburg (noel@cblue.be)</li>
       <li>Frédéric Burlet (fburlet@cblue.be)</li>

+ 3 - 2
main/document/download_scorm.php

@@ -58,7 +58,8 @@ if (Security::check_abs_path($sys_course_path.$doc_url, $sys_course_path.'/')) {
     $fixLinks = api_get_configuration_value('lp_replace_http_to_https');
     $result = DocumentManager::file_send_for_download($full_file_name, false, '', $fixLinks);
     if ($result === false) {
-        api_not_allowed(true);
+        api_not_allowed(true, get_lang('FileNotFound'), 404);
     }
+} else {
+    api_not_allowed(true, get_lang('FileNotFound'), 404);
 }
-exit;

+ 18 - 16
main/exercise/TestCategory.php

@@ -615,34 +615,36 @@ class TestCategory
 
     /**
      * @param int $questionId
-     * @param int $displayCategoryName
      */
-    public static function displayCategoryAndTitle($questionId, $displayCategoryName = 1)
+    public static function displayCategoryAndTitle($questionId)
     {
-        echo self::returnCategoryAndTitle($questionId, $displayCategoryName);
+        echo self::returnCategoryAndTitle($questionId);
     }
 
     /**
      * @param int $questionId
-     * @param int $in_display_category_name
      * @return null|string
      */
-    public static function returnCategoryAndTitle($questionId, $in_display_category_name = 1)
+    public static function returnCategoryAndTitle($questionId)
     {
-        $is_student = !(api_is_allowed_to_edit(null, true) || api_is_session_admin());
+        $isStudent = !(api_is_allowed_to_edit(null, true) || api_is_session_admin());
         $objExercise = Session::read('objExercise');
-        if (!empty($objExercise)) {
-            $in_display_category_name = $objExercise->display_category_name;
+        if (empty($objExercise)) {
+            return '';
         }
-        $content = null;
-        if (self::getCategoryNameForQuestion($questionId) != '' &&
-            ($in_display_category_name == 1 || !$is_student)
-        ) {
-            $content .= '<div class="page-header">';
-            $content .= '<h4>'.get_lang('Category').": ".self::getCategoryNameForQuestion($questionId).'</h4>';
-            $content .= "</div>";
+
+        $showCategoryName = !!$objExercise->display_category_name; //double negation to get a boolean value
+        $categoryName = self::getCategoryNameForQuestion($questionId);
+
+        if (empty($categoryName) || (!$showCategoryName && $isStudent)) {
+            return '';
         }
-        return $content;
+
+        return Display::page_header(
+            get_lang('Category').': '.$categoryName,
+            null,
+            'h4'
+        );
     }
 
     /**

+ 10 - 3
main/exercise/exercise_show.php

@@ -891,7 +891,11 @@ foreach ($questionList as $questionId) {
     }
 
     if (in_array($objQuestionTmp->type, [FREE_ANSWER, ORAL_EXPRESSION, ANNOTATION])) {
-        $check = $objQuestionTmp->isQuestionWaitingReview($score);
+        $scoreToReview = [
+            'score' => $my_total_score,
+            'comments' => isset($comnt) ? $comnt : null
+        ];
+        $check = $objQuestionTmp->isQuestionWaitingReview($scoreToReview);
         if ($check === false) {
             $countPendingQuestions++;
         }
@@ -902,7 +906,6 @@ foreach ($questionList as $questionId) {
 
     $contents = ob_get_clean();
     $question_content = '<div class="question_row">';
-
     if ($show_results) {
         $objQuestionTmp->export = $action == 'export';
         // Shows question title an description
@@ -953,7 +956,11 @@ if (!empty($category_list) && ($show_results || $show_only_total_score || $showT
 
 echo $total_score_text;
 echo $exercise_content;
-echo $total_score_text;
+
+// only show "score" in bottom of page if there's exercise content
+if ($show_results) {
+    echo $total_score_text;
+}
 
 if ($action == 'export') {
     $content = ob_get_clean();

+ 4 - 2
main/inc/lib/api.lib.php

@@ -3357,10 +3357,12 @@ function api_is_anonymous($user_id = null, $db_check = false)
  * Displays message "You are not allowed here..." and exits the entire script.
  * @param bool   $print_headers    Whether or not to print headers (default = false -> does not print them)
  * @param string $message
+ * @param int $responseCode
  */
 function api_not_allowed(
     $print_headers = false,
-    $message = null
+    $message = null,
+    $responseCode = 0
 ) {
     if (api_get_setting('sso_authentication') === 'true') {
         global $osso;
@@ -3406,7 +3408,7 @@ function api_not_allowed(
         $show_headers = 1;
     }
 
-    $tpl = new Template(null, $show_headers, $show_headers, false, true, false);
+    $tpl = new Template(null, $show_headers, $show_headers, false, true, false, true, $responseCode);
     $tpl->assign('hide_login_link', 1);
     $tpl->assign('content', $msg);
 

+ 0 - 2
main/inc/lib/document.lib.php

@@ -298,7 +298,6 @@ class DocumentManager
         $len = filesize($full_file_name);
         // Fixing error when file name contains a ","
         $filename = str_replace(',', '', $filename);
-
         $sendFileHeaders = api_get_configuration_value('enable_x_sendfile_headers');
 
         if ($forced) {
@@ -334,7 +333,6 @@ class DocumentManager
             return true;
         } else {
             //no forced download, just let the browser decide what to do according to the mimetype
-
             $content_type = self::file_get_mime_type($filename);
             $lpFixedEncoding = api_get_configuration_value('lp_fixed_encoding');
 

+ 5 - 2
main/inc/lib/exercise.lib.php

@@ -4160,7 +4160,6 @@ EOT;
                 $comnt = null;
                 if ($show_results) {
                     $comnt = Event::get_comments($exeId, $questionId);
-
                     $teacherAudio = ExerciseLib::getOralFeedbackAudio(
                         $exeId,
                         $questionId,
@@ -4197,7 +4196,11 @@ EOT;
                 }
 
                 if (in_array($objQuestionTmp->type, [FREE_ANSWER, ORAL_EXPRESSION, ANNOTATION])) {
-                    $check = $objQuestionTmp->isQuestionWaitingReview($score);
+                    $reviewScore = [
+                        'score' => $my_total_score,
+                        'comments' => Event::get_comments($exeId, $questionId)
+                    ];
+                    $check = $objQuestionTmp->isQuestionWaitingReview($reviewScore);
                     if ($check === false) {
                         $countPendingQuestions++;
                     }

+ 2 - 1
main/inc/lib/online.inc.php

@@ -119,11 +119,12 @@ function online_logout($user_id = null, $logout_redirect = false)
     		ORDER BY login_date DESC
     		LIMIT 0,1";
     $q_last_connection = Database::query($sql);
+    $i_id_last_connection = 0;
     if (Database::num_rows($q_last_connection) > 0) {
         $i_id_last_connection = Database::result($q_last_connection, 0, "login_id");
     }
 
-    if (!isset($_SESSION['login_as'])) {
+    if (!isset($_SESSION['login_as']) && !empty($i_id_last_connection)) {
         $current_date = api_get_utc_datetime();
         $sql = "UPDATE $tbl_track_login SET logout_date='".$current_date."'
         		WHERE login_id='$i_id_last_connection'";

+ 30 - 2
main/inc/lib/template.lib.php

@@ -46,6 +46,7 @@ class Template
     public $load_plugins = false;
     public $params = [];
     public $force_plugin_load = false;
+    public $responseCode = 0;
 
     /**
      * @param string $title
@@ -54,6 +55,7 @@ class Template
      * @param bool $show_learnpath
      * @param bool $hide_global_chat
      * @param bool $load_plugins
+     * @param int $responseCode
      * @param bool $sendHeaders send http headers or not
      */
     public function __construct(
@@ -63,12 +65,13 @@ class Template
         $show_learnpath = false,
         $hide_global_chat = false,
         $load_plugins = true,
-        $sendHeaders = true
+        $sendHeaders = true,
+        $responseCode = 0
     ) {
         // Page title
         $this->title = $title;
-
         $this->show_learnpath = $show_learnpath;
+        $this->setResponseCode($responseCode);
 
         if (empty($this->show_learnpath)) {
             $origin = api_get_origin();
@@ -1114,6 +1117,15 @@ class Template
                 'X-Powered-By: '.$_configuration['software_name'].' '.substr($_configuration['system_version'], 0, 1)
             );
             self::addHTTPSecurityHeaders();
+
+            $responseCode = $this->getResponseCode();
+            if (!empty($responseCode)) {
+                switch ($responseCode) {
+                    case '404':
+                        header("HTTP/1.0 404 Not Found");
+                        break;
+                }
+            }
         }
 
         $socialMeta = '';
@@ -1695,4 +1707,20 @@ class Template
 
         return implode(CourseManager::USER_SEPARATOR, $names);
     }
+
+    /**
+     * @param int $code
+     */
+    public function setResponseCode($code)
+    {
+        $this->responseCode = $code;
+    }
+
+    /**
+     * @param string $code
+     */
+    public function getResponseCode()
+    {
+        return $this->responseCode;
+    }
 }

+ 4 - 6
main/inc/lib/tracking.lib.php

@@ -7263,8 +7263,6 @@ class TrackingCourseLog
             $courseId = $courseInfo['real_id'];
 
             $user['official_code'] = $user['col0'];
-            $user['lastname'] = $user['col1'];
-            $user['firstname'] = $user['col2'];
             $user['username'] = $user['col3'];
 
             $user['time'] = api_time_to_hms(
@@ -7355,11 +7353,11 @@ class TrackingCourseLog
             $user_row = [];
             $user_row['official_code'] = $user['official_code']; //0
             if ($is_western_name_order) {
-                $user_row['firstname'] = $user['firstname'];
-                $user_row['lastname'] = $user['lastname'];
+                $user_row['firstname'] = $user['col2'];
+                $user_row['lastname'] = $user['col1'];
             } else {
-                $user_row['lastname'] = $user['lastname'];
-                $user_row['firstname'] = $user['firstname'];
+                $user_row['lastname'] = $user['col2'];
+                $user_row['firstname'] = $user['col1'];
             }
             $user_row['username'] = $user['username'];
             $user_row['time'] = $user['time'];

+ 1 - 1
main/inc/local.inc.php

@@ -365,7 +365,7 @@ if (!empty($_SESSION['_user']['user_id']) && !($login || $logout)) {
                         'update_type'
                     );
 
-                    $update_type = $update_type['update_type'];
+                    $update_type = isset($update_type['update_type']) ? $update_type['update_type'] : '';
                     if (!empty($extAuthSource[$update_type]['updateUser'])
                         && file_exists($extAuthSource[$update_type]['updateUser'])
                     ) {

+ 20 - 15
main/lp/lp_edit.php

@@ -72,8 +72,7 @@ $hide_toc_frame = $form->addElement(
     'checkbox',
     'hide_toc_frame',
     null,
-    get_lang('HideTocFrame'),
-    ['onclick' => '$("#lp_layout_column").toggle()']
+    get_lang('HideTocFrame')
 );
 if (api_get_setting('allow_course_theme') === 'true') {
     $mycourselptheme = api_get_course_setting('allow_learning_path_theme');
@@ -130,10 +129,12 @@ if (api_get_setting('search_enabled') === 'true') {
     }
 }
 
+$hideTableOfContents = $_SESSION['oLP']->getHideTableOfContents();
+
 $defaults['lp_encoding'] = Security::remove_XSS($_SESSION['oLP']->encoding);
 $defaults['lp_name'] = Security::remove_XSS($_SESSION['oLP']->get_name());
 $defaults['lp_author'] = Security::remove_XSS($_SESSION['oLP']->get_author());
-$defaults['hide_toc_frame'] = $_SESSION['oLP']->getHideTableOfContents();
+$defaults['hide_toc_frame'] = $hideTableOfContents;
 $defaults['category_id'] = intval($_SESSION['oLP']->getCategoryId());
 $defaults['accumulate_scorm_time'] = $_SESSION['oLP']->getAccumulateScormTime();
 
@@ -240,17 +241,21 @@ Display::display_header(get_lang('CourseSettings'), 'Path');
 
 echo $_SESSION['oLP']->build_action_menu(false, false, true, false);
 echo '<div class="row">';
-if ($_SESSION['oLP']->getHideTableOfContents() == 1) {
-    echo '<div class="col-md-12">';
-    $form->display();
-    echo '</div>';
-} else {
-    echo '<div class="col-md-8">';
-    $form->display();
-    echo '</div>';
-    echo '<div class="col-md-4" align="center">';
-    echo Display::return_icon('course_setting_layout.png');
-    echo '</div>';
-}
+echo '<div class="'.($hideTableOfContents ? 'col-md-12' : 'col-md-8').'" id="pnl-frm">';
+$form->display();
+echo '</div>';
+echo '<div class="'.($hideTableOfContents ? 'hide' : 'col-md-4').' text-right" id="pnl-toc">';
+echo Display::return_icon('course_setting_layout.png');
+echo '</div>';
 echo '</div>';
+echo "
+    <script>
+        $(document).on('ready', function () {
+            $('[name=\'hide_toc_frame\']').on('change', function() {
+                $('#pnl-frm').toggleClass('col-md-8').toggleClass('col-sm-12');
+                $('#pnl-toc').toggleClass('col-md-4').toggleClass('hide');
+            });
+        });
+    </script>
+";
 Display::display_footer();

+ 2 - 7
main/template/default/learnpath/view.tpl

@@ -94,12 +94,7 @@
     </div>
 
     {# right zone #}
-    {% if show_left_column == 1 %}
-        <div id="learning_path_right_zone" class="content-scorm">
-    {% else %}
-        <div id="" class="content-scorm">
-    {% endif %}
-
+    <div id="learning_path_right_zone" class="{{ show_left_column == 1 ? 'content-scorm' : 'no-right-col' }}">
         <div class="lp-view-zone-container">
             <div class="lp-view-tabs">
                 <div id="navTabsbar" class="nav-tabs-bar">
@@ -120,7 +115,7 @@
                 </div>
                 <div class="tab-content">
                     <div role="tabpanel" class="tab-pane active" id="lp-view-content">
-                        <div id="wrapper-iframe" style="width:100%; height:100%">
+                        <div id="wrapper-iframe">
                         {% if lp_mode == 'fullscreen' %}
                             <iframe id="content_id_blank" name="content_name_blank" src="blank.php" style="width:100%; height:100%" border="0" frameborder="0" allowfullscreen="true" webkitallowfullscreen="true" mozallowfullscreen="true"></iframe>
                         {% else %}

+ 39 - 41
plugin/bbb/lib/bbb.lib.php

@@ -352,7 +352,6 @@ class bbb
             // This setting currently limits the maximum conference duration,
             // to avoid lingering sessions on the video-conference server #6261
             $duration = 300;
-
             $bbbParams = array(
                 'meetingId' => $params['remote_id'], // REQUIRED
                 'meetingName' => $meetingName, // REQUIRED
@@ -392,8 +391,9 @@ class bbb
                 }
             }
 
-            return $this->logoutUrl;
+            return false;
         }
+        return false;
     }
 
     /**
@@ -482,8 +482,12 @@ class bbb
      * @assert ('') === false
      * @assert ('abcdefghijklmnopqrstuvwxyzabcdefghijklmno') === false
      */
-    public function joinMeeting($meetingName, $loop = false)
+    public function joinMeeting($meetingName)
     {
+        if ($this->debug) {
+            error_log("joinMeeting: $meetingName");
+        }
+
         if (empty($meetingName)) {
             return false;
         }
@@ -524,51 +528,47 @@ class bbb
             //  -- REQUIRED - The moderator password for the meeting
         );
 
-        $status = false;
         $meetingInfoExists = false;
-        while ($status === false) {
-            $meetingIsRunningInfo = $this->getMeetingInfo($params);
-            if ($meetingIsRunningInfo === false) {
-                //checking with the remote_id didn't work, so just in case and
-                // to provide backwards support, check with the id
-                $params = array(
-                    'meetingId' => $meetingData['id'],
-                    //  -- REQUIRED - The unique id for the meeting
-                    'password' => $this->getModMeetingPassword()
-                    //  -- REQUIRED - The moderator password for the meeting
-                );
-                $meetingIsRunningInfo = $this->getMeetingInfo($params);
-            }
+        $meetingIsRunningInfo = $this->getMeetingInfo($params);
+        if ($this->debug) {
+            error_log('Searching meeting with params:');
+            error_log(print_r($params, 1));
+            error_log('Result:');
+            error_log(print_r($meetingIsRunningInfo, 1));
+        }
 
+        if ($meetingIsRunningInfo === false) {
+            // checking with the remote_id didn't work, so just in case and
+            // to provide backwards support, check with the id
+            $params = array(
+                'meetingId' => $meetingData['id'],
+                //  -- REQUIRED - The unique id for the meeting
+                'password' => $this->getModMeetingPassword()
+                //  -- REQUIRED - The moderator password for the meeting
+            );
+            $meetingIsRunningInfo = $this->getMeetingInfo($params);
             if ($this->debug) {
+                error_log('Searching meetingId with params:');
+                error_log(print_r($params, 1));
+                error_log('Result:');
                 error_log(print_r($meetingIsRunningInfo, 1));
             }
+        }
 
-            if (strval($meetingIsRunningInfo['returncode']) == 'SUCCESS' &&
-                isset($meetingIsRunningInfo['meetingName']) &&
-                !empty($meetingIsRunningInfo['meetingName'])
-                //strval($meetingIsRunningInfo['running']) == 'true'
-            ) {
-                $meetingInfoExists = true;
-            }
-
-            if ($this->debug) {
-                error_log(
-                    "meeting is running: ".intval($meetingInfoExists)
-                );
-            }
-
-            if ($meetingInfoExists) {
-                $status = true;
-            }
+        if (strval($meetingIsRunningInfo['returncode']) == 'SUCCESS' &&
+            isset($meetingIsRunningInfo['meetingName']) &&
+            !empty($meetingIsRunningInfo['meetingName'])
+        ) {
+            $meetingInfoExists = true;
+        }
 
-            if ($loop) {
-                continue;
-            } else {
-                break;
-            }
+        if ($this->debug) {
+            error_log(
+                "meeting is running: ".intval($meetingInfoExists)
+            );
         }
 
+        $url = false;
         if ($meetingInfoExists) {
             $joinParams = array(
                 'meetingId' => $meetingData['remote_id'], //	-- REQUIRED - A unique id for the meeting
@@ -580,8 +580,6 @@ class bbb
             );
             $url = $this->api->getJoinMeetingURL($joinParams);
             $url = $this->protocol.$url;
-        } else {
-            $url = $this->logoutUrl;
         }
         if ($this->debug) {
             error_log("return url :".$url);

+ 7 - 3
plugin/bbb/start.php

@@ -56,15 +56,19 @@ if ($bbb->pluginEnabled) {
 
             $meetingParams = [];
             $meetingParams['meeting_name'] = $bbb->getCurrentVideoConferenceName();
-
             if ($bbb->meetingExists($meetingParams['meeting_name'])) {
-                $url = $bbb->joinMeeting($meetingParams['meeting_name']) ?: $bbb->createMeeting($meetingParams);
+                $joinUrl = $bbb->joinMeeting($meetingParams['meeting_name']);
+                if ($joinUrl) {
+                    $url = $joinUrl;
+                } else {
+                    $url = $bbb->createMeeting($meetingParams);
+                }
             } else {
                 $url = $bbb->isConferenceManager() ? $bbb->createMeeting($meetingParams) : $bbb->getListingUrl();
             }
 
             $meetingInfo = $bbb->findMeetingByName($meetingParams['meeting_name']);
-            if (!empty($meetingInfo)) {
+            if (!empty($meetingInfo) && $url) {
                 $bbb->saveParticipant($meetingInfo['id'], api_get_user_id());
                 $bbb->redirectToBBB($url);
             } else {