Discuz功能改進-如何在普通上傳中支持多檔上傳

近期因為Flash宣布即將停止支援小弟整個頭疼到快翻過去,
因為Discuz上傳,頭像等等都是透過Flash組件上傳。



剛好來自彼岸網的網友天香老師提供了許多Discuz功能改進上的修正,這邊也經過天香老師的同意轉載,所以在這邊會修正一些文句(這邊天香老師也同意囉~),後續會慢慢將天香老師其他Discuz功能改進文章通通轉過來並調整。

※本人只是翻譯成繁體中文,並修正部分文句讓臺灣這邊Discuz站長可以看更清楚,可能在修正文句上並不完美,請見諒。

※本文經過天香老師同意轉載並修正文句,若要再轉載修正文句,請先經過原作者同意,尊重原作者,原作者保留修改及調整權利。

本文探討如何在Disczu的普通上傳(意旨在不支援Flash或者Flash沒有允許啟用的狀況下)可支援多檔上傳。Discuz這個功能允許多次選擇多個檔案後上傳,但是每次只能選一個檔案然後再上傳,在PHP文檔中有說明多檔上傳的要點參見網頁:http://php.net/manual/zh/features.file-upload.multiple.php 上解釋。

首先先看圖片普通上傳部分範例:
1.點擊工具欄的圖片圖標後, 出現選擇圖片彈跳視窗:
2.點擊選擇按鈕,然後選擇問件可選擇多個檔案:
3.顯示所有選中的檔案&圖片名稱:



4.點擊上傳。



接下來開始介紹要修改的代碼:


1) 需要修改file属性讓普通上傳可以變成多檔選擇 
開啟路徑:template/default/forum/editor_menu_forum.htm
這邊需要修改兩個file元素,一個用於圖片上傳,另一個則是附件上傳
圖片上傳:
行數約在67行:
<input name="Filedata" size="45" class="filedata" type="file">
 
附件上傳:
行數約 254行:
<input type="file" name="Filedata" size="45" class="filedata" />
 
將兩個修改為以下代碼
<input name="Filedata[]" size="45" class="filedata" multiple="multiple" type="file">
 
添加multiple屬性是為了要讓選擇文件框中能夠選擇多個檔案&圖片,
name的修改是PHP的要求使用在服務器上能得上多個上傳文件


2) 選擇完成後要在網頁上顯示所選擇的檔案
 
開啟路徑檔案:static/js/forum_post.js 
這邊要修改addAttach,有兩個地方需要做修改。
首先由於我們上面修改了file元素的name,所以在函數 addAttach需要將下面幾個代碼做調整。
 查找行數約307行
