TRAJOIN is an Application to Translate symfony documents Jointly.

home > 1.2/cookbook/en > shopping_cart.txt

Edit this page

Show Markdown text

ショッピングカートを管理する方法


概要


symfonyはEビジネスウェブサイトにおいてショッピングカートを管理するプラグインを提供します。アイテムを追加し、量を変更しショッピングカートの内容を表示することは簡単で苦痛無しです。


インストール


The shopping cart classes are are not shipped with the default symfony installation, but packaged into a plugin called sfShoppingCart. Symfony plugins are installed via PEAR (find more about plugins in Chapter 17).


sfShoppingCartプラグインのインストールはプラグインページで説明されているように、とてもわかりやすいです。次のコマンドラインを入力する必要があるだけです:


$ symfony plugin:install sfShoppingCartPlugin

プラグインのクラス上のオートロードを有効にするためにキャッシュをクリアして下さい:


$ symfony cc

コンストラクタ


sfShoppingCartクラスはショッピングカートを管理することを目的としています。様々な種類のオブジェクトを含むことが出来ます。


コンストラクタはショッピングカートに適応する税率を宣言することを可能にします:



$my_shopping_cart = new sfShoppingCart(sfConfig::get('app_cart_tax'));

この例において。ショッピングカートの税率は簡単に変更するためにアプリケーションのapp.xml環境設定ファイルに書かれます:


all:
  cart:
    tax:  19.6

ユーザーのショッピングカートを作成する


newコンストラクタによるアクションで新しいsfShoppingCartオブジェクトを簡単に作成できます。しかしながら、ユーザーセッションにリンクされないのであれば何の役にも立ちません。ショッピングカートでユーザーの選択を保持するもっとも簡単な方法はsfShoppingCartオブジェクトの[構成][1]をsfUserオブジェクトにすることです。それをするために、カスタムメソッドをmyproject/apps/myapp/lib/myUser.phpクラスに追加して下さい:



class myUser extends sfUser
{
  public function getShoppingCart()
  {
    if (!$this->hasAttribute('shopping_cart'))
    {
      $this->setAttribute('shopping_cart', new sfShoppingCart(sfConfig::get('app_cart_tax')));
    }

    return $this->getAttribute('shopping_cart');
  }

  // ...
}

$user->getShoppingCart()メソッドはユーザーがまだ作成していないのであれば新しいショッピングカートを作成します。


: if you need more information about the way to override the default sfUser class by a custom myUser class, you should read the section about factories in Chapter 17.


項目を追加、修正、削除する


ショッピングカートは異なったクラスからのオブジェクトの量を含むことが出来ます。ショッピングカートに保存されたそれぞれのアイテムはsfShoppingCartItemクラスのインスタンスです。


sfShoppingCartクラスはaddItem()deleteItem()メソッドを持ちます。オブジェクトのタイプを追加もしくは削除することができるので、これらのメソッドコールの最初の引数はオブジェクトのクラス名です。


