[EC-CUBE]3.0.14
[Server] Google Cloud Platform
[OS]CentOS7
[PHP]5.4.16
[データベース]MySQL
[WEBサーバ]Apache2
======================================
上記環境で家具ショップを構築中の者です。
「商品詳細ページ」にて、お客様が「カートへ入れる」ボタンを押下する直前に、
「搬入経路確認は済んでいるかどうか」「組立サービスを利用するかどうか」を聞く必要があるので、
「商品詳細ページ」に、セレクトフォームを追加することにしました。
======================================
選択肢は、
「搬入経路確認はお済みですか?」
1.搬入経路OK
2.搬入経路に問題がある/又はよくわからないので連絡が欲しい
「組立サービスを利用しますか?」
1.組立を自分でやる
2.組立サービスを購入する
としました。
======================================
Eccube/Controller/ProductControllerのfront.product.detail.initializeイベントを利用し、
商品詳細ページのテンプレートコードを少し変更して、
セレクトフォームを追加するところまでは問題なくできました。
public function onFrontProductDetailInit(EventArgs $event)
{
$builder = $event->getArgument('builder');
$Product = $event->getArgument('Product');
$KaitekiProductDetailExtension = $this->app['kaiteki_product_detail_extension.repository.kaiteki_product_detail_extension']->find($Product->getId());
if($KaitekiProductDetailExtension->isNeedConstruct()){
$builder->add('plg_kaiteki_product_detail_extension_kumitateservice', 'choice', array(
'choices' => array(
'自分で組み立てる' => '自分で組み立てる',
'組立サービスを購入する' => '組立サービスを購入する',
),
'label' => 'こちらの商品は「お客様組立商品」です。組立設置サービスを購入すると、配送業者が配送後、製品組立てまでしてくれます。お一人で組立てられない方、忙しくて組み立てる時間の無い方はご利用ください。',
'mapped' => false,
'required' => false,
'placeholder' => false,
));
}
if($KaitekiProductDetailExtension->isLargeProduct()){
$builder->add('plg_kaiteki_product_detail_extension_oogatashouhin', 'choice', array(
'choices' => array(
'大型商品購入時のご注意を了解した。' => '大型商品購入時のご注意を了解した。',
'搬入について不安なので連絡を希望する。' => '搬入について不安なので連絡を希望する。',
),
'label' => 'こちらの商品は「大型商品」です。大型商品は、搬入経路のご確認が必須です。搬入経路が確保できない場合は、別途大型手数料がかかったり、お届け自体が不可能だったりする場合がございます。詳しくは以下リンクの「大型商品購入時のご注意」をお読みください。',
'mapped' => false,
'required' => false,
'placeholder' => false,
));
}
}
このように商品詳細ページで取得したフォームデータを、
以下の要領で保存して、商品購入ページ(Shopping::index)の
お問い合わせ欄に羅列表示したいです。
======================================
・商品詳細ページにてお客様が「2.搬入経路に問題がある/又はよくわからないので連絡が欲しい」、
または「2.組立サービスを購入する」を選択した時のみ、Cart内のCartItemにメッセージを保存する。
・メッセージの保存形式は[product_class_code: 搬入経路に問題がある/又はよくわからないので連絡が欲しい]、[product_class_code: 組立サービスを購入する]のようにする。
・メッセージはCartItemと紐づいている必要がある。CartItemがカートから削除された場合はメッセージも消去する必要がある。
・保存されたメッセージを「Shopping::index画面(注文確認画面)」の「お問い合わせ欄」フォームに羅列表示する。
======================================
下記の通り試してみたのですが、うまくいきません。
1.CartItemエンティティを拡張してメッセージを保存できるようにする。
CartItem.php
//プロパティ追加
private $message;
//getter追加
/**
* @return string
*/
public function getMessage()
{
return $this->message;
}
//setter追加
/**
* @param string $message
* @return CartItem
*/
public function addMessage($message)
{
$this->message .= $message;
return $this;
}
2.CartにCartItemをセットする処理の時にCartItemのmessageをコピーするように、Cart.phpも改造。
Cart.php
/**
* @param \Eccube\Entity\CartItem $AddCartItem
* @return \Eccube\Entity\Cart
*/
public function setCartItem(\Eccube\Entity\CartItem $AddCartItem)
{
$find = false;
foreach ($this->CartItems as $CartItem) {
if ($CartItem->getClassName() === $AddCartItem->getClassName() && $CartItem->getClassId() === $AddCartItem->getClassId()) {
$find = true;
$CartItem
->setPrice($AddCartItem->getPrice())
->setQuantity($AddCartItem->getQuantity())
//下の一行を追加。
->addMessage($AddCartItem->getMessage());
}
}
if (!$find) {
$this->addCartItem($AddCartItem);
}
return $this;
}
3.各Controllerから使う用に2つの関数をCartService.phpに追加。
CartService.php
/**
* @param integer $productClassId
* @param string $message
* @return \Eccube\Service\CartService
*/
public function addProductMessage($productClassId, $message)
{
$CartItem = $this->cart->getCartItemByIdentifier('Eccube\Entity\ProductClass', (string)$productClassId);
if ($CartItem) {
$CartItem->addMessage($message);
return $this;
} else {
throw new CartException('cart.product.class.not.exist');
}
}
/**
* @return string
*/
public function getAllProductMessage()
{
$message = '';
foreach($this->getCart()->getCartItems() as $CartItem){
$message .= $CartItem->getMessage();
}
return $message;
}
4.以上の改造を施した上で、商品詳細ページからカートに商品を追加する際にセレクトフォームのメッセージをCart内のCartItemエンティティに保存するように、ProductController.phpの278行目にあるtryの部分を以下のように変更しました。
ProductController::detail 278行目~
try {
$CartService = $app['eccube.service.cart'];
$CartService->addProduct($addCartData['product_class_id'], $addCartData['quantity']);
//CartItemに商品メッセージ追加
if($request->request->get('plg_kaiteki_product_detail_extension_kumitateservice')=='組立サービスを購入する'){
$CartService->addProductMessage($addCartData['product_class_id'],
$app['eccube.repository.product_class']->find($addCartData['product_class_id'])->getCode().": 組立サービスを購入する\n");
}
if($request->request->get('plg_kaiteki_product_detail_extension_oogatashouhin')=='搬入について不安なので連絡を希望する。'){
$CartService->addProductMessage($addCartData['product_class_id'],
$app['eccube.repository.product_class']->find($addCartData['product_class_id'])->getCode().": 搬入について不安なので連絡を希望する。\n");
}
$CartService->save();
//カートの中身をダンプしてみる。
dump($app['eccube.service.cart']->getCart());
======================================
以上の改造を終え、dumpでカートの中身を確認してみたところ、
商品詳細ページで商品をカートに入れた直後(Cart::indexにリダイレクトする直前)には、
きちんとCartItemにmessageが入っているのですが、、、
カート画面(Cart::index)にリダイレクトで飛ぶと、
CartItemのmessageがnullになってしまいます。。。
また、Cartオブジェクトのメモリ内の参照先や、
CartItemのメモリ内での参照先も変更になっているようです。。。
(#xxxxの部分、数字が変わっている。)
======================================
この問題、どなたか、お分かりになる方、
いらっしゃいませんでしょうか?
いらっしゃいましたら、何卒ご教授の程、
よろしくお願いいたします。