3
votes

Here is already two questions about this problem

Zf2 file upload by jQuery File Upload - file was not found

Can't get blueimp / jQuery-File-Upload and ZF2 running

without ansers. And i'm create issue on ZF2 with code examples. github.com/zendframework/zf2/issues/6291

And also have request from another developer on my email with question, how to implement jQuery File Upload with ZF2.

github.com/blueimp/jQuery-File-Upload

So, there is real problem for many peple, and no any manuals, no answers. Please, before send me to read documentation, notice, that i'm spend many hours on problem and already read all documentation and not only i'm have this problem.

Please, write manual with code examples, like How to implement it. Or just answer, why we have this error and how to resolve it?

There i'm copy my example from ZF2 issue.

I'm try use jQuery-File-Upload Just copy standard tpl, include css and scrypts and it's work, send files to my controller. But controller doesn't work.

Here is my code

public function processjqueryAction()
    {
        $request   = $this->getRequest();
        $response  = $this->getResponse();
        $jsonModel = new \Zend\View\Model\JsonModel();

        if ($request->isPost()) {

            try {
                $datas          = [];
                $datas['files'] = [];
                $uploadPath     = $this->getFileUploadLocation();
                $uploadFiles    = $this->params()->fromFiles('files');

//                throw new \Exception(json_encode("FILES " . serialize($_FILES)));

                // Сохранение выгруженного файла
                $adapter = new \Zend\File\Transfer\Adapter\Http();
                $adapter->setDestination($uploadPath);
                $adapter->setValidators(array(
                    new \Zend\Validator\File\Extension(array(
                        'extension' => array('jpg', 'jpeg', 'png', 'rtf')
                            )
                    ),
//                    new \Zend\Validator\File\Upload()
                ));

                if (!$adapter->isValid()) {
                    throw new \Exception(json_encode("!isValid " . implode(" ", $adapter->getMessages())));
                }

                $files = $adapter->getFileInfo();
//                throw new \Exception(json_encode($files));

                foreach ($files as $file => $info) {
//                    throw new \Exception(json_encode($info));

                    $name = $adapter->getFileName($file);

                    // file uploaded & is valid
                    if (!$adapter->isUploaded($file)) {
                        throw new \Exception(json_encode("!isUploaded") . implode(" ", $adapter->getMessages()));
                        continue;
                    }

                    if (!$adapter->isValid($file)) {
                        throw new \Exception(json_encode("!isValid " . implode(" ", $adapter->getMessages())));
                        continue;
                    }

                    // receive the files into the user directory
                    $check = $adapter->receive($file); // this has to be on top

                    if (!$check) {
                        throw new \Exception(json_encode("! receive" . implode(" ", $adapter->getMessages())));
                    }

                    /**
                     * "name": "picture1.jpg",
                      "size": 902604,
                      "url": "http:\/\/example.org\/files\/picture1.jpg",
                      "thumbnailUrl": "http:\/\/example.org\/files\/thumbnail\/picture1.jpg",
                      "deleteUrl": "http:\/\/example.org\/files\/picture1.jpg",
                      "deleteType": "DELETE"
                     */
                    $fileclass             = new stdClass();
                    // we stripped out the image thumbnail for our purpose, primarily for security reasons
                    // you could add it back in here.
                    $fileclass->name       = $name;
                    $fileclass->size       = $adapter->getFileSize($name);
                    $fileclass->type       = $adapter->getMimeType($name);
                    $fileclass->deleteUrl  = '/uploads/delete';
                    $fileclass->deleteType = 'DELETE';
                    //$fileclass->error = 'null';
                    $fileclass->url        = '/';

                    $datas['files'][] = $fileclass;
                }

                $response->getHeaders()->addHeaders(array(
                    'Pragma'        => 'no-cache',
                    'Cache-Control' => 'private, no-cache',
                    "Content-Type"  => 'application/json'
                ));

//                return $response->setContent(json_encode(array('files' => $files)));
                return $response->setContent(json_encode($datas));
            } catch (\Exception $e) {

                return $response->setContent(json_encode($e->getMessage()));
            }
        }

        return $jsonModel;

}

