app/Plugin/ExtensionRestriction40/EventListener/FileUploadListener.php line 49

Open in your IDE?
  1. <?php
  2. namespace Plugin\ExtensionRestriction40\EventListener;
  3. use Eccube\Common\EccubeConfig;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\HttpFoundation\RedirectResponse;
  6. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  7. use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
  8. use Symfony\Component\HttpKernel\KernelEvents;
  9. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  10. class FileUploadListener implements EventSubscriberInterface
  11. {
  12.     /** @var EccubeConfig */
  13.     private $eccubeConfig;
  14.     /** @var UrlGeneratorInterface */
  15.     private $router;
  16.     /** @var array */
  17.     private $errorFlg;
  18.     public function __construct(EccubeConfig $eccubeConfigUrlGeneratorInterface $router)
  19.     {
  20.         $this->eccubeConfig $eccubeConfig;
  21.         $this->router $router;
  22.         $this->errorFlg false;
  23.     }
  24.     /**
  25.      * イベントとコールバックメソッドの対応を定義
  26.      */
  27.     public static function getSubscribedEvents(): array
  28.     {
  29.         return [
  30.             KernelEvents::CONTROLLER => 'onExtensionRestriction',
  31.         ];
  32.     }
  33.     /**
  34.      * アップロードされたファイルの拡張子をチェックする
  35.      *
  36.      * @param FilterControllerEvent $event
  37.      * @return void
  38.      * @throws \Exception
  39.      */
  40.     public function onExtensionRestriction(FilterControllerEvent $event)
  41.     {
  42.         // リクエストの取得
  43.         $request $event->getRequest();
  44.         // コンテンツ管理>ファイル管理のルートの場合
  45.         if ($request->attributes->get('_route') === 'admin_content_file'
  46.             && $request->isMethod('POST')) {
  47.             // ファイルリストの取得
  48.             $uploadedFiles $request->files->get('form')['file'] ?? null;
  49.             if (!is_array($uploadedFiles) || count($uploadedFiles) === 0) {
  50.                 // ファイルがない場合
  51.                 return;
  52.             }
  53.             // セッションを取得しておく
  54.             $session $request->getSession();
  55.             // 制限された拡張子なのかチェックしていく
  56.             foreach ($uploadedFiles as $uploadedFile) {
  57.                 try {
  58.                     // ファイル名を取得
  59.                     $filename $uploadedFile->getClientOriginalName();
  60.                     // ファイルの拡張子を取得
  61.                     $extension pathinfo($filenamePATHINFO_EXTENSION);
  62.                     // 制限されているファイルの拡張子か
  63.                     if ($this->checkExtension($extension)) {
  64.                         // ホワイトリストに登録されている場合
  65.                         log_info("ホワイトリスト登録の拡張子です。");
  66.                     } else {
  67.                         // 登録されていない場合
  68.                         log_error("制限された拡張子です。");
  69.                         // 例外
  70.                         throw new UnsupportedMediaTypeHttpException(trans('admin.content.file.extension_error'));
  71.                     }
  72.                 } catch (UnsupportedMediaTypeHttpException $e) {
  73.                     // エラーを追加
  74.                     $this->errorFlg true;
  75.                     $session->getFlashBag()->add('eccube.admin.error'$e->getMessage());
  76.                     continue;
  77.                 }
  78.             }
  79.             // エラーがある場合、コントローラには行かず、リダイレクトで終了
  80.             if ($this->errorFlg) {
  81.                 $response = new RedirectResponse($this->router->generate('admin_content_file'));
  82.                 $event->setController(function () use ($response) {
  83.                     return $response;
  84.                 });
  85.             }
  86.         }
  87.     }
  88.     /**
  89.      * アップロード可能な拡張子のリストに記載されているのか判定
  90.      * @param $extension
  91.      * @return bool
  92.      */
  93.     public function checkExtension($extension): bool
  94.     {
  95.         // アップロードを許可する拡張子を取得
  96.         $whitelist $this->eccubeConfig['eccube_file_uploadable_extensions'];
  97.         // ホワイトリストに登録されているのか
  98.         if (in_array($extension$whitelist)) {
  99.             return true;
  100.         }
  101.         return false;
  102.     }
  103. }