🎆
投稿記事の画像の処理
zennは画像をクリップボードからコピペすると
![](https://storage.googleapis.com/zenn-user-upload/26aa03bb83d3-20240122.png)
自動で形を変換して保存してくれる
こいつを実装していきたい
マークダウンで画像を読み込む機能はParsedownにある
jQueryでできるみたいだからやってみよう
npm install jquery --save
npmでインストールしたらnode_modules下にファイルがあるからそれをwebroot/jsに移動
script.js
$(document).ready(function() {
$('#body').on('paste', function(event) { // '#body'は投稿フォームに合わせる
var items = (event.originalEvent || event).clipboardData.items;
for (var index in items) {
var item = items[index];
if (item.kind === 'file') {
var blob = item.getAsFile();
var formData = new FormData();
formData.append('image', blob);
$.ajax({
url: '/posts/uploadImage',
type: 'POST',
data: formData,
processData: false,
contentType: false,
headers: {
'X-CSRF-Token': window.CakephpCsrfToken
},
success: function(response) {
if(response.url) {
var markdownImageText = `![alt](${response.url})`;
insertAtCursor($('#body'), markdownImageText);
}
},
error: function() {
console.error('Failed to upload image');
}
});
}
}
});
});
function insertAtCursor($field, text) {
var cursorPos = $field.prop('selectionStart');
var v = $field.val();
var textBefore = v.substring(0, cursorPos);
var textAfter = v.substring(cursorPos, v.length);
$field.val(textBefore + text + textAfter);
}
jsとやりとりしてくれるやつをコントローラに記述
PostsController.php
use Cake\Http\Response;
use Cake\Routing\Router;
public function uploadImage(): Response
{
$this->request->allowMethod(['post']);
$image = $this->request->getData('image');
if ($image && $image->getError() === UPLOAD_ERR_OK) {
$ext = strtolower(pathinfo($image->getClientFilename(), PATHINFO_EXTENSION));
$allowedExtensions = ['jpg', 'jpeg', 'gif', 'png', 'webp'];
if (in_array($ext, $allowedExtensions)) {
$fileName = time() . '_' . $image->getClientFilename();
$filePath = WWW_ROOT . 'img' . DS . 'post_body_img' . DS . $fileName;
$image->moveTo($filePath);
// 画像のURLを生成
$imageUrl = Router::url('/img/post_body_img/' . $fileName, true);
return $this->response->withType('application/json')
->withStringBody(json_encode(['url' => $imageUrl]));
}
}
return $this->response->withStatus(400)
->withType('application/json')
->withStringBody(json_encode(['error' => 'Invalid image']));
}
最後にビューでCSRFトークンを準備する
edit.php
<!-- 一番ケツに書く -->
<script>
window.CakephpCsrfToken = <?= json_encode($this->request->getAttribute('csrfToken')); ?>;
</script>
コピペで画像を貼れるようになった
保存してあるファイルをアップできるようにしたほうがいいんだろうけど面倒だからやらない
編集画面
詳細画面
Discussion