Codeigniter - не может загружать файлы из нескольких файловых входов - PullRequest
0 голосов
/ 01 марта 2019

У меня есть многошаговая форма, которая имеет много полей ввода, включая несколько файловых входов, и некоторые из них динамически генерируются с помощью JavaScript. В одном разделе формы пользователи могут загружать несколько файлов.Я могу вставить данные формы в базу данных, но не могу загрузить файлы с несколькими документами, которые загружают пользователи. Я использую AJAX для загрузки данных и файлов формы.Это код моего контроллера,

<?php

defined('BASEPATH') or exit('No direct script access allowed');

class Employee extends MY_Controller
{

    public function index()
    {
        $data['title'] = 'employees';
        $this->view('employees/view_employee_view', $data);
    }

    public function save()
    {
        $req = $this->input->post();

            // Some other code here

            // First upload the profile picture
            if (!empty($_FILES['emp_photo']) AND $_FILES["emp_photo"]["error"] == 0) {

                // Upload employee photo
                $emp_photo_data = $this->upload_file(EMP_PHOTOS_FOLDER, 'emp_photo');

                if (array_key_exists('error', $emp_photo_data)) {
                    $this->response(['success'=>false, 'msg' => '<b>File upload failed!Try again</b>', 'data'=> ''], 500);
                    exit();
                }
                else {
                    $employee['emp_photo'] = $emp_photo_data['file_name'];
                }
            }

            $this->db->trans_start();

            $emp_id = $this->Employee_model->save($employee);

            // Save edu details of employee
            $this->add_edu_details($emp_id);

            // Upload employee documents
            $doc_details = $this->upload_emp_docs($emp_id); //<-- Here is the problem

            if (is_string($doc_details)) {
                // it's an error
                $this->response(['success' => false, 'msg' => '<b>Employee documents upload failed!</b>', 'data' => $doc_details]);
                $this->db->trans_rollback(); 
                exit();
            }
            else{
                if ($doc_details === FALSE) {
                    // Error occured - rollback
                    $this->response(['success' => false, 'msg' => '<b>Employee documents upload failed!</b>', 'data' => '']);
                    $this->db->trans_rollback();
                    exit();
                }
            }

    }


    private function upload_emp_docs($emp_id)
    {
        $counts = $this->input->post('emp_docs_count');

        $req = $this->input->post();

        $data = [];
        for ($i = 1; $i <= $counts; $i++) { 

            if (!empty($_FILES['emp_doc_' . $i])) {
                $res = $this->upload_file(EMP_DOCS_FOLDER, 'emp_doc_' . $i, 'pdf');
                $done = move_uploaded_file($_FILES["emp_doc_" . $i]["tmp_name"], EMP_PHOTOS_FOLDER . md5(time()) . '.jpg');
                if (array_key_exists('error', $res)) {
                    return $res['error']; // return error string
                }
                else {
                    $data[$i] = ["emp_id" => $emp_id, 'file_name' => $res["file_name"], 'doc_type'=> $req["emp_doc_type_{$i}"] ];
                }
            }
        }

        if (!empty($data)) {
            $done = $this->Emp_doc_model->save($data);
            return !empty($done) ? TRUE : FALSE;
        }
        else {
            return FALSE;
        }
    }

}

Вот код в MY_Controller.php , который фактически выполняет задачу загрузки

public function upload_file($dir, $input, $allowed_types = 'jpeg|jpg|png')
    {
        $config['upload_path']   = $dir;
        $config['allowed_types'] = !empty($allowed_types) ? $allowed_types : 'jpeg|jpg|png';
        $config['max_size']      = 0;
        $config['max_width']     = 0;
        $config['max_height']    = 0;
        $config['file_name']     = md5(time() . rand(1, 1000));

        $this->load->library('upload', $config);

        if (!$this->upload->do_upload($input)) {
            return array('error' => $this->upload->display_errors());
        } else {
            $data = $this->upload->data();

            // If it is image then resize it to reduce the image file size
            if ($data['is_image']) {
                $this->resize_image($data['full_path']);
            }

            return $data;
        }
    }

В одном разделе пользователь можетвыберите изображение профиля, и я могу загрузить этот файл, используя приведенный выше код, но не могу найти, почему он не работает, когда я пытаюсь загрузить несколько файлов.

Это HTML-код для этого раздела

<div class="col upload-area">
<div class="input-group">
   <a class="btn bg-grey btn-block" id="add-file-group">ADD FILE</a>
