投稿者 |
スレッド |
h_tanaka |
投稿日時: 2017/6/12 17:02
対応状況: 解決済
|
神 登録日: 2016/7/22 居住地: 愛媛県 投稿: 1899 |
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 居住地: 愛媛県 投稿: 1899 |
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 居住地: 愛媛県 投稿: 1899 |
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 居住地: 愛媛県 投稿: 1899 |
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 居住地: 愛媛県 投稿: 1899 |
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 居住地: 愛媛県 投稿: 1899 |
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,
));
}
|
|
|