Как добавить валидатор File\MimeType в объявление модели Zend Framework 2

На самом деле я разрабатываю простой загрузчик файлов.

В файле ImageUploader.php я определяю функцию getInputFilter, все работает, если я не попытаюсь добавить валидатор File\MimeType:

<?php

namespace Admin\Model;

use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;

use Zend\Validator\File\MimeType; //tried also with use Zend\Validator\File;

[...]
public function getInputFilter()
{
    [...]
    $inputFilter->add($factory->createInput(array(
       'name'     => 'image',
       'required' => true,
       'validators' => array(
            array(
                'name'    => 'MimeType', //tried also with File\MimeType
                'options' => array(
                   'mimeType' => array('image/jpeg'),
                ),
            ),
        ),
    )));
    [...]
}

Как правильно определить File\Validator\MimeType?

Заранее спасибо.


person DreaMin    schedule 06.12.2012    source источник
comment
Я могу ошибаться, но я думаю, что до того, как File-Module для ZF 2.1 не будет закончен, фильтр MimeType не будет найден :S   -  person Sam    schedule 07.12.2012


Ответы (2)


Вот пример из моего проекта с парой других полезных функций (например, переименование):

use Zend\File\Transfer\Adapter\Http,
    Zend\Validator\File\Size,
    Zend\Validator\File\IsImage;

[...]
public function editAction() {    
[...]
  if ($request->isPost()) {
    $params = $this->params()->fromPost();
    $files = $this->params()->fromFiles();

    $images = array();
    if(!empty($files['main_image']['name'])) $images['main_image'] = $files['main_image']['name'];
    if(!empty($files['detailed_image']['name'])) $images['detailed_image'] = $files['detailed_image']['name'];

    if(!empty($images)) {
      $adapter = new Http();
      $size = new Size(array('max'=>1000000));
      $is_image = new IsImage();
      $image_errors = array();
      foreach ($images as $field => $filename) {
        $adapter->setValidators(array($size,$is_image), $filename);
        if (!$adapter->isValid($filename)) {
          $adapter_errors = $adapter->getMessages();
          $errors = array();
          foreach($adapter_errors as $key=>$row) {
            $errors[] = $row;
          }
          if(!empty($errors)) {
            array_push($image_errors, $errors);
            $form->setMessages(array($field => $errors));
          }
        } else {
          $adapter->setDestination(IMAGES_PATH);
          $fileinfo = $adapter->getFileInfo();
          preg_match('/.+\/(.+)/', $fileinfo[$field]['type'], $matches);
          $extension = $matches[1];
          $old_filename = $item->__get($field);
          $new_filename = $item->id.'_'.$field.'.'.$extension;

          $adapter->addFilter('File\Rename',
            array(
              'target' => IMAGES_PATH.$new_filename,
              'overwrite' => true,
            )
          );

          if($adapter->receive($fileinfo[$field]['name'])) {
            if(!empty($old_filename) && $old_filename != $new_filename &&
              file_exists(IMAGES_PATH.$old_filename)) {
              unlink(IMAGES_PATH.$old_filename);
            }
            $params[$field] = $new_filename;
          }
        } 
      }
    }
  }
[...]
}
[...]

Однако код можно реорганизовать, чтобы перенести логику в какую-либо библиотеку или модель.

person trushkevich    schedule 10.12.2012
comment
Это хорошее решение, но почему я не могу сделать то же самое в модели? Возможно, передать $post=$request->getPost(); - person DreaMin; 13.12.2012
comment
Да, извините, я недостаточно ясно выразился. Я просто имел в виду, что стандартный способ $factory->createInput() не поддерживается для этого валидатора. Конечно, вы можете переместить логику в свою модель, если хотите (вам также нужно будет передать $form, установить сообщения об ошибках, если они есть, а затем вернуть их). Но я думаю, что лучше создать какой-нибудь вспомогательный класс и поместить туда эту логику вместо некой Модели. - person trushkevich; 15.12.2012

Не уверен, какую версию вы используете сейчас, но с Zendframework 2.4 теперь вы можете это сделать. Надеюсь это поможет.

public function getInputFilter()
{
    if (!$this->inputFilter) {
        $inputFilter = new InputFilter();

        $inputFilter->add(array(
            'name'     => 'fileupload',
            'required' => true,
            'allow_empty' => false,
            'filters'  => array(
                array('name' => 'StripTags'),
                array('name' => 'StringTrim'),
            ),
            'validators' => array(
                array(
                    'name' => 'Zend\Validator\File\UploadFile',
                    'name' => 'Zend\Validator\File\MimeType',
                        'options' => array(
                            'mimeType' => 'audio, video, image',
                        ),
                    ),
                ),
        ));

        $this->inputFilter = $inputFilter;
    }

    return $this->inputFilter;
 }
person HotRod    schedule 24.07.2015