バージョン選択

フォーラム

メニュー

オンライン状況

51 人のユーザが現在オンラインです。 (40 人のユーザが フォーラム を参照しています。)
登録ユーザ: 1
ゲスト: 50
tonybrown もっと...

サイト内検索

プラグイン > 開発について > form 内の choices をプラグイン側で変更したい

開発について

新規スレッドを追加する

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
h_tanaka
投稿日時: 2017/6/12 17:02
対応状況: 解決済
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1638
form 内の choices をプラグイン側で変更したい
EC-CUBE 3.0.14

formで定義されている choice タイプの選択肢 choices をプラグイン側で変更するにはどうすればよいでしょうか?

具体的には、フロント画面の注文内容確認ページにて表示される配送方法を条件によって変更したいと思っています。

src/Eccube/Form/Type/ShippingItemType.php(抜粋)
class ShippingItemType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->addEventListener(FormEvents::PRE_SET_DATA, function ($event) use ($app) {
                $form
                    ->add('delivery', 'entity', array(
                        'class' => 'Eccube\Entity\Delivery',
                        'property' => 'name',
                        'choices' => $deliveries,        // ★変更したい選択肢
                        'data' => $delivery,
                        'constraints' => array(
                            new Assert\NotBlank(),
                        ),
                    ));
            })
    }


src/Eccube/Controller/ShoppingController.php
134行目の
EccubeEvents::FRONT_SHOPPING_INDEX_INITIALIZE
にてプラグインを呼び出します。

app/Plugin/Test/event.yml
# 注文内容確認
front.shopping.index.initialize:
    - [onFrontShoppingIndexInitialize, NORMAL]