if(tags[i].name == 'Filedata') {
修改成以下 

if(tags[i].name == 'Filedata[]') {
 
其次函數insertAttach適用於在網頁上顯示選擇後的檔案,原來的代碼從file元素的value值中得到選擇的檔案名稱,
但是這種方式得不到多個檔案名稱。在多選的狀況下他還是只含一個檔案名稱,而file的files值是一個數值,
其中每一個元素對應了選擇的檔案。
我們要將這個數值下方的代碼做部分修改。 
 
查找下方代碼約343~366行:
var path = $(prefix + 'attachnew_' + id).value;var extpos = path.lastIndexOf('.');
var ext = extpos == -1 ? '' : path.substr(extpos + 1, path.length).toLowerCase();
var re = new RegExp("(^|\\s|,)" + ext + "($|\\s|,)", "ig");
var localfile = $(prefix + 'attachnew_' + id).value.substr($(prefix + 'attachnew_' + id).value.replace(/\\/g, '/').lastIndexOf('/') + 1);
var filename = mb_cutstr(localfile, 30);
if(path == '') {
    return;}if(extensions != '' && (re.exec(extensions) == null || ext == '')) {
    reAddAttach(prefix, id);
    showError('對不起,此類型擴展名不支持上傳。');
    return;}if(prefix == 'img' && imgexts.indexOf(ext) == -1) {
    reAddAttach(prefix, id);
    showError('請選擇圖片或文件(' + imgexts + ')');
    return;}
 
修改成
 

var files = $(prefix + 'attachnew_' + id).files;if (!files) return;
var filename = '';var localfile = '';for (var i = 0; i < files.length; i++) {
    var path = files[i].name;
    var extpos = path.lastIndexOf('.');
    var ext = extpos == -1 ? '' : path.substr(extpos + 1, path.length).toLowerCase();
    var re = new RegExp("(^|\\s|,)" + ext + "($|\\s|,)", "ig");
    if (extensions != '' && (re.exec(extensions) == null || ext == '')) {
        reAddAttach(prefix, id);
        showError('對不起,此類型擴展名不支持上傳。');
        return;
    }
    if (prefix == 'img' && imgexts.indexOf(ext) == -1) {
        reAddAttach(prefix, id);
        showError('請選擇圖片或文件(' + imgexts + ')');
        return;
    }
    if (i > 0) filename += '; ';
    filename += path;
    if (i > 0) localfile += '; ';
    localfile += path.substr(path.replace(/\\/g, '/').lastIndexOf('/') + 1);}

3)修改當點擊上傳後接收檔案的代碼
由於上面對於客戶端添加了多檔上傳的吃值,在服務器端收到的諸如$_FILES['Filedata']['name'],$_FILES['Filedata']['type']等值不再是字符串,而是成了數組。
數組的長度由上傳檔案的個數決定,其中每個元素紀載了一個文件的相應屬性。
所以我們對php代碼做一些調整,來支持整個保存多個檔案。
這邊需要修改兩個php檔案。

3a) 開啟在source/module/misc/misc_swupload.php
查找約50行
將下方這句代碼修改
$upload = new forum_upload();
 
修改為
if (is_array($_FILES['Filedata']['name'])) {
    $count = count($_FILES['Filedata']['name']);
    $file_keys = array_keys($_FILES['Filedata']);
    for($i=0; $i<$count; $i++) {
        $fd = array();
        foreach ($file_keys as $key) {
            $fd[$key] = $_FILES['Filedata'][$key][$i];
        }
        $upload = new forum_upload(0, $fd);
    }}else {
    $upload = new forum_upload();}exit;
 
3b) 開啟 source/class/forum/forum_upload.php
查找24行,將下方這句修改
function forum_upload($getaid = 0) {
 
修改為以下
function forum_upload($getaid = 0, $filedata) {
 
然後查找約38行
$upload = new discuz_upload();
$upload->init($_FILES['Filedata'], 'forum');
 
修改為
if (empty($filedata)) $filedata = $_FILES['Filedata'];
$upload = new discuz_upload();
$upload->init($filedata, 'forum');
 
最後將uploadmsg最後一句 

exit;
 
改成
if ($statusid) exit;

行數約161行。

補充:
這邊天香老師及我發現這個修改方式並不能說是非常完善。
因為Discuz在服務端只會先上傳後才壓縮,一般來講服務器都會限制檔案大小,會導致普通上傳的時候如果限制約2M,若多檔選擇後選擇超過2M上傳時會出現無法上傳的問題。
而且另外我有發現普通上傳的一個不方便之處,若你上傳之後發送帖子,再回頭編輯圖片是無法編輯以及刪除的,必須在上傳一張圖片&附件才會出現先前上傳的檔案。


出處:彼岸網
作者:天香公主
翻譯及修改部分文句:HF
原網址:點我

留言

  1. 能不能直接把「上傳圖片」改成用「普通上傳」..
    因為Firefox只有顯示「上傳圖片」

    回覆刪除
    回覆
    1. 沒事了…看到你其他地方的文章了~

      刪除

張貼留言

留言時請注意句子內容,若有色情、廣告、引戰等都會刪除唷,請遵守網路規範及保持風度^____^
※基本上您問問題,HF都會盡最快速度來回您(基本上24H內),希望HF的回答及解釋可以替您解決問題。

這個網誌中的熱門文章