如何将Blue Imp File Upload集成到CakePHP?

时间:2012-07-09 19:28:03

标签: php cakephp

Wa正在使用CakePHP,需要集成Blue Imp文件上传库。有没有人成功整合这些?如果是这样,您是否设置了上传以在数据库或文件系统上存储文件?你能分享一下这种整合的例子吗?

非常感谢您的帮助和指导。

1 个答案:

答案 0 :(得分:2)

是的我在php中集成了BlueImp文件上传功能。请找到以下组件和要使用的元素。

<?php
/*
 * jQuery File Upload Plugin PHP Class 5.9.1
 * https://github.com/blueimp/jQuery-File-Upload
 *
 * Copyright 2010, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/MIT
 * Created By: Arun Jain
 */
App::import('Core', 'Inflector');
class UploadComponent extends Component
{

protected $options;

function __construct($options=null) {
    $this->options = array(
        'script_url' => $this->getFullUrl().'/',
        'upload_dir' => dirname($_SERVER['SCRIPT_FILENAME']).'/attachments/files/',
        'upload_url' => $this->getFullUrl().'/files/',
        'param_name' => 'files',
        // Set the following option to 'POST', if your server does not support
        // DELETE requests. This is a parameter sent to the client:
        'delete_type' => 'POST',
        // The php.ini settings upload_max_filesize and post_max_size
        // take precedence over the following max_file_size setting:
        'max_file_size' => null,
        'min_file_size' => 1,
        'accept_file_types' => '/.+$/i',
        'max_number_of_files' => null,
        // Set the following option to false to enable resumable uploads:
        'discard_aborted_uploads' => true,
        // Set to true to rotate images based on EXIF meta data, if available:
        'orient_image' => false,
        'image_versions' => array(
            // Uncomment the following version to restrict the size of
            // uploaded images. You can also add additional versions with
            // their own upload directories:
            /*
            'large' => array(
                'upload_dir' => dirname($_SERVER['SCRIPT_FILENAME']).'/files/',
                'upload_url' => $this->getFullUrl().'/files/',
                'max_width' => 1920,
                'max_height' => 1200,
                'jpeg_quality' => 95
            ),
            */
            'thumbnail' => array(
                'upload_dir' => dirname($_SERVER['SCRIPT_FILENAME']).'/attachments/thumbnails/',
                'upload_url' => $this->getFullUrl().'/attachments/thumbnails/',
                'max_width' => 80,
                'max_height' => 80
            )
        )
    );
    if (is_array($options)) {
        $this->options = array_replace_recursive($this->options, $options);
    }
}

protected function getFullUrl() {
    return
        (isset($_SERVER['HTTPS']) ? 'https://' : 'http://').
        (isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').
        (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].
        (isset($_SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] === 443 ||
        $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).
        substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
}

protected function set_file_delete_url($file) {
    $file->delete_url = $this->options['script_url']
        .'?file='.rawurlencode($file->name);
    $file->delete_type = $this->options['delete_type'];
    if ($file->delete_type !== 'DELETE') {
        $file->delete_url .= '&_method=DELETE';
    }
}

protected 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);
            }
        }
        $this->set_file_delete_url($file);
        return $file;
    }
    return null;
}

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

protected 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) {
        if ($file_path !== $new_file_path) {
            return copy($file_path, $new_file_path);
        }
        return true;
    }
    $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';
            $image_quality = isset($options['jpeg_quality']) ?
                $options['jpeg_quality'] : 75;
            break;
        case 'gif':
            @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
            $src_img = @imagecreatefromgif ($file_path);
            $write_image = 'imagegif';
            $image_quality = null;
            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';
            $image_quality = isset($options['png_quality']) ?
                $options['png_quality'] : 9;
            break;
        default:
            $src_img = 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, $image_quality);
    // Free up memory (imagedestroy does not delete files):
    @imagedestroy($src_img);
    @imagedestroy($new_img);
    return $success;
}

protected 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;
}

protected function upcount_name_callback($matches) {
    $index = isset($matches[1]) ? intval($matches[1]) + 1 : 1;
    $ext = isset($matches[2]) ? $matches[2] : '';
    return ' ('.$index.')'.$ext;
}

protected function upcount_name($name) {
    return preg_replace_callback(
        '/(?:(?: \(([\d]+)\))?(\.[^.]+))?$/',
        array($this, 'upcount_name_callback'),
        $name,
        1
    );
}

