RSS-подписка

RSS-лента

Новые статьи

Последние комментарии


Получать обновления на эл. почту

Ваш e-mail:

Рассылка новостей от Loco

Загрузка файлов (картинок) по ajax через форму для Opencart

Загрузка файлов (картинок) по ajax через форму для Opencart Файлы или картинки при загрузке их через форму не передаются через "POST". То есть их не получается обработать PHP на сервере так, как это делаем с другими полями. Переменные для полей типа file остаются пустыми. Поэтому их нужно передавать специальным образом.

Посмотрим как на примере добавления отзывов о магазине в Opencart. Добавим поле загрузки файлов. И сделаем так, чтобы файл картинки загружался в папку на сервере, а в базе данных прописывалось имя файла с путём к нему.

Вот наша форма такая

<h2 id="review-title"><?php echo $text_write; ?></h2>
  <div class="content">
      <form name="uploader" enctype="multipart/form-data" method="post">
    <b><?php echo $entry_name; ?></b><br />
    <input type="text" name="name" value="" />
    <br />
    <br />
    <b><?php echo $entry_otzyv; ?></b>
    <textarea name="text" cols="40" rows="8" style="width: 98%;"></textarea>
    <span style="font-size: 11px;"><?php echo $text_note; ?></span><br /><br />
    <b><?php echo $entry_image; ?></b><br />
    <input type="hidden" name="MAX_FILE_SIZE" value="300000" />
    <input type="file" name="image" onchange="tstFile(this)" /><br />
    <br />
    <b><?php echo $entry_rating; ?></b> <span><?php echo $entry_bad; ?></span>&nbsp;
    <input type="radio" name="rating" value="1" />
    &nbsp;
    <input type="radio" name="rating" value="2" />
    &nbsp;
    <input type="radio" name="rating" value="3" />
    &nbsp;
    <input type="radio" name="rating" value="4" />
    &nbsp;
    <input type="radio" name="rating" value="5" />
    &nbsp; <span><?php echo $entry_good; ?></span><br />
    <br />
    <b><?php echo $entry_captcha; ?></b><br />
    <input type="text" name="captcha" value="" />
    <br />
    <img src="index.php?route=information/otzyv/captcha" alt="" id="captcha" /><br />
    <br /><br />
        <input type="submit" name="upload" value="Отправить" />    
      <!--<div class="left"><a id="button-review" class="button"><span><?//php echo $button_send; ?></span></a></div>-->
    </form>
  </div>

ниже в этом же файле представления скрипты пишем

<script type="text/javascript"><!--
...

function tstFile(val){
      var v = val.value;
      var v = v.search(/^.*\.(?:jpg|jpeg)\s*$/ig)
      $('.success, .warning').remove();
      if(v!=0){
        $('#review-title').after('<div class="warning">"Неправильный формат файла"</div>');
      }
      if(document.uploader.image.files[0].size > 300*1024) {
         $('#review-title').after('<div class="warning">"Очень большой файл картинки. Разрешенный размер не больше 300кб"</div>');
      }
    }

$("form[name='uploader']").submit(function(e) {
        var formData = new FormData($(this)[0]);
        //var imagesize = document.uploader.image.files[0].size;

        $.ajax({
            url: "index.php?route=information/otzyv/write",
            type: "POST",
            dataType: 'json', // чтобы сообщение об успехе или ошибке показывалось после отправки формы
            data: formData,
            async: false,
            beforeSend: function() {
                $('.success, .warning').remove();
                $("input[name='upload']").attr('disabled', true);
                $('#review-title').after('<div class="attention"><img src="catalog/view/theme/default/image/loading.gif" alt="" /> <?php echo $text_wait; ?></div>');
               
            },
            complete: function() {
                $("input[name='upload']").attr('disabled', false);
                $('.attention').remove();
            },
            success: function(data) {
                //alert(data)
                if (data.error) {
                    $('#review-title').after('<div class="warning">' + data.error + '</div>');
                }
               
                if (data.success) {
                    $('#review-title').after('<div class="success">' + data.success + '</div>');
                                   
                    $('input[name=\'name\']').val('');
                    $('textarea[name=\'text\']').val('');
                    $('input[name=\'image\']').val('');
                    $('input[name=\'rating\']:checked').attr('checked', '');
                    $('input[name=\'captcha\']').val('');
                   
                    $("form[name='uploader']").remove();
                }
            },
            cache: false,
            contentType: false,
            processData: false
        });

        e.preventDefault();
    });

