|  | <?php |  | <?php | 
|  | /* |  | /* | 
|  |  * This file is part of EC-CUBE |  |  * This file is part of EC-CUBE | 
|  |  * |  |  * | 
|  |  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. |  |  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved. | 
|  |  * |  |  * | 
|  |  * http://www.ec-cube.co.jp/ |  |  * http://www.ec-cube.co.jp/ | 
|  |  * |  |  * | 
|  |  * This program is free software; you can redistribute it and/or |  |  * This program is free software; you can redistribute it and/or | 
|  |  * modify it under the terms of the GNU General Public License |  |  * modify it under the terms of the GNU General Public License | 
|  |  * as published by the Free Software Foundation; either version 2 |  |  * as published by the Free Software Foundation; either version 2 | 
|  |  * of the License, or (at your option) any later version. |  |  * of the License, or (at your option) any later version. | 
|  |  * |  |  * | 
|  |  * This program is distributed in the hope that it will be useful, |  |  * This program is distributed in the hope that it will be useful, | 
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  |  * GNU General Public License for more details. |  |  * GNU General Public License for more details. | 
|  |  * |  |  * | 
|  |  * You should have received a copy of the GNU General Public License |  |  * You should have received a copy of the GNU General Public License | 
|  |  * along with this program; if not, write to the Free Software |  |  * along with this program; if not, write to the Free Software | 
|  |  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. |  |  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | 
|  |  */  |  |  */  | 
|  |   |  |   | 
|  |   |  |   | 
|  | namespace Eccube\Form\Type\Admin; |  | namespace Eccube\Form\Type\Admin; | 
|  |   |  |   | 
|  | use Doctrine\Common\Collections\ArrayCollection; |  | use Doctrine\Common\Collections\ArrayCollection; | 
|  | use Eccube\Application; |  | use Eccube\Application; | 
|  | use Symfony\Component\Form\AbstractType; |  | use Symfony\Component\Form\AbstractType; | 
|  | use Symfony\Component\Form\FormBuilderInterface; |  | use Symfony\Component\Form\FormBuilderInterface; | 
| . |   |  | use Symfony\Component\Form\FormError; | 
|  |   |  | use Symfony\Component\Form\FormEvent; | 
|  |   |  | use Symfony\Component\Form\FormEvents; | 
|  |   |  | use Symfony\Component\Form\FormInterface; | 
|  | use Symfony\Component\OptionsResolver\OptionsResolver; |  | use Symfony\Component\OptionsResolver\OptionsResolver; | 
|  | use Symfony\Component\Validator\Constraints as Assert; |  | use Symfony\Component\Validator\Constraints as Assert; | 
|  |   |  |   | 
|  | /** |  | /** | 
|  |  * Class ProductType. |  |  * Class ProductType. | 
|  |  */  |  |  */  | 
|  | class ProductType extends AbstractType |  | class ProductType extends AbstractType | 
|  | { |  | { | 
|  |     /** |  |     /** | 
|  |      * @var Application |  |      * @var Application | 
|  |      */  |  |      */  | 
|  |     public $app; |  |     public $app; | 
|  |   |  |   | 
|  |     /** |  |     /** | 
|  |      * ProductType constructor. |  |      * ProductType constructor. | 
|  |      * |  |      * | 
|  |      * @param Application $app |  |      * @param Application $app | 
|  |      */  |  |      */  | 
|  |     public function __construct(Application $app) |  |     public function __construct(Application $app) | 
|  |     { |  |     { | 
|  |         $this->app = $app; |  |         $this->app = $app; | 
|  |     } |  |     } | 
|  |   |  |   | 
|  |     /** |  |     /** | 
|  |      * {@inheritdoc} |  |      * {@inheritdoc} | 
|  |      */  |  |      */  | 
|  |     public function buildForm(FormBuilderInterface $builder, array $options) |  |     public function buildForm(FormBuilderInterface $builder, array $options) | 
|  |     { |  |     { | 
|  |         /** |  |         /** | 
|  |          * @var ArrayCollection $arrCategory array of category |  |          * @var ArrayCollection $arrCategory array of category | 
|  |          */  |  |          */  | 
|  |         $arrCategory = $this->app['eccube.repository.category']->getList(null, true); |  |         $arrCategory = $this->app['eccube.repository.category']->getList(null, true); | 
|  |   |  |   | 
|  |         $builder |  |         $builder | 
|  |             // 商品規格情報 |  |             // 商品規格情報 | 
|  |             ->add('class', 'admin_product_class', array( |  |             ->add('class', 'admin_product_class', array( | 
|  |                 'mapped' => false, |  |                 'mapped' => false, | 
|  |             )) |  |             )) | 
|  |             // 基本情報 |  |             // 基本情報 | 
|  |             ->add('name', 'text', array( |  |             ->add('name', 'text', array( | 
|  |                 'label' => '商品名', |  |                 'label' => '商品名', | 
|  |                 'constraints' => array( |  |                 'constraints' => array( | 
|  |                     new Assert\NotBlank(), |  |                     new Assert\NotBlank(), | 
|  |                 ), |  |                 ), | 
|  |             )) |  |             )) | 
|  |             ->add('product_image', 'file', array( |  |             ->add('product_image', 'file', array( | 
|  |                 'label' => '商品画像', |  |                 'label' => '商品画像', | 
|  |                 'multiple' => true, |  |                 'multiple' => true, | 
|  |                 'required' => false, |  |                 'required' => false, | 
|  |                 'mapped' => false, |  |                 'mapped' => false, | 
|  |             )) |  |             )) | 
|  |             ->add('description_detail', 'textarea', array( |  |             ->add('description_detail', 'textarea', array( | 
|  |                 'label' => '商品説明', |  |                 'label' => '商品説明', | 
|  |             )) |  |             )) | 
|  |             ->add('description_list', 'textarea', array( |  |             ->add('description_list', 'textarea', array( | 
|  |                 'label' => '商品説明(一覧)', |  |                 'label' => '商品説明(一覧)', | 
|  |                 'required' => false, |  |                 'required' => false, | 
|  |             )) |  |             )) | 
|  |             ->add('Category', 'entity', array( |  |             ->add('Category', 'entity', array( | 
|  |                 'class' => 'Eccube\Entity\Category', |  |                 'class' => 'Eccube\Entity\Category', | 
|  |                 'property' => 'NameWithLevel', |  |                 'property' => 'NameWithLevel', | 
|  |                 'label' => '商品カテゴリ', |  |                 'label' => '商品カテゴリ', | 
|  |                 'multiple' => true, |  |                 'multiple' => true, | 
|  |                 'mapped' => false, |  |                 'mapped' => false, | 
|  |                 // Choices list (overdrive mapped) |  |                 // Choices list (overdrive mapped) | 
|  |                 'choices' => $arrCategory, |  |                 'choices' => $arrCategory, | 
|  |             )) |  |             )) | 
|  |   |  |   | 
|  |             // 詳細な説明 |  |             // 詳細な説明 | 
|  |             ->add('Tag', 'tag', array( |  |             ->add('Tag', 'tag', array( | 
|  |                 'required' => false, |  |                 'required' => false, | 
|  |                 'multiple' => true, |  |                 'multiple' => true, | 
|  |                 'expanded' => true, |  |                 'expanded' => true, | 
|  |                 'mapped' => false, |  |                 'mapped' => false, | 
|  |             )) |  |             )) | 
|  |             ->add('search_word', 'textarea', array( |  |             ->add('search_word', 'textarea', array( | 
|  |                 'label' => "検索ワード", |  |                 'label' => "検索ワード", | 
|  |                 'required' => false, |  |                 'required' => false, | 
|  |             )) |  |             )) | 
|  |             // サブ情報 |  |             // サブ情報 | 
|  |             ->add('free_area', 'textarea', array( |  |             ->add('free_area', 'textarea', array( | 
|  |                 'label' => 'サブ情報', |  |                 'label' => 'サブ情報', | 
|  |                 'required' => false, |  |                 'required' => false, | 
|  |             )) |  |             )) | 
|  |   |  |   | 
|  |             // 右ブロック |  |             // 右ブロック | 
|  |             ->add('Status', 'disp', array( |  |             ->add('Status', 'disp', array( | 
|  |                 'constraints' => array( |  |                 'constraints' => array( | 
|  |                     new Assert\NotBlank(), |  |                     new Assert\NotBlank(), | 
|  |                 ), |  |                 ), | 
|  |             )) |  |             )) | 
|  |             ->add('note', 'textarea', array( |  |             ->add('note', 'textarea', array( | 
|  |                 'label' => 'ショップ用メモ帳', |  |                 'label' => 'ショップ用メモ帳', | 
|  |                 'required' => false, |  |                 'required' => false, | 
|  |             )) |  |             )) | 
|  |   |  |   | 
|  |             // タグ |  |             // タグ | 
|  |             ->add('tags', 'collection', array( |  |             ->add('tags', 'collection', array( | 
|  |                 'type' => 'hidden', |  |                 'type' => 'hidden', | 
|  |                 'prototype' => true, |  |                 'prototype' => true, | 
|  |                 'mapped' => false, |  |                 'mapped' => false, | 
|  |                 'allow_add' => true, |  |                 'allow_add' => true, | 
|  |                 'allow_delete' => true, |  |                 'allow_delete' => true, | 
|  |             )) |  |             )) | 
|  |             // 画像 |  |             // 画像 | 
|  |             ->add('images', 'collection', array( |  |             ->add('images', 'collection', array( | 
|  |                 'type' => 'hidden', |  |                 'type' => 'hidden', | 
|  |                 'prototype' => true, |  |                 'prototype' => true, | 
|  |                 'mapped' => false, |  |                 'mapped' => false, | 
|  |                 'allow_add' => true, |  |                 'allow_add' => true, | 
|  |                 'allow_delete' => true, |  |                 'allow_delete' => true, | 
|  |             )) |  |             )) | 
|  |             ->add('add_images', 'collection', array( |  |             ->add('add_images', 'collection', array( | 
|  |                 'type' => 'hidden', |  |                 'type' => 'hidden', | 
|  |                 'prototype' => true, |  |                 'prototype' => true, | 
|  |                 'mapped' => false, |  |                 'mapped' => false, | 
|  |                 'allow_add' => true, |  |                 'allow_add' => true, | 
|  |                 'allow_delete' => true, |  |                 'allow_delete' => true, | 
|  |             )) |  |             )) | 
|  |             ->add('delete_images', 'collection', array( |  |             ->add('delete_images', 'collection', array( | 
|  |                 'type' => 'hidden', |  |                 'type' => 'hidden', | 
|  |                 'prototype' => true, |  |                 'prototype' => true, | 
|  |                 'mapped' => false, |  |                 'mapped' => false, | 
|  |                 'allow_add' => true, |  |                 'allow_add' => true, | 
|  |                 'allow_delete' => true, |  |                 'allow_delete' => true, | 
|  |             )) |  |             )) | 
|  |         ; |  |         ; | 
| . |   |  |   | 
|  |   |  |         $that = $this; | 
|  |   |  |         $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($that) { | 
|  |   |  |             /** @var FormInterface $form */  | 
|  |   |  |             $form = $event->getForm(); | 
|  |   |  |             $saveImgDir = $that->app['config']['image_save_realdir']; | 
|  |   |  |             $tempImgDir = $that->app['config']['image_temp_realdir']; | 
|  |   |  |             $that->validateFilePath($form->get('delete_images'), array($saveImgDir, $tempImgDir)); | 
|  |   |  |             $that->validateFilePath($form->get('add_images'), array($tempImgDir)); | 
|  |   |  |         }); | 
|  |   |  |     } | 
|  |   |  |   | 
|  |   |  |     /** | 
|  |   |  |      * 指定された複数ディレクトリのうち、いずれかのディレクトリ以下にファイルが存在するかを確認。 | 
|  |   |  |      * | 
|  |   |  |      * @param $form FormInterface | 
|  |   |  |      * @param $dirs array | 
|  |   |  |      */  | 
|  |   |  |     private function validateFilePath($form, $dirs) | 
|  |   |  |     { | 
|  |   |  |         foreach ($form->getData() as $fileName) { | 
|  |   |  |             $fileInDir = array_filter($dirs, function ($dir) use ($fileName) { | 
|  |   |  |                 $filePath = realpath($dir.'/'.$fileName); | 
|  |   |  |                 $topDirPath = realpath($dir); | 
|  |   |  |                 return strpos($filePath, $topDirPath) === 0 && $filePath !== $topDirPath; | 
|  |   |  |             }); | 
|  |   |  |             if (!$fileInDir) { | 
|  |   |  |                 $formRoot = $form->getRoot(); | 
|  |   |  |                 $formRoot['product_image']->addError(new FormError('画像のパスが不正です。')); | 
|  |   |  |             } | 
|  |   |  |         } | 
|  |     } |  |     } | 
|  |   |  |   | 
|  |     /** |  |     /** | 
|  |      * {@inheritdoc} |  |      * {@inheritdoc} | 
|  |      */  |  |      */  | 
|  |     public function configureOptions(OptionsResolver $resolver) |  |     public function configureOptions(OptionsResolver $resolver) | 
|  |     { |  |     { | 
|  |     } |  |     } | 
|  |   |  |   | 
|  |     /** |  |     /** | 
|  |      * {@inheritdoc} |  |      * {@inheritdoc} | 
|  |      */  |  |      */  | 
|  |     public function getName() |  |     public function getName() | 
|  |     { |  |     { | 
|  |         return 'admin_product'; |  |         return 'admin_product'; | 
|  |     } |  |     } | 
|  | } |  | } | 
|  |   |  |   |