質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Symfony2

Symphony2は、簡単で速く堅牢なプログラムの開発サイクルに焦点を当てた、オープンソースのPHPウェブアプリケーション開発フレームワークです。PHP version 5.3.3以上を対象としています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Symfony

Symfony はPHPで記述されたWebアプリケーションフレームワークです。よく利用するコーディングをテンプレーティングするなど、Webアプリケーション開発の効率化を目的として設計されています。

Silex

Silexは、Symfony2の機能を持ち、sinatoraからインスパイアされた PHP5.3以上で動作するPHPマイクロフレームワークです。

EC-CUBE

EC-CUBEは、主に日本国内で開発されているECコンテンツ管理システムです。ロックオン社のECKitを元にしてオープンソース化され、商品管理・受注管理・顧客管理・売上集計などECに特化した様々な機能を備えています。

Q&A

解決済

1回答

1797閲覧

EC-CUBE3系で商品詳細ページ(product_detail)にリダイレクトさせる方法

MyQuestioner

総合スコア57

Symfony2

Symphony2は、簡単で速く堅牢なプログラムの開発サイクルに焦点を当てた、オープンソースのPHPウェブアプリケーション開発フレームワークです。PHP version 5.3.3以上を対象としています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Symfony

Symfony はPHPで記述されたWebアプリケーションフレームワークです。よく利用するコーディングをテンプレーティングするなど、Webアプリケーション開発の効率化を目的として設計されています。

Silex

Silexは、Symfony2の機能を持ち、sinatoraからインスパイアされた PHP5.3以上で動作するPHPマイクロフレームワークです。

EC-CUBE

EC-CUBEは、主に日本国内で開発されているECコンテンツ管理システムです。ロックオン社のECKitを元にしてオープンソース化され、商品管理・受注管理・顧客管理・売上集計などECに特化した様々な機能を備えています。

0グッド

0クリップ

投稿2018/06/07 17:56

編集2018/06/09 11:35

お世話になります。

ECサイト構築に興味を持ち、先日EC-CUBE3.0.16をインストールして使用してみました。一つ気になったのが商品をカートに入れると購入画面に進まない限り商品を削除できない点です。

