2015/12/03

CKEditor Image Upload On Codeigniter

這篇文章會一步步實作 CKEditorCodeIgniter 中圖片以及檔案上傳到 server 的功能,首先我們前往 CKEditor 官網下載最新的版本,這個 demo 使用的是 4.6,存檔後我會放在 assets/ckeditor/ 下,我會使用 Sybio/ImageWorkshop 這個套件對圖片做第一次的壓縮,我們通常不希望 user 存超大的東西在我們這啦,畢竟不是相簿,前台可以順利顯示為準則。

assets/ckeditor/config.js
CKEDITOR.editorConfig = function( config ) {
    config.toolbar =
        [
            {name:'document', items:['Source','-','Preview','Print']},
            {name:'clipboard', items:['Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo']},
            {name:'basicstyles', items:['Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat']},
            '/',
            {name:'paragraph', items:['NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','BidiLtr','BidiRtl']},
            {name:'links', items:['Link','Unlink']},
            {name:'insert', items:['Image','Table']},
            {name:'tools', items:['Maximize']}
        ];
    config.enterMode = CKEDITOR.ENTER_BR;
    config.filebrowserImageUploadUrl = baseUrl + 'ckeditor/image_upload';
    config.filebrowserUploadUrl = baseUrl + 'ckeditor/file_upload';
};

這是我常用的 config,工具可以自行增減。

application/views/ckeditor.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CKEditor Upload Demo</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="assets/ckeditor/ckeditor.js"></script>
    <script src="assets/ckeditor/adapters/jquery.js"></script>
    <script type="text/javascript" charset="utf-8">
    var baseUrl = "<?php echo base_url(); ?>";
    window.CKEDITOR_BASEPATH = "<?php echo base_url('assets/ckeditor'); ?>";

    $(function() {
        $('.ckeditor').ckeditor();
    });
    </script>
</head>
<body>
<?php echo form_open_multipart('ckeditor/upload'); ?>
<?php echo form_textarea(['name' => 'content', 'class' => 'ckeditor']); ?>
<?php echo form_submit('submit', '上傳'); ?>
<?php echo form_close(); ?>
</body>
</html>

簡單的設定一下 ckeditor 必要的環境。

application/controllers/Ckeditor.php
<?php

defined('BASEPATH') or exit('No direct script access allowed');

use PHPImageWorkshop\ImageWorkshop;

class Ckeditor extends CI_Controller
{
    /**
     * Upload path.
     *
     * @var string
     */
    private $path = 'assets/uploads/ckeditor/';

    /**
     * Index page.
     */
    public function index()
    {
        $this->load->helper('form');
        $this->load->helper('url');
        $this->load->view('ckeditor');
    }

    /**
     * CKEditor image upload
     *
     * Upload by ImageWorkshop package
     *
     * @return string
     */
    public function image_upload()
    {
        $this->load->helper('url');
        $funcNum = $this->input->get('CKEditorFuncNum');
        $source = $_FILES['upload']['tmp_name'];
        $file = $_FILES['upload']['name'];
        $ext = pathinfo($file, PATHINFO_EXTENSION);
        $ratio = 1200; // 寬度最大比例
        $allows = [1, 2, 3]; // GIF, JPEG, PNG
        $newName = date('YmdHis').rand(1000, 9999); //新檔名
        $message = '';
        $url = '';

        try {
            $exif = exif_imagetype($source);

            if (!$exif) {
                throw new Exception('檔案格式錯誤');
            }

            if (!in_array($exif, $allows)) {
                throw new Exception('僅允許 gif, jpeg, png');
            }

            $imageInfo = getimagesize($source);
            $layer = ImageWorkshop::initFromPath($source);

            // 若寬度大於比例,縮放置比例
            if ($imageInfo[0] > $ratio) {
                $layer->resizeInPixel($ratio, null, true);
            }

            $fileName = "{$newName}.{$ext}";
            $layer->save($this->path, $fileName);
            $url = base_url($this->path.$fileName);
        } catch (Exception $e) {
            $message = $e->getMessage();
        }

        $string = "<script type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction({$funcNum}, '{$url}', '{$message}');</script>";

        $this->output
            ->set_content_type('text/html')
            ->set_output($string);
    }

    /**
     * CKEditor image upload
     *
     * @return string
     */
    public function file_upload()
    {
        $this->load->helper('url');
        $funcNum = $this->input->get('CKEditorFuncNum');
        $source = $_FILES['upload']['tmp_name'];
        $file = $_FILES['upload']['name'];
        $ext = pathinfo($file, PATHINFO_EXTENSION);
        $newName = date('YmdHis').rand(1000, 9999); //新檔名
        $message = '';
        $url = '';

        try {
            $fileName = "{$newName}.{$ext}";
            $target = $this->path.$fileName;

            if (move_uploaded_file($source, $target)) {
                $url = base_url($target);
            } else {
                $message = '上傳失敗';
            }
        } catch (Exception $e) {
            $message = $e->getMessage();
        }

        $string = "<script type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction({$funcNum}, '{$url}', '{$message}');</script>";

        $this->output
            ->set_content_type('text/html')
            ->set_output($string);
    }
}

我們建立了 Ckeditor 的 controller,把 form 放在首頁,這個部份包含了圖片跟檔案上傳的程式碼,圖片部份也包含了檔案格式檢查、檔案尺寸檢查,如果還需要檢查更多的東西就在 try catch 裡面再加。

沒有留言: