檔案上傳 AJAX 多檔案 與 建立Zip檔

1 篇文章 / 0 new
author
檔案上傳 AJAX 多檔案 與 建立Zip檔
表單
function example_ajax_mfile_form($form, &$form_state) {
    //初始化
    if (empty($form_state['num_files'])) {
        $form_state['num_files'] = 1;
    }
    if (empty($form_state['uploaded_files'])) {
        $form_state['uploaded_files'] = array();
    }
    $form['file_upload_fieldset'] = array(
        '#type' => 'fieldset',
        '#title' => t('上傳檔案清單'),
        '#prefix' => '<div id="uploaded-files-fieldset-wrapper">',//清單呈現區
        '#suffix' => '</div>',
    );
    //顯示上傳清單 item
    for ($i = 0; $i < $form_state['num_files']; $i++) {
        $key = 'file_upload_' . $i;
        $btnRemove = 'file_upload_remove_' . $i;
        $fieldSet = isset($form_state['uploaded_files']['files']['name'][$key]);
        if ($fieldSet) {
            $fieldValue = $form_state['uploaded_files']['files']['name'][$key];
        } else {
            $fieldValue = FALSE;
        }
        if ( !$fieldSet || ($fieldSet && $fieldValue !== FALSE)) {
            $form['file_upload_fieldset'][$key] = array(
                '#type' => 'file',
                '#prefix' => '<div class="clear-block">',
                '#size' => 22,
                '#theme_wrappers' => array(),
            );
            $form['file_upload_fieldset'][$btnRemove] = array(
                '#type' => 'submit',
                '#name' => $btnRemove,
                '#value' => t('Remove'),
                '#submit' => array('example_ajax_mfile_remove'),
                '#ajax' => array(
                    'callback' => 'example_ajax_mfile_refresh',
                    'wrapper' => 'uploaded-files-fieldset-wrapper',
                ),
                '#suffix' => '</div>',
                '#access' => false,
            );
            //檔案已上傳則替換為檔案名稱
            //if ( $fieldSet && !empty($form_state['uploaded_files']['files']['name'][$key]) ) {
            if ($fieldSet && $fieldValue !== FALSE) {
                $form['file_upload_fieldset'][$key]['#type'] = 'markup';
                $form['file_upload_fieldset'][$key]['#markup'] = t('File: @filename', array('@filename' => $fieldValue));
                $form['file_upload_fieldset'][$btnRemove]['#access'] = true;
            }
        }
    }
    // Add new button.
    $form['add_new'] = array(
        '#type' => 'submit',
        '#value' => t('上傳檔案'),
        '#submit' => array('example_ajax_mfile_add'),
        '#ajax' => array(
            'callback' => 'example_zip_file_refresh',
            'wrapper' => 'uploaded-files-fieldset-wrapper',
        ),
        '#limit_validation_errors' => array(),
    );
    // Submit button.
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('完成'),
    );
    return $form;
}
Button 事件處理
function example_ajax_mfile_remove($form, &$form_state) {
    $file_to_remove_name = str_replace('_remove', '', $form_state['clicked_button']['#name']);//key
    $form_state['uploaded_files']['files']['name'][$file_to_remove_name] = FALSE;
 
    if (!empty($form_state['uploaded_files']['files']['fid'][$file_to_remove_name])) {
        $file = file_load($form_state['uploaded_files']['files']['fid'][$file_to_remove_name]);
        file_delete($file);//移除暫存檔
        $form_state['uploaded_files']['files']['fid'][$file_to_remove_name] = FALSE;
    }
    save_file($form_state);
    $form_state['rebuild'] = TRUE;
}
// 儲存 or 增加上傳item
function example_ajax_mfile_add($form, &$form_state) {
    save_file($form_state);
    $form_state['rebuild'] = TRUE;
}
function save_file(&$form_state) {
    $result = 0;
    if (isset($_FILES['files']['name'])) {
        foreach ($_FILES['files']['name'] as $file_key => $value) {
            if ($value<>'') {
                $file = file_save_upload($file_key);
                $_FILES['files']['fid'][$file_key] = $file->fid;
                if (isset($form_state['num_files'])) $form_state['num_files']++;
                $result = 1;
            }
        }
        if ($result==1)
            $form_state['uploaded_files'] = setFileRecord($form_state['uploaded_files'], $_FILES);
    } else {
        $form_state['num_files']++;
    }
}
function example_ajax_mfile_refresh($form, $form_state) {
    return $form['file_upload_fieldset'];
}
完成所有檔案上傳後處理
function example_ajax_mfile_form_submit($form, &$form_state) {
    save_file($form_state);//處理最後一個已選取但尚未儲存的檔案
    $fileLists = $form_state['uploaded_files'];//所以上傳檔案內容
    //轉移到目標區
    $uploaded_files = array();
    $zip_files = array();
    foreach ($fileLists['files']['name'] as $file_key => $value) {
        if ($fileLists['files']['name'][$file_key] <> FALSE) {
            $file = file_load($fileLists['files']['fid'][$file_key]);
            if ($file = file_move($file, 'public://')) {//複選模式一定先存放在 暫存目錄下
                if ($file->status == 0) {//0: 檔案上傳後初始值為 0, 一般表示為暫時性檔案
                    $file->status = FILE_STATUS_PERMANENT;//1 註記為永久
                    file_save($file);
                    //file_usage_add($file, 'multifiles_example', 'sample_image', 1);//登錄使用紀錄
                }
            }
            $uploaded_files[] = file_uri_target($file->uri);
            $zip_files[] = $file;
        }
    }
    $form_state['uploaded_files'] = array();//完成清除
    drupal_set_message(t('upload file;') . implode(', ', $uploaded_files));
    createZip($zip_files);//建立壓縮檔
}
合併兩個陣列資料,
php array_merge 的函式不適合多維型態
array_merge_recursive($array1, $array2), 也是以遞歸方式合併兩個以上的陣列, 使用內定 array_merge_recursive 所傳入的參數必須全是陣列, 否則會錯誤
function setFileRecord($array1, $array2) {//以遞歸方式合併兩個陣列
    foreach ($array2 as $key => $value) {
        if (array_key_exists($key, $array1) && is_array($value)) {
            $array1[$key] = setFileRecord($array1[$key], $array2[$key]);
        } else {
            $array1[$key] = $value;
        }
    }
    return $array1;
}
建立 Zip 檔, 需啟用 extension=php_zip.dll, 詳細使用說明 http://php.net/manual/en/class.ziparchive.php
function createZip($zip_files) {
    //$archive_uri = 'temporary://download_' . REQUEST_TIME . '.zip'; //需有權限才能下載
    $archive_uri = 'public://download_' . REQUEST_TIME . '.zip';
    $zip = new ZipArchive;
    if ($zip->open(drupal_realpath($archive_uri), ZipArchive::CREATE) === TRUE) {
        foreach ($zip_files as $file) {
            $zip->addFile(drupal_realpath($file->uri), $file->filename);
        }
        $zip->close();
        drupal_set_message(t('ZIP壓縮檔路徑 !link', array('!link' => l(file_create_url($archive_uri), file_create_url($archive_uri)))));
    } else {
        drupal_set_message(t('壓縮檔建立失敗.'), 'error');
    }
}
Free Web Hosting