質問 > 管理機能 > 画像アップロード項目の追加 |
管理機能
スレッド表示 | 古いものから | 前のトピック | 次のトピック | 下へ |
投稿者 | スレッド |
---|---|
Rights |
投稿日時: 2021/3/15 20:26
対応状況: 解決済
|
一人前 登録日: 2019/3/12 居住地: 投稿: 99 |
Re: 画像アップロード項目の追加 自己レスです。
ファイルアップロードのサンプルを元にしていましたが、データベースが絡まない(フォームにファイルアップロードの項目を追加して、添付したファイルを送信するのみ)処理だったため、既存の登録したファイルがあった場合の値の保持や取得の仕方に問題がありました。 削除処理についても見直しを行い、解決しました。 失礼しました。 |
Rights |
投稿日時: 2021/3/12 19:04
対応状況: −−−
|
一人前 登録日: 2019/3/12 居住地: 投稿: 99 |
画像アップロード項目の追加 新着情報に画像登録(2項目でそれぞれ1つのファイルをアップロード)を追加しましたが、次の場合の挙動で解決できない点があります。
※アップロードの処理自体はできています。 FormTypeExtensionで、Formの拡張 <?php /* * This file is part of EC-CUBE * * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. * * http://www.ec-cube.co.jp/ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Customize\Form\Extension; use Customize\Service\FileUploader; use Eccube\Common\EccubeConfig; use Eccube\Entity\News; use Eccube\Form\Type\Admin\NewsType; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\Form\Extension\Core\Type\FileType; use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\HttpFoundation\File\File; class NewsTypeExtension extends AbstractTypeExtension { /** * @var EccubeConfig */ private $eccubeConfig; /** * @var FileUploader */ private $fileUploader; public function __construct( EccubeConfig $eccubeConfig, FileUploader $fileUploader ) { $this->eccubeConfig = $eccubeConfig; $this->fileUploader = $fileUploader; } /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder // ファイルアップロード用の項目 ->add('file1', FileType::class, [ 'mapped' => false, 'required' => false, 'constraints' => [ new \Symfony\Component\Validator\Constraints\File([ 'maxSize' => '10240k', 'mimeTypes' => [ 'application/pdf', 'application/x-pdf', ], 'uploadErrorMessage' => 'PDFファイルを選択してください' ]) ] ]) ->add('filename1', HiddenType::class) ->add('file2', FileType::class, [ 'mapped' => false, 'required' => false, 'constraints' => [ new \Symfony\Component\Validator\Constraints\File([ 'maxSize' => '10240k', 'mimeTypes' => [ 'image/gif', 'image/jpeg', 'image/png', ], 'uploadErrorMessage' => '画像ファイルを選択してください' ]) ] ]) ->add('filename2', HiddenType::class) ; $builder ->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event){ $form = $event->getForm(); $News= $event->getData(); if($News instanceof News) { if($News->getFilename1()) { $form["file1"]->setData( new File( $this->eccubeConfig["eccube_save_image_dir"]."/".$News->getFilename1() ) ); } if($News->getFilename2()) { $form["file2"]->setData( new File( $this->eccubeConfig["eccube_save_image_dir"]."/".$News->getFilename2() ) ); } } }) ->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event){ $form = $event->getForm(); $News= $event->getData(); if($Newsinstanceof News) { $file1 = $form["file1"]->getData(); if($file1) { $filename1 = $this->fileUploader->pdf_upload($file1, $News->getFilename1()); $News->setFilename1($filename1); } $file2 = $form["file2"]->getData(); if($file2) { $filename2 = $this->fileUploader->img_upload($file2, $News->getFilename2()); $News->setFilename2($filename2); } } }) ; } /** * {@inheritdoc} */ public function getExtendedType() { return NewsType::class; } } ファイルアップロードを行う処理をServiceに追加 <?php namespace Customize\Service; use Eccube\Common\EccubeConfig; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException; class FileUploader { /** * @var EccubeConfig */ private $eccubeConfig; public function __construct( EccubeConfig $eccubeConfig ) { $this->eccubeConfig = $eccubeConfig; } public function img_upload(UploadedFile $file, $old_file) { //ファイルフォーマット検証 $allowExtensions = ['gif', 'jpg', 'jpeg', 'png']; // 拡張子 $extension = $file->guessExtension(); $filename = NULL; if (in_array(strtolower($extension), $allowExtensions)) { // 加工前の画像の情報を取得 list($origin_w, $origin_h, $type) = getimagesize($file); // 加工前のファイルをフォーマット別に読み出す switch ($type) { case IMAGETYPE_JPEG: $origin_image = imagecreatefromjpeg($file); break; case IMAGETYPE_PNG: $origin_image = imagecreatefrompng($file); break; case IMAGETYPE_GIF: $origin_image = imagecreatefromgif($file); break; default: throw new UnsupportedMediaTypeHttpException(); } if ($this->eccubeConfig->get('eccube_product_image_resize')) { // 新しく描画するキャンバスを作成 $canvas = imagecreatetruecolor($origin_w, $origin_h); imagecopyresampled($canvas, $origin_image, 0,0,0,0, $origin_w, $origin_h, $origin_w, $origin_h); $filename = date('mdHis').uniqid('_').'.'.$extension; // 保存先を指定 $resize_path = $this->eccubeConfig['eccube_save_image_dir'] . '/' . $filename; switch ($type) { case IMAGETYPE_JPEG: imagejpeg($canvas, $resize_path, $this->eccubeConfig->get('eccube_product_image_jpg_quality')); break; case IMAGETYPE_PNG: imagepng($canvas, $resize_path, $this->eccubeConfig->get('eccube_product_image_png_quality')); break; case IMAGETYPE_GIF: imagegif($canvas, $resize_path); break; } imagedestroy($origin_image); imagedestroy($canvas); } else { $filename = date('mdHis').uniqid('_').'.'.$extension; $file->move( $this->eccubeConfig["eccube_save_image_dir"], $filename ); } // 削除 if ($old_file && $filename) { $fs = new Filesystem(); $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$old_file); } elseif ($old_file && !$filename) { $filename = $old_file; } } return $filename; } public function pdf_upload(UploadedFile $file, $old_file) { //ファイルフォーマット検証 $allowExtensions = ['pdf']; // 拡張子 $extension = $file->guessExtension(); $filename = NULL; if (in_array(strtolower($extension), $allowExtensions)) { $basename = date('mdHis').uniqid('_'); $filename = $basename.'.'.$extension; $file->move( $this->eccubeConfig["eccube_save_image_dir"], $filename ); // 削除 if ($old_file && $filename) { $fs = new Filesystem(); $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$old_file); } elseif ($old_file && !$filename) { $filename = $old_file; } } return $filename; } } twigテンプレート(該当箇所抜粋) <div class="row"> <div class="col-3"><span>ファイル1</span></div> <div class="col mb-2"> {{ form_widget(form.file1, { 'attr': { 'class': 'form-control', 'data-trigger': 'change' }}) }} {{ form_errors(form.file1) }} {% if form.file1.vars.data and form.file1.vars.data.filename %} <div class="c-form__uploadedFilename1"> <img src="{{ asset(form.file1.vars.data.filename, 'save_image') }}" width="360"> ファイル名:{{ form.file1.vars.data.filename }} <a class="delete-file1"> 削除する </a> </div> {% endif %} {{ form_widget(form.filename1) }} {{ form_errors(form.filename1) }} <script> $(function () { $('.delete-file1').click(function () { $(this).parents('div.c-form__uploadedFilename1').remove(); $("input#{{ form.filename1.vars.id }}").val(""); }); }); </script> </div> </div> <div class="row"> <div class="col-3"><span>ファイル2</span></div> <div class="col mb-2"> {{ form_widget(form.file2, { 'attr': { 'class': 'form-control', 'data-trigger': 'change' }}) }} {{ form_errors(form.file2) }} {% if form.file2.vars.data and form.file2.vars.data.filename %} <div class="c-form__uploadedFilename2"> <img src="{{ asset(form.file2.vars.data.filename, 'save_image') }}" width="360"> ファイル名:{{ form.file2.vars.data.filename }} <a class="delete-file2"> 削除する </a> </div> {% endif %} {{ form_widget(form.filename2) }} {{ form_errors(form.filename2) }} <script> $(function () { $('.delete-file2').click(function () { $(this).parents('div.c-form__uploadedFilename2').remove(); $("input#{{ form.filename2.vars.id }}").val(""); }); }); </script> </div> </div> 画像をアップロードする項目で、アップロードファイルが、mimeTypesで引っ掛かった場合、エラーメッセージが表示されますが、編集画面の画像プレビュー表示でアップロード前の一時ファイル名を拾ってしまい。リンク切れ画像表示となってしまう。(PDFを上げる処理もありますがここは無視) 一度アップロードした画像が存在した状態で、mimeTypesで引っ掛かった場合、元々アップしている画像のパスが取得できない。(上記同様、一時ファイルのパスをとってしまいリンク切れ画像表示となってしまう。) 新たにファイルをアップした場合で以前のファイルがある場合の以前のファイルの削除はできますが、無条件で現在上げているファイルの削除ができない。 長文となりましたが、アップロードや削除できない場合のバリデーションや例外処理で不足があればご教示ください。 |
スレッド表示 | 古いものから | 前のトピック | 次のトピック | トップ |