app/Plugin/Test/Event.php
    /**
     * フロント画面:注文内容確認ページで配送方法を変更
     *
     * @param EventArgs $event
     */
    public function onFrontShoppingIndexInitialize(EventArgs $event)
    {
        $app = $this->app;
        if ($app->isGranted('ROLE_ADMIN')) {
            return;
        }

        $builder = $event->getArgument('builder');
        if (empty($builder)) {
            return;
        }
        $Order = $event->getArgument('Order');
        if (empty($Order)) {
            return;
        }

        $form = $builder->getForm();
        $Shippings = $form->get('shippings')->getData();
        if (!empty($Shippings)) {
            foreach ($Shippings as $key => $Shipping) {
                $Delivery = $Shipping->getDelivery();
                if ($Delivery) {
                  // ★choicesを変えたい
                }
            }
        }


----------------
EC-CUBE 《プラチナ》ランクパートナー
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

hata
投稿日時: 2017/6/12 19:16
対応状況: −−−
長老
登録日: 2015/8/3
居住地: 宮城県(2017/09末引退)
投稿: 156
Re: form 内の choices をプラグイン側で変更したい
こうかな?
                $options = $Delivery->getConfig()->getOptions();
                $choices = $options['choices'];
                $choice_list = $options['choice_list']->getValues();★元のが見たい時はこれ(だったかな...)を使って
                $update_choice_list = array('xx' => 'xxxxx');★変更したいものを突っ込む
                $Shipping->remove('delivery');
                $Shipping->add('delivery', 'choice', array(
                        'choices' => $update_choice_list,
                        'required' => true,
                        'empty_value' => false,
                        'mapped' => false,
                    ));
h_tanaka
投稿日時: 2017/6/13 10:14
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1638
Re: form 内の choices をプラグイン側で変更したい
hataさん

ありがとうございます。

でも怒られちゃいました。

UndefinedMethodException in Event.php line 637:
Attempted to call an undefined method named "remove" of class "Eccube\Entity\Shipping".
Did you mean to call "removeShipmentItem"?


----------------
EC-CUBE 《プラチナ》ランクパートナー
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

hata
投稿日時: 2017/6/13 10:23
対応状況: −−−
長老
登録日: 2015/8/3
居住地: 宮城県(2017/09末引退)
投稿: 156
Re: form 内の choices をプラグイン側で変更したい
あ。ここを
$Shippings = $form->get('shippings')->getData();
こうしてみてください。
$Shippings = $form->get('shippings');
h_tanaka
投稿日時: 2017/6/13 10:31
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1638
Re: form 内の choices をプラグイン側で変更したい
エラーは出なくなりましたが、選択肢は変更前と変わらずです。
ちなみに処理が通っていることは確認しています。
うむむ。。


        $form = $builder->getForm();
        $Shippings = $form->get('shippings');
        if (!empty($Shippings)) {
            foreach ($Shippings as $key => $Shipping) {
                $deliveries = null;
                $Shipping->remove('delivery')
                    ->add('delivery', 'entity', array(
                        'class' => 'Eccube\Entity\Delivery',
                        'property' => 'name',
                        'choices' => $deliveries,
//                        'data' => $delivery,
                        'constraints' => array(
                            new Assert\NotBlank(),
                        ),
                    ));


----------------
EC-CUBE 《プラチナ》ランクパートナー
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

h_tanaka
投稿日時: 2017/6/13 10:38
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1638
Re: form 内の choices をプラグイン側で変更したい
EC-CUBE本体で定義している箇所を直接変更してみましたが変わりませんでした。
表示しているフォームはこれじゃない??

src/Eccube/Form/Type/ShippingItemType.php

                $form
                    ->add('delivery', 'entity', array(
                        'class' => 'Eccube\Entity\Delivery',
                        'property' => 'name',
                        'choices' => $deliveries,    // ★ここをnullにしても変わらない
                        'data' => $delivery,
                        'constraints' => array(
                            new Assert\NotBlank(),
                        ),
                    ))


src/Eccube/Resource/template/default/Shopping/index.twig

                            <div id="shopping_confirm_box__shipping_delivery--{{ idx }}" class="form-inline form-group">
                                <label>配送方法</label>
                                {{ form_widget(form.shippings[idx].delivery, {'attr': {'class': 'delivery'}}) }}
                                {{ form_errors(form.shippings[idx].delivery) }}
                            </div>


----------------
EC-CUBE 《プラチナ》ランクパートナー
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

hata
投稿日時: 2017/6/13 10:56
対応状況: −−−
長老
登録日: 2015/8/3
居住地: 宮城県(2017/09末引退)
投稿: 156
Re: form 内の choices をプラグイン側で変更したい
追加したロジックの直後とフックポイントの直後で$builder->getForm()するとchoicesの値は変わっていないで
しょうか?
ほかのプラグインや後続の処理でリセットされるのでしょうか?

eventのパラメータみたいにどこかにsetし直してどうにかなる問題ならよいですが、もし書き換えられないよう
でしたら、FormEvents::POST_SET_DATAで入れ替えるのが無難かもしれません。

それからほかの関数でも return $app->render('Shopping/index.twig ... が複数箇所あるのでそれらの全部に
対処が必要みたいですね。念のためこちらもお忘れなく。
h_tanaka
投稿日時: 2017/6/13 11:12
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1638
Re: form 内の choices をプラグイン側で変更したい
フックポイント直後でchoicesを出力させるために次のように実装しましたがエラーになりました。
UndefinedMethodException in ShoppingController.php line 144:
Attempted to call an undefined method named "getConfig" of class "Eccube\Entity\Delivery".

src/Eccube/Controller/ShoppingController.php

$app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_INDEX_INITIALIZE, $event);
$form = $builder->getForm();
$Shippings = $form->get('shippings')->getData();
if (!empty($Shippings)) {
    foreach ($Shippings as $key => $Shipping) {
        $Delivery = $Shipping->getDelivery();
        if ($Delivery) {
            $options = $Delivery->getConfig()->getOptions();
            $choices = $options['choices'];
            $choice_list = $options['choice_list']->getValues();
            var_dump($choice_list);
        }
    }
}


なお、プラグインは他に何も入れていません。

それから、FormEvents::POST_SET_DATA でのchoicesの変更も試してみましたが選択肢は変わらなかったです。

app/Plugin/Test/Form/Extension/ShoppingTypeExtension.php

class ShoppingTypeExtension extends AbstractTypeExtension
{
    public $app;

    public function __construct($app)
    {
        $this->app = $app;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $app = $this->app;
        if ($app->isGranted('ROLE_ADMIN')) {
            return;
        }

        $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) use ($app) {
            $delivery_id = null;
            $form = $event->getForm();
            $Shippings = $form->get('shippings');
            if (!empty($Shippings)) {
                foreach ($Shippings as $key => $Shipping) {
                    $deliveries = null;
                    $Shipping->remove('delivery');
                    $Shipping
                        ->add('delivery', 'entity', array(
                            'class' => 'Eccube\Entity\Delivery',
                            'property' => 'name',
                            'choices' => $deliveries,
    //                        'data' => $delivery,
                            'constraints' => array(
                                new Assert\NotBlank(),
                            ),
                        ));
                }
            }
        });
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
    }

    public function getExtendedType()
    {
        return 'shopping';
    }
}


----------------
EC-CUBE 《プラチナ》ランクパートナー
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

h_tanaka
投稿日時: 2017/6/13 11:27
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1638
Re: form 内の choices をプラグイン側で変更したい
上記ShoppingTypeExtension.phpの
                    $Shipping->remove('delivery');

直後にvar_dump($Shipping);してみましたが、modelData、normData、viewDataのいずれもDeliveryが存在していました。

object(Symfony\Component\Form\Form)[3306]
  private 'modelData' => 
    object(Eccube\Entity\Shipping)[2942]
      private 'Delivery' => 
        object(Eccube\Entity\Delivery)[2932]
  private 'normData' => 
    object(Eccube\Entity\Shipping)[2942]
      private 'Delivery' => 
        object(Eccube\Entity\Delivery)[2932]
  private 'viewData' => 
    object(Eccube\Entity\Shipping)[2942]
      private 'Delivery' => 
        object(Eccube\Entity\Delivery)[2932]


----------------
EC-CUBE 《プラチナ》ランクパートナー
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

hata
投稿日時: 2017/6/13 11:58
対応状況: −−−
長老
登録日: 2015/8/3
居住地: 宮城県(2017/09末引退)
投稿: 156
Re: form 内の choices をプラグイン側で変更したい
検証してみました。
下記のロジックを追加してみたところ配送業者を入れ替えられたので、$form = $builder->getForm();で
再設定されるのではないでしょうか?
ということはFormEvents::POST_SET_DATAで入れ替えるのが妥当なようです。
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_INDEX_INITIALIZE, $event);

        $form = $builder->getForm();
