Browse Source

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

Angel Fernando Quiroz Campos 7 years ago
parent
commit
6346f56ce4

+ 48 - 0
documentation/security.html

@@ -85,6 +85,54 @@ This will prevent direct access to your settings and make it seem totally the sa
     <p>Don't hesitate to hire an experienced administrator to do that,
         it might be a bit more expensive now, but you'll be happy not to have to loose
         all of your data to a hacker who attacked your site.</p>
+    <p>Only the following directories have required (or optional) write 
+        permissions from the web server:<br />
+        <ul>
+          <li>app/cache/</li>
+          <li>app/courses/</li>
+          <li>app/home/</li>
+          <li>app/logs/</li>
+          <li>app/upload/</li>
+          <li>main/default_course_document/images/</li>
+          <li>main/lang/ (optional, only for sublanguages)</li>
+          <li>web/css/ (optional, only for switching CSS through the web)</li>
+        </ul>
+        <br />
+        Because these directories have "write by the web server" permissions,
+        it is important to prevent the execution of PHP scripts from those
+        directories (because a specially-crafted attack could end up allowing
+        the upload of a PHP script to one of these). To do that, taking into
+        account we authorize overrides through .htaccess, we need to set
+        something that a .htaccess file cannot revert, and we need to set it
+        for each of those directories. This can be done as follows inside
+        your VirtualHost definition in Apache (you'll have to translate it for
+        Nginx configueations), where "/var/www/URL/" is the path of your VirtualHost web root:<br />
+        <pre>
+  <Directory /var/www/URL/app/cache>
+    php_admin_value engine Off
+  </Directory>
+  <Directory /var/www/URL/app/courses>
+    php_admin_value engine Off
+  </Directory>
+  <Directory /var/www/URL/app/home>
+    php_admin_value engine Off
+  </Directory>
+  <Directory /var/www/URL/app/logs>
+    php_admin_value engine Off
+  </Directory>
+  <Directory /var/www/URL/app/upload>
+    php_admin_value engine Off
+  </Directory>
+  <Directory /var/www/URL/main/default_course_document/images>
+    php_admin_value engine Off
+  </Directory>
+  <Directory /var/www/URL/main/lang>
+    php_admin_value engine Off
+  </Directory>
+  <Directory /var/www/URL/web/css>
+    php_admin_value engine Off
+  </Directory>
+        </pre>
 
 
 <hr />

+ 30 - 10
main/admin/career_diagram.php

@@ -55,7 +55,7 @@ $interbreadcrumb[] = array(
     'name' => get_lang('Careers'),
 );
 
-$action = isset($_GET['action']) ? $_GET['action'] : null;
+$action = isset($_GET['action']) ? $_GET['action'] : '';
 $check = Security::check_token('request');
 $token = Security::get_token();
 
@@ -79,19 +79,39 @@ $item = $extraFieldValue->get_values_by_handler_and_field_variable(
     false
 );
 
+// Check urls
+$itemUrls = $extraFieldValue->get_values_by_handler_and_field_variable(
+    $careerId,
+    'career_urls',
+    false,
+    false,
+    false
+);
+
+$urlToString = '';
+if (!empty($itemUrls) && !empty($itemUrls['value'])) {
+    $urls = explode(',', $itemUrls['value']);
+    $urlToString = '&nbsp;&nbsp;';
+    if (!empty($urls)) {
+        foreach ($urls as $urlData) {
+            $urlData = explode('@', $urlData);
+            $urlToString .= Display::url($urlData[0], $urlData[1]).'&nbsp;';
+        }
+    }
+}
+
+$tpl = new Template(get_lang('Diagram'));
 if (!empty($item) && isset($item['value']) && !empty($item['value'])) {
+    $html = Display::page_subheader2($careerInfo['name'].$urlToString);
     $graph = unserialize($item['value']);
-    $tpl = new Template(get_lang('Diagram'));
-    $html = Display::page_subheader2($careerInfo['name']);
     $html .= Career::renderDiagram($careerInfo, $graph);
     $tpl->assign('content', $html);
-    $tpl->display_one_col_template();
 } else {
-    api_not_allowed(
-        true,
+    Display::addFlash(
         Display::return_message(
-            sprintf(get_lang('CareerXDoesntHaveADiagram'), $careerInfo['name']),
-            'warning'
-        )
-    );
+        sprintf(get_lang('CareerXDoesntHaveADiagram'), $careerInfo['name']),
+        'warning'
+    ));
 }
