WYSIWYGエディタで画像のアップロードを行う

WYSIWYGのエディタSummernoteではファイルアップロード機能を実装できる

Data URI schemeとFile Upload

Bootstrap3でデザインされたWYSIWYGのエディタSummernoteに画像アップロード機能を実装する。

SummernoteをCakePHPで利用する

SummernoteにはデフォルトでData URI schemeで画像ファイルをエディタに貼り付けることが可能。実際に画像を貼り付けて、HTMLのソースコードを確認してみたのが下の画像の状態になる。

summernote-base64

Data URI schemeの方法を用いると画像をサーバ側にアップロードすることなく、画像をすべてエンコードしてテキスト状態にして貼り付けるため、画像を参照するためのHTTPリクエストが発生しないというメリットがある。

File Upload方式にて画像を管理したい場合には、SummernoteのonImageUploadコールバックを利用して実装することが可能。

CakePHPのSummernoteにFile Upload機能を実装

onImageUploadコールバックを利用すればローカルの画像を選択したタイミングでサーバ側へのファイルアップロード処理を挿入することが可能で、そのヒントが下のURLに書かれている。

https://github.com/HackerWins/summernote/issues/72

layoutのjs

CakePHPのlayoutのjsを下のように変更した。Ajaxのリクエスト先は、

/summernote

にしてある。

サーバサイドで画像サイズのチェックを行い、規定のサイズを超えていた場合はエラーとするため、errorコールバックを設定してある。

    $(document).ready(function() {
      $('#summernote').summernote({
        onImageUpload: function(files, editor, welEditable) {
            sendFile(files[0], editor, welEditable);
        },
      });
    });

	function sendFile(file, editor, welEditable) {
	    data = new FormData();
	    data.append("file", file);
	    $.ajax({
	        data: data,
	        type: "POST",
	        url: "/summernote",
	        cache: false,
	        contentType: false,
	        processData: false,
		beforeSend: function() {
				$('#error').html("");
				$('#loading').html("");
				$('#loading').html("<img src='http://test.local/images/loading.gif' />");
			},
	        success: function(url) {
	            editor.insertImage(welEditable, url);
	        },
		error: function(response){
				$('#error').html(response.responseText);
		},
		complete: function() {
				$('#loading').html("");
		},
	    });
	}

Controller側で画像のサイズチェック

/summernote

へのリクエストをAjaxか通常のHTTPリクエストか判定した上で、Ajaxリクエストの場合には画像のサイズチェックを行っている。規定のサイズ以下の場合は、画像をアップロードし、サイズを超えている場合にはHTTPのエラーコードとメッセージをレスポンスするようにしたのが下のコード

public function summernote() {

	if( !$this->request->is('ajax') )
	{
		$this->layout = "summernote";
    	}
	
	else
	{
            $tmp_file = $_FILES["file"]["tmp_name"];

            if( filesize($tmp_file) > 500000 )
		{
	                header("HTTP/1.0 404 Not Found");
			echo '<p>サイズオーバーです</p>';
			exit();
		}
		
		else
		{
	        $name = $this->randomString();
	        $ext = explode('.',$_FILES['file']['name']);
	        $filename = $name.'.'.$ext[1];
	        $destination = '/path/to/images/'.$filename;
	        $location = $_FILES["file"]["tmp_name"];
	        move_uploaded_file($location, $destination);
	        echo 'http://test.local/images/'.$filename;
			exit();
		}
	}
}

public function randomString() {
    return md5(rand(100, 200));
}

Viewには空のHTMLを用意しておく

Viewには一時的に表示されるローディング画像とエラーメッセージを表示する空のHTMLを追加した。

<textarea id="summernote"></textarea>
<aside id="error"></aside>
<aside id="loading"></aside>

ローディング画像とエラーの内容は、Ajaxオブジェクトのbeforesendコールバックで表示/非表示を制御している。

ファイルアップロードのHTMLソース

ファイルアップロード方式であれば下のようにHTMLのソースは完結な状態になる。

summernote-fileupload

  • Data URI scheme
  • File Upload

双方の方式で一長一短あるが、Summernoteでは両方の方式に無理なく対処することが可能。

Webエンジニアブログにコメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

WYSIWYGエディタで画像のアップロードを行うの記事にコメントを投稿