protected function trim_file_name($name, $type) {
    // 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");
    // Add missing file extension for known image types:
    if (strpos($file_name, '.') === false &&
        preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
        $file_name .= '.'.$matches[1];
    }
    if ($this->options['discard_aborted_uploads']) {
        while(is_file($this->options['upload_dir'].$file_name)) {
            $file_name = $this->upcount_name($file_name);
        }
    }
    return $file_name;
}

protected function orient_image($file_path) {
    $exif = exif_read_data($file_path);
    $orientation = intval(@$exif['Orientation']);
    if (!in_array($orientation, array(3, 6, 8))) { 
        return false;
    }
    $image = @imagecreatefromjpeg($file_path);
    switch ($orientation) {
          case 3:
            $image = @imagerotate($image, 180, 0);
            break;
          case 6:
            $image = @imagerotate($image, 270, 0);
            break;
          case 8:
            $image = @imagerotate($image, 90, 0);
            break;
        default:
            return false;
    }
    $success = imagejpeg($image, $file_path);
    // Free up memory (imagedestroy does not delete files):
    @imagedestroy($image);
    return $success;
}

protected function handle_file_upload($uploaded_file, $name, $size, $type, $error) {
    $file = new stdClass();
    $file->name = $this->trim_file_name($name, $type);
    $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) {
            if ($this->options['orient_image']) {
                $this->orient_image($file_path);
            }
            $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)) {
                    if ($this->options['upload_dir'] !== $options['upload_dir']) {
                        $file->{$version.'_url'} = $options['upload_url']
                            .rawurlencode($file->name);
                    } else {
                        clearstatcache();
                        $file_size = filesize($file_path);
                    }
                }
            }
        } else if ($this->options['discard_aborted_uploads']) {
            unlink($file_path);
            $file->error = 'abort';
        }
        $file->size = $file_size;
        $this->set_file_delete_url($file);
    } 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() {
    if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE') {
        return $this->delete();
    }
    $upload = isset($_FILES[$this->options['param_name']]) ?
        $_FILES[$this->options['param_name']] : null;
    $info = array();
    if ($upload && is_array($upload['tmp_name'])) {
        // param_name is an array identifier like "files[]",
        // $_FILES is a multi-dimensional array:
        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]
            );
        }
    } elseif ($upload || isset($_SERVER['HTTP_X_FILE_NAME'])) {
        // param_name is a single object identifier like "file",
        // $_FILES is a one-dimensional array:
        $info[] = $this->handle_file_upload(
            isset($upload['tmp_name']) ? $upload['tmp_name'] : null,
            isset($_SERVER['HTTP_X_FILE_NAME']) ?
                $_SERVER['HTTP_X_FILE_NAME'] : (isset($upload['name']) ?
                    $upload['name'] : null),
            isset($_SERVER['HTTP_X_FILE_SIZE']) ?
                $_SERVER['HTTP_X_FILE_SIZE'] : (isset($upload['size']) ?
                    $upload['size'] : null),
            isset($_SERVER['HTTP_X_FILE_TYPE']) ?
                $_SERVER['HTTP_X_FILE_TYPE'] : (isset($upload['type']) ?
                    $upload['type'] : null),
            isset($upload['error']) ? $upload['error'] : null
        );
    }
    header('Vary: Accept');
    $json = json_encode($info);
    $redirect = isset($_REQUEST['redirect']) ?
        stripslashes($_REQUEST['redirect']) : null;
    if ($redirect) {
        header('Location: '.sprintf($redirect, rawurlencode($json)));
        return;
    }
    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;
}

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);
}

}

你的元素看起来应该是这样的:

<!-- Bootstrap CSS Toolkit styles -->
<?php echo $this->Html->css('fileuploads/bootstrap.min');?>
<!-- Bootstrap styles for responsive website layout, supporting different screen sizes     -->
<?php echo $this->Html->css('fileuploads/bootstrap-responsive.min');?>
<!-- Bootstrap CSS fixes for IE6 -->
<!--[if lt IE 7]><?php echo $this->Html->css('fileuploads/bootstrap-ie6.min');?>        <![endif]-->
<!-- Bootstrap Image Gallery styles -->
<?php echo $this->Html->css('fileuploads/bootstrap-image-gallery.min');?>
<!-- CSS to style the file input field as button and adjust the Bootstrap progress      bars -->
<?php echo $this->Html->css('fileuploads/jquery.fileupload-ui');?>
<!-- Shim to make HTML5 elements usable in older Internet Explorer versions -->
<!--[if lt IE 9]><?php echo $this->Html->script('html5');?></script><![endif]-->

                                                                                                                         添加文件...                                                                                                 开始上传                                                                            取消上传                                                                            删除                                                                                                                                                                                     
                              

        </tbody>
    </table>