Sorry for debug code, but with it you can see, i'm try hard to make it work, over 3 hours.

Error is "File 'CIMG0042.JPG' was not found"

When i'm call $adapter->isValid() Or when call it with file name, same error. Path, where files uploaded, is correct and writable. $_FILES array is exist and valid.

Here is $_FILES json

FILES a:1:{s:5:\"files\";a:5:{s:4:\"name\";a:1:{i:0;s:28:\"52876065d17dce0a7472e5d6.jpg\";}s:4:\"type\";a:1:{i:0;s:10:\"image\/jpeg\";}s:8:\"tmp_name\";a:1:{i:0;s:14:\"\/tmp\/phpmfT2mB\";}s:5:\"error\";a:1:{i:0;i:0;}s:4:\"size\";a:1:{i:0;i:82640;}}}

And result of $files = $adapter->getFileInfo();

"{"files_0_":{"name":"52876065d17dce0a7472e5d6.jpg","type":"image\/jpeg","tmp_name":"\/tmp\/phpF6VoO9","error":0,"size":"82640","options":{"ignoreNoFile":false,"useByteString":true,"magicFile":null,"detectInfos":true},"validated":false,"received":false,"filtered":false,"validators":["Zend\\Validator\\File\\Upload","Zend\\Validator\\File\\Extension"],"destination":"\/home\/seyfer\/www\/zend2-tutorial.me\/module\/Users\/config\/..\/..\/..\/data\/uploads"}}"

isUploaded passes, but isValid not.

What i'm doing wrong?

Documentation say this

Zend_File_Transfer has been deprecated in favor of using the standard ZF2 Zend\Form and Zend\InputFilter features.

Maybe it's mean, that Form need to be used for file uploading in any way?

UPD 25.05.14

Now i'm add form

class UploadJqueryForm extends BaseForm
{

    public function __construct()
    {
        parent::__construct(__CLASS__);
        $this->setAttribute('method', 'post');
        $this->setAttribute('enctype', 'multipart/form-data');

        $this->init();
    }

    public function init()
    {
        $fileupload = new Element\File('files');
        $fileupload->setLabel("files");
        $fileupload->setAttribute('multiple', 'multiple');
        $this->add($fileupload);

        $button = new Element\Button('start');
        $button->setAttribute("type", 'submit');
        $button->setValue("Start upload")->setLabel("Start upload");
        $this->add($button);

        $button = new Element\Button('cancel');
        $button->setAttribute("type", 'reset');
        $button->setValue("Cancel upload")->setLabel("Cancel upload");
        $this->add($button);

        $button = new Element\Button('delete');
        $button->setAttribute("type", 'button');
        $button->setValue("Delete")->setLabel("Delete");
        $this->add($button);

        $checkbox = new Element\Checkbox('toggle');
        $checkbox->setValue("Toggle")->setLabel("Toggle");
        $checkbox->setAttribute("required", "");
        $this->add($checkbox);
    }

}

Use it

public function processjqueryAction()
    {
        $form      = new \Users\Form\UploadJqueryForm();
        $request   = $this->getRequest();
        $response  = $this->getResponse();
        $jsonModel = new \Zend\View\Model\JsonModel();

        try {

            if ($request->isPost()) {

                $data = array_merge_recursive(
                        $this->getRequest()->getPost()->toArray(), $this->getRequest()->getFiles()->toArray()
                );

//                throw new \Exception(json_encode("data " . serialize($data)));

                $form->setData($data);
                if ($form->isValid()) {
                    $datas          = [];
                    $datas['files'] = [];
                    $uploadPath     = $this->getFileUploadLocation();
//                $uploadFiles    = $this->params()->fromFiles('files');
//                throw new \Exception(json_encode("FILES " . serialize($_FILES)));
                    // Сохранение выгруженного файла
                    $adapter        = new \Zend\File\Transfer\Adapter\Http();
                    $adapter->setDestination($uploadPath);
                    $adapter->setValidators(array(
                        new \Zend\Validator\File\Extension(array(
                            'extension' => array('jpg', 'jpeg', 'png', 'rtf')
                                )
                        ),
                    ));

                    if (!$adapter->isValid()) {
                        throw new \Exception(json_encode("!isValid " . implode(" ", $adapter->getMessages())));
                    }

                    $files = $adapter->getFileInfo();
//                throw new \Exception(json_encode($files));

                    foreach ($files as $file => $info) {
//                    throw new \Exception(json_encode($info));

                        $name = $adapter->getFileName($file);

                        // file uploaded & is valid
                        if (!$adapter->isUploaded($file)) {
                            throw new \Exception(json_encode("!isUploaded") . implode(" ", $adapter->getMessages()));
                            continue;
                        }

                        if (!$adapter->isValid($file)) {
                            throw new \Exception(json_encode("!isValid " . implode(" ", $adapter->getMessages())));
                            continue;
                        }

                        // receive the files into the user directory
                        $check = $adapter->receive($file); // this has to be on top

                        if (!$check) {
                            throw new \Exception(json_encode("! receive" . implode(" ", $adapter->getMessages())));
                        }

                        /**
                         * "name": "picture1.jpg",
                          "size": 902604,
                          "url": "http:\/\/example.org\/files\/picture1.jpg",
                          "thumbnailUrl": "http:\/\/example.org\/files\/thumbnail\/picture1.jpg",
                          "deleteUrl": "http:\/\/example.org\/files\/picture1.jpg",
                          "deleteType": "DELETE"
                         */
                        $fileclass             = new stdClass();
                        // we stripped out the image thumbnail for our purpose, primarily for security reasons
                        // you could add it back in here.
                        $fileclass->name       = $name;
                        $fileclass->size       = $adapter->getFileSize($name);
                        $fileclass->type       = $adapter->getMimeType($name);
                        $fileclass->deleteUrl  = '/uploads/delete';
                        $fileclass->deleteType = 'DELETE';
                        //$fileclass->error = 'null';
                        $fileclass->url        = '/';

                        $datas['files'][] = $fileclass;
                    }

                    $response->getHeaders()->addHeaders(array(
                        'Pragma'        => 'no-cache',
                        'Cache-Control' => 'private, no-cache',
                        "Content-Type"  => 'application/json'
                    ));

                    return $response->setContent(json_encode($datas));
                } else {
                    throw new \Exception(json_encode("!isValid form" . serialize($form->getMessages())));
                }
            }
        } catch (\Exception $e) {

            return $response->setContent(json_encode($e->getMessage()));
        }

        return $jsonModel;

And still get error File '24866-fu-blyad-otvratitelno.jpg' was not found

Also I tried with InputFilter

class UploadJqueryFilter extends InputFilter implements
InputFilterAwareInterface
{

    public function __construct()
    {
        $this->getInputFilter();
    }

    public function getInputFilter()
    {
        $toggle = new Input('toggle');
        $toggle->setRequired(FALSE);
        $this->add($toggle);

        $files = new \Zend\InputFilter\FileInput('files');
        $files->setRequired(TRUE);
        $files->getValidatorChain()->attach(new Validator\File\UploadFile);
        $files->getFilterChain()->attach(new \Zend\Filter\File\RenameUpload(array(
            'target'    => __DIR__ . '/../../../../../../tmpuploads/tmp',
            'randomize' => true,
        )));
        $this->add($files);

        return $this;
    }

    public function setInputFilter(InputFilterInterface $inputFilter)
    {
        return false;
    }

}

And have same error.

1

1 Answers

4
votes

I had this problem too. Wasting several hours before found the problem. Turn out it's because the name attribute for input tag cannot be set as 'files'.

So this is a no:

<input id="files" type="file" name="files" data-url="/upload-action" />

Changing the name attribute to any string other than files such as file will solve this problem.

<input id="files" type="file" name="file" data-url="/upload-action" />

I see from $_FILES that you had set name as files. Try changing that. Make sure you update the reference you made in your controller too.