バージョン選択

フォーラム

メニュー

オンライン状況

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

サイト内検索

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

開発について

新規スレッドを追加する

スレッド表示 | 古いものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
h_tanaka
投稿日時: 2017/6/13 15:28
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1646
Re: form 内の choices をプラグイン側で変更したい
さらにアドバイスまでいただいて、泣きそうになるほど嬉しいです!
複数配送対応は必須と思いますが、これがなかなか難しそうな気はしています。。
送料の計算もいろいろ試してみないといけないですね。

またつまずくようなことがあれば、別スレッドで質問しようと思います!


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

hata
投稿日時: 2017/6/13 15:17
対応状況: −−−
長老
登録日: 2015/8/3
居住地: 宮城県(2017/09末引退)
投稿: 156
Re: form 内の choices をプラグイン側で変更したい
お疲れさまでした。

注文画面への介入は色々と不具合が起きやすいので、販売用でしたら考慮漏れがないように
以下の組み合わせの評価をしておいた方が無難です。

・配送業者毎に支払方法が異なるケース
・お届け先・支払方法などの変更時の正常系/異常系
・注文時の異常系
・クレジット決済画面からの戻り
・ポイントプラグインとの組み合わせ
・クーポンプラグインとの組み合わせ

配送業者を変えたときに、支払方法の既定値が使えなくなるようなケースがあると、画面には不正なデータの
エラーが出そうです。


それから、前に何かで配送業者名と送料が不一致になる現象があって、以下を直したことがありました。
src/Eccube/Service/ShoppingService.php
----
    public function setFormData(Order $Order, array $data)
    {

        // お問い合わせ
        $Order->setMessage($data['message']);

        // お届け先情報を更新
        $shippings = $data['shippings'];
        foreach ($shippings as $Shipping) {

            $deliveryTime = $Shipping->getDeliveryTime();
            if (!empty($deliveryTime)) {
                $Shipping->setShippingDeliveryTime($deliveryTime->getDeliveryTime());
                $Shipping->setShippingDeliveryName($Shipping->getDelivery()->getName());★追加
:
            }
条件を覚えていなくてすみませんが、そんな不具合を見つけたらお試しください。
異常系だったような...
h_tanaka
投稿日時: 2017/6/13 14:53
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1646
Re: form 内の choices をプラグイン側で変更したい
$choice_list がそのまま使えないということでしたので、 $choice を試してみたらそのままでいけました!
$choice は Delivery エンティティを配列化したものでした。

なので、最終的に次のコードでうまくいきました。

hataさん、
最後まで質問にご回答いただきありがとうございました!!

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();

            $delivery_ids = array();
            $Shippings = $form['shippings'];
            foreach ($Shippings as $Shipping) {
                $delivery = $Shipping->get('delivery');
                $options = $delivery->getConfig()->getOptions();
                $choices = $options['choices'];
                $deliveries = array();
                $choice_list = $options['choice_list']->getValues();
                foreach($choice_list as $key => $choice) {
                    if (in_array($choice, $delivery_ids)) {
                        $deliveries[] = $app['eccube.repository.delivery']->findOneBy(array('id' => $choice));    // ★エンティティを配列につめる
                    }
                }
                $data = $options['data'];  // ★dataはそのまま
                $Shipping->remove('delivery');
                $Shipping
                    ->add('delivery', 'entity', array(
                        'class' => 'Eccube\Entity\Delivery',
                        'property' => 'name',
                        'choices' => $deliveries,
                        'data' => $data,
                        'constraints' => array(
                            new Assert\NotBlank(),
                        ),
                    ));
            }
        });
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
    }

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


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

hata
投稿日時: 2017/6/13 14:43
対応状況: −−−
長老
登録日: 2015/8/3
居住地: 宮城県(2017/09末引退)
投稿: 156
Re: form 内の choices をプラグイン側で変更したい
さっき検証したときchoice_listはそのまま使えないというのがわかって(配送業者のIDしか入ってない)、
自前で配列を定義して渡していました。
まずは実在するものを1個いれて動作確認してみてください。
$update_choice_list = array('2' => 'サンプル宅配');

エンティティだとちょっとよくわからないです$choicesの方かな?
h_tanaka
投稿日時: 2017/6/13 14:27
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1646
Re: form 内の choices をプラグイン側で変更したい
なるほど!
私寝ぼけてました(^ω^)

選択肢を書き換えできるとこまでいったのですが、いざformのタイプをchoiceからentityにしようとしたらエラーになりました。
choicesをnullにするとエラーが出なくなることからchoicesに指定する型がおかしいのだとは思うのですが。。

ContextErrorException in UnitOfWork.php line 1189:
Warning: spl_object_hash() expects parameter 1 to be object, string given

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


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


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

hata
投稿日時: 2017/6/13 12:55
対応状況: −−−
長老
登録日: 2015/8/3
居住地: 宮城県(2017/09末引退)
投稿: 156
Re: form 内の choices をプラグイン側で変更したい
あとから一部書き換えるようにするだけなのでフック箇所はそのままで下記ではダメですか?
front.shopping.index.initialize:
    - [onFrontShoppingIndexInitialize, NORMAL]
--------------------------------------------------------
    protected function hogehoge(EventArgs $event)
    {
        $app = $this->app;
        $builder = $event->getArgument('builder');
        $builder->addEventListener(FormEvents::POST_SET_DATA, function ($event) use ($app) {
            ここはそのまま使えるはず。
        });
    }

    public function onFrontShoppingIndexInitialize(EventArgs $event)
    {
        $this->hogehoge($event);
    }
複数箇所あるからextensionの方がいいのかしら...

ええとsrc/Eccube/Form/Type/ShippingItemType.phpのbuildForm()で$form->addしてる$formは、
$form = $event->getForm();で取得したやつなので、さっきまでのロジックだとShippingのフォームを
取り出してましたが、それは要らなくなってformをそのまま使えるのでは?
$form->remove('delivery')->add('delivery', ... でどうですか?
h_tanaka
投稿日時: 2017/6/13 12:35
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1646
Re: form 内の choices をプラグイン側で変更したい
検証までしていただいてありがとうございます!
ご提示のコードでこちらでも動作確認できました。

あとはFormEvents::POST_SET_DATAの実装ですが、またもエラーが解決できないです。。
拡張するFormがShippingItemTypeでいいのかどうかも自信ないです。

OutOfBoundsException in Form.php line 965:
Child "shippings" does not exist.

app/Plugin/Test/Form/Extension/ShippingItemTypeExtension.php
class ShippingItemTypeExtension 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) {
            $form = $event->getForm();
            $Shippings = $form['shippings'];
        });
    }

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


----------------
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,
                    ));
            }
h_tanaka
投稿日時: 2017/6/13 11:27
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1646
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の機能やデザインのカスタマイズ承ります。

h_tanaka
投稿日時: 2017/6/13 11:12
対応状況: −−−
登録日: 2016/7/22
居住地: 愛媛県
投稿: 1646
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の機能やデザインのカスタマイズ承ります。

(1) 2 »
スレッド表示 | 古いものから 前のトピック | 次のトピック | トップ


 



ログイン


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

統計情報

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

投稿数ランキング

1
seasoft
7367
2
468
3217
3
AMUAMU
2712
4
nanasess
2313
5
umebius
2085
6
yuh
1819
7
h_tanaka
1646
8
red
1570
9
mcontact
1290
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.