summernoteで画像選択時にサーバにファイルをアップロードする方法
summernoteで画像を選択した際、ファイルはアップロードされずBase64エンコードされた値がエディタ内に挿入される。これを画像ファイルがサーバにアップロードされるようにしたい。また、サイズ圧縮のためJPG / PNGファイルの場合はWebP画像に変換したい。以下に対応方法をメモ。
目次
summernoteについて
summernote自体の使用方法については過去記事参照。
対応方法
WYSIWYGエディタ側(index.php)
<form action="./" method="post" enctype="multipart/form-data">
<div>
<label>
<input type="radio" value="on" name="switching" checked>On
</label>
<label>
<input type="radio" value="off" name="switching">Off
</label>
</div>
<textarea name="editor" id="editor"></textarea><br>
<input type="submit" value="送信">
</form>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-lite.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.20/dist/summernote-lite.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.20/lang/summernote-ja-JP.min.js" type="text/javascript"></script>
<script>
$(function(){
const selector = '#editor';
//summernoteの開始
startSummernote(selector);
//summernoteのOn / Off切り替え
$('input[name="switching"]').on('change', function(){
if( $(this).val() == 'on' ){
//summernoteの開始
startSummernote(selector);
}else{
//空の場合はsummernote側で<p><br></p>が挿入されるので削除
if( $(selector).summernote('code') == '<p><br></p>' ){
$(selector).val('');
}
//summernoteの破棄
$(selector).summernote('destroy');
}
});
//summernoteの開始用関数
function startSummernote( selector ){
if( !selector ) return false;
//オプション設定
const summernote_option = {
lang: 'ja-JP',
height: 300,
focus: true,
callbacks: {
onImageUpload: function( file ){
uploadImg( file[0], selector );
},
}
}
$(selector)
//オプションを指定して初期化
.summernote(summernote_option)
//エンタークリック時に<br>タグを挿入
.on('summernote.enter',
function(we, e){
$(this).summernote('pasteHTML', '<br>​');
e.preventDefault();
}
);
}
function uploadImg( file, selector ){
if( !file || !selector ){
alert('エラーが発生しました。');
return false;
}
if( !file.type.match(/^image/) ){
alert('画像を選択してください');
return false;
}
const limit_size = 5;
if( file.size > limit_size * 1024 * 1024 ){
alert(`画像サイズは${limit_size}MBまでです`);
return false;
}
data = new FormData();
data.append('file', file);
$.ajax({
data: data,
type: 'POST',
url: './upload.php',
cache: false,
contentType: false,
processData: false,
}).done(function(data, textStatus, jqXHR){
const result = JSON.parse(data);
if( !result.uploaded || !result.url ){
const msg = ( result.message ) ? result.message : 'エラーが発生しました。';
return false;
}
$(selector).summernote('insertImage', result.url);
});
}
});
</script>
画像アップロード側(upload.php)
<?php
do{
//アップロード先のパス
$path = '/path/to/img/';
//アップロード先のURL
$url = 'https://test.com/path/to/img/';
$img = $_FILES['file'];
if( !$img['size'] ){
$msg = '画像がアップロードされていません。';
break;
}
$ext = $img['type'];
if ($ext == 'image/jpeg' || $ext == 'image/jpg') {
$tmp_ext = '.jpg';
} elseif ($ext == 'image/png') {
$tmp_ext = '.png';
} elseif ($ext == 'image/gif') {
$tmp_ext = '.gif';
} elseif ($ext == 'image/webp') {
$tmp_ext = '.webp';
}
if( !$tmp_ext ){
$msg = 'jpg / png / gif / webpファイルのみアップロードいただけます。';
break;
}
$img_name = md5(uniqid(rand(), true)) . '_' . time();
if( !move_uploaded_file($img['tmp_name'], $path . $img_name . $tmp_ext) ){
$msg = 'アップロード中にエラーが発生しました。';
break;
}
$img = $img_name . $tmp_ext;
if( $tmp_ext == '.jpg' ){
$old_img = imagecreatefromjpeg($path . $img);
}else if( $tmp_ext == '.png' ){
$old_img = imagecreatefrompng($path . $img);
}else{
break;
}
if( imagewebp($old_img, $path . $img_name . '.webp') ){
$img = $img_name . '.webp';
}
$flg = true;
}while(0);
if( $msg ){
$response = array(
'uploaded' => false,
'error' => array(
'message' => $msg,
),
);
}else{
$response = array(
'url' => $url . $img,
'uploaded' => true,
);
}
echo json_encode($response);
注意点
WebP変換にはPHPのGDライブラリが必要になる。レンタルサーバだと大丈夫だと思うが、VPSとかの場合は必要に応じてインストールすること。
画像のstyleを指定したい場合
$(selector).summernote('insertImage', result.url);
で画像を出力すると以下のようにwidthが自動で指定される。
<img style="width: 1050px;" src="https://test.com/img/xxxxx.webp">
これをレスポンシブ対応でmax-width:100%にしたい等、自身でstyleを指定したいような場合は以下で出力すると良い。
$(selector).summernote('pasteHTML', `<img src="${result.url}" style="max-width: 100%;">`);
関連記事
-
-
jQueryで画像が存在すれば表示、なければノーイメージ画像を表示
やりたかった事は以下の通り。 ・画像のURLはcode.jpgみたいになってる ...
-
-
画像アップロード前の時点で画像が選択されているか確認
やりたかった事は、フォーム内で画像をアップロードする際、 ちゃんと画像がローカル ...
-
-
NicEdit(WYSIWYGエディタ)とテキストエリアの切り替え
チェックボックスのON / OFFでNicEdit(WYSIWYGエディタ)とt ...
-
-
「slick」でブラウザ幅がPCの場合はスライダーを表示し、スマホ幅の場合はスライダー無しにする方法
slickプラグインで画像スライダーを設置しているページがあり、PCのブラウザ幅 ...
-
-
Lightboxで画像拡大時にダウンロードリンクを設置する方法
Lightboxで画像拡大時にダウンロードリンクを設置したいと要望を受けた。もち ...