Yannick Warnier 10 years ago
parent
commit
8f796e7eec

+ 30 - 3
main/css/base.css

@@ -44,7 +44,32 @@ header #logo img{
     margin-left: 30px;
 }
 
+/* button load ajax form */
 
+.button-load{
+  background: url("../img/icons/64/file_upload.png") no-repeat center 20px;
+  padding-top: 70px;
+  /*-webkit-animation:glide 2250ms infinite;
+  animation:glide 2250ms infinite;*/
+}
+/*@-webkit-keyframes glide {
+  from {
+    background-position: center 0;
+  } to {
+      background-position: center 20px;
+
+    }
+
+}
+
+@keyframes glide {
+  from {
+    background-position:center 0;
+  } to {
+      background-position:center 20px;
+
+    }
+}*/
 /* START COURSE PROGRESS */
 .thematic-postit{
   padding-top: 5px;
@@ -3898,14 +3923,16 @@ a.forum_group_link {
 .forum_description {
     color: #000;
     font-weight: normal;
-    font-size: 11px;
+    font-size: 15px;
+    padding-top: 1em;
+    padding-bottom: .5em;
 }
 .forum_description p{
     font-size: 11px;
 }
-.forum_title {
+.forum_title h1{
     color: #000;
-    font-size: 14px;
+    padding-top: 1em;
 }
 .forum_low_description {
     color: #737780;

+ 21 - 12
main/forum/editpost.php

@@ -57,7 +57,6 @@ $htmlHeadXtra[] = '<script>
         if(document.getElementById(\'id_qualify\').style.display == \'none\') {
             document.getElementById(\'id_qualify\').style.display = \'block\';
             document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.Display::return_icon('div_hide.gif', get_lang('Hide'), array('style' => 'vertical-align:middle')).'&nbsp;'.get_lang('AdvancedParameters').'\';
-
         } else {
             document.getElementById(\'id_qualify\').style.display = \'none\';
             document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.Display::return_icon('div_show.gif', get_lang('Show'), array('style' => 'vertical-align:middle')).'&nbsp;'.get_lang('AdvancedParameters').'\';
@@ -130,7 +129,6 @@ if ($origin == 'learnpath') {
 } else {
     Display :: display_header(null);
 }
-
 /* Is the user allowed here? */
 
 // The user is not allowed here if
@@ -185,17 +183,22 @@ if ($origin != 'learnpath') {
 
 /* Display Forum Category and the Forum information */
 
-echo "<table class=\"forum_table\" width=\"100%\">";
-// The forum category
-echo "<tr><th class=\"forum_head\" colspan=\"2\">";
-echo '<a href="viewforum.php?&amp;origin='.$origin.'&amp;forum='.$current_forum['forum_id'].'" '.class_visible_invisible($current_forum['visibility']).'>'.prepare4display($current_forum['forum_title']).'</a><br />';
-echo '<span class="forum_description">'.prepare4display($current_forum['forum_comment']).'</span>';
-echo "</th>";
-echo "</tr>";
-echo '</table>';
-
+/*New display forum div*/
+    echo '<div class="row">';
+    echo '<div class="span12">';
+    echo '<div class="forum_title">';
+    echo '<h1><a href="viewforum.php?&amp;origin='.$origin.'&amp;forum='.$current_forum['forum_id'].'" '.class_visible_invisible($current_forum['visibility']).'>'.prepare4display($current_forum['forum_title']).'</a></h1>';
+    echo '<p class="forum_description">'.prepare4display($current_forum['forum_comment']).'</p>';
+    echo '</div></div></div>';
+/* End new display forum */
+
+// Set forum attachment data into $_SESSION
+getAttachedFiles($current_forum['forum_id'], $current_thread['thread_id'], $current_post['post_id']);
 // The form for the reply
+echo '<div class="row">';
+echo '<div class="span12">';
 $values = show_edit_post_form($forum_setting, $current_post, $current_thread, $current_forum, isset($_SESSION['formelements']) ? $_SESSION['formelements'] : '');
+echo '</div></div>';
 
 if (!empty($values) and isset($_POST['SubmitPost'])) {
     store_edit_post($values);
@@ -216,9 +219,15 @@ if (!empty($values) and isset($_POST['SubmitPost'])) {
             Database::query('UPDATE '.$table_link.' SET weight='.$weight_calification.' WHERE id='.$link_id.'');
         }
     }
+} else {
+    // Only show Forum attachment ajax form when do not pass form submit
+    echo '<div class="row"><div class="span12">';
+    $attachmentAjaxForm = getAttachmentAjaxForm($current_forum['forum_id'], $current_thread['thread_id'], $current_post['post_id']);
+    echo $attachmentAjaxForm;
+    echo '</div></div>';
 }
 
 // Footer
 if ($origin != 'learnpath') {
     Display :: display_footer();
-}
+}

+ 457 - 69
main/forum/forumfunction.inc.php

@@ -26,8 +26,11 @@ use \ChamiloSession as Session;
 require_once api_get_path(LIBRARY_PATH).'mail.lib.inc.php';
 require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/gradebook_functions.inc.php';
 
+define('FORUM_NEW_POST', 0);
+
 get_notifications_of_user();
 
+$htmlHeadXtra[] = api_get_jquery_libraries_js(array('jquery-ui', 'jquery-upload'));
 $htmlHeadXtra[] = '<script type="text/javascript">
 function setFocus(){
     $("#forum_title").focus();
@@ -38,6 +41,84 @@ $(document).ready(function () {
     setFocus();
 });
 </script>';
+$htmlHeadXtra[] = '<script>
+
+function check_unzip() {
+    if(document.upload.unzip.checked){
+        document.upload.if_exists[0].disabled=true;
+        document.upload.if_exists[1].checked=true;
+        document.upload.if_exists[2].disabled=true;
+    } else {
+        document.upload.if_exists[0].checked=true;
+        document.upload.if_exists[0].disabled=false;
+        document.upload.if_exists[2].disabled=false;
+    }
+}
+function setFocus() {
+    $("#title_file").focus();
+}
+</script>';
+// The next javascript script is to manage ajax upload file
+$htmlHeadXtra[] = "
+<script>
+$(function () {
+    setFocus();
+    $('#file_upload').fileUploadUI({
+        uploadTable:   $('.files'),
+        downloadTable: $('.files'),
+        buildUploadRow: function (files, index) {
+            $('.files').closest('.control-group').show();
+            return $('<tr><td>' + files[index].name + '<\/td>' +
+                    '<td class=\"file_upload_progress\"><div><\/div><\/td>' +
+                    '<td class=\"file_upload_cancel\">' +
+                    '<button class=\"ui-state-default ui-corner-all\" title=\"".get_lang('Cancel')."\">' + '<span class=\"ui-icon ui-icon-cancel\">".get_lang('Cancel')."<\/span>' +'<\/button>'+
+                    '<\/td><\/tr>');
+        },
+        buildDownloadRow: function (file) {
+            if (!file.error) {
+                return $('<tr id=' + file.id + ' ><td>' + file.name + '<\/td><td>' + file.size + '<\/td><td>&nbsp;' + file.result +
+                    ' <\/td><td> <input style=\"width:90%;\" type=\"text\" value=\"' + file.comment + '\" name=\"file_comments[]\"> <\/td><td>' +
+                    file.delete + '<\/td>' +
+                    '<input type=\"hidden\" value=\"' + file.id +'\" name=\"file_ids[]\">' + '<\/tr>');
+            } else {
+                alert('" . get_lang('ErrorUploadAttachment') . "');
+            }
+        }
+    });
+    enableDeleteFile();
+});
+</script>";
+// Recover Thread ID, will be used to generate delete attachment URL to do ajax
+$threadId = isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : 0;
+// The next javascript script is to delete file by ajax
+$htmlHeadXtra[] =
+    '<script>
+        function enableDeleteFile() {
+            $(document).on("click", ".deleteLink", function(e) {
+                e.preventDefault();
+                e.stopPropagation();
+                var l = $(this);
+                var id = l.closest("tr").attr("id");
+                var filename = l.closest("tr").find(".attachFilename").html();
+                if (confirm("' . get_lang('AreYouSureToDeleteFileX') . '".replace("%s", filename))) {
+                    $.ajax({
+                        type: "POST",
+                        url: "' . api_get_path(WEB_AJAX_PATH) . 'forum.ajax.php?a=delete_file&attachId=" + id +"&thread=" + ' .
+                            $threadId . ',
+                        dataType: "json",
+                        success: function(data) {
+                                if (data.error == false) {
+                                    l.closest("tr").remove();
+                                    if ($(".files td").length < 1) {
+                                        $(".files").closest(".control-group").hide();
+                                    }
+                                }
+                            }
+                    })
+                }
+            });
+        }
+    </script>';
 
 /**
  * This function handles all the forum and forumcategories actions. This is a wrapper for the
@@ -2183,6 +2264,13 @@ function store_thread($current_forum, $values)
         Database::query($sql);
         $last_post_id = Database::insert_id();
 
+        // Update attached files
+        if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
+            foreach ($_POST['file_ids'] as $key => $id) {
+                editAttachedFile(array('comment' => $_POST['file_comments'][$key], 'post_id' => $last_post_id), $id);
+            }
+        }
+
         // Now we have to update the thread table to fill the thread_last_post field (so that we know when the thread has been updated for the last time).
         $sql = "UPDATE $table_threads SET thread_last_post='".Database::escape_string($last_post_id)."'
                 WHERE c_id = $course_id AND thread_id='".Database::escape_string($last_thread_id)."'";
@@ -2250,6 +2338,7 @@ function store_thread($current_forum, $values)
 function show_add_post_form($current_forum, $forum_setting, $action = '', $id = '', $form_values = '')
 {
     $_user = api_get_user_info();
+    $courseId = api_get_course_int_id();
     $gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : null;
     $action = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : null;
 
@@ -2299,6 +2388,14 @@ function show_add_post_form($current_forum, $forum_setting, $action = '', $id =
     );
 
     $form->addRule('post_text', get_lang('ThisFieldIsRequired'), 'required');
+    $iframe = null;
+    $myThread = Security::remove_XSS($myThread);
+    if ($forum_setting['show_thread_iframe_on_reply'] && $action != 'newthread' && !empty($myThread)) {
+        $iframe = "<iframe style=\"border: 1px solid black\" src=\"iframe_thread.php?forum=".Security::remove_XSS($my_forum)."&amp;thread=".$myThread."#".Security::remove_XSS($my_post)."\" width=\"100%\"></iframe>";
+    }
+    if (!empty($iframe)) {
+        $form->addElement('label', get_lang('Thread'), $iframe);
+    }
     $form->addElement('advanced_settings', '<a href="javascript://" onclick="return advanced_parameters()">
                               <span id="img_plus_and_minus">&nbsp;'.Display::return_icon('div_show.gif', get_lang('Show'), array('style' => 'vertical-align:middle')).' '.get_lang('AdvancedParameters').'</span></a>');
 
@@ -2341,15 +2438,9 @@ function show_add_post_form($current_forum, $forum_setting, $action = '', $id =
         $values = $form->exportValues();
     }
 
-    // User upload
-    $form->addElement('static', null, null, get_lang('AddAnAttachment'));
-    $form->addElement('file', 'user_upload', get_lang('FileName'), '');
-    $form->addElement('textarea', 'file_comment', get_lang('FileComment'), array('rows' => 4, 'cols' => 34));
-    $form->applyFilter('file_comment', 'html_filter');
     $form->addElement('html', '</div>');
 
     $form->addElement('style_submit_button', 'SubmitPost', $text, 'class="'.$class.'"');
-    $form->add_real_progress_bar('DocumentUpload', 'user_upload');
 
     if (!empty($form_values)) {
         $defaults['post_title'] = prepare4display($form_values['post_title']);
@@ -2401,15 +2492,13 @@ function show_add_post_form($current_forum, $forum_setting, $action = '', $id =
         $form->addElement('hidden', 'sec_token');
         $form->setConstants(array('sec_token' => $token));
 
-        $iframe = null;
-        $myThread = Security::remove_XSS($myThread);
-        if ($forum_setting['show_thread_iframe_on_reply'] && $action != 'newthread' && !empty($myThread)) {
-            $iframe = "<iframe style=\"border: 1px solid black\" src=\"iframe_thread.php?forum=".Security::remove_XSS($my_forum)."&amp;thread=".$myThread."#".Security::remove_XSS($my_post)."\" width=\"100%\"></iframe>";
-        }
-
-        if (!empty($iframe)) {
-            $form->addElement('label', get_lang('Thread'), $iframe);
-        }
+        // Delete from $_SESSION forum attachment from other posts
+        // and keep only attachments for new post
+        clearAttachedFiles(FORUM_NEW_POST);
+        // Get forum attachment ajax table to add it to form
+        $attachmentAjaxTable = getAttachmentsAjaxTable(0, $current_forum['forum_id']);
+        $ajaxHtml = $attachmentAjaxTable;
+        $form->addElement('html', $ajaxHtml);
         $form->display();
     }
 }
@@ -2630,11 +2719,7 @@ function store_reply($current_forum, $values)
     }
 
     $upload_ok = 1;
-    $has_attachment = false;
-    if (!empty($_FILES['user_upload']['name'])) {
-        $upload_ok = process_uploaded_file($_FILES['user_upload']);
-        $has_attachment = true;
-    }
+
     $return = array();
 
     if ($upload_ok) {
@@ -2656,35 +2741,9 @@ function store_reply($current_forum, $values)
         $values['new_post_id'] = $new_post_id;
         $message = get_lang('ReplyAdded');
 
-        if ($has_attachment) {
-            $course_dir = $_course['path'].'/upload/forum';
-            $sys_course_path = api_get_path(SYS_COURSE_PATH);
-            $updir = $sys_course_path.$course_dir;
-
-            // Try to add an extension to the file if it hasn't one.
-            $new_file_name = add_ext_on_mime(stripslashes($_FILES['user_upload']['name']), $_FILES['user_upload']['type']);
-
-            // User's file name
-            $file_name = $_FILES['user_upload']['name'];
-
-            if (!filter_extension($new_file_name)) {
-                $return['msg'] = get_lang('UplUnableToSaveFileFilteredExtension');
-                $return['type'] = 'error';
-            } else {
-                $new_file_name = uniqid('');
-                $new_path = $updir.'/'.$new_file_name;
-                $result = @move_uploaded_file($_FILES['user_upload']['tmp_name'], $new_path);
-                $comment = $values['file_comment'];
-
-                // Storing the attachments if any.
-                if ($result) {
-                    $sql = 'INSERT INTO '.$forum_table_attachment.'(c_id, filename,comment, path, post_id,size) '.
-                        "VALUES (".api_get_course_int_id().", '".Database::escape_string($file_name)."', '".Database::escape_string($comment)."', '".Database::escape_string($new_file_name)."' , '".$new_post_id."', '".intval($_FILES['user_upload']['size'])."' )";
-                    Database::query($sql);
-                    $message .= ' / '.get_lang('FileUploadSucces');
-                    $last_id = Database::insert_id();
-                    api_item_property_update($_course, TOOL_FORUM_ATTACH, $last_id, 'ForumAttachmentAdded', api_get_user_id());
-                }
+        if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
+            foreach ($_POST['file_ids'] as $key => $id) {
+                editAttachedFile(array('comment' => $_POST['file_comments'][$key], 'post_id' => $new_post_id), $id);
             }
         }
 
@@ -2743,7 +2802,7 @@ function show_edit_post_form($forum_setting, $current_post, $current_thread, $cu
     $form = new FormValidator(
         'edit_post',
         'post',
-        api_get_self().'?'.api_get_cidreq().'&forum='.Security::remove_XSS($_GET['forum']).'&amp;gradebook='.$gradebook.'&thread='.Security::remove_XSS($_GET['thread']).'&amp;post='.Security::remove_XSS($_GET['post'])
+        api_get_self().'?'.api_get_cidreq().'&forum='.Security::remove_XSS($_GET['forum']).'&gradebook='.$gradebook.'&thread='.Security::remove_XSS($_GET['thread']).'&post='.Security::remove_XSS($_GET['post'])
     );
     $form->addElement('header', get_lang('EditPost'));
     // Setting the form elements.
@@ -2813,20 +2872,6 @@ function show_edit_post_form($forum_setting, $current_post, $current_thread, $cu
         }
     }
 
-    $attachment_list = get_attachment($current_post['post_id']);
-    $message = get_lang('AddAnAttachment');
-    if (!empty($attachment_list)) {
-        //$message = ;
-        $form->addElement('label', get_lang('EditAnAttachment'), Display::return_icon('attachment.gif', get_lang('Attachment')).'&nbsp;'.$attachment_list['filename'].(!empty($attachment_list['comment']) ? '('.$attachment_list['comment'].')' : ''));
-        $form->addElement('checkbox', 'remove_attach', null, get_lang('DeleteAttachmentFile'));
-    } else {
-        // User upload
-        $form->addElement('label', $message);
-        $form->addElement('file', 'user_upload', get_lang('FileName'), '');
-        $form->addElement('textarea', 'file_comment', get_lang('FileComment'), array('rows' => 4, 'cols' => 34));
-        $form->applyFilter('file_comment', 'html_filter');
-    }
-
     if ($current_forum['allow_attachments'] == '1' || api_is_allowed_to_edit(null, true)) {
         if (empty($form_values) && !isset($_POST['SubmitPost'])) {
             //edit_added_resources('forum_post', $current_post['post_id']);
@@ -2864,6 +2909,11 @@ function show_edit_post_form($forum_setting, $current_post, $current_thread, $cu
         }
         return $values;
     } else {
+        // Delete from $_SESSION forum attachment from other posts
+        clearAttachedFiles($current_post['post_id']);
+        // Get forum attachment ajax table to add it to form
+        $fileData = getAttachmentsAjaxTable($current_post['post_id'], $current_forum['forum_id']);
+        $form->addElement('html', $fileData);
         $form->display();
     }
 }
@@ -2915,6 +2965,13 @@ function store_edit_post($values)
 
     Database::query($sql);
 
+    // Update attached files
+    if (!empty($_POST['file_ids']) && is_array($_POST['file_ids'])) {
+        foreach ($_POST['file_ids'] as $key => $id) {
+            editAttachedFile(array('comment' => $_POST['file_comments'][$key], 'post_id' => $values['post_id']), $id);
+        }
+    }
+
     if (!empty($values['remove_attach'])) {
         delete_attachment($values['post_id']);
     }
@@ -3863,6 +3920,7 @@ function search_link()
  */
 function add_forum_attachment_file($file_comment, $last_id)
 {
+    require_once api_get_path(LIBRARY_PATH) . 'fileUpload.lib.php';
     $_course = api_get_course_info();
     $agenda_forum_attachment = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
 
@@ -3900,9 +3958,13 @@ function add_forum_attachment_file($file_comment, $last_id)
 
                 $last_id_file = Database::insert_id();
                 api_item_property_update($_course, TOOL_FORUM_ATTACH, $last_id_file, 'ForumAttachmentAdded', api_get_user_id());
+
+                return $last_id_file;
             }
         }
     }
+
+    return false;
 }
 
 /**
@@ -3978,15 +4040,38 @@ function get_attachment($post_id)
     return $row;
 }
 
+function getAllAttachment($postId)
+{
+    $forumAttachmentTable = Database :: get_course_table(TABLE_FORUM_ATTACHMENT);
+    $courseId = api_get_course_int_id();
+    $postId = intval($postId);
+    $columns = array('id', 'path', 'filename', 'comment');
+    $conditions = array(
+        'where' => array(
+            'c_id = ? AND post_id = ?' => array($courseId, $postId)
+        )
+    );
+    $array = Database::select(
+        $columns,
+        $forumAttachmentTable,
+        $conditions,
+        'all',
+        'ASSOC'
+    );
+
+    return $array;
+}
+
 /**
  * Delete the all the attachments from the DB and the file according to the post's id or attach id(optional)
  * @param post id
- * @param attach id (optional)
+ * @param int $id_attach
+ * @param bool $display to show or not result message
  * @return void
  * @author Julio Montoya Dokeos
- * @version avril 2008, dokeos 1.8.5
+ * @version october 2014, chamilo 1.9.8
  */
-function delete_attachment($post_id, $id_attach = 0)
+function delete_attachment($post_id, $id_attach = 0, $display = true)
 {
     $_course = api_get_course_info();
 
@@ -4010,15 +4095,21 @@ function delete_attachment($post_id, $id_attach = 0)
     // Delete from forum_attachment table.
     $sql = "DELETE FROM $forum_table_attachment WHERE c_id = $course_id AND $cond ";
     $result = Database::query($sql);
-    $last_id_file = Database::insert_id();
+    if ($result !== false) {
+        $affectedRows = Database::affected_rows($result);
+    } else {
+        $affectedRows = 0;
+    }
 
     // Update item_property.
     api_item_property_update($_course, TOOL_FORUM_ATTACH, $id_attach, 'ForumAttachmentDelete', api_get_user_id());
 
-    if (!empty($result) && !empty($id_attach)) {
+    if (!empty($result) && !empty($id_attach) && $display) {
         $message = get_lang(get_lang('AttachmentFileDeleteSuccess'));
         Display::display_confirmation_message($message);
     }
+
+    return $affectedRows;
 }
 
 /**
@@ -4669,3 +4760,300 @@ function _phorum_recursive_sort($rows, &$threads, $seed = 0, $indent = 0)
         }
     }
 }
+
+/**
+ * Update forum attachment data, used to update comment and post ID.
+ * @param $array Array (field => value) to update forum attachment row.
+ * @param $id Attach ID to find row to update.
+ * @param null $courseId Course ID to find row to update.
+ * @return int Number of affected rows.
+ */
+function editAttachedFile($array, $id, $courseId = null) {
+    // Init variables
+    $setString = '';
+    $id = intval($id);
+    $courseId = intval($courseId);
+    if (empty($courseId)) {
+        // $courseId can be null, use api method
+        $courseId= api_get_course_int_id();
+    }
+    /*
+     * Check if Attachment ID and Course ID are greater than zero
+     * and array of field values is not empty
+     */
+    if ($id > 0 && $courseId > 0 && !empty($array) && is_array($array)) {
+        foreach($array as $key => &$item) {
+            $item = Database::escape_string($item);
+            $setString .= $key . ' = "' .$item . '", ';
+        }
+        // Delete last comma
+        $setString = substr($setString, 0, strlen($setString) - 2);
+        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
+        $sql = "UPDATE $forumAttachmentTable SET $setString WHERE c_id = $courseId AND id = $id";
+        $result = Database::query($sql);
+        if ($result !== false) {
+            $affectedRows = Database::affected_rows($result);
+            if ($affectedRows > 0) {
+                /*
+                 * If exist in $_SESSION variable, then delete them from it
+                 * because they would be deprecated
+                 */
+                if (!empty($_SESSION['forum']['upload_file'][$courseId][$id])) {
+                    unset($_SESSION['forum']['upload_file'][$courseId][$id]);
+                }
+            }
+
+            return $affectedRows;
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * Return a form to upload asynchronously attachments to forum post.
+ * @param $forumId Forum ID from where the post are
+ * @param $threadId Thread ID where forum post are
+ * @param $postId Post ID to identify Post
+ * @return string The Forum Attachment Ajax Form
+ */
+function getAttachmentAjaxForm($forumId, $threadId, $postId)
+{
+    // Init variables
+    $forumId = intval($forumId);
+    $postId = intval($postId);
+    $threadId = !empty($threadId) ? intval($threadId) : isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : '';
+    if ($forumId === 0) {
+        // Forum ID must be defined
+
+        return '';
+    }
+    $url = api_get_path(WEB_AJAX_PATH).'forum.ajax.php?forum=' . $forumId . '&thread=' . $threadId . '&postId=' . $postId . '&a=upload_file';
+    // Form
+    $formFileUpload = '<div class="form-ajax">
+        <form id="file_upload" action="'.$url.'" method="POST" enctype="multipart/form-data">
+            <input type="file" name="user_upload" multiple>
+            <button type="submit">Upload</button><div class="button-load">
+            '.get_lang('UploadFiles').'</div>
+        </form></div>
+        ';
+
+    return $formFileUpload;
+}
+
+/**
+ * Return a table where the attachments will be set
+ * @param null $postId Forum Post ID
+ * @return string The Forum Attachments Ajax Table
+ */
+function getAttachmentsAjaxTable($postId = null)
+{
+    // Init variables
+    $postId = intval($postId);
+    $courseId = api_get_course_int_id();
+    $attachIds = getAttachmentIdsByPostId($postId, $courseId);
+    $fileDataContent = '';
+    // Update comment to show if form did not pass validation
+    if (!empty($_REQUEST['file_ids']) && is_array($_REQUEST['file_ids'])) {
+        // 'file_ids is the name from forum attachment ajax form
+        foreach ($_REQUEST['file_ids'] as $key => $attachId) {
+            if (!empty($_SESSION['forum']['upload_file'][$courseId][$attachId]) && is_array($_SESSION['forum']['upload_file'][$courseId][$attachId])) {
+                // If exist forum attachment then update into $_SESSION data
+                $_SESSION['forum']['upload_file'][$courseId][$attachId]['comment'] = $_POST['file_comments'][$key];
+            }
+        }
+    }
+    // Get data to fill into attachment files table
+    if (!empty($_SESSION['forum']['upload_file'][$courseId]) && is_array($_SESSION['forum']['upload_file'][$courseId])) {
+        $uploadedFiles = $_SESSION['forum']['upload_file'][$courseId];
+        foreach ($uploadedFiles as $k => $uploadedFile) {
+            if (!empty($uploadedFile) && in_array($uploadedFile['id'], $attachIds)) {
+                // Buil html table including an input with attachmentID
+                $fileDataContent .= '<tr id="' . $uploadedFile['id'] . '" ><td>' . $uploadedFile['name'] . '</td><td>' . $uploadedFile['size'] . '</td><td>&nbsp;' . $uploadedFile['result'] .
+                    ' </td><td> <input style="width:90%;" type="text" value="' . $uploadedFile['comment'] . '" name="file_comments[]"> </td><td>' .
+                    $uploadedFile['delete'] . '</td>' .
+                    '<input type="hidden" value="' . $uploadedFile['id'] .'" name="file_ids[]">' . '</tr>';
+            } else {
+                /*
+                 * If attachment data is empty, then delete it from $_SESSION
+                 * because could generate and empty row into html table
+                 */
+                unset($_SESSION['forum']['upload_file'][$courseId][$k]);
+            }
+        }
+    }
+    $style = empty($fileDataContent) ? 'display: none;' : '';
+    // Forum attachment Ajax table
+    $fileData = '
+    <div class="control-group " style="'. $style . '">
+        <label class="control-label">'.get_lang('AttachmentFilesList').'</label>
+        <div class="controls">
+            <table id="attachmentFileList" class="files data_table span10">
+                <tr>
+                    <th>'.get_lang('FileName').'</th>
+                    <th>'.get_lang('Size').'</th>
+                    <th>'.get_lang('Status').'</th>
+                    <th>'.get_lang('Comment').'</th>
+                    <th>'.get_lang('Delete').'</th>
+                </tr>
+                '.$fileDataContent.'
+            </table>
+        </div>
+    </div>';
+
+    return $fileData;
+}
+
+/**
+ * Return an array of prepared attachment data to build forum attachment table
+ * Also, save this array into $_SESSION to do available the attachment data
+ * @param $forumId
+ * @param $threadId
+ * @param null $postId
+ * @param null $attachId
+ * @param null $courseId
+ * @return array
+ */
+function getAttachedFiles($forumId, $threadId, $postId = null, $attachId = null, $courseId = null) {
+    // Init values
+    $forumId = intval($forumId);
+    $courseId = intval($courseId);
+    $attachId = intval($attachId);
+    $postId = intval($postId);
+    $threadId = !empty($threadId) ? intval($threadId) : isset($_REQUEST['thread']) ? intval($_REQUEST['thread']) : '';
+    if (empty($courseId)) {
+        // $courseId can be null, use api method
+        $courseId = api_get_course_int_id();
+    }
+    if (empty($forumId)) {
+        if (!empty($_REQUEST['forum'])) {
+            $forumId = intval($_REQUEST['forum']);
+        } else {
+            // if forum ID is empty, cannot generate delete url
+
+            return array();
+        }
+    }
+    // Check if exist at least one of them to filter forum attachment select query
+    if (empty($postId) && empty($attachId)) {
+
+        return array();
+    } elseif (empty($postId)) {
+        $filter = "AND id = $attachId";
+    } elseif (empty($attachId)) {
+        $filter = "AND post_id = $postId";
+    } else {
+        $filter = "AND post_id = $postId AND id = $attachId";
+    }
+    $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
+    $sql = "SELECT id, comment, filename, path, size FROM $forumAttachmentTable WHERE c_id = $courseId $filter";
+    $result = Database::query($sql);
+    if ($result !== false && Database::num_rows($result) > 0) {
+        while ($row = Database::fetch_array($result, 'ASSOC')) {
+            // name contains an URL to download attachment file and its filename
+            $json['name'] = Display::url(
+                api_htmlentities($row['filename']),
+                api_get_path(WEB_CODE_PATH) . 'forum/download.php?file='.$row['path'],
+                array('target'=>'_blank', 'class' => 'attachFilename')
+            );
+            $json['id'] = $row['id'];
+            $json['comment'] = $row['comment'];
+            // Format file size
+            $json['size'] = format_file_size($row['size']);
+            // Check if $row is consistent
+            if (!empty($row) && is_array($row)) {
+                // Set result as succes and bring delete URL
+                $json['result'] = Display::return_icon('accept.png', get_lang('Uploaded'));
+                $json['delete'] = '<a class="deleteLink" href="'.api_get_path(WEB_CODE_PATH) . 'forum/viewthread.php' .
+                    '?' . api_get_cidreq() . '&amp;origin=' . Security::remove_XSS($_GET['origin']) .
+                    '&amp;action=delete_attach&amp;forum=' . $forumId . '&amp;thread=' . $threadId .
+                    '&amp;id_attach=' . $row['id'] . '">' .
+                    Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
+            } else {
+                // If not, set an exclamation result
+                $json['result'] = Display::return_icon('exclamation.png', get_lang('Error'));
+            }
+            // Store array data into $_SESSION
+            $_SESSION['forum']['upload_file'][$courseId][$json['id']] = $json;
+        }
+    }
+
+    return $json;
+}
+
+/**
+ * Clear forum attachment data stored in $_SESSION,
+ * If is not defined post, it will clear all forum attachment data from course
+ * @param null $postId -1 : Clear all attachments from course stored in $_SESSION
+ *                      0 : Clear attachments from course, except from temporal post "0"
+ *                          but without delete them from file system and database
+ *                     Other values : Clear attachments from course except specified post
+ *                          and delete them from file system and database
+ * @param null $courseId : Course ID, if it is null, will use api_get_course_int_id()
+ * @return array
+ */
+function clearAttachedFiles($postId = null, $courseId = null) {
+    // Init variables
+    $courseId = intval($courseId);
+    $postId = intval($postId);
+    $array = array();
+    if (empty($courseId)) {
+        // $courseId can be null, use api method
+        $courseId = api_get_course_int_id();
+    }
+    if ($postId === -1) {
+        // If post ID is -1 then delete course's attachment data from $_SESSION
+        if (!empty($_SESSION['forum']['upload_file'][$courseId])) {
+            $array = array_keys($_SESSION['forum']['upload_file'][$courseId]);
+            unset($_SESSION['forum']['upload_file'][$courseId]);
+        }
+    } else {
+        $attachIds = getAttachmentIdsByPostId($postId, $courseId);
+        if (!empty($_SESSION['forum']['upload_file'][$courseId]) &&
+            is_array($_SESSION['forum']['upload_file'][$courseId])) {
+            foreach ($_SESSION['forum']['upload_file'][$courseId] as $attachId => $attach) {
+                if (!in_array($attachId, $attachIds)) {
+                    // If attach ID is not into specified post, delete attachment
+                    // Save deleted attachment ID
+                    $array[] = $attachId;
+                    if ($postId !== 0) {
+                        // Post 0 is temporal, delete them from file system and DB
+                        delete_attachment(0, $attachId, false);
+                    }
+                    // Delete attachment data from $_SESSION
+                    unset($_SESSION['forum']['upload_file'][$courseId][$attachId]);
+                }
+            }
+        }
+    }
+
+    return $array;
+}
+
+/**
+ * Returns an array of forum attachment ids into a course and forum post
+ * @param $postId
+ * @param null $courseId
+ * @return array
+ */
+function getAttachmentIdsByPostId($postId, $courseId = null) {
+    // Init variables
+    $array = array();
+    $courseId = intval($courseId);
+    $postId = intval($postId);
+    if (empty($courseId)) {
+        // $courseId can be null, use api method
+        $courseId = api_get_course_int_id();
+    }
+    if ($courseId > 0) {
+        $forumAttachmentTable = Database::get_course_table(TABLE_FORUM_ATTACHMENT);
+        $sql = "SELECT id FROM $forumAttachmentTable WHERE c_id = $courseId AND post_id = $postId";
+        $result = Database::query($sql);
+        if ($result !== false && Database::num_rows($result) > 0) {
+            while ($row = Database::fetch_array($result,'ASSOC')) {
+                $array[] = $row['id'];
+            }
+        }
+    }
+    return $array;
+}

+ 12 - 3
main/forum/newthread.php

@@ -149,7 +149,6 @@ if ($origin == 'learnpath') {
 } else {
     Display :: display_header(null);
 }
-
 handle_forum_and_forumcategories();
 
 // Action links
@@ -158,15 +157,25 @@ echo '<span style="float:right;">'.search_link().'</span>';
 echo '<a href="viewforum.php?origin='.$origin.'&forum='.Security::remove_XSS($_GET['forum']).'&'.api_get_cidreq().'">'.Display::return_icon('back.png',get_lang('BackToForum'),'',ICON_SIZE_MEDIUM).'</a>';
 echo '</div>';
 
+// Set forum attachment data into $_SESSION
+echo '<div class="row">';
+echo '<div class="span12">';
+getAttachedFiles($current_forum['forum_id'], 0, 0);
 $values = show_add_post_form($current_forum, $forum_setting, 'newthread', '', isset($_SESSION['formelements']) ? $_SESSION['formelements'] : null);
-
+echo '</div></div>';
 if (!empty($values) && isset($values['SubmitPost'])) {
     // Add new thread in table forum_thread.
     store_thread($current_forum, $values);
+} else {
+    // Only show Forum attachment ajax form when do not pass form submit
+    echo '<div class="row"><div class="span12">';
+    $attachmentAjaxForm = getAttachmentAjaxForm($current_forum['forum_id'], $current_thread['thread_id'], 0);
+    echo $attachmentAjaxForm;
+    echo '</div></div>';
 }
 
 /* FOOTER */
 
 if ($origin != 'learnpath') {
     Display :: display_footer();
-}
+}

+ 18 - 7
main/forum/reply.php

@@ -48,7 +48,6 @@ function advanced_parameters() {
     if(document.getElementById(\'id_qualify\').style.display == \'none\') {
         document.getElementById(\'id_qualify\').style.display = \'block\';
         document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.Display::return_icon('div_hide.gif',get_lang('Hide'),array('style'=>'vertical-align:middle')).'&nbsp;'.get_lang('AdvancedParameters').'\';
-
     } else {
         document.getElementById(\'id_qualify\').style.display = \'none\';
         document.getElementById(\'img_plus_and_minus\').innerHTML=\'&nbsp;'.Display::return_icon('div_show.gif',get_lang('Show'),array('style'=>'vertical-align:middle')).'&nbsp;'.get_lang('AdvancedParameters').'\';
@@ -139,7 +138,6 @@ if ($origin == 'learnpath') {
     // The last element of the breadcrumb navigation is already set in interbreadcrumb, so give an empty string.
     Display :: display_header('');
 }
-
 /* Action links */
 
 if ($origin != 'learnpath') {
@@ -150,14 +148,21 @@ if ($origin != 'learnpath') {
 } else {
     echo '<div style="height:15px">&nbsp;</div>';
 }
-
+/*New display forum div*/
+echo '<div class="row">';
+echo '<div class="span12">';
+echo '<div class="forum_title">';
+echo '<h1><a href="viewforum.php?&amp;origin='.$origin.'&amp;forum='.$current_forum['forum_id'].'" '.class_visible_invisible($current_forum['visibility']).'>'.prepare4display($current_forum['forum_title']).'</a></h1>';
+echo '<p class="forum_description">'.prepare4display($current_forum['forum_comment']).'</p>';
+echo '</div></div></div>';
+/* End new display forum */
 // The form for the reply
 $my_action   = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) : '';
 $my_post     = isset($_GET['post']) ?   Security::remove_XSS($_GET['post']) : '';
 $my_elements = isset($_SESSION['formelements']) ? $_SESSION['formelements'] : '';
-
-$values = show_add_post_form($current_forum, $forum_setting, $my_action, $my_post, $my_elements);
-
+echo '<div class="row"><div class="span12">';
+    $values = show_add_post_form($current_forum, $forum_setting, $my_action, $my_post, $my_elements);
+echo '</div></div>';
 if (!empty($values) AND isset($_POST['SubmitPost'])) {
     $result = store_reply($current_forum, $values);
     //@todo split the show_add_post_form function
@@ -167,8 +172,14 @@ if (!empty($values) AND isset($_POST['SubmitPost'])) {
     <script>
     window.location = "'.$url.'";
     </script>';
+} else {
+    // Only show Forum attachment ajax form when do not pass form submit
+    echo '<div class="row"><div class="span12">';
+    $attachmentAjaxForm = getAttachmentAjaxForm($current_forum['forum_id'], $current_thread['thread_id'], 0);
+    echo $attachmentAjaxForm;
+    echo '</div></div>';
 }
 
 if ($origin != 'learnpath') {
     Display :: display_footer();
-}
+}

+ 12 - 11
main/forum/viewpost.inc.php

@@ -57,19 +57,20 @@ if (isset($rows)) {
         echo "</tr>";
 
         // The check if there is an attachment
-        $attachment_list=get_attachment($row['post_id']);
+        $attachment_list=getAllAttachment($row['post_id']);
 
         if (!empty($attachment_list)) {
-            echo '<tr ><td height="50%">';
-            $realname=$attachment_list['path'];
-            $user_filename=$attachment_list['filename'];
-
-            echo Display::return_icon('attachment.gif',get_lang('Attachment'));
-            echo '<a href="download.php?file=';
-            echo $realname;
-            echo ' "> '.$user_filename.' </a>';
-            echo '<span class="forum_attach_comment" >'.$attachment_list['comment'].'</span><br />';
-            echo '</td></tr>';
+            foreach ($attachment_list as $attachment) {
+                echo '<tr ><td height="50%">';
+                $realname=$attachment['path'];
+                $user_filename=$attachment['filename'];
+                echo Display::return_icon('attachment.gif',get_lang('Attachment'));
+                echo '<a href="download.php?file=';
+                echo $realname;
+                echo ' "> '.$user_filename.' </a>';
+                echo '<span class="forum_attach_comment" >'.$attachment['comment'].'</span><br />';
+                echo '</td></tr>';
+            }
         }
 
         // The post has been displayed => it can be removed from the what's new array

+ 14 - 11
main/forum/viewthread_flat.inc.php

@@ -137,23 +137,26 @@ if (isset($current_thread['thread_id'])) {
             // see comments inside forumfunction.inc.php to lower filtering and allow more visual changes
             echo "<td class=\"$messageclass\">".prepare4display($row['post_text'])."</td>";
             echo "</tr>";
+            echo "</tr>";
 
             // The check if there is an attachment
 
-            $attachment_list = get_attachment($row['post_id']);
-            if (!empty($attachment_list)) {
-                echo '<tr><td colspan="2" height="50%">';
-                $realname=$attachment_list['path'];
-                $user_filename=$attachment_list['filename'];
+            $attachment_list = getAllAttachment($row['post_id']);
+            if (!empty($attachment_list) && is_array($attachment_list)) {
+                foreach ($attachment_list as $attachment) {
+                    echo '<tr><td colspan="2" height="50%">';
+                    $realname=$attachment['path'];
+                    $user_filename=$attachment['filename'];
 
-                echo Display::return_icon('attachment.gif',get_lang('Attachment'));
-                echo '<a href="download.php?file='.$realname.'"> '.$user_filename.' </a>';
+                    echo Display::return_icon('attachment.gif',get_lang('Attachment'));
+                    echo '<a href="download.php?file='.$realname.'"> '.$user_filename.' </a>';
 
-                if (($current_forum['allow_edit']==1 AND $row['user_id']==$_user['user_id']) or (api_is_allowed_to_edit(false,true)  && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session'])))	{
-                    echo '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;origin='.Security::remove_XSS($_GET['origin']).'&amp;action=delete_attach&amp;id_attach='.$attachment_list['id'].'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'.Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL).'</a><br />';
+                    if (($current_forum['allow_edit']==1 AND $row['user_id']==$_user['user_id']) or (api_is_allowed_to_edit(false,true)  && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session'])))	{
+                        echo '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;origin='.Security::remove_XSS($_GET['origin']).'&amp;action=delete_attach&amp;id_attach='.$attachment['id'].'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'.Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL).'</a><br />';
+                    }
+                    echo '<span class="forum_attach_comment" >'.$attachment['comment'].'</span>';
+                    echo '</td></tr>';
                 }
-                echo '<span class="forum_attach_comment" >'.$attachment_list['comment'].'</span>';
-                echo '</td></tr>';
             }
 
             // The post has been displayed => it can be removed from the what's new array

+ 17 - 17
main/forum/viewthread_nested.inc.php

@@ -146,24 +146,24 @@ foreach ($rows as $post) {
     echo "</tr>";
 
     // The check if there is an attachment
-    $attachment_list = get_attachment($post['post_id']);
-
-    if (!empty($attachment_list)) {
-        echo '<tr><td height="50%">';
-        $realname=$attachment_list['path'];
-        $user_filename=$attachment_list['filename'];
-
-        echo Display::return_icon('attachment.gif',get_lang('Attachment'));
-        echo '<a href="download.php?file=';
-        echo $realname;
-        echo ' "> '.$user_filename.' </a>';
-        echo '<span class="forum_attach_comment" >'.$attachment_list['comment'].'</span>';
-        if (($current_forum['allow_edit']==1 AND $post['user_id']==$_user['user_id']) OR
-            (api_is_allowed_to_edit(false,true) && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session']))
-        ) {
-            echo '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;origin='.Security::remove_XSS($_GET['origin']).'&amp;action=delete_attach&amp;id_attach='.$attachment_list['id'].'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'.Display::return_icon('delete.gif',get_lang('Delete')).'</a><br />';
+    $attachment_list = getAllAttachment($post['post_id']);
+    if (!empty($attachment_list) && is_array($attachment_list)) {
+        foreach ($attachment_list as $attachment) {
+            echo '<tr><td height="50%">';
+            $realname=$attachment['path'];
+            $user_filename=$attachment['filename'];
+            echo Display::return_icon('attachment.gif',get_lang('Attachment'));
+            echo '<a href="download.php?file=';
+            echo $realname;
+            echo ' "> '.$user_filename.' </a>';
+            echo '<span class="forum_attach_comment" >'.$attachment['comment'].'</span>';
+            if (($current_forum['allow_edit']==1 AND $post['user_id']==$_user['user_id']) OR
+                (api_is_allowed_to_edit(false,true) && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session']))
+            ) {
+                echo '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;origin='.Security::remove_XSS($_GET['origin']).'&amp;action=delete_attach&amp;id_attach='.$attachment['id'].'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'.Display::return_icon('delete.gif',get_lang('Delete')).'</a><br />';
+            }
+            echo '</td></tr>';
         }
-        echo '</td></tr>';
     }
 
     // The post has been displayed => it can be removed from the what's new array

+ 282 - 130
main/forum/viewthread_threaded.inc.php

@@ -21,8 +21,8 @@
  * @package chamilo.forum
  */
 
-require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
-$forumUrl = api_get_path(WEB_CODE_PATH).'forum/';
+require_once api_get_path(SYS_CODE_PATH) . 'forum/forumfunction.inc.php';
+$forumUrl = api_get_path(WEB_CODE_PATH) . 'forum/';
 
 $rows = get_posts($_GET['thread']);
 $rows = calculate_children($rows);
@@ -30,7 +30,7 @@ $rows = calculate_children($rows);
 if (isset($_GET['post']) && $_GET['post']) {
     $display_post_id = intval($_GET['post']);
 } else {
-    // we need to display the first post
+    // We need to display the first post
     reset($rows);
     $current = current($rows);
     $display_post_id = $current['post_id'];
@@ -38,61 +38,75 @@ if (isset($_GET['post']) && $_GET['post']) {
 
 // Are we in a lp ?
 $origin = '';
-if(isset($_GET['origin'])) {
+if (isset($_GET['origin'])) {
     $origin =  Security::remove_XSS($_GET['origin']);
 }
 
 // Delete attachment file.
-if ((isset($_GET['action']) && $_GET['action']=='delete_attach') && isset($_GET['id_attach'])) {
+if (
+    isset($_GET['action']) &&
+    $_GET['action']=='delete_attach' &&
+    isset($_GET['id_attach'])
+) {
     delete_attachment(0, $_GET['id_attach']);
+    if (!isset($_GET['thread'])) {
+        exit;
+    }
 }
 
-// 		Displaying the thread (structure)
+// Displaying the thread (structure)
 
-$thread_structure="<div class=\"structure\">".get_lang('Structure')."</div>";
-$counter=0;
-$count=0;
-$prev_next_array=array();
+$thread_structure = "<div class=\"structure\">" .
+    get_lang('Structure') . "</div>";
+$counter = 0;
+$count = 0;
+$prev_next_array = array();
 
-$clean_forum_id  = intval($_GET['forum']);
-$clean_thread_id = intval($_GET['thread']);
+$forumId  = intval($_GET['forum']);
+$threadId = intval($_GET['thread']);
 $group_id = api_get_group_id();
 
 foreach ($rows as $post) {
     $counter++;
-    $indent=$post['indent_cnt']*'20';
-    $thread_structure.= "<div style=\"margin-left: ".$indent."px;\">";
+    $indent = $post['indent_cnt'] * '20';
+    $thread_structure .= "<div style=\"margin-left: " . $indent . "px;\">";
 
-    if (isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) AND
-        !empty($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) AND
-        !empty($whatsnew_post_info[$_GET['forum']][$post['thread_id']])
+    if (
+        !empty($whatsnew_post_info[$forumId][$post['thread_id']]) AND
+        isset($whatsnew_post_info[$forumId][$threadId][$post['post_id']]) AND
+        !empty($whatsnew_post_info[$forumId][$threadId][$post['post_id']])
     ) {
         $post_image = Display::return_icon('forumpostnew.gif');
     } else {
         $post_image = Display::return_icon('forumpost.gif');
     }
-    $thread_structure.= $post_image;
-    if (isset($_GET['post']) &&
-        $_GET['post'] == $post['post_id'] OR
-        ($counter==1 AND !isset($_GET['post']))
+    $thread_structure .= $post_image;
+    if (
+        isset($_GET['post']) &&
+        $_GET['post'] == $post['post_id'] || (
+            $counter == 1 AND !isset($_GET['post'])
+        )
     ) {
-        $thread_structure .= '<strong>'.prepare4display($post['post_title']).'</strong></div>';
-        $prev_next_array[]= $post['post_id'];
+        $thread_structure .= '<strong>' .
+            prepare4display($post['post_title']) . '</strong></div>';
+        $prev_next_array[] = $post['post_id'];
     } else {
-        if ($post['visible']=='0') {
-            $class=' class="invisible"';
+        if ($post['visible'] == '0') {
+            $class = ' class="invisible"';
         } else {
-            $class='';
+            $class = '';
         }
-        $count_loop=($count==0)?'&amp;id=1' : '';
-        $thread_structure.= "<a href=\"viewthread.php?".api_get_cidreq()."&forum=".$clean_forum_id."&thread=".$clean_thread_id."&post=".$post['post_id']."&amp;origin=$origin$count_loop\" $class>".
-            prepare4display($post['post_title'])."</a></div>";
-        $prev_next_array[]=$post['post_id'];
+        $count_loop = ($count == 0) ? '&id=1' : '';
+        $thread_structure .= "<a href=\"viewthread.php?" . api_get_cidreq() .
+            "&forum=" . $forumId . "&thread=" . $threadId .
+            "&post=" . $post['post_id'] . "&origin=$origin$count_loop\"" .
+            "$class>" . prepare4display($post['post_title']) . "</a></div>";
+        $prev_next_array[] = $post['post_id'];
     }
     $count++;
 }
 
-$locked = api_resource_is_locked_by_gradebook($clean_thread_id, LINK_FORUM_THREAD);
+$locked = api_resource_is_locked_by_gradebook($threadId, LINK_FORUM_THREAD);
 
 /* NAVIGATION CONTROLS */
 
@@ -101,13 +115,13 @@ $max = count($prev_next_array);
 $next_id = $current_id + 1;
 $prev_id = $current_id - 1;
 
-// text
+// Text
 $first_message = get_lang('FirstMessage');
 $last_message = get_lang('LastMessage');
 $next_message = get_lang('NextMessage');
 $prev_message = get_lang('PrevMessage');
 
-// images
+// Images
 $first_img = Display::return_icon(
     'action_first.png',
     get_lang('FirstMessage'),
@@ -129,36 +143,48 @@ $next_img = Display::return_icon(
     array('style' => 'vertical-align: middle;')
 );
 
-// links
-$first_href = $forumUrl.'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&id=1&amp;post='.$prev_next_array[0];
-$last_href 	= $forumUrl.'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&post='.$prev_next_array[$max-1];
-$prev_href	= $forumUrl.'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&post='.$prev_next_array[$prev_id];
-$next_href	= $forumUrl.'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&post='.$prev_next_array[$next_id];
+// Links
+$first_href = $forumUrl . 'viewthread.php?' . api_get_cidreq() .
+    '&forum=' . $forumId . '&thread=' . $threadId .
+    '&gradebook=' . $gradebook . '&id=1&post=' . $prev_next_array[0];
+$last_href 	= $forumUrl . 'viewthread.php?' . api_get_cidreq() .
+    '&forum=' . $forumId . '&thread=' . $threadId .
+    '&gradebook=' . $gradebook . '&post=' . $prev_next_array[$max-1];
+$prev_href	= $forumUrl . 'viewthread.php?' . api_get_cidreq() .
+    '&forum=' . $forumId . '&thread=' . $threadId .
+    '&gradebook=' . $gradebook . '&post=' . $prev_next_array[$prev_id];
+$next_href	= $forumUrl . 'viewthread.php?' . api_get_cidreq() .
+    '&forum=' . $forumId . '&thread=' . $threadId .
+    '&gradebook=' . $gradebook . '&post=' . $prev_next_array[$next_id];
 
 echo '<center style="margin-top: 10px; margin-bottom: 10px;">';
-//go to: first and previous
-if ((int)$current_id > 0) {
-    echo '<a href="'.$first_href.'" '.$class.' title='.$first_message.'>'.$first_img.' '.$first_message.'</a>';
-    echo '<a href="'.$prev_href.'" '.$class_prev.' title='.$prev_message.'>'.$prev_img.' '.$prev_message.'</a>';
+// Go to: first and previous
+if (((int) $current_id) > 0) {
+    echo '<a href="' . $first_href . '" ' . $class . ' title=' .
+        $first_message . '>' . $first_img . ' ' . $first_message .'</a>';
+    echo '<a href="' . $prev_href . '" ' . $class_prev . ' title=' .
+        $prev_message . '>' . $prev_img . ' ' . $prev_message . '</a>';
 } else {
-    echo '<b><span class="invisible">'.$first_img.' '.$first_message.'</b></span>';
-    echo '<b><span class="invisible">'.$prev_img.' '.$prev_message.'</b></span>';
+    echo '<b><span class="invisible">' .
+        $first_img . ' ' . $first_message . '</b></span>';
+    echo '<b><span class="invisible">' .
+        $prev_img . ' ' . $prev_message . '</b></span>';
 }
 
-//  current counter
-echo ' [ '.($current_id+1).' / '.$max.' ] ';
+// Current counter
+echo ' [ ' . ($current_id + 1) . ' / ' . $max . ' ] ';
 
-// go to: next and last
-if (($current_id+1) < $max) {
-    echo '<a href="'.$next_href.'" '.$class_next.' title='.$next_message.'>'.$next_message.' '.$next_img.'</a>';
-    echo '<a href="'.$last_href.'" '.$class.' title='.$last_message.'>'.$last_message.' '.$last_img.'</a>';
+// Go to: next and last
+if (($current_id + 1) < $max) {
+    echo '<a href="' . $next_href . '" ' . $class_next . ' title=' . $next_message . '>' . $next_message . ' ' . $next_img . '</a>';
+    echo '<a href="' . $last_href . '" ' . $class . ' title=' . $last_message . '>' . $last_message . ' ' . $last_img . '</a>';
 } else {
-    echo '<b><span class="invisible">'.$next_message.' '.$next_img.'</b></span>';
-    echo '<b><span class="invisible">'.$last_message.' '.$last_img.'</b></span>';
+    echo '<b><span class="invisible">' . $next_message . ' ' . $next_img . '</b></span>';
+    echo '<b><span class="invisible">' . $last_message . ' ' . $last_img . '</b></span>';
 }
 echo '</center>';
 
-// the style depends on the status of the message: approved or not
+// The style depends on the status of the message: approved or not
 if ($rows[$display_post_id]['visible'] == '0') {
     $titleclass = 'forum_message_post_title_2_be_approved';
     $messageclass = 'forum_message_post_text_2_be_approved';
@@ -169,63 +195,119 @@ if ($rows[$display_post_id]['visible'] == '0') {
     $leftclass = 'forum_message_left';
 }
 
-// 		Displaying the message
+// Displaying the message
 
-// we mark the image we are displaying as set
-unset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$rows[$display_post_id]['post_id']]);
+// We mark the image we are displaying as set
+unset($whatsnew_post_info[$forumId][$threadId][$rows[$display_post_id]['post_id']]);
 
-echo "<table width=\"100%\"  class=\"forum_table\"  cellspacing=\"5\" border=\"0\">";
+echo "<table width=\"100%\" class=\"forum_table\" cellspacing=\"5\" border=\"0\">";
 echo "<tr>";
 echo "<td rowspan=\"3\" class=\"$leftclass\">";
 $username = sprintf(get_lang('LoginX'), $rows[$display_post_id]['username']);
-if ($rows[$display_post_id]['user_id']=='0') {
+if ($rows[$display_post_id]['user_id'] == '0') {
     $name = prepare4display($rows[$display_post_id]['poster_name']);
 } else {
     $name = api_get_person_name($rows[$display_post_id]['firstname'], $rows[$display_post_id]['lastname']);
 }
 
 if (api_get_course_setting('allow_user_image_forum')) {
-    echo '<br />'.display_user_image($rows[$display_post_id]['user_id'],$name, $origin).'<br />';
+    echo '<br />' . display_user_image($rows[$display_post_id]['user_id'], $name, $origin) . '<br />';
 }
-echo display_user_link($rows[$display_post_id]['user_id'], $name, $origin, $username)."<br />";
-echo api_convert_and_format_date($rows[$display_post_id]['post_date']).'<br /><br />';
-// get attach id
-$attachment_list=get_attachment($display_post_id);
-$id_attach = !empty($attachment_list)?$attachment_list['id']:'';
+echo display_user_link(
+        $rows[$display_post_id]['user_id'],
+        $name,
+        $origin,
+        $username
+    ) . "<br />";
+echo api_convert_and_format_date(
+        $rows[$display_post_id]['post_date']
+    ) . '<br /><br />';
+// Get attach id
+$attachment_list = get_attachment($display_post_id);
+$id_attach = !empty($attachment_list) ? $attachment_list['id'] : '';
 
 // The user who posted it can edit his thread only if the course admin allowed this in the properties of the forum
 // The course admin him/herself can do this off course always
-if (GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR ($current_forum['allow_edit']==1 AND $row['user_id']==$_user['user_id']) or (api_is_allowed_to_edit(false,true)  && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session']))) {
+if (
+    GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR (
+        $current_forum['allow_edit'] == 1 AND
+        $row['user_id'] == $_user['user_id']
+    ) OR (
+        api_is_allowed_to_edit(false,true) && !(
+            api_is_course_coach() &&
+            $current_forum['session_id'] != $_SESSION['id_session']
+        )
+    )
+) {
     if ($locked == false) {
-        echo "<a href=\"editpost.php?".api_get_cidreq()."&forum=".$clean_forum_id."&thread=".$clean_thread_id."&post=".$rows[$display_post_id]['post_id']."&amp;id_attach=".$id_attach."\">".
-            Display::return_icon('edit.png',get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
+        echo "<a href=\"editpost.php?" . api_get_cidreq() .
+            "&forum=" . $forumId . "&thread=" . $threadId .
+            "&post=" . $rows[$display_post_id]['post_id'] .
+            "&id_attach=" . $id_attach . "\">" .
+            Display::return_icon(
+                'edit.png',
+                get_lang('Edit'),
+                array(),
+                ICON_SIZE_SMALL
+            ) . '</a>';
     }
 }
 
-if (GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR
-    api_is_allowed_to_edit(false,true) &&
-    !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session'])
+if (
+    GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR
+    api_is_allowed_to_edit(false,true) && !(
+        api_is_course_coach() &&
+        $current_forum['session_id'] != $_SESSION['id_session']
+    )
 ) {
     if ($locked == false) {
-        echo "<a href=\"".api_get_self()."?".api_get_cidreq()."&forum=".$clean_forum_id."&amp;thread=".$clean_thread_id."&amp;action=delete&amp;content=post&amp;id=".$rows[$display_post_id]['post_id']."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES))."')) return false;\">".Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL)."</a>";
+        echo "<a href=\"" . api_get_self() . "?" . api_get_cidreq() .
+            "&forum=" . $forumId . "&thread=" . $threadId .
+            "&action=delete&content=post&id=" .
+            $rows[$display_post_id]['post_id'] .
+            "\" onclick=\"javascript:if(!confirm('" .
+            addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES)) .
+            "')) return false;\">" . Display::return_icon(
+                'delete.png',
+                get_lang('Delete'),
+                array(),
+                ICON_SIZE_SMALL
+            )."</a>";
     }
-    display_visible_invisible_icon('post', $rows[$display_post_id]['post_id'], $rows[$display_post_id]['visible'],array('forum'=>$clean_forum_id,'thread'=>$clean_thread_id, 'post'=>Security::remove_XSS($_GET['post']) ));
-    echo "";
-    //verified the post minor
-    $my_post=get_posts($_GET['thread']);
-    $id_posts=array();
-
-    foreach ($my_post as $post_value) {
-        $id_posts[]=$post_value['post_id'];
-    }
-
-    sort($id_posts,SORT_NUMERIC);
-    reset($id_posts);
-    //the post minor
-    $post_minor=(int)$id_posts[0];
-    $post_id = isset($_GET['post'])?(int)$_GET['post']:0;
-    if (!isset($_GET['id']) && $post_id>$post_minor) {
-        echo "<a href=\"viewthread.php?".api_get_cidreq()."&amp;gidReq=".Security::remove_XSS($_GET['gidReq'])."&amp;forum=".$clean_forum_id."&amp;thread=".$clean_thread_id."&amp;origin=".$origin."&amp;action=move&amp;post=".$rows[$display_post_id]['post_id']."\">".Display::return_icon('move.png',get_lang('MovePost'), array(), ICON_SIZE_SMALL)."</a>";
+    display_visible_invisible_icon(
+        'post',
+        $rows[$display_post_id]['post_id'],
+        $rows[$display_post_id]['visible'],
+        array(
+            'forum' => $forumId,
+            'thread' => $threadId,
+            'post' => Security::remove_XSS($_GET['post']) ));
+    // Verified the post minor
+    $my_post = get_posts($_GET['thread']);
+    $id_posts = array();
+
+    if (!empty($my_post) && is_array($my_post)) {
+        foreach ($my_post as $post_value) {
+            $id_posts[] = $post_value['post_id'];
+        }
+        sort($id_posts, SORT_NUMERIC);
+        reset($id_posts);
+        // The post minor
+        $post_minor = (int) $id_posts[0];
+        $post_id = isset($_GET['post']) ? (int) $_GET['post'] : 0;
+        if (!isset($_GET['id']) && $post_id > $post_minor) {
+            echo "<a href=\"viewthread.php?" . api_get_cidreq() .
+                "&gidReq=" . Security::remove_XSS($_GET['gidReq']) .
+                "&forum=" . $forumId . "&thread=" . $threadId .
+                "&origin=" . $origin . "&action=move&post=" .
+                $rows[$display_post_id]['post_id'] . "\">" .
+                Display::return_icon(
+                    'move.png',
+                    get_lang('MovePost'),
+                    array(),
+                    ICON_SIZE_SMALL
+                ) . "</a>";
+        }
     }
 }
 $userinf = api_get_user_info($rows[$display_post_id]['user_id']);
@@ -233,78 +315,148 @@ $user_status = api_get_status_of_user_in_course(
     $rows[$display_post_id]['user_id'],
     api_get_course_id()
 );
-if (api_is_allowed_to_edit(null,true)) {
+if (api_is_allowed_to_edit(null, true)) {
     if ($post_id > $post_minor) {
-        $current_qualify_thread=show_qualify('1', $rows[$display_post_id]['user_id'],$_GET['thread']);
-
+        $current_qualify_thread = show_qualify(
+            '1',
+            $rows[$display_post_id]['user_id'],
+            $_GET['thread']
+        );
         if ($locked == false) {
-            echo "<a href=\"forumqualify.php?".api_get_cidreq()."&amp;forum=".$clean_forum_id."&amp;thread=".$clean_thread_id."&amp;action=list&amp;post=".$rows[$display_post_id]['post_id']."&amp;user=".$rows[$display_post_id]['user_id']."&amp;user_id=".$rows[$display_post_id]['user_id']."&amp;origin=".$origin."&amp;idtextqualify=".$current_qualify_thread."\" >".Display::return_icon('new_test_small.gif',get_lang('Qualify'))."</a>";
+            echo "<a href=\"forumqualify.php?" . api_get_cidreq() .
+                "&forum=" . $forumId . "&thread=" . $threadId .
+                "&action=list&post=" . $rows[$display_post_id]['post_id'] .
+                "&user=" . $rows[$display_post_id]['user_id'] . "&user_id=" .
+                $rows[$display_post_id]['user_id'] . "&origin=" . $origin .
+                "&idtextqualify=" . $current_qualify_thread .
+                "\" >" . Display::return_icon(
+                    'new_test_small.gif',
+                    get_lang('Qualify')
+                ) . "</a>";
         }
     }
 }
-if (($current_forum_category && $current_forum_category['locked']==0) AND $current_forum['locked']==0 AND $current_thread['locked']==0 OR api_is_allowed_to_edit(false,true)) {
-    if ($_user['user_id'] OR ($current_forum['allow_anonymous']==1 AND !$_user['user_id'])) {
-        if (!api_is_anonymous() && api_is_allowed_to_session_edit(false,true)) {
-            echo '<a href="reply.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;post='.$rows[$display_post_id]['post_id'].'&amp;action=replymessage&amp;origin='. $origin .'">'.Display :: return_icon('message_reply_forum.png', get_lang('ReplyToMessage'))."</a>";
-            echo '<a href="reply.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;post='.$rows[$display_post_id]['post_id'].'&amp;action=quote&amp;origin='. $origin .'">'.Display :: return_icon('quote.gif', get_lang('QuoteMessage'))."</a>";
+if (
+    (
+        $current_forum_category &&
+        $current_forum_category['locked'] == 0
+    ) AND $current_forum['locked'] == 0 AND
+    $current_thread['locked'] == 0 OR
+    api_is_allowed_to_edit(false,true)
+) {
+    if (
+        $_user['user_id'] OR (
+            $current_forum['allow_anonymous'] == 1 AND
+            !$_user['user_id']
+        )
+    ) {
+        if (
+            !api_is_anonymous() &&
+            api_is_allowed_to_session_edit(false, true)
+        ) {
+            echo '<a href="reply.php?' . api_get_cidreq() .
+                '&forum=' . $forumId . '&thread=' . $threadId .
+                '&post=' . $rows[$display_post_id]['post_id'] .
+                '&action=replymessage&origin=' . $origin . '">' .
+                Display::return_icon(
+                    'message_reply_forum.png',
+                    get_lang('ReplyToMessage')
+                ) . "</a>";
+            echo '<a href="reply.php?' . api_get_cidreq() .
+                '&forum=' . $forumId . '&thread=' . $threadId .
+                '&post=' . $rows[$display_post_id]['post_id'] .
+                '&action=quote&origin=' . $origin . '">' .
+                Display::return_icon(
+                    'quote.gif',
+                    get_lang('QuoteMessage')
+                ) . "</a>";
         }
     }
 } else {
-    if ($current_forum_category && $current_forum_category['locked']==1) {
-        echo get_lang('ForumcategoryLocked').'<br />';
+    if ($current_forum_category && $current_forum_category['locked'] == 1) {
+        echo get_lang('ForumcategoryLocked') . '<br />';
     }
-    if ($current_forum['locked']==1) {
-        echo get_lang('ForumLocked').'<br />';
+    if ($current_forum['locked'] == 1) {
+        echo get_lang('ForumLocked') . '<br />';
     }
-    if ($current_thread['locked']==1) {
-        echo get_lang('ThreadLocked').'<br />';
+    if ($current_thread['locked'] == 1) {
+        echo get_lang('ThreadLocked') . '<br />';
     }
 }
 echo "</td>";
-// note: this can be removed here because it will be displayed in the tree
-if (isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$rows[$display_post_id]['post_id']]) AND
-    !empty($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$rows[$display_post_id]['post_id']]) AND
+// Note: this can be removed here because it will be displayed in the tree
+if (
+    isset($whatsnew_post_info[$forumId][$threadId][$rows[$display_post_id]['post_id']]) AND
+    !empty($whatsnew_post_info[$forumId][$threadId][$rows[$display_post_id]['post_id']]) AND
     !empty($whatsnew_post_info[$_GET['forum']][$rows[$display_post_id]['thread_id']])
 ) {
-    $post_image=Display::return_icon('forumpostnew.gif');
+    $post_image = Display::return_icon('forumpostnew.gif');
 } else {
-    $post_image=Display::return_icon('forumpost.gif');
+    $post_image = Display::return_icon('forumpost.gif');
 }
-if ($rows[$display_post_id]['post_notification']=='1' AND $rows[$display_post_id]['poster_id']==$_user['user_id']) {
-    $post_image.=Display::return_icon('forumnotification.gif',get_lang('YouWillBeNotified'));
+if (
+    $rows[$display_post_id]['post_notification'] == '1' AND
+    $rows[$display_post_id]['poster_id'] == $_user['user_id']
+) {
+    $post_image .= Display::return_icon('forumnotification.gif',get_lang('YouWillBeNotified'));
 }
 // The post title
-echo "<td class=\"$titleclass\">".prepare4display($rows[$display_post_id]['post_title'])."</td>";
+echo "<td class=\"$titleclass\">" .
+    prepare4display($rows[$display_post_id]['post_title']) . "</td>";
 echo "</tr>";
 
 // The post message
 echo "<tr>";
-echo "<td class=\"$messageclass\">".prepare4display($rows[$display_post_id]['post_text'])."</td>";
+echo "<td class=\"$messageclass\">" .
+    prepare4display($rows[$display_post_id]['post_text']) . "</td>";
 echo "</tr>";
 
 // The check if there is an attachment
-$attachment_list = get_attachment($display_post_id);
-
-if (!empty($attachment_list)) {
-    echo '<tr><td height="50%">';
-    $realname = $attachment_list['path'];
-    $user_filename = $attachment_list['filename'];
-
-    echo Display::return_icon('attachment.gif',get_lang('Attachment'));
-    echo '<a href="download.php?file=';
-    echo $realname;
-    echo ' "> '.$user_filename.' </a>';
-    echo '<span class="forum_attach_comment" >'.Security::remove_XSS($attachment_list['comment'], STUDENT).'</span>';
-    if (($current_forum['allow_edit']==1 AND $rows[$display_post_id]['user_id']==$_user['user_id']) or (api_is_allowed_to_edit(false,true)  && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session'])))	{
-        echo '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;origin='.Security::remove_XSS($_GET['origin']).'&amp;action=delete_attach&amp;id_attach='.$attachment_list['id'].'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTESt)).'\')) return false;">'.Display::return_icon('delete.gif',get_lang('Delete')).'</a><br />';
+$attachment_list = getAllAttachment($display_post_id);
+if (!empty($attachment_list) && is_array($attachment_list)) {
+    foreach ($attachment_list as $attachment) {
+        echo '<tr><td height="50%">';
+        $realname = $attachment['path'];
+        $user_filename = $attachment['filename'];
+        echo Display::return_icon('attachment.gif', get_lang('Attachment'));
+        echo '<a href="download.php?file=';
+        echo $realname;
+        echo ' "> ' . $user_filename . ' </a>';
+        echo '<span class="forum_attach_comment">' .
+            Security::remove_XSS($attachment['comment'], STUDENT) . '</span>';
+        if (
+            (
+                $current_forum['allow_edit'] == 1 AND
+                $rows[$display_post_id]['user_id'] == $_user['user_id']
+            ) OR (
+                api_is_allowed_to_edit(false, true) && !(
+                    api_is_course_coach() &&
+                    $current_forum['session_id'] != $_SESSION['id_session']
+                )
+            )
+        )	{
+            echo '&nbsp;&nbsp;<a href="' . api_get_self() . '?' .
+                api_get_cidreq() . '&origin=' .
+                Security::remove_XSS($_GET['origin']) .
+                '&action=delete_attach&id_attach=' .
+                $attachment['id'] . '&forum=' . $forumId .
+                '&thread=' . $threadId .
+                '" onclick="javascript:if(!confirm(\'' .
+                addslashes(api_htmlentities(
+                    get_lang('ConfirmYourChoice'), ENT_QUOTESt)
+                ) . '\')) return false;">' . Display::return_icon(
+                    'delete.gif',
+                    get_lang('Delete')
+                ).'</a><br />';
+        }
+        echo '</td></tr>';
     }
-    echo '</td></tr>';
 }
 
 // The post has been displayed => it can be removed from the what's new array
-if (isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$row['post_id']])) {
-  unset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$row['post_id']]);
-  unset($_SESSION['whatsnew_post_info'][$current_forum['forum_id']][$current_thread['thread_id']][$row['post_id']]);
+if (isset($whatsnew_post_info[$forumId][$threadId][$row['post_id']])) {
+  unset($whatsnew_post_info[$forumId][$threadId][$row['post_id']]);
+  unset($_SESSION['whatsnew_post_info'][$forumId][$threadId][$row['post_id']]);
 }
 echo "</table>";
 

BIN
main/img/icons/64/file_upload.png


+ 123 - 0
main/inc/ajax/forum.ajax.php

@@ -0,0 +1,123 @@
+<?php
+/** For licensing terms, see /license.txt */
+/**
+ * Responses to AJAX calls for forum attachments
+ * @package chamilo/forum
+ * @author Daniel Barreto Alva <daniel.barreto@beeznest.com>
+ */
+
+/**
+ * Init
+ */
+require_once '../global.inc.php';
+require_once api_get_path(LIBRARY_PATH).'document.lib.php';
+
+/**
+ * Main code
+ */
+// Create a default error response
+$json = array(
+    'error' => true,
+    'errorMessage' => 'ERROR',
+);
+$action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
+// Check if exist action
+if (!empty($action)) {
+    require_once api_get_path(SYS_CODE_PATH) . 'forum/forumfunction.inc.php';
+    switch($action) {
+        case 'upload_file':
+            // First, protect this script
+            api_protect_course_script(false);
+            if (!empty($_FILES) && !empty($_REQUEST['forum'])) {
+                // The user is not allowed here if
+                // 1. the forum category, forum or thread is invisible (visibility==0)
+                // 2. the forum category, forum or thread is locked (locked <>0)
+                // 3. if anonymous posts are not allowed
+                // The only exception is the course manager
+                // They are several pieces for clarity.
+                if (!api_is_allowed_to_edit(null, true) AND (($current_forum_category && $current_forum_category['visibility'] == 0) OR $current_forum['visibility'] == 0)) {
+                    $json['errorMessage'] = '1. the forum category, forum or thread is invisible (visibility==0)';
+                    break;
+                }
+                if (!api_is_allowed_to_edit(null, true) AND (($current_forum_category && $current_forum_category['locked'] <> 0 ) OR $current_forum['locked'] <> 0 OR $current_thread['locked'] <> 0)) {
+                    $json['errorMessage'] = '2. the forum category, forum or thread is locked (locked <>0)';
+                    break;
+                }
+                if (api_is_anonymous() AND $current_forum['allow_anonymous'] == 0) {
+                    $json['errorMessage'] = '3. if anonymous posts are not allowed';
+                    break;
+                }
+                // If pass all previous control, user can edit post
+                $courseId = isset($_REQUEST['c_id'])? intval($_REQUEST['c_id']) : api_get_course_int_id();
+                $json['courseId'] = $courseId;
+                $forumId = isset($_REQUEST['forum'])? intval($_REQUEST['forum']) : null;
+                $json['forum'] = $forumId;
+                $threadId = isset($_REQUEST['thread'])? intval($_REQUEST['thread']) : null;
+                $json['thread'] = $threadId;
+                $postId = isset($_REQUEST['postId'])? intval($_REQUEST['postId']) : null;
+                $json['postId'] = $postId;
+                if (!empty($courseId) && !is_null($forumId) && !is_null($threadId) && !is_null($postId)) {
+                    // Save forum attachment
+                    $attachId = add_forum_attachment_file('', $postId);
+                    if ($attachId !== false) {
+                        // Get prepared array of attachment data
+                        $array = getAttachedFiles($forumId, $threadId, $postId, $attachId, $courseId);
+                        // Check if array data is consistent
+                        if (isset($array['name'])) {
+                            $json['error'] = false;
+                            $json['errorMessage'] = 'Success';
+                            $json = array_merge($json, $array);
+                        }
+                    }
+                }
+            }
+            break;
+        case 'delete_file':
+            // First, protect this script
+            api_protect_course_script(false);
+            // Check if set attachment ID and thread ID
+            if (isset($_REQUEST['attachId']) && isset($_REQUEST['thread'])) {
+                api_block_course_item_locked_by_gradebook($_REQUEST['thread'], LINK_FORUM_THREAD);
+                // The user is not allowed here if
+                // 1. the forum category, forum or thread is invisible (visibility==0)
+                // 2. the forum category, forum or thread is locked (locked <>0)
+                // 3. if anonymous posts are not allowed
+                // 4. if editing of replies is not allowed
+                // The only exception is the course manager
+                // They are several pieces for clarity.
+                if (!api_is_allowed_to_edit(null, true) AND (($current_forum_category && $current_forum_category['visibility'] == 0) OR $current_forum['visibility'] == 0)) {
+                    $json['errorMessage'] = '1. the forum category, forum or thread is invisible (visibility==0)';
+                    break;
+                }
+                if (!api_is_allowed_to_edit(null, true) AND (($current_forum_category && $current_forum_category['locked'] <> 0 ) OR $current_forum['locked'] <> 0 OR $current_thread['locked'] <> 0)) {
+                    $json['errorMessage'] = '2. the forum category, forum or thread is locked (locked <>0)';
+                    break;
+                }
+                if (api_is_anonymous() AND $current_forum['allow_anonymous'] == 0) {
+                    $json['errorMessage'] = '3. if anonymous posts are not allowed';
+                    break;
+                }
+                $group_id = api_get_group_id();
+                if (!api_is_allowed_to_edit(null, true) AND $current_forum['allow_edit'] == 0 && !GroupManager::is_tutor_of_group(api_get_user_id(), $group_id)) {
+                    $json['errorMessage'] = '4. if editing of replies is not allowed';
+                    break;
+                }
+                // If pass all previous control, user can edit post
+                $attachId = $_REQUEST['attachId'];
+                $threadId = $_REQUEST['thread'];
+                // Delete forum attachment from database and file system
+                $affectedRows = delete_attachment(0, $attachId, false);
+                if ($affectedRows > 0) {
+                    $json['error'] = false;
+                    $json['errorMessage'] = 'Success';
+                }
+            }
+            break;
+    }
+}
+
+/**
+ * Display
+ */
+echo json_encode($json);
+exit;

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

@@ -1176,7 +1176,7 @@ class Database
      * @todo known issues, it doesn't work when using LIKE conditions
      * @example array('where'=> array('course_code LIKE "?%"'))
      * @example array('where'=> array('type = ? AND category = ?' => array('setting', 'Plugins'))
-     * @example array('where'=> array('name = "Julio" AND lastname = "montoya"))
+     * @example array('where'=> array('name = "Julio" AND lastname = "montoya"'))
     */
 
     public static function select($columns, $table_name, $conditions = array(), $type_result = 'all', $option = 'ASSOC')

+ 14 - 5
main/inc/lib/javascript/jquery-upload/jquery.fileupload-ui.css

@@ -9,14 +9,23 @@
     -moz-border-radius: 10px;
     -webkit-border-radius: 10px;
     border-radius: 10px;
-    width: 500px;
-    height: 50px;
+    width: auto;
+    margin-left: auto;
+    margin-right: auto;
+    height: auto;
     line-height: 50px;
-    background: palegreen;
-    border: 1px solid limegreen;
+    background-color: #D4E6F0;
+    border: 2px dashed #bbbbbb;
     font-size:120%;
+    margin-bottom: 0;
+}
+.form-ajax{
+  border: 2px solid #bbbbbb;
+  padding: .5em;
+  -moz-border-radius: 10px;
+  -webkit-border-radius: 10px;
+  border-radius: 10px;
 }
-
 .file_upload_small {
     width: 500px;
     height: 50px;

+ 2 - 0
main/lang/english/forum.inc.php

@@ -147,4 +147,6 @@ $ThreadMoved = "Thread moved";
 $MigrateForum = "Migrate forum";
 $YouWillBeNotified = "You will be notified";
 $ForumCategories = "Forum Categories";
+$AttachmentFilesList = "Attachments list";
+$ErrorUploadAttachment = "There was an error when uploading attachment";
 ?>

+ 4 - 0
main/lang/english/trad4all.inc.php

@@ -1675,4 +1675,8 @@ $DataTableSearch = "Search";
 $HideColumn = "Hide column";
 $DisplayColumn = "Show column";
 $LegalAgreementAccepted = "Legal agreement accepted";
+$FieldTypeMobilePhoneNumber = "Mobile phone";
+$CountryDialCode = "Include the country dial code";
+$MobilePhoneNumberWrong = "Mobile phone number is incomplete or contains not valid characters";
+$AreYouSureToDeleteFileX = "Are you sure you want to delete file %s ?";
 ?>

+ 1 - 0
main/lang/french/forum.inc.php

@@ -147,4 +147,5 @@ $ThreadMoved = "Fil de discussion déplacé";
 $MigrateForum = "Déplacer le forum";
 $YouWillBeNotified = "Vous serez prévenu";
 $ForumCategories = "Catégories de forums";
+$AttachmentFilesList = "Liste de fichiers joints";
 ?>

+ 2 - 0
main/lang/spanish/forum.inc.php

@@ -147,4 +147,6 @@ $ThreadMoved = "Tema movido";
 $MigrateForum = "Migrar foro";
 $YouWillBeNotified = "Ud. será notificado";
 $ForumCategories = "Categorías de foro";
+$AttachmentFilesList = "Lista de archivos adjuntos";
+$ErrorUploadAttachment = "Hubo un error al subir el archivo";
 ?>

+ 4 - 0
main/lang/spanish/trad4all.inc.php

@@ -1680,4 +1680,8 @@ $DataTableSearch = "Buscar";
 $HideColumn = "Ocultar columna";
 $DisplayColumn = "Mostrar columna";
 $LegalAgreementAccepted = "Condiciones legales aceptadas";
+$FieldTypeMobilePhoneNumber = "Número de móvil"; 
+$CountryDialCode = "Incluya el prefijo de llamada del país";
+$MobilePhoneNumberWrong = "El número de móvil que ha escrito está incompleto o contiene caracteres no válidos.";
+$AreYouSureToDeleteFileX = "¿Está seguro de querer eliminar el archivo %s ?";
 ?>