+
+$tpl->display_one_col_template();

+ 1 - 1
main/admin/careers.php

@@ -151,7 +151,7 @@ switch ($action) {
         break;
     case 'edit':
         // Action handling: Editing
-        $url  = api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&id='.intval($_GET['id']);
+        $url = api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&id='.intval($_GET['id']);
         $form = $career->return_form($url, 'edit');
 
         // The validation or display

+ 38 - 1
main/cron/import_csv.php

@@ -42,6 +42,7 @@ class ImportCsv
         'user' => 'external_user_id',
         'calendar_event' => 'external_calendar_event_id',
         'career' => 'external_career_id',
+        'career_urls' => 'career_urls',
         'career_diagram' => 'career_diagram',
     );
     public $defaultAdminId = 1;
@@ -337,6 +338,15 @@ class ImportCsv
                 'display_text' => 'Career diagram',
             )
         );
+
+        $extraField->save(
+            array(
+                'visible_to_self' => 1,
+                'field_type' => ExtraField::FIELD_TYPE_TEXTAREA,
+                'variable' => $this->extraFieldIdNameList['career_urls'],
+                'display_text' => 'Career urls',
+            )
+        );
     }
 
     /**
@@ -2347,6 +2357,20 @@ class ImportCsv
                             'extra_'.$extraFieldName => $itemId,
                         ];
                         $extraFieldValue->saveFieldValues($params);
+
+                        $links = isset($row['HLinks']) ? $row['HLinks'] : [];
+                        if (!empty($links)) {
+                            $extraFieldUrlName = $this->extraFieldIdNameList['career_urls'];
+                            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
+                                $extraFieldUrlName
+                            );
+
+                            $params = [
+                                'item_id' => $careerId,
+                                'extra_'.$extraFieldUrlName => $itemId,
+                            ];
+                            $extraFieldValue->saveFieldValues($params);
+                        }
                     }
                 } else {
                     if (isset($item['item_id'])) {
@@ -2355,6 +2379,20 @@ class ImportCsv
                             'name' => $row['CareerName']
                         ];
                         $career->update($params);
+                        $links = isset($row['HLinks']) ? $row['HLinks'] : [];
+
+                        if (!empty($links)) {
+                            $extraFieldUrlName = $this->extraFieldIdNameList['career_urls'];
+                            $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable(
+                                $extraFieldUrlName
+                            );
+
+                            $params = [
+                                'item_id' => $item['item_id'],
+                                'extra_'.$extraFieldUrlName => $links
+                            ];
+                            $extraFieldValue->saveFieldValues($params);
+                        }
                     }
                 }
             }
@@ -2510,7 +2548,6 @@ class ImportCsv
                         $parentList = explode(',', $row['DependedOn']);
                         foreach ($parentList as $parentId) {
                             $parentId = (int) $parentId;
-                            echo $parentId.PHP_EOL;
                             if ($graph->hasVertex($parentId)) {
                                 /** @var Vertex $parent */
                                 $parent = $graph->getVertex($parentId);

+ 14 - 2
main/inc/ajax/model.ajax.php

