| <?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/ |
| * |
| * |
| * For the full copyright and license information, please view the LICENSE |
| * For the full copyright and license information, please view the LICENSE |
| * file that was distributed with this source code. |
| * file that was distributed with this source code. |
| */ |
| */ |
| |
| |
| namespace Eccube\Form\Type\Admin; |
| namespace Eccube\Form\Type\Admin; |
| |
| |
| use Eccube\Common\EccubeConfig; |
| use Eccube\Common\EccubeConfig; |
| use Eccube\Entity\Category; |
| use Eccube\Entity\Category; |
| use Eccube\Form\Type\Master\ProductStatusType; |
| use Eccube\Form\Type\Master\ProductStatusType; |
| use Eccube\Form\Validator\TwigLint; |
| use Eccube\Form\Validator\TwigLint; |
| use Eccube\Repository\CategoryRepository; |
| use Eccube\Repository\CategoryRepository; |
| use Symfony\Bridge\Doctrine\Form\Type\EntityType; |
| use Symfony\Bridge\Doctrine\Form\Type\EntityType; |
| use Symfony\Component\Form\AbstractType; |
| use Symfony\Component\Form\AbstractType; |
| use Symfony\Component\Form\Extension\Core\Type\ChoiceType; |
| use Symfony\Component\Form\Extension\Core\Type\ChoiceType; |
| use Symfony\Component\Form\Extension\Core\Type\CollectionType; |
| use Symfony\Component\Form\Extension\Core\Type\CollectionType; |
| use Symfony\Component\Form\Extension\Core\Type\FileType; |
| use Symfony\Component\Form\Extension\Core\Type\FileType; |
| use Symfony\Component\Form\Extension\Core\Type\HiddenType; |
| use Symfony\Component\Form\Extension\Core\Type\HiddenType; |
| use Symfony\Component\Form\Extension\Core\Type\TextareaType; |
| use Symfony\Component\Form\Extension\Core\Type\TextareaType; |
| use Symfony\Component\Form\Extension\Core\Type\TextType; |
| use Symfony\Component\Form\Extension\Core\Type\TextType; |
| 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 CategoryRepository |
| * @var CategoryRepository |
| */ |
| */ |
| protected $categoryRepository; |
| protected $categoryRepository; |
| |
| |
| /** |
| /** |
| * @var EccubeConfig |
| * @var EccubeConfig |
| */ |
| */ |
| protected $eccubeConfig; |
| protected $eccubeConfig; |
| |
| |
| /** |
| /** |
| * ProductType constructor. |
| * ProductType constructor. |
| * |
| * |
| * @param CategoryRepository $categoryRepository |
| * @param CategoryRepository $categoryRepository |
| * @param EccubeConfig $eccubeConfig |
| * @param EccubeConfig $eccubeConfig |
| */ |
| */ |
| public function __construct( |
| public function __construct( |
| CategoryRepository $categoryRepository, |
| CategoryRepository $categoryRepository, |
| EccubeConfig $eccubeConfig |
| EccubeConfig $eccubeConfig |
| ) { |
| ) { |
| $this->categoryRepository = $categoryRepository; |
| $this->categoryRepository = $categoryRepository; |
| $this->eccubeConfig = $eccubeConfig; |
| $this->eccubeConfig = $eccubeConfig; |
| } |
| } |
| |
| |
| /** |
| /** |
| * {@inheritdoc} |
| * {@inheritdoc} |
| */ |
| */ |
| public function buildForm(FormBuilderInterface $builder, array $options) |
| public function buildForm(FormBuilderInterface $builder, array $options) |
| { |
| { |
| $builder |
| $builder |
| // 商品規格情報 |
| // 商品規格情報 |
| ->add('class', ProductClassType::class, [ |
| ->add('class', ProductClassType::class, [ |
| 'mapped' => false, |
| 'mapped' => false, |
| ]) |
| ]) |
| // 基本情報 |
| // 基本情報 |
| ->add('name', TextType::class, [ |
| ->add('name', TextType::class, [ |
| 'constraints' => [ |
| 'constraints' => [ |
| new Assert\NotBlank(), |
| new Assert\NotBlank(), |
| new Assert\Length(['max' => $this->eccubeConfig['eccube_stext_len']]), |
| new Assert\Length(['max' => $this->eccubeConfig['eccube_stext_len']]), |
| ], |
| ], |
| ]) |
| ]) |
| ->add('product_image', FileType::class, [ |
| ->add('product_image', FileType::class, [ |
| 'multiple' => true, |
| 'multiple' => true, |
| 'required' => false, |
| 'required' => false, |
| 'mapped' => false, |
| 'mapped' => false, |
| ]) |
| ]) |
| ->add('description_detail', TextareaType::class, [ |
| ->add('description_detail', TextareaType::class, [ |
| 'constraints' => [ |
| 'constraints' => [ |
| new Assert\Length(['max' => $this->eccubeConfig['eccube_ltext_len']]), |
| new Assert\Length(['max' => $this->eccubeConfig['eccube_ltext_len']]), |
| ], |
| ], |
| ]) |
| ]) |
| ->add('description_list', TextareaType::class, [ |
| ->add('description_list', TextareaType::class, [ |
| 'required' => false, |
| 'required' => false, |
| 'constraints' => [ |
| 'constraints' => [ |
| new Assert\Length(['max' => $this->eccubeConfig['eccube_ltext_len']]), |
| new Assert\Length(['max' => $this->eccubeConfig['eccube_ltext_len']]), |
| ], |
| ], |
| ]) |
| ]) |
| ->add('Category', ChoiceType::class, [ |
| ->add('Category', ChoiceType::class, [ |
| 'choice_label' => 'Name', |
| 'choice_label' => 'Name', |
| 'multiple' => true, |
| 'multiple' => true, |
| 'mapped' => false, |
| 'mapped' => false, |
| 'expanded' => true, |
| 'expanded' => true, |
| 'choices' => $this->categoryRepository->getList(null, true), |
| 'choices' => $this->categoryRepository->getList(null, true), |
| 'choice_value' => function (Category $Category = null) { |
| 'choice_value' => function (Category $Category = null) { |
| return $Category ? $Category->getId() : null; |
| return $Category ? $Category->getId() : null; |
| }, |
| }, |
| ]) |
| ]) |
| |
| |
| // 詳細な説明 |
| // 詳細な説明 |
| ->add('Tag', EntityType::class, [ |
| ->add('Tag', EntityType::class, [ |
| 'class' => 'Eccube\Entity\Tag', |
| 'class' => 'Eccube\Entity\Tag', |
| 'query_builder' => function ($er) { |
| 'query_builder' => function ($er) { |
| return $er->createQueryBuilder('t') |
| return $er->createQueryBuilder('t') |
| ->orderBy('t.sort_no', 'DESC'); |
| ->orderBy('t.sort_no', 'DESC'); |
| }, |
| }, |
| 'required' => false, |
| 'required' => false, |
| 'multiple' => true, |
| 'multiple' => true, |
| 'expanded' => true, |
| 'expanded' => true, |
| 'mapped' => false, |
| 'mapped' => false, |
| ]) |
| ]) |
| ->add('search_word', TextType::class, [ |
| ->add('search_word', TextType::class, [ |
| 'required' => false, |
| 'required' => false, |
| 'constraints' => [ |
| 'constraints' => [ |
| new Assert\Length(['max' => $this->eccubeConfig['eccube_ltext_len']]), |
| new Assert\Length(['max' => $this->eccubeConfig['eccube_ltext_len']]), |
| ], |
| ], |
| ]) |
| ]) |
| // サブ情報 |
| // サブ情報 |
| ->add('free_area', TextareaType::class, [ |
| ->add('free_area', TextareaType::class, [ |
| 'required' => false, |
| 'required' => false, |
| 'constraints' => [ |
| 'constraints' => [ |
| new TwigLint(), |
| new TwigLint(), |
| ], |
| ], |
| ]) |
| ]) |
| |
| |
| // 右ブロック |
| // 右ブロック |
| ->add('Status', ProductStatusType::class, [ |
| ->add('Status', ProductStatusType::class, [ |
| 'constraints' => [ |
| 'constraints' => [ |
| new Assert\NotBlank(), |
| new Assert\NotBlank(), |
| ], |
| ], |
| ]) |
| ]) |
| ->add('note', TextareaType::class, [ |
| ->add('note', TextareaType::class, [ |
| 'required' => false, |
| 'required' => false, |
| 'constraints' => [ |
| 'constraints' => [ |
| new Assert\Length(['max' => $this->eccubeConfig['eccube_ltext_len']]), |
| new Assert\Length(['max' => $this->eccubeConfig['eccube_ltext_len']]), |
| ], |
| ], |
| ]) |
| ]) |
| |
| |
| // タグ |
| // タグ |
| ->add('tags', CollectionType::class, [ |
| ->add('tags', CollectionType::class, [ |
| 'entry_type' => HiddenType::class, |
| 'entry_type' => HiddenType::class, |
| 'prototype' => true, |
| 'prototype' => true, |
| 'mapped' => false, |
| 'mapped' => false, |
| 'allow_add' => true, |
| 'allow_add' => true, |
| 'allow_delete' => true, |
| 'allow_delete' => true, |
| ]) |
| ]) |
| // 画像 |
| // 画像 |
| ->add('images', CollectionType::class, [ |
| ->add('images', CollectionType::class, [ |
| 'entry_type' => HiddenType::class, |
| 'entry_type' => HiddenType::class, |
| 'prototype' => true, |
| 'prototype' => true, |
| 'mapped' => false, |
| 'mapped' => false, |
| 'allow_add' => true, |
| 'allow_add' => true, |
| 'allow_delete' => true, |
| 'allow_delete' => true, |
| ]) |
| ]) |
| ->add('add_images', CollectionType::class, [ |
| ->add('add_images', CollectionType::class, [ |
| 'entry_type' => HiddenType::class, |
| 'entry_type' => HiddenType::class, |
| 'prototype' => true, |
| 'prototype' => true, |
| 'mapped' => false, |
| 'mapped' => false, |
| 'allow_add' => true, |
| 'allow_add' => true, |
| 'allow_delete' => true, |
| 'allow_delete' => true, |
| ]) |
| ]) |
| ->add('delete_images', CollectionType::class, [ |
| ->add('delete_images', CollectionType::class, [ |
| 'entry_type' => HiddenType::class, |
| 'entry_type' => HiddenType::class, |
| 'prototype' => true, |
| 'prototype' => true, |
| 'mapped' => false, |
| 'mapped' => false, |
| 'allow_add' => true, |
| 'allow_add' => true, |
| 'allow_delete' => true, |
| 'allow_delete' => true, |
| ]) |
| ]) |
| ->add('return_link', HiddenType::class, [ |
| ->add('return_link', HiddenType::class, [ |
| 'mapped' => false, |
| 'mapped' => false, |
| ]) |
| ]) |
| ; |
| ; |
. | |
| |
| |
| $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) { |
| |
| /** @var FormInterface $form */ |
| |
| $form = $event->getForm(); |
| |
| $saveImgDir = $this->eccubeConfig['eccube_save_image_dir']; |
| |
| $tempImgDir = $this->eccubeConfig['eccube_temp_image_dir']; |
| |
| $this->validateFilePath($form->get('delete_images'), [$saveImgDir, $tempImgDir]); |
| |
| $this->validateFilePath($form->get('add_images'), [$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) { |
| |
| $form->getRoot()['product_image']->addError(new FormError('画像のパスが不正です。')); |
| |
| } |
| |
| } |
| } |
| } |
| |
| |
| /** |
| /** |
| * {@inheritdoc} |
| * {@inheritdoc} |
| */ |
| */ |
| public function configureOptions(OptionsResolver $resolver) |
| public function configureOptions(OptionsResolver $resolver) |
| { |
| { |
| } |
| } |
| |
| |
| /** |
| /** |
| * {@inheritdoc} |
| * {@inheritdoc} |
| */ |
| */ |
| public function getBlockPrefix() |
| public function getBlockPrefix() |
| { |
| { |
| return 'admin_product'; |
| return 'admin_product'; |
| } |
| } |
| } |
| } |
| |
| |