背景: 不喜歡資料庫中儲存大段的 base64 圖片, 太佔空間了; laravel-admin 中沒找到其它特別好用的富文字編輯器, 所以改吧.
- 最初的想法是直接改 summernote 的 js 檔案, 可是要動到 vendor 中的內容, 不想改
- 在表單內容儲存到資料庫之前 (或之後) 把 base64 的圖片儲存成檔案, 並用檔案的路徑代替之前的 base64串
實現:
在 laravel-admin 的控制器中重寫 store, update, destroy 方法, 前兩個用於 base64 轉 檔案, 後一個用於刪除圖片
// ArticlesController.php
/********** 以下重寫 store, update, destroy 方法, 用於 summernote 上傳的base64圖片轉檔案或刪除 *******/
public function store()
{
request()['content'] = summernote_base64_to_file(request()['content']);
parent::store();
}
public function update($id)
{
request()['content'] = summernote_base64_to_file(request()['content']);
parent::update($id);
}
public function destroy($id)
{
$article = Article::find($id);
summernote_delete_image($article->content);
parent::destroy($id);
}
// helpers.php
function summernote_base64_to_file($content)
{
if (!($content && \Str::contains($content, ['src="data:image', 'src=\'data:image']))) {
return $content;
}
$pattern = '/(data:image\/)([^;]+)(;base64,)([^\"]+)/';
$res = preg_replace_callback($pattern, function ($matches) {
// 生成路徑
$public_path = public_path();
$folder_path = '/summernote/' . date('Ym') . '/' . date('d') . '/';
if (!is_dir($dir = $public_path . $folder_path)) {
mkdir($dir, 0777, true);
}
// 生成檔名
$matches[2] = $matches[2] === 'jpeg' ? 'jpg' : $matches[2];
$filename = md5(time() . \Illuminate\Support\Str::random()) . '.' . $matches[2];
$file = $dir . $filename;
// 儲存檔案
file_put_contents($file, base64_decode($matches[4]));// base64 轉圖片
// 返回相對路徑
return $folder_path . $filename;
}, $content);
return $res;
}
function summernote_delete_image($content)
{
if (!($content && \Str::contains($content, ['summernote']))) {
return null;
}
$pattern = '/(\/summernote[^\'\"]+)/';
$times = preg_match_all($pattern, $content, $matches);
if ($times) {
foreach ($matches[0] as $value) {
unlink(public_path() . $value);
}
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結