投稿者 |
スレッド |
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の機能やデザインのカスタマイズ承ります。
|
|
|