一つのアイテムの量を修正するために、sfShoppingCartItemオブジェクト自身(sfShoppingCartオブジェクトのgetItems()メソッド経由で)を取得しsetQuantity()`メソッドを呼び出します。


ショッピングカートモジュール


'Product'クラス(製品を表す)のオブジェクトが'add'、'update'と'delete'アクションによって追加、修正もしくは制限することが出来るショッピングカートマネジメントのモジュール実装です:



class shoppingcartActions extends sfActions
{
  // ...

  public function executeIndex()
  {
    $this->shopping_cart = $shopping_cart;
    $this->items = $shopping_cart->getItems();

    // ...
  }

  public function executeAdd($request)
  {
    // ...

    if ($request->hasParameter('id'))
    {
      $product = ProductPeer::retrieveByPk($request->getParameter('id'));
      $item = new sfShoppingCartItem('Product', $request->getParameter('id'));
      $item->setQuantity(1);
      $item->setPrice($product->getPrice());
      $shopping_cart = $this->getUser()->getShoppingCart();
      $shopping_cart->addItem($item);
    }

    // ...
  }

  public function executeUpdate($request)
  {
    $shopping_cart = $this->getUser()->getShoppingCart();
    foreach ($shopping_cart->getItems() as $item)
    {
      if ($request->hasParameter('quantity_'.$item->getId()))
      {
        $item->setQuantity($request->getParameter('quantity_'.$item->getId()));
      }
    }

    // ...
  }

  public function executeDelete($request)
  {
    if ($request->hasParameter('id'))
    {
      $shopping_cart = $this->getUser()->getShoppingCart();
      $shopping_cart->deleteItem('Product', $requets->getParameter('id'));
    }

    // ...
  }

  ...
}

項目を追加する


このコードをより詳しく見てみましょう。


ショッピングカートにアイテムを追加するために、addItem()メソッドを呼び出し、sfShoppingCartItemオブジェクトを渡します。このオブジェクトはオブジェクトクラス、追加されるアイテムのユニークID、追加される量、アイテムの価格を含みます。このことによってショッピングカートがどのクラスのオブジェクトを含むことを可能にします。この例においては、本とCDを含むショッピングカートを持つことが出来ます。


バックオフィスにおいて製品の価格が修正される場合(もしくはカートがセッションの期間を保持する場合)、 製品追加と会計の間の価格の違いを避けるためにこの瞬間の価格は保存されます。このことによってクライアントによって注文された量に従って価格のディスカウントを提供することも可能になります:



if ($quantity > 10)
{
  $item->setPrice($product->getPrice() * 0.8);
}
else
{
  $item->setPrice($product->getPrice());
}

問題はこの方法でディスカウントを提供する場合オリジナルの価格を失ってしまうことです。sfShoppingCartItemオブジェクトがディスカウント率を予期するsetDiscount()メソッドを持つ理由です:



if ($quantity > 10)
{
  $item->setPrice($product->getPrice());
  $item->setDiscount(20);
}
else
{
  $item->setPrice($product->getPrice());
}

項目を修正する


アイテムの量を変更するために、sfShoppingCartItemオブジェクトのsetQuantity()メソッドを使用して下さい。 アイテムを削除するために、deleteItem()メソッドを呼び出す、もしくはsetQuantity(0)を呼び出すことで量を0に変更することが出来ます。


ユーザーが同じアイテム(同じクラスと同じid)を何度も追加する場合、ショッピングカートはアイテムの量を増加させ、新しいものは追加しません:



$item = new sfShoppingCartItem('Product', $request->getParameter('id'));
$item->setQuantity(1);
$item->setPrice($product->getPrice());
$shopping_cart = $this->getUser()->getShoppingCart();
$shopping_cart->addItem($item);
$shopping_cart->addItem($item);

// 同じ

$item = new sfShoppingCartItem('Product', $request->getParameter('id'));
$item->setQuantity(2);
$item->setPrice($product->getPrice());
$shopping_cart = $this->getUser()->getShoppingCart();
$shopping_cart->addItem($item);

結局、updateアクションが'id=2313&quantity=4'の代わりに'quantity_2313=4'のような引数を使用するのは何故なのかと不思議に思うかもしれません。当然のことながら、このアクションが実装されている方法によって一度に複数の記事の量の更新を可能にします。


ショッピングカート全体を削除する


ショッピングカートをリセットするためにsfShoppingCartインスタンスのclear()メソッドを呼び出します。



$this->getUser()->getShoppingCart()->clear();

テンプレートにショッピングカートを表示する


shoppingcart/indexアクションはショッピングカートの内容を表示します。可能な実装を試してみましょう。


ショッピングカートの内容を取得する


sfShoppingCartオブジェクトの3つのメソッドがショッピングカートの内容を手助けしてくれます:


  • ショッピングカートにあるすべてのsfShoppingCartItemオブジェクトの配列
  • ->getItem($class_name, $object_id): sfShoppingCartItemオブジェクトの特定の一つ
  • ->getTotal(): ショッピングカートの総量(それぞれのアイテムごとの量×価格の合計)

Shopping cart items also have a parameter holder. This means that you can add custom information to any item.


例えば、自動車の部品を売るウェブサイトにおいて、sfShoppingCartItemオブジェクトは追加されたオブジェクトを保存する必要がありますが、どの部品が購入されるために乗用車も保存します。これは次のコードを追加することでシンプルに行われます:



$item->setParameter('vehicle', $vehicle_id);

: getItems()の代わりにgetObjects()メソッドが必要かもしれません。このメソッドは存在しますが、[Propel][2]データアクセスレイヤーに依存します。Propelの使用はオプションなので、それを使用することはできないかもしれません。データアクセスレイヤーーについては8章でもっと多くのことを学んで下さい。


値をテンプレートに渡す


ショッピングカートの内容を表示するために、indexアクションはテンプレートにアクセスできるいくつかの変数を定義しなければなりません:



// ...

$this->shopping_cart = $shopping_cart;
$this->items = $shopping_cart->getItems();

次の例はそれぞれのアイテムについての情報を示すショッピングカートのすべてのアイテムについてのイテレーションに基づいたindexSuccess.phpテンプレートを示しています:



<?php if ($shopping_cart->isEmpty()): ?>

  Your shopping cart is empty.

<?php else: ?>

  <?php foreach ($items as $item): ?>
    <?php $object = call_user_func(array($item->getClass().'Peer', 'retrieveByPK'), $item->getId()) ?> 
    <?php echo $object->getLabel() ?><br />
    <?php echo $item->getQuantity() ?><br />
    <?php echo currency_format($item->getPrice(), 'EUR' ) ?> 
    <?php if ($item->getDiscount()): >
       (- <?php echo $item->getDiscount() ?> %)
    <?php endif; ?><br />
  <?php endforeach; ?>

  Total : <?php echo currency_format($shopping_cart->getTotal(), 'EUR' ) ?><br />

<?php endif; ?>

この例でPropelデータアクセスレイヤーが使用していることを留意して下さい。あなたのプロジェクトが他のデータベースアクセスレイヤーーを使用している場合、この例は改作する必要があるかもしれません。


税金有りもしくは無し


デフォルトでは、すべての実行($shoppinng_cart->addItem()に加えて、$get->getPrice()$shopping_cart->getTotal()でのアクセス)は税無しで価格を使用します。


税を伴う合計金額を取得するために、次のコードを呼び出さなければなりません:



$total_with_taxes = $shopping_cart->getTotalWithTaxes()

必要な場合、sfShoppingCartオブジェクトは初期化されaddgetメソッドは税を含む価格を使用します:



class myUser extends sfUser
{
  public function getShoppingCart()
  {
    if (!$this->hasAttribute('shopping_cart'))
    {
      $this->setAttribute('shopping_cart', new sfShoppingCart(sfConfig::get('app_cart_tax')));
    }
    $this->getAttribute('shopping_cart')->setUnitPriceWithTaxes(sfConfig::get('app_cart_withtaxes'));

    return $this->getAttribute('shopping_cart');
  }

  // ...
}

APP_CART_WITHTAXEStrueに設定される場合、$shopping_cart->addItem()$item->getPrice()メソッドは税を伴う価格を使用します。getTotal()getTotalWithTaxes()メソッドはまだ正しい結果を与えます。


繰り返しますが、環境設定ファイルに税の環境設定を保存することは良い習慣です: 上記の例ではシンプルなtrueの代わりにAPP_CART_WITHTAXES定数を使用するのはそういうわけです。myproject/apps/myapp/config/app.ymlは次の内容を含みます:



all:
  cart:
    tax:       19.6
    withtaxes: true

税が処理される方法に信頼がおけない場合、ショッピングカートに尋ねて下さい:



$uses_tax = $shopping_cart->getUnitPriceWithTaxes();


Show Markdown text

Menu

Documentation



block contents