Файл загружается в папку в зависимости от имени файла и расширения. Jquery / Blueimp - плагин - PullRequest
0 голосов
/ 10 ноября 2011

Я прошу всех вас помочь мне. Я работаю в Zend Framework и мне нужно настроить свой код так, когда пользователь удаляет файл в браузере (перед фактической загрузкой), имя файла и расширение проверяются в том смысле, если он уже существует. В зависимости от наличия ИФЛ, появится значок справа от значка корзины (зеленая галочка, если новая загрузка, других файлов с тем же именем нет. Красный крестик, если есть файл).

Но для решения более важного для меня вопроса, который заключается в том, чтобы я настраивал код таким образом, чтобы при загрузке в зависимости от имени файла и расширения файла файл загружался в определенную папку. Так, например X.png попадает в папку «png» - подпапка «X», а Y.pdf попадает в папку «pdf» - подпапка «Y»

Вот мой код, далеко ...

Это application.js и jquery.fileupload-ui.js. (JavaScript) http://pastebin.com/eqpK1KmX

Это index.phtml и макет index.phtml (просмотр) http://pastebin.com/mh5jnLju

InterfaceController.php (контроллер):

<?php
class Design_InterfaceController extends Zend_Controller_Action
{
    public function init()
    {
        $this->_helper->layout()->setLayout('media');
        set_include_path(implode(PATH_SEPARATOR, array(
        realpath(APPLICATION_PATH . '/modules/design/models'),
        realpath(APPLICATION_PATH . '/models'),
        realpath(APPLICATION_PATH . '/../library'),
        get_include_path(),
        )));
    }

    public function indexAction()
    { 

    }

    public function mediaAction()
    {
    $this->_helper->layout()->setLayout('media');

    }

    public function checkFile(){



        //isn't doing anything at all, just my start of thinking in a way of
            //sloving this


    }

    function uploadjqAction()
    { 
    $this->_helper->layout()->setLayout('media');
            Zend_Loader::loadClass('Upload',
                                    array(
                                        APPLICATION_PATH.'/modules/design/models/vendors'
                                    )
            );


        $upload_handler = new Upload();

        header('Pragma: no-cache');
        header('Cache-Control: private, no-cache');
        header('Content-Disposition: inline; filename="files.json"');
        header('X-Content-Type-Options: nosniff');

        switch ($_SERVER['REQUEST_METHOD']) {
            case 'HEAD':
            case 'GET':
                $upload_handler->get();
                break;
            case 'POST':
                $upload_handler->post();
                break;
            case 'DELETE':
                $upload_handler->delete();
                break;
            case 'OPTIONS':
                break;
            default:
                header('HTTP/1.0 405 Method Not Allowed');
        }
        exit;

    }






}

Это файл upload.php (действующий как модель):

<?php
/*
 * Copyright 2010, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * http://creativecommons.org/licenses/MIT/
 */

error_reporting(E_ALL | E_STRICT);

class Upload
{
    /*  public function uploadAction() {
        ini_set("max_execution_time", 10000);
        $this->_helper->layout->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);
            if (!empty($_FILES)) {
            $tempFile = $_FILES['Filedata']['tmp_name'];
            $targetPath = STORAGE_PATH.'/books/' . $_POST['bookid'] . '/' . $_POST['folder'];
            $targetFile =  str_replace('//','/',$targetPath) . "/".$_POST['name'].".".$_POST['ext'];
            if (!file_exists(str_replace('//','/',$targetPath))) mkdir(str_replace('//','/',$targetPath), 0755, true);
            $result = move_uploaded_file($tempFile,$targetFile);
            echo ($result)?"Success":"Fail";
        }
    }
 */
    private $options;

    function __construct($options=null) {
        $this->options = array(
            'script_url' => $_SERVER['PHP_SELF'],
            'upload_dir' => dirname(__FILE__).'/vendors/files/',
            'upload_url' => dirname($_SERVER['PHP_SELF']).'/vendors/files/',
            'param_name' => 'files',
            // The php.ini settings upload_max_filesize and post_max_size
            // take precedence over the following max_file_size setting:
            'max_file_size' => 10000000,
            'min_file_size' => 1,
            'accept_file_types' =>'/(\.|\/)(gif|jpeg|jpg|png|pdf)$/i',
            'max_number_of_files' => null,
            'discard_aborted_uploads' => true,
            'image_versions' => array(
                'thumbnail' => array(
                    'upload_dir' => dirname(__FILE__).'/vendors/thumbnails/',
                    'upload_url' => dirname($_SERVER['PHP_SELF']).'/vendors/thumbnails/',
                    'max_width' => 80,
                    'max_height' => 150
                )
            )
        );
        if ($options) {
            $this->options = array_replace_recursive($this->options, $options);
        }
    }