★↓ここに追加★
            $formShippings = $form['shippings'];

            foreach ($formShippings as $formShipping) {
                $Shipping = $formShipping->getData();★ちょっとわかりやすいようにformShippingとShippingを書いてみました。
                $ShipmentItems = $Shipping->getShipmentItems();★↑↓こんな感じで使うShippingとちょっと混同しそうなので。
                foreach ($ShipmentItems as $ShipmentItem) {
                }

★↓こっちがフォームの方
dump($formShipping);
                $delivery = $formShipping->get('delivery');
dump($delivery);
                $options = $delivery->getConfig()->getOptions();
dump($options);
                $choices = $options['choices'];
dump($choices);
                $choice_list = $options['choice_list']->getValues();
dump($choice_list);
                $update_choice_list = array('2' => 'サンプル宅配');
                $delivery = $formShipping->get('delivery');
dump($delivery);
                $formShipping->remove('delivery');
//                $delivery = $formShipping->get('delivery');
//dump($delivery);★ちなみに↑のコメントを外すとchildにdeliveryが無いとエラーになるのでremoveはできていました。
                $formShipping->add('delivery', 'choice', array(
                        'choices' => $update_choice_list,
                        'required' => true,
                        'empty_value' => false,
                        'mapped' => false,
                    ));
            }
(1) 2 »
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ


 



ログイン


EC-CUBE公式 Amazon Payプラグイン

統計情報

総メンバー数は88,714名です
総投稿数は109,952件です

投稿数ランキング

1
seasoft
7367
2
468
3217
3
AMUAMU
2712
4
nanasess
2313
5
umebius
2085
6
yuh
1819
7
h_tanaka
1638
8
red
1570
9
mcontact
1285
10
tsuji
958
11
fukap
907
12
shutta
835
13
tao_s
799
14 ramrun 789
15 karin 689
16 sumida 641
17
homan
633
18 DELIGHT 572
19
patapata
502
20
flealog
485


ネットショップの壺

EC-CUBEインテグレートパートナー

Copyright© EC-CUBE CO.,LTD. All Rights Reserved.