こんばんは、のるぼるのんです。
前回までの記事ではLaravel5.6, 5.7 Voyagerで記事の名前を維持したままアップロード、日本語ファイル名を維持したままアップロードを行う方法を紹介しました。
今回はVoyagerのメディア機能のアップロードから既にアップロードしている画像を更新してみましょう。
基本的なイメージとしては、元ファイル名取得→元ファイル名と同名のファイルをアップロードした時画像を更新する、という感じです。
今回の記事の内容では、VoyagerMediaControllerを編集することになります。
ですのでまず先にVoyagerのコントローラーをvendor外に出し、編集可能にしましょう。
それでは早速、ファイルを編集していきます。
今回いじるのはVoyagerMediaController.php/uploadメソッドです。
元ファイルではこんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public function upload(Request $request) { try { $realPath = Storage::disk($this->filesystem)->getDriver()->getAdapter()->getPathPrefix(); $allowedImageMimeTypes = [ 'image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/svg+xml', ]; $file = $request->file->store($request->upload_path, $this->filesystem); //このstore関数では乱数で名前が決定します。さらに、同名ファイルだと.png1のような拡張子で保存されます。 //ここから先は正直関係ないです if (in_array($request->file->getMimeType(), $allowedImageMimeTypes)) { $image = Image::make($realPath.$file); if ($request->file->getClientOriginalExtension() == 'gif') { copy($request->file->getRealPath(), $realPath.$file); } else { $image->orientate()->save($realPath.$file); } } $success = true; $message = __('voyager::media.success_uploaded_file'); $path = preg_replace('/^public\//', '', $file); } catch (Exception $e) { $success = false; $message = $e->getMessage(); $path = ''; } return response()->json(compact('success', 'message', 'path')); } |
store関数ではファイル名をランダムにしているので、画像の更新ができません。
ですので、元ファイル名を取得し、storeAs関数で保存します。
vendor外に出したVoyagerMediaControllerのuploadメソッドをオーバーライドします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
public function upload(Request $request) { try { $realPath = Storage::disk($this->filesystem)->getDriver()->getAdapter()->getPathPrefix(); // 元ファイルの名前取得、存在確認 $fileName = $request->file->getClientOriginalName(); //元ファイル名を取得します。 $exists = Storage::disk($this->filesystem)->exists($request->upload_path.'/'.$fileName); //元ファイルと同名のファイルがあるか確認します。 if ($exists) { Storage::disk($this->filesystem)->delete($request->upload_path.'/'.$fileName); 元ファイルと同名のファイルがあるとき一旦削除します } $allowedImageMimeTypes = [ 'image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/bmp', 'image/svg+xml', ]; $file = $request->file->storeAs($request->upload_path, $fileName, $this->filesystem); //ファイル名を維持して画像をアップロード保存します。これで、同名ファイルは削除→保存、と更新と同じ動きが出来ます。 if (in_array($request->file->getMimeType(), $allowedImageMimeTypes)) { $image = Image::make($realPath.$file); if ($request->file->getClientOriginalExtension() == 'gif') { copy($request->file->getRealPath(), $realPath.$file); } else { $image->orientate()->save($realPath.$file); } } $success = true; $message = __('voyager::media.success_uploaded_file'); // $path = preg_replace('/^public\//', '', $file); } catch (Exception $e) { $success = false; $message = $e->getMessage(); $path = ''; } return response()->json(compact('success', 'message', 'path')); } |
基本的にはこれだけです!getClientOriginalName()で元ファイルのファイル名取得→元ファイル名と同名のファイル削除→storeAsで元ファイル名で保存、という流れです。
元ファイル名で削除の流れを組みこまないと、hoge.png1のような名前で保存されます。
日本語ファイルを挙げる場合、以前の記事で紹介したsetLocaleを挟むことで、表示確認です。今回の改造ではbasename関数を経由していないので、保存自体はマルチバイト文字でもうまくいきます。
また、VoyagerMediaControllerではstorage以下、閲覧できるディレクトリなどを
1 |
private $directory = '/posts'; |
とすることで編集できます。この例ですと/posts以下のファイルをメディアでいじれる感じですね。
一時的なファイル置き場は見せたくないよって時はこちらである程度対応可能かな、と思います!(Bread TinyMCEのパス変更やcsvをインサートできるようにするなど、一時ディレクトリってマジ便利。。。)
余談ですが。
最近Voyagerも更新があって、ウィジェットなどはデフォルトで表示されなくなったみたいですね。
Laravel + Voyagerは色々便利なので、機能確認をしっかりしていきたいところです。今話題に出したので、ウィジェット関係もそのうち記事にしたいですね。
あと、Voyagerは機能がしっかりしてて、正直かなりいい感じなんですけど、たまに重いんですよね。
Voyagerくらい便利で、サクサクな管理画面パッケージはないか、今後試していきたいと思います。その時はまた、記事として共有させていただきます。
コメントを書く