</form>    
</div>
<!-- modal-gallery is the modal dialog used for the image gallery -->
<div id="modal-gallery" class="modal modal-gallery hide fade">
    <div class="modal-header">
        <a class="close" data-dismiss="modal">&times;</a>
        <h3 class="modal-title"></h3>
    </div>

    <div class="modal-body"><div class="modal-image"></div></div>
<div class="modal-footer">
    <a class="btn modal-download" target="_blank">
        <i class="icon-download"></i>
        <span>Download</span>
    </a>
    <a class="btn btn-success modal-play modal-slideshow" data-slideshow="5000">
        <i class="icon-play icon-white"></i>
        <span>Slideshow</span>
    </a>
    <a class="btn btn-info modal-prev">
        <i class="icon-arrow-left icon-white"></i>
        <span>Previous</span>
    </a>
    <a class="btn btn-primary modal-next">
        <span>Next</span>
        <i class="icon-arrow-right icon-white"></i>
    </a>
</div>
</div>
<!-- The template to display files available for upload -->
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-upload fade">
    <td class="preview"><span class="fade"></span></td>
    <td class="name"><span>{%=file.name%}</span></td>
    <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
    {% if (file.error) { %}
        <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>

        {% } else if (o.files.valid && !i) { %}
        <td>
            <div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div>
        </td>
        <td class="start">{% if (!o.options.autoUpload) { %}
            <button class="btn btn-primary">
                <i class="icon-upload icon-white"></i>
                <span>{%=locale.fileupload.start%}</span>
            </button>
        {% } %}</td>
    {% } else { %}
        <td colspan="2"></td>
    {% } %}
    <td class="cancel">{% if (!i) { %}
        <button class="btn btn-warning">
            <i class="icon-ban-circle icon-white"></i>
            <span>{%=locale.fileupload.cancel%}</span>
        </button>
    {% } %}</td>
</tr>
{% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-download fade">
    {% if (file.error) { %}
        <td></td>
        <td class="name"><span>{%=file.name%}</span></td>
        <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
        <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
    {% } else { %}
        <td class="preview">{% if (file.thumbnail_url) { %}
            <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
        {% } %}</td>
        <td class="name">
            <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=file.name%}</a>
        </td>
        <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
        <td colspan="2"></td>
    {% } %}
    <td class="delete">
        <button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
            <i class="icon-trash icon-white"></i>
            <span>{%=locale.fileupload.destroy%}</span>
        </button>
        <input type="checkbox" name="delete" value="1">
    </td>
</tr>
{% } %}

<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
<?php echo $this->Html->script('fileuploads/vendor/jquery.ui.widget');?>
<!-- The Templates plugin is included to render the upload/download listings -->
<?php echo $this->Html->script('fileuploads/tmpl.min');?>
<!-- The Load Image plugin is included for the preview images and image resizing 
functionality -->
<?php echo $this->Html->script('fileuploads/load-image.min');?>
<!-- The Canvas to Blob plugin is included for image resizing functionality -->
<?php echo $this->Html->script('fileuploads/canvas-to-blob.min');?>
<!-- Bootstrap JS and Bootstrap Image Gallery are not required, but included for the demo -->
<?php echo $this->Html->script(array('fileuploads/bootstrap.min', 'fileuploads/bootstrap-image-gallery.min'));?>
<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
<?php echo $this->Html->script('fileuploads/jquery.iframe-transport');?>
<!-- The basic File Upload plugin -->
<?php echo $this->Html->script('fileuploads/jquery.fileupload');?>
<!-- The File Upload image processing plugin -->
<?php echo $this->Html->script('fileuploads/jquery.fileupload-ip');?>
<!-- The File Upload user interface plugin -->
<?php echo $this->Html->script('fileuploads/jquery.fileupload-ui');?>
<!-- The localization script -->
<?php echo $this->Html->script('fileuploads/locale');?>
<!-- The main application script -->
<?php echo $this->Html->script('fileuploads/main');?>
<!-- The XDomainRequest Transport is included for cross-domain file deletion for IE8+ -->
<!--[if gte IE 8]><?php echo $this->Html->script('fileuploads/cors/jquery.xdr-transport');?><!  [endif]-->