</div>
<input type="hidden" id="emp_docs_count" name="emp_docs_count" value="1">
<div class="row clearfix file-upload-group">
   <div class="col-lg-4 col-md-4 col-sm-4 col-xs-6">
      <div class="form-group">
         <div class="form-line">
            <input name="emp_doc_1" type="file" class="form-control">
         </div>
      </div>
   </div>
   <div class="col-lg-4 col-md-4 col-sm-4 col-xs-6">
      <div class="form-group">
         <div class="form-line">
            <select name="emp_doc_type_1" id="emp_doc_type_1" class="form-control show-tick selectpicker" title="Choose one of the following...">
               <option value="<?= OFFER_LETTER ?>"><?= OFFER_LETTER ?></option>
               <option value="<?= APPOINT_LETTER ?>"><?= APPOINT_LETTER ?></option>
               <option value="<?= CONF_LETTER ?>"><?= CONF_LETTER ?></option>
               <option value="<?= APP_LETTER_1 ?>"><?= APP_LETTER_1 ?></option>
               <option value="<?= APP_LETTER_2 ?>"><?= APP_LETTER_2 ?></option>
               <option value="<?= REL_LETTER ?>"><?= REL_LETTER ?></option>
               <option value="<?= EXP_TER_LETTER ?>"><?= EXP_TER_LETTER ?></option>
            </select>
         </div>
      </div>
   </div>
   <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
      <!-- <button type="button" class="btn btn-primary btn-sm  waves-effect"><i class="material-icons">cloud_upload</i></button> -->
      <button type="button" class="btn btn-danger btn-sm  waves-effect remove-me"><i class="material-icons">delete_forever</i></button>
   </div>
</div>

Это код JS для генерации тегов ввода дианмически

$("#add-file-group").click(function() {
    // Dynamically generate the id for upload-group elements
    const count = $(".upload-area").find(".file-upload-group").length + 1;

    const newID = "upload-area-id-" + count;

    const fileUploadGroup = `<div class="row clearfix file-upload-group">
    <div class="col-lg-4 col-md-4 col-sm-4 col-xs-6">
        <div class="form-group">
            <div class="form-line">
                <input type="file" class="form-control" id="file_${count}" name="emp_doc_${count}">
            </div>
        </div>
    </div>
    <div class="col-lg-4 col-md-4 col-sm-4 col-xs-6">
        <div class="form-group">
            <div class="form-line">
            <select name="emp_doc_type_${count}" id="emp_doc_type_${count}" data-size="2" class="form-control show-tick selectpicker" title="Choose one of the following..." tabindex="-98"><option class="bs-title-option" value="">Choose one of the following...</option>
                <option value="OFFER LETTER">OFFER LETTER</option>
                <option value="APPOINTEMENT LETTER">APPOINTEMENT LETTER</option>
                <option value="CONFIRMATION LETTER">CONFIRMATION LETTER</option>
                <option value="APPRAISAL LETTER 1">APPRAISAL LETTER 1</option>
                <option value="APPRAISAL LETTER 2">APPRAISAL LETTER 2</option>
                <option value="RELIVING LETTER">RELIVING LETTER</option>
                <option value="EXPERIENCE / TERMINATION LETTER">EXPERIENCE / TERMINATION LETTER</option>
            </select>
            </div>
        </div>
    </div>
    <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
        <button type="button" class="btn btn-primary btn-sm  waves-effect"><i class="material-icons">cloud_upload</i></button>
        <button type="button" class="btn btn-danger btn-sm  waves-effect remove-me"><i class="material-icons">delete_forever</i></button>

    </div>
</div>`;

    $(".upload-area").append(fileUploadGroup);

    // Increament the doc counter of hidden field
    $('#emp_docs_count').val(count);

    // Refresh the selectpicker to work on this generated element
    $(".selectpicker").selectpicker("refresh");
});

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Я наконец-то решил это, мне просто нужно инициализировать библиотеку загрузки каждый раз, когда я вызываю метод upload_file(), я только что добавил одну строку, и она начинает работать,

public function upload_file($dir, $input, $allowed_types = 'jpeg|jpg|png')
    {
        $config['upload_path']   = $dir;
        $config['allowed_types'] = !empty($allowed_types) ? $allowed_types : 'jpeg|jpg|png';
        $config['max_size']      = 0;
        $config['max_width']     = 0;
        $config['max_height']    = 0;
        $config['file_name']     = md5(time() . rand(1, 1000));

        $this->load->library('upload');

        $this->upload->initialize($config); //<-- this line solved it

        if (!$this->upload->do_upload($input)) {
            return array('error' => $this->upload->display_errors());
        } else {
            $data = $this->upload->data();

            // If it is image then resize it to reduce the image file size
            if ($data['is_image']) {
                $this->resize_image($data['full_path']);
            }

            return $data;
        }
    }
0 голосов
/ 01 марта 2019

Убедитесь, что у вашего ввода формы есть атрибут enctype, равный multipart/form-data, а ваш ввод как файл имеет имя name[] (чтобы создать каждый файл в выбранном массиве) и иметь атрибут multiple.

...