ECサイトを使う側からすれば少し不便かなと思いまして、カートから商品を削除する方法を色々調べてみたのですが、カートクリアボタン追加プラグイン(https://www.ec-cube.net/products/detail.php?product_id=1346)というプラグインを見つけ導入してみました。
しかし、このプラグインはどのページからでも新品を削除できるものではなく、
購入手続きの画面に入ってから機能するプラグインのようです。

EC-CUBEコミュニティで質問をしてみたのですが、返ってきた答えを見ますと自分の能力では無理そうなので、カートクリアボタン追加プラグインをカスタマイズして何とかしようと思ったのですが、リダイレクト方法がわからずに困っています。

カートクリアプラグインにはCartClearController.phpというファイルがあり、その中に「return $app->redirect($app->url('cart'));」という部分があるのですが、cartの部分を商品詳細ページ(product_detail)に変更してリダイレクトさせようするとシステムエラーが起きます。

トップページ(homepage)や商品リスト(product_list)はエラーが出ずにリダイレクトされるのですが、商品詳細ページの場合ページごとにIDが振ってあるため、単にproduct_detailを指定するだけでは上手くいかないようです。
どなたかカートクリアをすると商品詳細ページにリダイレクトされる方法をご存知の方はおられないでしょうか?

カート遷移しませんプラグインというプラグインがあって
以下のように商品をカートに入れた後、ページ遷移せずに商品詳細ページに戻ってくる記述があります。

/** * かーとに商品追加後、商品ページを表示する。 * @param \Eccube\Event\EventArgs $EventArgs */ public function toProductDetail(\Eccube\Event\EventArgs $EventArgs){ if (!$this->app['session']->getFlashBag()->has('eccube.front.request.error')) { $this->app['session']->getFlashBag()->set('eccube.front.cart.success', '購入画面に進む'); } $Product = $EventArgs->getArgument('Product'); $EventArgs->setResponse( new RedirectResponse( $this->app->url('product_detail', array('id' => $Product->getId())) ) ); }

これを何とか取り入れて商品詳細ページ(product_detail)にリダイレクトさせたいのですが、相当難しいのでしょうか?
カートの商品を削除した後に商品詳細ページ(product_detail)に戻ってくる方法を教えて頂きたいです。
よろしくお願いいたします。

※6/8追記です。
マルチポストの件は知りませんでした。
大変申し訳ありません。
EC-CUBEコミュニティで投稿した内容は以下のページです。
https://xoops.ec-cube.net/modules/newbb/viewtopic.php?topic_id=20466&forum=2

プラグインは改造しないほうが良いとのご指摘をいただきましたが、
カート削除後のリダイレクト処理を変更するという1点だけなので可能なのかなと考えていました。

自分がどうして商品詳細ページにリダイレクトさせたいかといいますと、カート遷移しませんプラグインというプラグインを使用して
購入手続き画面に行く前に合計金額と商品の数量を表示させてから
「購入へ進む」ボタンを押すようにしてあるからです。
この時に商品の数を間違えたという場合に、いったんカートをクリアできる削除ボタンがあれば便利なのではないかと。。。

カートクリアプラグインは商品詳細ページに設置できますが、
削除処理後のリダイレクト先が、商品詳細ページでないので、
なんとか商品詳細ページにリダイレクトさせたいというのが実現したいことです。

※6/8追記2です。
自分の環境を前提でお話すると分かりにくいようなので、デモを利用してご説明しますと、
例えばhttps://demo3.ec-cube.net/products/detail/23で商品をカートに入れた場合、
ショッピングカート(https://demo3.ec-cube.net/cart)に移動します。
この時、画面遷移せずに買い物カゴの商品が増え、
なおかつ買い物カゴの商品を空にできる削除ボタンが欲しいということです。
画面遷移させないプラグインはあるので、あとは買い物カゴの商品を削除する仕組みがあればと。。。
現状はショッピングカート(https://demo3.ec-cube.net/cart)の画面でないと商品の削除ができないため、
商品詳細ページ(https://demo3.ec-cube.net/products/detail/23)で買い物カゴの中身を削除する機能が
あれば使い勝手が良くなるのではと思った次第です。

EC-CUBEコミュニティで教えていただいたのは以下の部分です。

引用テキスト

カートの中身を消すには基本的に、src/Eccube/Service/CartService.phpというクラスのclearメソッドを呼べば良いので、3系ではさほど難しくはございません。
下記のように使用できます。
$app['eccube.service.cart']->clear()->save();
ボタンを押したときにこのメソッドが呼ばれるようにカスタマイズしてやればOKです。

引用テキスト

・削除ボタンをカートブロック内に追加
・削除ボタンを押すと、カート商品削除専用URLへ遷移(URLは・FrontControllerProviderでコントローラーを定義。/Block/CartClearController.phpで問題ございません)
・上記で定義したコントローラーでclearする。
・元のページにリダイレクト

※6/9追記です。
ProductController.php

public function detail(Application $app, Request $request, $id) { $BaseInfo = $app['eccube.repository.base_info']->get(); if ($BaseInfo->getNostockHidden() === Constant::ENABLED) { $app['orm.em']->getFilters()->enable('nostock_hidden'); } /* @var $Product \Eccube\Entity\Product */ $Product = $app['eccube.repository.product']->get($id); if (!$request->getSession()->has('_security_admin') && $Product->getStatus()->getId() !== 1) { throw new NotFoundHttpException(); } if (count($Product->getProductClasses()) < 1) { throw new NotFoundHttpException(); } /* @var $builder \Symfony\Component\Form\FormBuilderInterface */ $builder = $app['form.factory']->createNamedBuilder('', 'add_cart', null, array( 'product' => $Product, 'id_add_product_id' => false, )); $event = new EventArgs( array( 'builder' => $builder, 'Product' => $Product, ), $request ); $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_PRODUCT_DETAIL_INITIALIZE, $event); /* @var $form \Symfony\Component\Form\FormInterface */ $form = $builder->getForm(); if ($request->getMethod() === 'POST') { $form->handleRequest($request); if ($form->isValid()) { $addCartData = $form->getData(); if ($addCartData['mode'] === 'add_favorite') { if ($app->isGranted('ROLE_USER')) { $Customer = $app->user(); $app['eccube.repository.customer_favorite_product']->addFavorite($Customer, $Product); $app['session']->getFlashBag()->set('product_detail.just_added_favorite', $Product->getId()); $event = new EventArgs( array( 'form' => $form, 'Product' => $Product, ), $request ); $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_PRODUCT_DETAIL_FAVORITE, $event); if ($event->getResponse() !== null) { return $event->getResponse(); } return $app->redirect($app->url('product_detail', array('id' => $Product->getId()))); } else { // 非会員の場合、ログイン画面を表示 // ログイン後の画面遷移先を設定 $app->setLoginTargetPath($app->url('product_detail', array('id' => $Product->getId()))); $app['session']->getFlashBag()->set('eccube.add.favorite', true); return $app->redirect($app->url('mypage_login')); } } elseif ($addCartData['mode'] === 'add_cart') { log_info('カート追加処理開始', array('product_id' => $Product->getId(), 'product_class_id' => $addCartData['product_class_id'], 'quantity' => $addCartData['quantity'])); try { $app['eccube.service.cart']->addProduct($addCartData['product_class_id'], $addCartData['quantity'])->save(); } catch (CartException $e) { log_info('カート追加エラー', array($e->getMessage())); $app->addRequestError($e->getMessage()); } log_info('カート追加処理完了', array('product_id' => $Product->getId(), 'product_class_id' => $addCartData['product_class_id'], 'quantity' => $addCartData['quantity'])); $event = new EventArgs( array( 'form' => $form, 'Product' => $Product, ), $request ); $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_PRODUCT_DETAIL_COMPLETE, $event); if ($event->getResponse() !== null) { return $event->getResponse(); } return $app->redirect($app->url('cart')); } elseif ($addCartData['mode'] === 'clear-cart') { try { $app['eccube.service.cart']->clear()->save(); } catch (CartException $e) { log_info('カートクリアエラー', array($e->getMessage())); } return $app->redirect($app->url('product_detail', array('id' => $Product->getId()))); } } } else { $addFavorite = $app['session']->getFlashBag()->get('eccube.add.favorite'); if (!empty($addFavorite)) { // お気に入り登録時にログインされていない場合、ログイン後にお気に入り追加処理を行う if ($app->isGranted('ROLE_USER')) { $Customer = $app->user(); $app['eccube.repository.customer_favorite_product']->addFavorite($Customer, $Product); $app['session']->getFlashBag()->set('product_detail.just_added_favorite', $Product->getId()); } } }

AddCartType.php

public function validate($data, ExecutionContext $context) { if ($mode !== 'add_favorite' && $mode !== 'clear-cart') { $context->validateValue($data['product_class_id'], array( new Assert\NotBlank(), ), '[product_class_id]'); if ($this->Product->getClassName1()) { $context->validateValue($data['classcategory_id1'], array( new Assert\NotBlank(), new Assert\NotEqualTo(array( 'value' => '__unselected', 'message' => 'form.type.select.notselect' )), ), '[classcategory_id1]'); } //商品規格2初期状態(未選択)の場合の返却値は「NULL」で「__unselected」ではない if ($this->Product->getClassName2()) { $context->validateValue($data['classcategory_id2'], array( new Assert\NotBlank(), new Assert\NotEqualTo(array( 'value' => '__unselected', 'message' => 'form.type.select.notselect' )), ), '[classcategory_id2]'); } } } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2018/06/08 00:08 編集

コミュニティでどのような回答がきたのか分かりませんが、プラグインのカスタマイズとどちらがいいかというと既にできている人の回答の方が良いかと思うのですが、いかがでしょうか・・?理解できないところは聞いていって理解を深めれば良いですし。プラグインは基本的にほぼできあがったものなので、カスタマイズしようと思うとプラグインの仕様を全て理解した上で行わないと思わぬバグが発生する可能性が高いので危険かと思います。
退会済みユーザー

退会済みユーザー

2018/06/08 01:07

リダイレクトしたくないならメイン画面をターゲットにしなければいいだけじゃろ
xenbeat

2018/06/08 03:03 編集

mts10806さんが言うように第三者のプラグインをカスタマイズするというアプローチはあまりよろしくないように思います。コミュニティでも回答があるように「カートを削除するAPI」は自分で実装しなくても既に用意されているので、自分で作ったControllerからそれを呼び出せばいいだけです。
MyQuestioner

2018/06/08 04:36

皆様ご指摘ありがとうございます。 マルチポストの件は追記に記述いたしました。 また長文でわかりにくい文章だったと思いましたので、要点をまとめてみました。 ご意見がありましたらよろしくお願いいたします。
xenbeat

2018/06/08 12:22 編集

> カート削除後のリダイレクト処理を変更するという1点だけなので可能なのかなと考えていました → 可能/不可能でいうともちろん可能ですがよろしくはないというだけです。 要点をまとめていただいたとのことですが、用語(なんちゃらボタンとかなんちゃらプラグインとか)が良くわからないのでどの画面のどのボタンのことを言っていて、今導入しているプラグインがどんなことをしているのか等、いろいろわからないです。 デモ(https://demo3.ec-cube.net/)もソースコード(https://github.com/EC-CUBE/ec-cube)もあるので順を追ってどこの何が問題で自分は何をしてどこでつまづいているのか明確にしていただけますか? どのみちTeratailでは現状のソースコードを提示いただかないと回答できないです。
MyQuestioner

2018/06/08 13:03

分かりにくい説明で大変申し訳ございません。
guest

回答1

0

ベストアンサー

追記2でなんとなくやりたいことはわかったような気がします。
やり方はいくらでもあると思いますが、色々説明が大変そうなので、既存のソースコードを流用するアプローチで回答します。

Viewの修正

1.これを複製して削除ボタンを作る

HTML

1<li class="col-xs-12 col-sm-8"><button type="submit" id="clear-cart" class="btn btn-info btn-block prevention-btn prevention-mask">カートクリア</button></li>

2.これを複製して削除ボタンが押されたときにhiddenにリクエスト識別名を突っ込む

Javascript

1 $('#clear-cart').click(function() { 2 $('#mode').val('clear-cart'); 3 });
Formの修正

ここを以下のように修正

PHP

1if ($data['mode'] !== 'add_favorite' && $data['mode'] !== 'clear-cart') {
Controllerの修正

ここで以下のようなコードを入れてカートクリアのAPIを呼び出す

PHP

1} elseif ($addCartData['mode'] === 'clear-cart') { 2 try { 3 $app['eccube.service.cart']->clear()->save(); 4 } catch (CartException $e) { 5 log_info('カートクリアエラー', array($e->getMessage())); 6 } 7 return $app->redirect($app->url('product_detail', array('id' => $Product->getId()))); 8}

Githubのソースコードを見ながらの回答(未検証)なのでその点ご容赦ください。

あと、ECCUBEの3系でこのようなソースコードレベルのご質問をされる際は、[Symfony], [Symfony2], [Silex]といったタグを質問に付けたほうが、色んな視点で回答が集まりやすいと思います。
理由は、ECCUBEの3系SilexSymfony Components)を使って実装されているというのと、ECCUBE3系の知識がなくともそれらの知識を持ったエンジニアであれば回答できる内容もあるからです。

投稿2018/06/08 17:20

編集2018/06/09 12:14
xenbeat

総合スコア4258

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MyQuestioner

2018/06/09 03:21

maverixz様 ご回答有り難うございます。 自分の説明の仕方が悪く回答は得られないものと思っていたので本当にありがたいです。 回答いただいたコードは適用させるファイルは detail.twig AddCartType.php ProductController.php の3つかと思われますが、修正してアップロードしたところ 削除ボタンを押してもカートが空にならず何も起きない状態です。 具体的には、項目がある商品画面で押すと「入力されていません。」 というエラーめッサージが表示されるため 何らかのカート処理は行わているようですが、カートが空になりません。 私の記述の何処かが間違っていると思うのですが、 Viewの修正とFormの修正は問題ないように感じましたので、 Controllerの修正の記述が間違っているのかなという気がします。 該当付近の記述です。 return $app->redirect($app->url('cart')); } elseif ($addCartData['mode'] === 'clear-cart') { try { $app['eccube.service.cart']->clear()->save(); } catch (CartException $e) { log_info('カートクリアエラー', array($e->getMessage())); } return $app->redirect($app->url('product_detail', array('id' => $Product->getId()))); } } } else { $addFavorite = $app['session']->getFlashBag()->get('eccube.add.favorite'); システムエラーが出ない記述は上記のとおりなのですが、カートクリアが行われていないことから コードの挿入の仕方が違うのではないかと思っています。 それからアドバイスに従って[Symfony], [Symfony2], [Silex]の3つのタグを追加いたしました。 色々とありがとうございます。
xenbeat

2018/06/09 03:59

コメント欄にソースコードを書くと非常に見にくいので質問欄に追記ください。 途中からではなくdetailメソッドをまるごと追記ください。
MyQuestioner

2018/06/09 09:03 編集

detailメソッド丸ごとというのはどこからどこまでなのか分かりませんが、 ファイル丸ごとだと文字数制限エラーが出ますので、コメントアウト~コメントアウトのところまで 記述いたしました。
xenbeat

2018/06/09 09:20

> detailメソッド丸ごとというのはどこからどこまでなのか分かりません えっと、、、そもそもなんですがPHPのif文やメソッドは理解されていますでしょうか? 追記されたソースコードは非常に見にくく見る気になれません。 回答者の立場になってインデントをしっかり整えてメソッドの最初から最後までを省略しないで記述ください。 文字数制限エラーが出るなら質問文を整理すれば良い話でしょう。ここまでやり取りしていれば回答者にとって何が必要な情報かわかるのではないでしょうか。
MyQuestioner

2018/06/09 10:54

>えっと、、、そもそもなんですがPHPのif文やメソッドは理解されていますでしょうか? if文はif~elseまでかなというぐらいです。メソッドというのは、一つの処理が実行される塊のようなものでしょうか? >追記されたソースコードは非常に見にくく見る気になれません。 PHP整形ツールというのを使用してみましたが、github.comのようなコードが一番見やすいということでしょうか?
xenbeat

2018/06/09 11:17 編集

> if文はif~elseまでかなというぐらいです。メソッドというのは、一つの処理が実行される塊のようなものでしょうか? 調べてください。 > PHP整形ツールというのを使用してみましたが、github.comのようなコードが一番見やすいということでしょうか? 一番見やすいとかの問題ではなくて、 今マスタ(githubのソースコード)をベースにして、お互いの目線を合わせながらサポートしているのに、 インデントを崩したり、if文の途中から記載したりしないでくださいと言ってます。 PHPの基礎知識がなかったり、上記前提がずれるとまた1から色々説明することになるので正直付き合いきれないです。 ↓detailメソッド https://github.com/EC-CUBE/ec-cube/blob/master/src/Eccube/Controller/ProductController.php#L202
MyQuestioner

2018/06/09 11:44

>PHPの基礎知識がなかったり、上記前提がずれるとまた1から色々説明することになるので正直付き合いきれないです。 コミュティで情報が得られないので、優秀な方が集める本サイトでなんとか解決できないかと考えていたのですが…。厳しいでしょうか。。。
xenbeat

2018/06/09 12:17 編集

まだ見にくいですがまあ今回は初心者ということで多めにみます。 このサイトでは、回答者にたよるだけではなくてあなたの努力も必要なのですよ。 https://teratail.com/help/question-tips#questionTips3 全体踏まえて再確認しました。 おそらく原因は、私が提示したFormのソースコードですね。失礼しました。 回答に反映するのでご確認ください。
MyQuestioner

2018/06/09 12:53

maverixz様 修正頂いたコードで無事目的を達成することがdきました。 本当にご迷惑をおかけいたしました。最後までお付き合い頂きありがとうございます。 >このサイトでは、回答者にたよるだけではなくてあなたの努力も必要なのですよ。 自分でしかわからないことばかり書き連ね、回答される方に全く伝わらない文章を記述していた事を反省しております。 コードの件も勉強になりました。見づらいコードでも動けばいいというものではないのですね。 次に質問をする機会がいつあるか分かりませんが、今回の経験を活かせるように様々なこと勉強し、回答者の方が困らないような質問が出来るようになりたいです。 maverixz様には本当にお世話になりました。EC-CUBEコミュニティにも解決法を書いておきます。 ありがとうございましたm(_ _)m
退会済みユーザー

退会済みユーザー

2018/06/09 13:38

まあ、リダイレクト先をもと頁にするなら ajax でアクセスする。 iframe に向けてPOST/GETする。 という単純処理でいいんだけどね。( iframe.onload や xrh.done 等で画面更新)
xenbeat

2018/06/09 13:53

> まあ、リダイレクト先をもと頁にするなら > ajax でアクセスする。 > iframe に向けてPOST/GETする。 > という単純処理 何を持って単純と言ってるのかわからないですが、そのアプローチをとったとしてもサーバー側の修正は必要でしょう。 まあ、単純回答できるならここのコメントではなく別回答してあげてくださいな。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問