    private function get_file_object($file_name) {
        $file_path = $this->options['upload_dir'].$file_name;
        if (is_file($file_path) && $file_name[0] !== '.') {
            $file = new stdClass();
            $file->name = $file_name;
            $file->size = filesize($file_path);
            $file->url = $this->options['upload_url'].rawurlencode($file->name);
            foreach($this->options['image_versions'] as $version => $options) {
                if (is_file($options['upload_dir'].$file_name)) {
                    $file->{$version.'_url'} = $options['upload_url']
                        .rawurlencode($file->name);
                }
            }
            $file->delete_url = $this->options['script_url']
                .'?file='.rawurlencode($file->name);
            $file->delete_type = 'DELETE';
            return $file;
        }
        return null;
    }

    private function get_file_objects() {
        return array_values(array_filter(array_map(
            array($this, 'get_file_object'),
            scandir($this->options['upload_dir'])
        )));
    }

    private function create_scaled_image($file_name, $options) {
        $file_path = $this->options['upload_dir'].$file_name;
        $new_file_path = $options['upload_dir'].$file_name;
        list($img_width, $img_height) = @getimagesize($file_path);
        if (!$img_width || !$img_height) {
            return false;
        }
        $scale = min(
            $options['max_width'] / $img_width,
            $options['max_height'] / $img_height
        );
        if ($scale > 1) {
            $scale = 1;
        }
        $new_width = $img_width * $scale;
        $new_height = $img_height * $scale;
        $new_img = @imagecreatetruecolor($new_width, $new_height);
        switch (strtolower(substr(strrchr($file_name, '.'), 1))) {
            case 'jpg':
            case 'jpeg':
                $src_img = @imagecreatefromjpeg($file_path);
                $write_image = 'imagejpeg';
                break;
            case 'gif':
                @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
                $src_img = @imagecreatefromgif($file_path);
                $write_image = 'imagegif';
                break;
            case 'png':
                @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
                @imagealphablending($new_img, false);
                @imagesavealpha($new_img, true);
                $src_img = @imagecreatefrompng($file_path);
                $write_image = 'imagepng';
                break;
            default:
                $src_img = $image_method = null;
        }
        $success = $src_img && @imagecopyresampled(
            $new_img,
            $src_img,
            0, 0, 0, 0,
            $new_width,
            $new_height,
            $img_width,
            $img_height
        ) && $write_image($new_img, $new_file_path);
        // Free up memory (imagedestroy does not delete files):
        @imagedestroy($src_img);
        @imagedestroy($new_img);
        return $success;
    }

    private function has_error($uploaded_file, $file, $error) {
        if ($error) {
            return $error;
        }
        if (!preg_match($this->options['accept_file_types'], $file->name)) {
            return 'acceptFileTypes';
        }
        if ($uploaded_file && is_uploaded_file($uploaded_file)) {
            $file_size = filesize($uploaded_file);
        } else {
            $file_size = $_SERVER['CONTENT_LENGTH'];
        }
        if ($this->options['max_file_size'] && (
                $file_size > $this->options['max_file_size'] ||
                $file->size > $this->options['max_file_size'])
            ) {
            return 'maxFileSize';
        }
        if ($this->options['min_file_size'] &&
            $file_size < $this->options['min_file_size']) {
            return 'minFileSize';
        }
        if (is_int($this->options['max_number_of_files']) && (
                count($this->get_file_objects()) >= $this->options['max_number_of_files'])
            ) {
            return 'maxNumberOfFiles';
        }
        return $error;
    }

    private function handle_file_upload($uploaded_file, $name, $size, $type, $error) {
        $file = new stdClass();
        // Remove path information and dots around the filename, to prevent uploading
        // into different directories or replacing hidden system files.
        // Also remove control characters and spaces (\x00..\x20) around the filename:
        $file->name = trim(basename(stripslashes($name)), ".\x00..\x20");
        $file->size = intval($size);
        $file->type = $type;
        $error = $this->has_error($uploaded_file, $file, $error);
        if (!$error && $file->name) {
            $file_path = $this->options['upload_dir'].$file->name;
            $append_file = !$this->options['discard_aborted_uploads'] &&
                is_file($file_path) && $file->size > filesize($file_path);
            clearstatcache();
            if ($uploaded_file && is_uploaded_file($uploaded_file)) {
                // multipart/formdata uploads (POST method uploads)
                if ($append_file) {
                    file_put_contents(
                        $file_path,
                        fopen($uploaded_file, 'r'),
                        FILE_APPEND
                    );
                } else {
                    move_uploaded_file($uploaded_file, $file_path);
                }
            } else {
                // Non-multipart uploads (PUT method support)
                file_put_contents(
                    $file_path,
                    fopen('php://input', 'r'),
                    $append_file ? FILE_APPEND : 0
                );
            }
            $file_size = filesize($file_path);
            if ($file_size === $file->size) {
                $file->url = $this->options['upload_url'].rawurlencode($file->name);
                foreach($this->options['image_versions'] as $version => $options) {
                    if ($this->create_scaled_image($file->name, $options)) {
                        $file->{$version.'_url'} = $options['upload_url']
                            .rawurlencode($file->name);
                    }
                }
            } else if ($this->options['discard_aborted_uploads']) {
                unlink($file_path);
                $file->error = 'abort';
            }
            $file->size = $file_size;
            $file->delete_url = $this->options['script_url']
                .'?file='.rawurlencode($file->name);
            $file->delete_type = 'DELETE';
        } else {
            $file->error = $error;
        }
        return $file;
    }