//--></script>

 

Основная идея в том, что используем FormData для передачи всех данных формы.

Это мы сделали ajax часть. Теперь посмотрим, как обрабатываем данные на сервере. В контроллере вот что у нас. Когда мы отправили данные через FormData, то теперь доступна наша картинка из формы в глобальной переменной $_FILES.

$_FILES['image']. По идее в Opencart это то же, что и $this->files['image'], но у меня не работает, может что где не так пишу. Оставил в виде $_FILES

public function write() {
        $this->language->load('information/otzyv');
       
        $this->load->model('catalog/otzyv');
       
        $json = array();
       
        if ((utf8_strlen($this->request->post['name']) < 3) || (utf8_strlen($this->request->post['name']) > 25)) {
            $json['error'] = $this->language->get('error_name');
        }
       
        if ((utf8_strlen($this->request->post['text']) < 25) || (utf8_strlen($this->request->post['text']) > 1000)) {
            $json['error'] = $this->language->get('error_text');
        }

        if (!isset($this->request->post['rating'])) {
            $json['error'] = $this->language->get('error_rating');
        }

        if (!isset($this->session->data['captcha']) || ($this->session->data['captcha'] != $this->request->post['captcha'])) {
            $json['error'] = $this->language->get('error_captcha');
        }
       
        //if(($_FILES['image']['size']) > 500) {
        //        $json['error'] = $this->language->get('error_filesize');
        //    }
           
       
       
       
               
        if (($this->request->server['REQUEST_METHOD'] == 'POST') && !isset($json['error'])) {
           
            $extensions = array('jpeg', 'jpg', 'png', 'gif');
            $max_size = 300000;
            $path = DIR_IMAGE."data/otzyv_images/";
            $response = '';
            if ($_FILES['image'] != '')
            {
              if ($_FILES['image']['size'] > $max_size)
              {
                $response = 'File is too large';
              }
              else
              {
                $ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION));
                if (in_array($ext, $extensions))
                {
                  $newname = uniqid() . '.' . $ext;
                  $path = $path . $newname;

                  if (move_uploaded_file($_FILES['image']['tmp_name'], $path))
                  {
                    $response = "<img style='height: 100px' src='$path' />";
                    $this->request->post['image'] = "data/otzyv_images/".$newname; // так как через post не передается файл по ajax, прописываем его сами из переменной $_FILES
                  }
                }
                else
                {
                  $response = 'File must be an image!';
                }
              }
            }
           
           
            $this->model_catalog_otzyv->addOtzyv($this->request->post);
            $this->model_catalog_otzyv->sendNotification($this->request->post);
           
            $json['success'] = $this->language->get('text_success');
        }
       
        $this->response->setOutput(json_encode($json));
    }

addOtzyv - это функция в модели, она прописывает в базу данных.

public function addOtzyv($data) {
       
        $this->db->query("INSERT INTO " . DB_PREFIX . "otzyv SET author = '" . $this->db->escape($data['name']) . "', customer_id = '" . (int)$this->customer->getId() . "', text = '" . $this->db->escape(strip_tags($data['text'])) . "', rating = '" . (int)$data['rating'] . "', date_added = NOW()");
    
        $review_id = $this->db->getLastId();
       
        if (isset($data['image'])) {
            $this->db->query("UPDATE " . DB_PREFIX . "otzyv SET image = '" . $this->db->escape($data['image']) . "' WHERE review_id = '" . (int)$review_id . "'");
        }
    
    }

Я просто принцип передал. Самая важная часть - как по javascript передавать данные из формы, если на ней есть поле для загрузки файла.

 

Источник: loco.ru

almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

Вы можете почитать все статьи от almix'а.



Другие статьи по этой теме:

Комментарии (0)     Подпишитесь на RSS комментариев к этой статье.