@@ -523,9 +523,21 @@ switch ($action) {
         break;
     case 'get_exercise_results_report':
         $exerciseId = $_REQUEST['exercise_id'];
-        $courseId = $_REQUEST['course_id'];
+        $courseId = isset($_REQUEST['course_id']) ? $_REQUEST['course_id'] : 0;
+        if (!empty($courseId)) {
+            $courseInfo = api_get_course_info_by_id($courseId);
+        } else {
+            $courseCode = isset($_REQUEST['cidReq']) ? $_REQUEST['cidReq'] : '';
+            if (!empty($courseCode)) {
+                $courseInfo = api_get_course_info($courseCode);
+            }
+        }
+
+        if (empty($courseInfo)) {
+            exit;
+        }
+
         $startDate = Database::escape_string($_REQUEST['start_date']);
-        $courseInfo = api_get_course_info_by_id($courseId);
         $whereCondition .= " AND exe_date > '$startDate' ";
         $count = ExerciseLib::get_count_exam_results(
             $exerciseId,

+ 7 - 5
main/inc/lib/MoodleImport.php

@@ -24,12 +24,14 @@ class MoodleImport
 
         if (is_file($file) && is_readable($file)) {
             $package = new PclZip($file);
-            $packageContent = $package->listContent();
             $mainFileKey = 0;
-            foreach ($packageContent as $index => $value) {
-                if ($value['filename'] == 'moodle_backup.xml') {
-                    $mainFileKey = $index;
-                    break;
+            $packageContent = $package->listContent();
+            if (!empty($packageContent)) {
+                foreach ($packageContent as $index => $value) {
+                    if ($value['filename'] == 'moodle_backup.xml') {
+                        $mainFileKey = $index;
+                        break;
+                    }
                 }
             }
 

+ 58 - 51
main/inc/lib/TicketManager.php

@@ -275,7 +275,7 @@ class TicketManager
      * @param string $subject
      * @param string $content
      * @param string $personalEmail
-     * @param $file_attachments
+     * @param array $fileAttachments
      * @param string $source
      * @param string $priority
      * @param string $status
@@ -292,7 +292,7 @@ class TicketManager
         $subject,
         $content,
         $personalEmail = '',
-        $file_attachments = [],
+        $fileAttachments = [],
         $source = '',
         $priority = '',
         $status = '',
@@ -397,9 +397,9 @@ class TicketManager
                 ));
             }
 
-            if (!empty($file_attachments)) {
+            if (!empty($fileAttachments)) {
                 $attachmentCount = 0;
-                foreach ($file_attachments as $attach) {
+                foreach ($fileAttachments as $attach) {
                     if (!empty($attach['tmp_name'])) {
                         $attachmentCount++;
                     }
@@ -409,7 +409,7 @@ class TicketManager
                         $ticketId,
                         '',
                         '',
-                        $file_attachments,
+                        $fileAttachments,
                         $currentUserId
                     );
                 }
@@ -613,7 +613,7 @@ class TicketManager
      * @param int $ticketId
      * @param string $subject
      * @param string $content
-     * @param array $file_attachments
+     * @param array $fileAttachments
      * @param int $userId
      * @param string $status
      * @param bool $sendConfirmation
@@ -624,7 +624,7 @@ class TicketManager
         $ticketId,
         $subject,
         $content,
-        $file_attachments,
+        $fileAttachments,
         $userId,
         $status = 'NOL',
         $sendConfirmation = false
@@ -670,10 +670,10 @@ class TicketManager
                     WHERE id = $ticketId ";
             Database::query($sql);
 
-            if (is_array($file_attachments)) {
-                foreach ($file_attachments as $file_attach) {
+            if (is_array($fileAttachments)) {
+                foreach ($fileAttachments as $file_attach) {
                     if ($file_attach['error'] == 0) {
-                        self::save_message_attachment_file(
+                        self::saveMessageAttachmentFile(
                             $file_attach,
                             $ticketId,
                             $messageId
@@ -697,7 +697,7 @@ class TicketManager
      * @param $message_id
      * @return array
      */
-    public static function save_message_attachment_file(
+    public static function saveMessageAttachmentFile(
         $file_attach,
         $ticketId,
         $message_id
@@ -717,45 +717,35 @@ class TicketManager
                 'error'
             );
         } else {
-            $new_file_name = uniqid('');
-            $path_attachment = api_get_path(SYS_ARCHIVE_PATH);
-            $path_message_attach = $path_attachment.'plugin_ticket_messageattch/';
-            if (!file_exists($path_message_attach)) {
-                @mkdir($path_message_attach, api_get_permissions_for_new_directories(), true);
-            }
-            $new_path = $path_message_attach.$new_file_name;
-            if (is_uploaded_file($file_attach['tmp_name'])) {
-                @copy($file_attach['tmp_name'], $new_path);
-            }
-            $safe_file_name = Database::escape_string($file_name);
-            $safe_new_file_name = Database::escape_string($new_file_name);
-            $sql = "INSERT INTO $table_support_message_attachments (
-                    filename,
-                    path,
-                    ticket_id,
-                    message_id,
-                    size,
-                    sys_insert_user_id,
-                    sys_insert_datetime,
-                    sys_lastedit_user_id,
-                    sys_lastedit_datetime
-                ) VALUES (
-                    '$safe_file_name',
-                    '$safe_new_file_name',
-                    '$ticketId',
-                    '$message_id',
-                    '".$file_attach['size']."',
-                    '$userId',
-                    '$now',
-                    '$userId',
-                    '$now'
-                )";
-            Database::query($sql);
+            $result = api_upload_file('ticket_attachment', $file_attach, $ticketId);
+            if ($result) {
+                $safe_file_name = Database::escape_string($new_file_name);
+                $safe_new_file_name = Database::escape_string($result['path_to_save']);
+                $sql = "INSERT INTO $table_support_message_attachments (
+                        filename,
+                        path,
+                        ticket_id,
+                        message_id,
+                        size,
+                        sys_insert_user_id,
+                        sys_insert_datetime,
+                        sys_lastedit_user_id,
+                        sys_lastedit_datetime
+                    ) VALUES (
+                        '$safe_file_name',
+                        '$safe_new_file_name',
+                        '$ticketId',
+                        '$message_id',
+                        '".$file_attach['size']."',
+                        '$userId',
+                        '$now',
+                        '$userId',
+                        '$now'
+                    )";
+                Database::query($sql);
 
-            return array(
-                'path' => $path_message_attach.$safe_new_file_name,
-                'filename' => $safe_file_name,
-            );
+                return true;
+            }
         }
     }
 
@@ -1088,6 +1078,23 @@ class TicketManager
         return (int)$obj->total;
     }
 
+    /**
+     * @param int $id
+     * @return \Chamilo\TicketBundle\Entity\MessageAttachment
+     */
+    public static function getTicketMessageAttachment($id)
+    {
+        $id = (int) $id;
+        $em = Database::getManager();
+
+        $item = $em->getRepository('ChamiloTicketBundle:MessageAttachment')->find($id);
+        if ($item) {
+            return $item;
+        }
+
+        return false;
+    }
+
     /**
      * @param int $ticketId
      * @return array
@@ -1181,8 +1188,8 @@ class TicketManager
 
                 $result_attach = Database::query($sql);
                 while ($row2 = Database::fetch_assoc($result_attach)) {
-                    $archiveURL = $archiveURL = $webPath.'ticket/download.php?ticket_id='.$ticketId.'&file=';
-                    $row2['attachment_link'] = $attach_icon.'&nbsp;<a href="'.$archiveURL.$row2['path'].'&title='.$row2['filename'].'">'.$row2['filename'].'</a>&nbsp;('.$row2['size'].')';
+                    $archiveURL = $webPath.'ticket/download.php?ticket_id='.$ticketId.'&id='.$row2['id'];
+                    $row2['attachment_link'] = $attach_icon.'&nbsp;<a href="'.$archiveURL.'">'.$row2['filename'].'</a>&nbsp;('.$row2['size'].')';
                     $message['attachments'][] = $row2;
                 }
                 $ticket['messages'][] = $message;

+ 40 - 0
main/inc/lib/api.lib.php

@@ -8451,6 +8451,46 @@ function api_upload_file($type, $file, $itemId, $cropParameters = '')
     }
 }
 
+/**
+ * @param string $type
+ * @param int $itemId
+ * @param string $file
+ *
+ * @return bool
+ */
+function api_get_uploaded_file($type, $itemId, $file)
+{
+    $itemId = (int) $itemId;
+    $pathId = '/'.substr((string) $itemId, 0, 1).'/'.$itemId.'/';
+    $path = api_get_path(SYS_UPLOAD_PATH).$type.$pathId;
+
+    $file = basename($file);
+
+    $file = $path.'/'.$file;
+    if (file_exists($file)) {
+        return $file;
+    }
+    return false;
+}
+
+/**
+ * @param string $type
+ * @param int $itemId
+ * @param string $file
+ * @param string $title
+ */
+function api_download_uploaded_file($type, $itemId, $file, $title = '')
+{
+    $file = api_get_uploaded_file($type, $itemId, $file);
+    if ($file) {
+        if (Security::check_abs_path($file, api_get_path(SYS_UPLOAD_PATH).$type)) {
+            DocumentManager::file_send_for_download($file, true, $title);
+            exit;
+        }
+    }
+    api_not_allowed(true);
+}
+
 /**
  * @param string $type
  * @param string $file

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

@@ -151,6 +151,7 @@ class Career extends Model
         if (!empty($defaults['updated_at'])) {
             $defaults['updated_at'] = api_convert_and_format_date($defaults['updated_at']);
         }
+
         $form->setDefaults($defaults);
 
         // Setting the rules
@@ -308,7 +309,6 @@ class Career extends Model
         /** @var Vertex $vertex */
         foreach ($graph->getVertices() as $vertex) {
             $group = $vertex->getAttribute('Group');
-
             $groupData = explode(':', $group);
             $group = $groupData[0];
             $groupLabel = isset($groupData[1]) ? $groupData[1] : '';

+ 4 - 0
main/inc/lib/exercise.lib.php

@@ -1917,6 +1917,10 @@ HOTSPOT;
                     tth.exe_date DESC";
         }
 
+        if (empty($sql)) {
+            return false;
+        }
+
         if ($get_count) {
             $resx = Database::query($sql);
             $rowx = Database::fetch_row($resx, 'ASSOC');

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

@@ -379,7 +379,7 @@ class MessageManager
                 $i = 0;
                 foreach ($file_attachments as $file_attach) {
                     if ($file_attach['error'] == 0) {
-                        self::save_message_attachment_file(
+                        self::saveMessageAttachmentFile(
                             $file_attach,
                             isset($file_comments[$i]) ? $file_comments[$i] : null,
                             $inbox_last_id,
@@ -413,7 +413,7 @@ class MessageManager
                     foreach ($file_attachments as $file_attach) {
                         if ($file_attach['error'] == 0) {
                             $comment = isset($file_comments[$o]) ? $file_comments[$o] : '';
-                            self::save_message_attachment_file(
+                            self::saveMessageAttachmentFile(
                                 $file_attach,
                                 $comment,
                                 $outbox_last_id,
@@ -676,7 +676,7 @@ class MessageManager
      * @param  int        sender user id (optional)
      * @param  int        group id (optional)
      */
-    public static function save_message_attachment_file(
+    public static function saveMessageAttachmentFile(
         $file_attach,
         $file_comment,
         $message_id,

+ 3 - 4
main/inc/lib/userportal.lib.php

@@ -1165,7 +1165,7 @@ class IndexManager
         $gameModeIsActive = api_get_setting('gamification_mode');
         $listCourse = '';
         $specialCourseList = '';
-        $viewGridCourses = api_get_configuration_value('view_grid_courses') === 'true';
+        $viewGridCourses = api_get_configuration_value('view_grid_courses') === true;
         $showSimpleSessionInfo = api_get_configuration_value('show_simple_session_info');
 
         $coursesWithoutCategoryTemplate = '/user_portal/classic_courses_without_category.tpl';
@@ -1188,7 +1188,6 @@ class IndexManager
         $studentInfo = api_get_configuration_value('course_student_info');
         $viewGrid = api_get_configuration_value('view_grid_courses');
 
-
         $studentInfoProgress = !empty($studentInfo['progress']) && $studentInfo['progress'] === true;
         $studentInfoScore = !empty($studentInfo['score']) && $studentInfo['score'] === true;
         $studentInfoCertificate = !empty($studentInfo['certificate']) && $studentInfo['certificate'] === true;
@@ -1294,7 +1293,7 @@ class IndexManager
                                     $courses['in_category'][$key1]['student_info']['certificate'] = null;
                                     $isCertificateAvailable = $category[0]->is_certificate_available($user_id);
                                     if (isset($category[0])) {
-                                        if ($viewGrid == 'true') {
+                                        if ($viewGrid) {
                                             if ($isCertificateAvailable) {
                                                 $courses['in_category'][$key1]['student_info']['certificate'] = get_lang('Yes');
                                             } else {
@@ -1352,7 +1351,7 @@ class IndexManager
 
                             if (isset($category[0])) {
                                 $certificateAvailable = $category[0]->is_certificate_available($user_id);
-                                if ($viewGrid == 'true') {
+                                if ($viewGrid) {
                                     if ($certificateAvailable) {
                                         $courses['not_category'][$key]['student_info']['certificate'] = get_lang('Yes');
                                     } else {

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

@@ -1173,7 +1173,7 @@ if ((isset($uidReset) && $uidReset) || (isset($cidReset) && $cidReset)) {
                 ) {
                     $redirect = false;
                 }
-                if ($redirect) {
+                if ($redirect && !api_is_platform_admin()) {
                     $url = api_get_path(WEB_CODE_PATH).'auth/inscription.php';
                     header("Location:".$url);
                     exit;

+ 1 - 1
main/install/configuration.dist.php

@@ -583,7 +583,7 @@ $_configuration['score_grade_model'] = [
 // 3 = Session link will make course list foldable
 //$_configuration['courses_list_session_title_link'] = 1;
 // New grid view the list of courses
-//$_configuration['view_grid_courses'] = 'true';
+//$_configuration['view_grid_courses'] = true;
 // Show courses grouped by categories when $_configuration['view_grid_courses'] is enabled
 //$_configuration['view_grid_courses_grouped_categories_in_sessions'] = true;
 // Load course notifications in user_portal.php using ajax

+ 5 - 2
main/lp/learnpath.class.php

@@ -5872,7 +5872,8 @@ class learnpath
                     $url,
                     array(
                         'class' => 'ajax moved',
-                        'data-title' => $title_cut
+                        'data-title' => $title,
+                        'title' => $title
                     )
                 );
             }
@@ -6043,7 +6044,8 @@ class learnpath
                             array(
                                 'target' => '_blank',
                                 'class' => 'btn btn-default',
-                                'data-title' => $arrLP[$i]['title']
+                                'data-title' => $arrLP[$i]['title'],
+                                'title' => $arrLP[$i]['title']
                             )
                         );
                         break;
@@ -6073,6 +6075,7 @@ class learnpath
                             [
                                 'class' => $class,
                                 'data-title' => $arrLP[$i]['title'],
+                                'title' => $arrLP[$i]['title'],
                                 'target' => $target
                             ]
                         );

+ 23 - 22
main/mySpace/exercise_category_report.php

@@ -25,7 +25,6 @@ $defaults = [];
 $defaults['start_date'] = isset($_GET['start_date']) ? Security::remove_XSS($_GET['start_date']) : '';
 $defaults['course_id'] = $courseId;
 
-
 $htmlHeadXtra[] = api_get_jqgrid_js();
 $htmlHeadXtra[] = '<script>
 $(document).ready( function() {
@@ -40,8 +39,6 @@ $(document).ready( function() {
 });
 </script>';
 
-Display::display_header($nameTools);
-
 $form = new FormValidator('exercise', 'get');
 $form->addDatePicker('start_date', get_lang('StartDate'));
 if (empty($courseId)) {
@@ -55,36 +52,41 @@ if (empty($courseId)) {
     );
 } else {
     $courseInfo = api_get_course_info_by_id($courseId);
-    $form->addHidden('course_id', $courseId);
-    $form->addLabel(get_lang('Course'), $courseInfo['name']);
-    $exerciseList = ExerciseLib::get_all_exercises_for_course_id(
-        $courseInfo,
-        0,
-        $courseId,
-        true
-    );
-
-    if (!empty($exerciseList)) {
-        $options = [];
-        foreach ($exerciseList as $exercise) {
-            $options[$exercise['id']] = $exercise['title'];
+    if (!empty($courseInfo)) {
+        $form->addHidden('course_id', $courseId);
+        $form->addLabel(get_lang('Course'), $courseInfo['name']);
+        $exerciseList = ExerciseLib::get_all_exercises_for_course_id(
+            $courseInfo,
+            0,
+            $courseId,
+            true
+        );
+
+        if (!empty($exerciseList)) {
+            $options = [];
+            foreach ($exerciseList as $exercise) {
+                $options[$exercise['id']] = $exercise['title'];
+            }
+            $form->addSelect('exercise_id', get_lang('Exercises'), $options);
+        } else {
+            $form->addLabel(get_lang('Exercises'), Display::return_message(get_lang('NoExercises')));
         }
-        $form->addSelect('exercise_id', get_lang('Exercises'), $options);
     } else {
-        $form->addLabel(get_lang('Exercises'), Display::return_message(get_lang('NoExercises')));
+        Display::addFlash(Display::return_message(get_lang('CourseDoesNotExist'), 'warning'));
     }
 }
 
 $form->setDefaults($defaults);
 $form->addButtonSearch(get_lang('Search'));
 
+Display::display_header($nameTools);
 $form->display();
 
-if ($form->validate()) {
+if ($form->validate() && !empty($courseInfo)) {
     $values = $form->getSubmitValues();
-    $exerciseId = $values['exercise_id'];
+    $exerciseId = isset($values['exercise_id']) ? $values['exercise_id'] : 0;
     $startDate = Security::remove_XSS($values['start_date']);
-    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_exercise_results_report&exercise_id='.$exerciseId.'&course_id='.$courseId.'&start_date='.$startDate;
+    $url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_exercise_results_report&exercise_id='.$exerciseId.'&start_date='.$startDate.'&cidReq='.$courseInfo['code'];
 
     $categoryList = TestCategory::getListOfCategoriesIDForTest($exerciseId, $courseId);
     $columns = array(
@@ -205,7 +207,6 @@ if ($form->validate()) {
     ];
 
     echo Display::actions($items);
-
     echo Display::grid_html('results');
 }
 

+ 21 - 19
main/ticket/download.php

@@ -9,17 +9,27 @@ require_once __DIR__.'/../inc/global.inc.php';
 
 api_block_anonymous_users();
 $user_id = api_get_user_id();
-if (!isset($_GET['file']) || !isset($_GET['title']) || !isset($_GET['ticket_id'])) {
-    api_not_allowed();
+
+if (!isset($_GET['id']) || !isset($_GET['ticket_id'])) {
+    api_not_allowed(true);
+}
+
+$ticket_id = intval($_GET['ticket_id']);
+$ticketInfo = TicketManager::get_ticket_detail_by_id($ticket_id);
+if (empty($ticketInfo)) {
+    api_not_allowed(true);
+}
+$messageAttachment = TicketManager::getTicketMessageAttachment($_GET['id']);
+if (empty($messageAttachment)) {
+    api_not_allowed(true);
 }
 
 if (!api_is_platform_admin()) {
-    $ticket_id = intval($_GET['ticket_id']);
     $table_support_messages = Database::get_main_table(TABLE_TICKET_MESSAGE);
     $table_support_tickets = Database::get_main_table(TABLE_TICKET_TICKET);
     $table_support_message_attachments = Database::get_main_table(TABLE_TICKET_MESSAGE_ATTACHMENTS);
     $sql = "SELECT DISTINCT  ticket.request_user
-          FROM  $table_support_tickets ticket,
+            FROM $table_support_tickets ticket,
                 $table_support_messages message,
                 $table_support_message_attachments attch
             WHERE ticket.ticket_id = message.ticket_id
@@ -29,22 +39,14 @@ if (!api_is_platform_admin()) {
     $row_users = Database::fetch_array($rs, 'ASSOC');
     $user_request_id = $row_users['request_user'];
     if (intval($user_request_id) != $user_id) {
-        api_not_allowed();
+        api_not_allowed(true);
     }
 }
 
-// @todo replace by Security::check_abs_path()?
-$file_url = $_GET['file'];
-$file_url = str_replace('///', '&', $file_url);
-$file_url = str_replace(' ', '+', $file_url);
-$file_url = str_replace('/..', '', $file_url);
-$file_url = Database::escape_string($file_url);
-$title = $_GET['title'];
-$path_attachment = api_get_path(SYS_ARCHIVE_PATH);
-$path_message_attach = $path_attachment.'plugin_ticket_messageattch/';
-$full_file_name = $path_message_attach.$file_url;
-if (Security::check_abs_path($full_file_name, $path_message_attach)) {
-    DocumentManager::file_send_for_download($full_file_name, true, $title);
-}
-
+api_download_uploaded_file(
+    'ticket_attachment',
+    $ticket_id,
+    $messageAttachment->getPath(),
+    $messageAttachment->getFilename()
+);
 exit;

+ 97 - 0
src/Chamilo/TicketBundle/Entity/MessageAttachment.php

@@ -90,4 +90,101 @@ class MessageAttachment
      */
     protected $lastEditDateTime;
 
+    /**
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * @param int $id
+     * @return MessageAttachment
+     */
+    public function setId($id)
+    {
+        $this->id = $id;
+
+        return $this;
+    }
+
+    /**
+     * @return Message
+     */
+    public function getMessage()
+    {
+        return $this->message;
+    }
+
+    /**
+     * @param Message $message
+     * @return MessageAttachment
+     */
+    public function setMessage($message)
+    {
+        $this->message = $message;
+
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getPath()
+    {
+        return $this->path;
+    }
+
+    /**
+     * @param string $path
+     * @return MessageAttachment
+     */
+    public function setPath($path)
+    {
+        $this->path = $path;
+
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getFilename()
+    {
+        return $this->filename;
+    }
+
+    /**
+     * @param string $filename
+     * @return MessageAttachment
+     */
+    public function setFilename($filename)
+    {
+        $this->filename = $filename;
+
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function getSize()
+    {
+        return $this->size;
+    }
+
+    /**
+     * @param int $size
+     * @return MessageAttachment
+     */
+    public function setSize($size)
+    {
+        $this->size = $size;
+
+        return $this;
+    }
+
+
+
 }