    public function get() {
        $file_name = isset($_REQUEST['file']) ?
            basename(stripslashes($_REQUEST['file'])) : null; 
        if ($file_name) {
            $info = $this->get_file_object($file_name);
        } else {
            $info = $this->get_file_objects();
        }
        header('Content-type: application/json');
        echo json_encode($info);
    }

    public function post() {
        $upload = isset($_FILES[$this->options['param_name']]) ?
            $_FILES[$this->options['param_name']] : array(
                'tmp_name' => null,
                'name' => null,
                'size' => null,
                'type' => null,
                'error' => null
            );
        $info = array();
        if (is_array($upload['tmp_name'])) {
            foreach ($upload['tmp_name'] as $index => $value) {
                $info[] = $this->handle_file_upload(
                    $upload['tmp_name'][$index],
                    isset($_SERVER['HTTP_X_FILE_NAME']) ?
                        $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'][$index],
                    isset($_SERVER['HTTP_X_FILE_SIZE']) ?
                        $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'][$index],
                    isset($_SERVER['HTTP_X_FILE_TYPE']) ?
                        $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'][$index],
                    $upload['error'][$index]
                );
            }
        } else {
            $info[] = $this->handle_file_upload(
                $upload['tmp_name'],
                isset($_SERVER['HTTP_X_FILE_NAME']) ?
                    $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'],
                isset($_SERVER['HTTP_X_FILE_SIZE']) ?
                    $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'],
                isset($_SERVER['HTTP_X_FILE_TYPE']) ?
                    $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'],
                $upload['error']
            );
        }
        header('Vary: Accept');
        if (isset($_SERVER['HTTP_ACCEPT']) &&
            (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
            header('Content-type: application/json');
        } else {
            header('Content-type: text/plain');
        }
        echo json_encode($info);
    }

    public function delete() {
        $file_name = isset($_REQUEST['file']) ?
            basename(stripslashes($_REQUEST['file'])) : null;
        $file_path = $this->options['upload_dir'].$file_name;
        $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
        if ($success) {
            foreach($this->options['image_versions'] as $version => $options) {
                $file = $options['upload_dir'].$file_name;
                if (is_file($file)) {
                    unlink($file);
                }
            }
        }
        header('Content-type: application/json');
        echo json_encode($success);
    }
}

?>

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

Заранее спасибо! и, пожалуйста, не сердитесь на меня.

1 Ответ

2 голосов
/ 10 ноября 2011

Несколько общих комментариев.

Обычно настройка include_path выполняется в Bootstrap, а не в контроллере.

Я бы четко разделил в своем уме, что происходит на стороне сервера и что происходит на стороне клиента.

Во-первых, сначала подумайте об этом как о представлении стандартной формы. Форма имеет элемент file, пользователь просматривает свою файловую систему, чтобы выбрать свой файл. Он нажимает кнопку «Отправить». Это или успешно или неудачно. Перетаскивание и изменение значков - это просто конфетка на стороне клиента, которую нужно добавить после того, как основные функции будут на месте.

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

Тогда я бы добавил немного обработки AJAX. Клиентский сценарий перехватывает событие отправки формы, и вы используете помощник действий AjaxContext на стороне сервера для отправки ответов JSON. Эти ответы обрабатываются клиентским кодом, который отображает ваши значки ok / fail.

Наконец, я бы применил функцию перетаскивания на стороне клиента, чтобы вызвать событие submit.

Преимущества:

  1. В нем четко разграничены проблемы на стороне сервера и на стороне клиента.
  2. Он разбивает всю работу на целевую совокупность четко определенных задач.
  3. Прогрессивное улучшение / постепенное ухудшение.
  4. Кажется, более соответствует способу ZF обработки отправки формы в контроллерах (создание формы с валидаторами, проверка isValid (), обработка успешной отправки).

Я понимаю, что это только широкие мазки, но я надеюсь, что это поможет прояснить некоторые мысли.

...