source: branches/version-2_13-dev/data/class/SC_CartSession.php @ 23170

Revision 23170, 29.6 KB checked in by m_uehara, 11 years ago (diff)

#2363 r23157 - r23159, r23165 - r23167, r23169 をマージ

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2013 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24/**
25 * カートセッション管理クラス
26 *
27 * @author LOCKON CO.,LTD.
28 * @version $Id$
29 */
30class SC_CartSession
31{
32    /** ユニークIDを指定する. */
33    public $key_tmp;
34
35    /** カートのセッション変数. */
36    public $cartSession;
37
38    /* コンストラクタ */
39    public function __construct($cartKey = 'cart')
40    {
41        if (!isset($_SESSION[$cartKey])) {
42            $_SESSION[$cartKey] = array();
43        }
44        $this->cartSession =& $_SESSION[$cartKey];
45    }
46
47    // 商品購入処理中のロック
48    public function saveCurrentCart($key_tmp, $productTypeId)
49    {
50        $this->key_tmp = 'savecart_' . $key_tmp;
51        // すでに情報がなければ現状のカート情報を記録しておく
52        if (count($_SESSION[$this->key_tmp]) == 0) {
53            $_SESSION[$this->key_tmp] = $this->cartSession[$productTypeId];
54        }
55        // 1世代古いコピー情報は、削除しておく
56        foreach ($_SESSION as $key => $value) {
57            if ($key != $this->key_tmp && preg_match('/^savecart_/', $key)) {
58                unset($_SESSION[$key]);
59            }
60        }
61    }
62
63    // 商品購入中の変更があったかをチェックする。
64    public function getCancelPurchase($productTypeId)
65    {
66        $ret = isset($this->cartSession[$productTypeId]['cancel_purchase'])
67            ? $this->cartSession[$productTypeId]['cancel_purchase'] : '';
68        $this->cartSession[$productTypeId]['cancel_purchase'] = false;
69
70        return $ret;
71    }
72
73    // 購入処理中に商品に変更がなかったかを判定
74    public function checkChangeCart($productTypeId)
75    {
76        $change = false;
77        $max = $this->getMax($productTypeId);
78        for ($i = 1; $i <= $max; $i++) {
79            if ($this->cartSession[$productTypeId][$i]['quantity']
80                != $_SESSION[$this->key_tmp][$i]['quantity']) {
81                $change = true;
82                break;
83            }
84            if ($this->cartSession[$productTypeId][$i]['id']
85                != $_SESSION[$this->key_tmp][$i]['id']) {
86                $change = true;
87                break;
88            }
89        }
90        if ($change) {
91            // 一時カートのクリア
92            unset($_SESSION[$this->key_tmp]);
93            $this->cartSession[$productTypeId]['cancel_purchase'] = true;
94        } else {
95            $this->cartSession[$productTypeId]['cancel_purchase'] = false;
96        }
97
98        return $this->cartSession[$productTypeId]['cancel_purchase'];
99    }
100
101    // 次に割り当てるカートのIDを取得する
102    public function getNextCartID($productTypeId)
103    {
104        $count = array();
105        foreach ($this->cartSession[$productTypeId] as $key => $value) {
106            $count[] = $this->cartSession[$productTypeId][$key]['cart_no'];
107        }
108
109        return max($count) + 1;
110    }
111
112    // 値のセット
113    public function setProductValue($id, $key, $val, $productTypeId)
114    {
115        $max = $this->getMax($productTypeId);
116        for ($i = 0; $i <= $max; $i++) {
117            if (isset($this->cartSession[$productTypeId][$i]['id'])
118                && $this->cartSession[$productTypeId][$i]['id'] == $id
119            ) {
120                $this->cartSession[$productTypeId][$i][$key] = $val;
121            }
122        }
123    }
124
125    // カート内商品の最大要素番号を取得する。
126    public function getMax($productTypeId)
127    {
128        $max = 0;
129        if (count($this->cartSession[$productTypeId]) > 0) {
130            foreach ($this->cartSession[$productTypeId] as $key => $value) {
131                if (is_numeric($key)) {
132                    if ($max < $key) {
133                        $max = $key;
134                    }
135                }
136            }
137        }
138
139        return $max;
140    }
141
142    // カート内商品数量の合計
143    public function getTotalQuantity($productTypeId)
144    {
145        $total = 0;
146        $max = $this->getMax($productTypeId);
147        for ($i = 0; $i <= $max; $i++) {
148            $total+= $this->cartSession[$productTypeId][$i]['quantity'];
149        }
150
151        return $total;
152    }
153
154    // 全商品の合計価格
155    public function getAllProductsTotal($productTypeId, $pref_id = 0, $country_id = 0)
156    {
157        // 税込み合計
158        $total = 0;
159        $max = $this->getMax($productTypeId);
160        for ($i = 0; $i <= $max; $i++) {
161            if (!isset($this->cartSession[$productTypeId][$i]['price'])) {
162                $this->cartSession[$productTypeId][$i]['price'] = '';
163            }
164
165            $price = $this->cartSession[$productTypeId][$i]['price'];
166
167            if (!isset($this->cartSession[$productTypeId][$i]['quantity'])) {
168                $this->cartSession[$productTypeId][$i]['quantity'] = '';
169            }
170            $quantity = $this->cartSession[$productTypeId][$i]['quantity'];
171            $incTax = SC_Helper_TaxRule_Ex::sfCalcIncTax($price,
172                $this->cartSession[$productTypeId][$i]['productsClass']['product_id'],
173                $this->cartSession[$productTypeId][$i]['productsClass']['product_class_id'],
174                $pref_id, $country_id);
175
176            $total+= ($incTax * $quantity);
177        }
178
179        return $total;
180    }
181
182    // 全商品の合計税金
183    public function getAllProductsTax($productTypeId, $pref_id = 0, $country_id = 0)
184    {
185        // 税合計
186        $total = 0;
187        $max = $this->getMax($productTypeId);
188        for ($i = 0; $i <= $max; $i++) {
189            $price = $this->cartSession[$productTypeId][$i]['price'];
190            $quantity = $this->cartSession[$productTypeId][$i]['quantity'];
191            $tax = SC_Helper_TaxRule_Ex::sfTax($price,
192                $this->cartSession[$productTypeId][$i]['productsClass']['product_id'],
193                $this->cartSession[$productTypeId][$i]['productsClass']['product_class_id'],
194                $pref_id, $country_id);
195
196            $total+= ($tax * $quantity);
197        }
198
199        return $total;
200    }
201
202    // 全商品の合計ポイント
203    public function getAllProductsPoint($productTypeId)
204    {
205        // ポイント合計
206        $total = 0;
207        if (USE_POINT !== false) {
208            $max = $this->getMax($productTypeId);
209            for ($i = 0; $i <= $max; $i++) {
210                $price = $this->cartSession[$productTypeId][$i]['price'];
211                $quantity = $this->cartSession[$productTypeId][$i]['quantity'];
212
213                if (!isset($this->cartSession[$productTypeId][$i]['point_rate'])) {
214                    $this->cartSession[$productTypeId][$i]['point_rate'] = '';
215                }
216                $point_rate = $this->cartSession[$productTypeId][$i]['point_rate'];
217
218                if (!isset($this->cartSession[$productTypeId][$i]['id'][0])) {
219                    $this->cartSession[$productTypeId][$i]['id'][0] = '';
220                }
221                $point = SC_Utils_Ex::sfPrePoint($price, $point_rate);
222                $total+= ($point * $quantity);
223            }
224        }
225
226        return $total;
227    }
228
229    // カートへの商品追加
230    public function addProduct($product_class_id, $quantity)
231    {
232        $objProduct = new SC_Product_Ex();
233        $arrProduct = $objProduct->getProductsClass($product_class_id);
234        $productTypeId = $arrProduct['product_type_id'];
235        $find = false;
236        $max = $this->getMax($productTypeId);
237        for ($i = 0; $i <= $max; $i++) {
238            if ($this->cartSession[$productTypeId][$i]['id'] == $product_class_id) {
239                $val = $this->cartSession[$productTypeId][$i]['quantity'] + $quantity;
240                if (strlen($val) <= INT_LEN) {
241                    $this->cartSession[$productTypeId][$i]['quantity'] += $quantity;
242                }
243                $find = true;
244            }
245        }
246        if (!$find) {
247            $this->cartSession[$productTypeId][$max+1]['id'] = $product_class_id;
248            $this->cartSession[$productTypeId][$max+1]['quantity'] = $quantity;
249            $this->cartSession[$productTypeId][$max+1]['cart_no'] = $this->getNextCartID($productTypeId);
250        }
251    }
252
253    // 前頁のURLを記録しておく
254    public function setPrevURL($url, $excludePaths = array())
255    {
256        // 前頁として記録しないページを指定する。
257        $arrExclude = array(
258            '/shopping/'
259        );
260        $arrExclude = array_merge($arrExclude, $excludePaths);
261        $exclude = false;
262        // ページチェックを行う。
263        foreach ($arrExclude as $val) {
264            if (preg_match('|' . preg_quote($val) . '|', $url)) {
265                $exclude = true;
266                break;
267            }
268        }
269        // 除外ページでない場合は、前頁として記録する。
270        if (!$exclude) {
271            $_SESSION['prev_url'] = $url;
272        }
273    }
274
275    // 前頁のURLを取得する
276    public function getPrevURL()
277    {
278        return isset($_SESSION['prev_url']) ? $_SESSION['prev_url'] : '';
279    }
280
281    // キーが一致した商品の削除
282    public function delProductKey($keyname, $val, $productTypeId)
283    {
284        $max = count($this->cartSession[$productTypeId]);
285        for ($i = 0; $i < $max; $i++) {
286            if ($this->cartSession[$productTypeId][$i][$keyname] == $val) {
287                unset($this->cartSession[$productTypeId][$i]);
288            }
289        }
290    }
291
292    public function setValue($key, $val, $productTypeId)
293    {
294        $this->cartSession[$productTypeId][$key] = $val;
295    }
296
297    public function getValue($key, $productTypeId)
298    {
299        return $this->cartSession[$productTypeId][$key];
300    }
301
302    /**
303     * セッション中の商品情報データの調整。
304     * productsClass項目から、不必要な項目を削除する。
305     */
306    public function adjustSessionProductsClass(&$arrProductsClass)
307    {
308        $arrNecessaryItems = array(
309            'product_id'          => true,
310            'product_class_id'    => true,
311            'name'                => true,
312            'price02'             => true,
313            'point_rate'          => true,
314            'main_list_image'     => true,
315            'main_image'          => true,
316            'product_code'        => true,
317            'stock'               => true,
318            'stock_unlimited'     => true,
319            'sale_limit'          => true,
320            'class_name1'         => true,
321            'classcategory_name1' => true,
322            'class_name2'         => true,
323            'classcategory_name2' => true,
324        );
325
326        // 必要な項目以外を削除。
327        foreach ($arrProductsClass as $key => $value) {
328            if (!isset($arrNecessaryItems[$key])) {
329                unset($arrProductsClass[$key]);
330            }
331        }
332    }
333
334    /**
335     * getCartList用にcartSession情報をセットする
336     *
337     * @param  integer $product_type_id 商品種別ID
338     * @param  integer $key
339     * @return void
340     *
341     * MEMO: せっかく一回だけ読み込みにされてますが、税率対応の関係でちょっと保留
342     */
343    public function setCartSession4getCartList($productTypeId, $key)
344    {
345        $objProduct = new SC_Product_Ex();
346
347        $this->cartSession[$productTypeId][$key]['productsClass']
348            =& $objProduct->getDetailAndProductsClass($this->cartSession[$productTypeId][$key]['id']);
349
350        $price = $this->cartSession[$productTypeId][$key]['productsClass']['price02'];
351        $this->cartSession[$productTypeId][$key]['price'] = $price;
352
353        $this->cartSession[$productTypeId][$key]['point_rate']
354            = $this->cartSession[$productTypeId][$key]['productsClass']['point_rate'];
355
356        $quantity = $this->cartSession[$productTypeId][$key]['quantity'];
357        $incTax = SC_Helper_TaxRule_Ex::sfCalcIncTax($price,
358            $this->cartSession[$productTypeId][$key]['productsClass']['product_id'],
359            $this->cartSession[$productTypeId][$key]['id'][0]);
360
361        $total = $incTax * $quantity;
362
363        $this->cartSession[$productTypeId][$key]['price_inctax'] = $incTax;
364        $this->cartSession[$productTypeId][$key]['total_inctax'] = $total;
365    }
366
367    /**
368     * 商品種別ごとにカート内商品の一覧を取得する.
369     *
370     * @param  integer $productTypeId 商品種別ID
371     * @param  integer $pref_id       税金計算用注文者都道府県ID
372     * @param  integer $country_id    税金計算用注文者国ID
373     * @return array   カート内商品一覧の配列
374     */
375    public function getCartList($productTypeId, $pref_id = 0, $country_id = 0)
376    {
377        $objProduct = new SC_Product_Ex();
378        $max = $this->getMax($productTypeId);
379        $arrRet = array();
380/*
381
382        $const_name = '_CALLED_SC_CARTSESSION_GETCARTLIST_' . $productTypeId;
383        if (defined($const_name)) {
384            $is_first = true;
385        } else {
386            define($const_name, true);
387            $is_first = false;
388        }
389
390*/
391        for ($i = 0; $i <= $max; $i++) {
392            if (isset($this->cartSession[$productTypeId][$i]['cart_no'])
393                && $this->cartSession[$productTypeId][$i]['cart_no'] != '') {
394
395                // 商品情報は常に取得
396                // TODO: 同一インスタンス内では1回のみ呼ぶようにしたい
397                // TODO: ここの商品の合計処理は getAllProductsTotalや getAllProductsTaxとで類似重複なので統一出来そう
398/*
399                // 同一セッション内では初回のみDB参照するようにしている
400                if (!$is_first) {
401                    $this->setCartSession4getCartList($productTypeId, $i);
402                }
403*/
404
405                $this->cartSession[$productTypeId][$i]['productsClass']
406                    =& $objProduct->getDetailAndProductsClass($this->cartSession[$productTypeId][$i]['id']);
407
408                $price = $this->cartSession[$productTypeId][$i]['productsClass']['price02'];
409                $this->cartSession[$productTypeId][$i]['price'] = $price;
410
411                $this->cartSession[$productTypeId][$i]['point_rate']
412                    = $this->cartSession[$productTypeId][$i]['productsClass']['point_rate'];
413
414                $quantity = $this->cartSession[$productTypeId][$i]['quantity'];
415
416                $arrTaxRule = SC_Helper_TaxRule_Ex::getTaxRule(
417                                    $this->cartSession[$productTypeId][$i]['productsClass']['product_id'],
418                                    $this->cartSession[$productTypeId][$i]['productsClass']['product_class_id'],
419                                    $pref_id,
420                                    $country_id);
421                $incTax = $price + SC_Helper_TaxRule_Ex::calcTax($price, $arrTaxRule['tax_rate'], $arrTaxRule['tax_rule'], $arrTaxRule['tax_adjust']);
422
423                $total = $incTax * $quantity;
424                $this->cartSession[$productTypeId][$i]['price_inctax'] = $incTax;
425                $this->cartSession[$productTypeId][$i]['total_inctax'] = $total;
426                $this->cartSession[$productTypeId][$i]['tax_rate'] = $arrTaxRule['tax_rate'];
427                $this->cartSession[$productTypeId][$i]['tax_rule'] = $arrTaxRule['tax_rule'];
428                $this->cartSession[$productTypeId][$i]['tax_adjust'] = $arrTaxRule['tax_adjust'];
429
430                $arrRet[] = $this->cartSession[$productTypeId][$i];
431
432                // セッション変数のデータ量を抑制するため、一部の商品情報を切り捨てる
433                // XXX 上で「常に取得」するのだから、丸ごと切り捨てて良さそうにも感じる。
434                $this->adjustSessionProductsClass($this->cartSession[$productTypeId][$i]['productsClass']);
435            }
436        }
437
438        return $arrRet;
439    }
440
441    /**
442     * 全てのカートの内容を取得する.
443     *
444     * @return array 全てのカートの内容
445     */
446    public function getAllCartList()
447    {
448        $results = array();
449        $cartKeys = $this->getKeys();
450        $i = 0;
451        foreach ($cartKeys as $key) {
452            $cartItems = $this->getCartList($key);
453            foreach ($cartItems as $itemKey => $itemValue) {
454                $cartItem =& $cartItems[$itemKey];
455                $results[$key][$i] =& $cartItem;
456                $i++;
457            }
458        }
459
460        return $results;
461    }
462
463    /**
464     * カート内にある商品規格IDを全て取得する.
465     *
466     * @param  integer $productTypeId 商品種別ID
467     * @return array   商品規格ID の配列
468     */
469    public function getAllProductClassID($productTypeId)
470    {
471        $max = $this->getMax($productTypeId);
472        $productClassIDs = array();
473        for ($i = 0; $i <= $max; $i++) {
474            if ($this->cartSession[$productTypeId][$i]['cart_no'] != '') {
475                $productClassIDs[] = $this->cartSession[$productTypeId][$i]['id'];
476            }
477        }
478
479        return $productClassIDs;
480    }
481
482    /**
483     * 商品種別ID を指定して, カート内の商品を全て削除する.
484     *
485     * @param  integer $productTypeId 商品種別ID
486     * @return void
487     */
488    public function delAllProducts($productTypeId)
489    {
490        $max = $this->getMax($productTypeId);
491        for ($i = 0; $i <= $max; $i++) {
492            unset($this->cartSession[$productTypeId][$i]);
493        }
494    }
495
496    // 商品の削除
497    public function delProduct($cart_no, $productTypeId)
498    {
499        $max = $this->getMax($productTypeId);
500        for ($i = 0; $i <= $max; $i++) {
501            if ($this->cartSession[$productTypeId][$i]['cart_no'] == $cart_no) {
502                unset($this->cartSession[$productTypeId][$i]);
503            }
504        }
505    }
506
507    // 数量の増加
508    public function upQuantity($cart_no, $productTypeId)
509    {
510        $quantity = $this->getQuantity($cart_no, $productTypeId);
511        if (strlen($quantity + 1) <= INT_LEN) {
512            $this->setQuantity($quantity + 1, $cart_no, $productTypeId);
513        }
514    }
515
516    // 数量の減少
517    public function downQuantity($cart_no, $productTypeId)
518    {
519        $quantity = $this->getQuantity($cart_no, $productTypeId);
520        if ($quantity > 1) {
521            $this->setQuantity($quantity - 1, $cart_no, $productTypeId);
522        }
523    }
524
525    /**
526     * カート番号と商品種別IDを指定して, 数量を取得する.
527     *
528     * @param  integer $cart_no       カート番号
529     * @param  integer $productTypeId 商品種別ID
530     * @return integer 該当商品規格の数量
531     */
532    public function getQuantity($cart_no, $productTypeId)
533    {
534        $max = $this->getMax($productTypeId);
535        for ($i = 0; $i <= $max; $i++) {
536            if ($this->cartSession[$productTypeId][$i]['cart_no'] == $cart_no) {
537                return $this->cartSession[$productTypeId][$i]['quantity'];
538            }
539        }
540    }
541
542    /**
543     * カート番号と商品種別IDを指定して, 数量を設定する.
544     *
545     * @param integer $quantity      設定する数量
546     * @param integer $cart_no       カート番号
547     * @param integer $productTypeId 商品種別ID
548     * @retrun void
549     */
550    public function setQuantity($quantity, $cart_no, $productTypeId)
551    {
552        $max = $this->getMax($productTypeId);
553        for ($i = 0; $i <= $max; $i++) {
554            if ($this->cartSession[$productTypeId][$i]['cart_no'] == $cart_no) {
555                $this->cartSession[$productTypeId][$i]['quantity'] = $quantity;
556            }
557        }
558    }
559
560    /**
561     * カート番号と商品種別IDを指定して, 商品規格IDを取得する.
562     *
563     * @param  integer $cart_no       カート番号
564     * @param  integer $productTypeId 商品種別ID
565     * @return integer 商品規格ID
566     */
567    public function getProductClassId($cart_no, $productTypeId)
568    {
569        for ($i = 0; $i < count($this->cartSession[$productTypeId]); $i++) {
570            if ($this->cartSession[$productTypeId][$i]['cart_no'] == $cart_no) {
571                return $this->cartSession[$productTypeId][$i]['id'];
572            }
573        }
574    }
575
576    /**
577     * カート内の商品の妥当性をチェックする.
578     *
579     * エラーが発生した場合は, 商品をカート内から削除又は数量を調整し,
580     * エラーメッセージを返す.
581     *
582     * 1. 商品種別に関連づけられた配送業者の存在チェック
583     * 2. 削除/非表示商品のチェック
584     * 3. 販売制限数のチェック
585     * 4. 在庫数チェック
586     *
587     * @param  string $productTypeId 商品種別ID
588     * @return string エラーが発生した場合はエラーメッセージ
589     */
590    public function checkProducts($productTypeId)
591    {
592        $objProduct = new SC_Product_Ex();
593        $objDelivery = new SC_Helper_Delivery_Ex();
594        $arrDeliv = $objDelivery->getList($productTypeId);
595        $tpl_message = '';
596
597        // カート内の情報を取得
598        $arrItems = $this->getCartList($productTypeId);
599        foreach ($arrItems as &$arrItem) {
600            $product =& $arrItem['productsClass'];
601            /*
602             * 表示/非表示商品のチェック
603             */
604            if (SC_Utils_Ex::isBlank($product) || $product['status'] != 1) {
605                $this->delProduct($arrItem['cart_no'], $productTypeId);
606                $tpl_message .= "※ 現時点で販売していない商品が含まれておりました。該当商品をカートから削除しました。\n";
607            } else {
608                /*
609                 * 配送業者のチェック
610                 */
611                if (SC_Utils_Ex::isBlank($arrDeliv)) {
612                    $tpl_message .= '※「' . $product['name'] . '」はまだ配送の準備ができておりません。';
613                    $tpl_message .= '恐れ入りますがお問い合わせページよりお問い合わせください。' . "\n";
614                    $this->delProduct($arrItem['cart_no'], $productTypeId);
615                }
616
617                /*
618                 * 販売制限数, 在庫数のチェック
619                 */
620                $limit = $objProduct->getBuyLimit($product);
621                if (!is_null($limit) && $arrItem['quantity'] > $limit) {
622                    if ($limit > 0) {
623                        $this->setProductValue($arrItem['id'], 'quantity', $limit, $productTypeId);
624                        $total_inctax = $limit * SC_Helper_TaxRule_Ex::sfCalcIncTax($arrItem['price'],
625                            $product['product_id'],
626                            $arrItem['id'][0]);
627                        $this->setProductValue($arrItem['id'], 'total_inctax', $total_inctax, $productTypeId);
628                        $tpl_message .= '※「' . $product['name'] . '」は販売制限(または在庫が不足)しております。';
629                        $tpl_message .= "一度に数量{$limit}を超える購入はできません。\n";
630                    } else {
631                        $this->delProduct($arrItem['cart_no'], $productTypeId);
632                        $tpl_message .= '※「' . $product['name'] . "」は売り切れました。\n";
633                        continue;
634                    }
635                }
636            }
637        }
638
639        return $tpl_message;
640    }
641
642    /**
643     * 送料無料条件を満たすかどうかチェックする
644     *
645     * @param  integer $productTypeId 商品種別ID
646     * @return boolean 送料無料の場合 true
647     */
648    public function isDelivFree($productTypeId)
649    {
650        $objDb = new SC_Helper_DB_Ex();
651
652        $subtotal = $this->getAllProductsTotal($productTypeId);
653
654        // 送料無料の購入数が設定されている場合
655        if (DELIV_FREE_AMOUNT > 0) {
656            // 商品の合計数量
657            $total_quantity = $this->getTotalQuantity($productTypeId);
658
659            if ($total_quantity >= DELIV_FREE_AMOUNT) {
660                return true;
661            }
662        }
663
664        // 送料無料条件が設定されている場合
665        $arrInfo = $objDb->sfGetBasisData();
666        if ($arrInfo['free_rule'] > 0) {
667            // 小計が送料無料条件以上の場合
668            if ($subtotal >= $arrInfo['free_rule']) {
669                return true;
670            }
671        }
672
673        return false;
674    }
675
676    /**
677     * カートの内容を計算する.
678     *
679     * カートの内容を計算し, 下記のキーを保持する連想配列を返す.
680     *
681     * - tax: 税額
682     * - subtotal: カート内商品の小計
683     * - deliv_fee: カート内商品の合計送料
684     * - total: 合計金額
685     * - payment_total: お支払い合計
686     * - add_point: 加算ポイント
687     *
688     * @param integer       $productTypeId 商品種別ID
689     * @param SC_Customer   $objCustomer   ログイン中の SC_Customer インスタンス
690     * @param integer       $use_point     今回使用ポイント
691     * @param integer|array $deliv_pref    配送先都道府県ID.
692                                        複数に配送する場合は都道府県IDの配列
693     * @param  integer $charge           手数料
694     * @param  integer $discount         値引き
695     * @param  integer $deliv_id         配送業者ID
696     * @param  integer $order_pref       注文者の都道府県ID
697     * @param  integer $order_country_id 注文者の国
698     * @return array   カートの計算結果の配列
699     */
700    public function calculate($productTypeId, &$objCustomer, $use_point = 0,
701        $deliv_pref = '', $charge = 0, $discount = 0, $deliv_id = 0,
702        $order_pref = 0, $order_country_id = 0
703    ) {
704
705        $results = array();
706        $total_point = $this->getAllProductsPoint($productTypeId);
707        // MEMO: 税金計算は注文者の住所基準
708        $results['tax'] = $this->getAllProductsTax($productTypeId, $order_pref, $order_country_id);
709        $results['subtotal'] = $this->getAllProductsTotal($productTypeId, $order_pref, $order_country_id);
710        $results['deliv_fee'] = 0;
711
712        // 商品ごとの送料を加算
713        if (OPTION_PRODUCT_DELIV_FEE == 1) {
714            $cartItems = $this->getCartList($productTypeId);
715            foreach ($cartItems as $arrItem) {
716                $results['deliv_fee'] += $arrItem['productsClass']['deliv_fee'] * $arrItem['quantity'];
717            }
718        }
719
720        // 配送業者の送料を加算
721        if (OPTION_DELIV_FEE == 1
722            && !SC_Utils_Ex::isBlank($deliv_pref)
723            && !SC_Utils_Ex::isBlank($deliv_id)) {
724            $results['deliv_fee'] += SC_Helper_Delivery_Ex::getDelivFee($deliv_pref, $deliv_id);
725        }
726
727        // 送料無料チェック
728        if ($this->isDelivFree($productTypeId)) {
729            $results['deliv_fee'] = 0;
730        }
731
732        // 合計を計算
733        $results['total'] = $results['subtotal'];
734        $results['total'] += $results['deliv_fee'];
735        $results['total'] += $charge;
736        $results['total'] -= $discount;
737
738        // お支払い合計
739        $results['payment_total'] = $results['total'] - $use_point * POINT_VALUE;
740
741        // 加算ポイントの計算
742        if (USE_POINT !== false) {
743            $results['add_point'] = SC_Helper_DB_Ex::sfGetAddPoint($total_point, $use_point);
744            if ($objCustomer != '') {
745                // 誕生日月であった場合
746                if ($objCustomer->isBirthMonth()) {
747                    $results['birth_point'] = BIRTH_MONTH_POINT;
748                    $results['add_point'] += $results['birth_point'];
749                }
750            }
751            if ($results['add_point'] < 0) {
752                $results['add_point'] = 0;
753            }
754        }
755
756        return $results;
757    }
758
759    /**
760     * カートが保持するキー(商品種別ID)を配列で返す.
761     *
762     * @return array 商品種別IDの配列
763     */
764    public function getKeys()
765    {
766        $keys = array_keys($this->cartSession);
767        // 数量が 0 の商品種別は削除する
768        foreach ($keys as $key) {
769            $quantity = $this->getTotalQuantity($key);
770            if ($quantity < 1) {
771                unset($this->cartSession[$key]);
772            }
773        }
774
775        return array_keys($this->cartSession);
776    }
777
778    /**
779     * カートに設定された現在のキー(商品種別ID)を登録する.
780     *
781     * @param  integer $key 商品種別ID
782     * @return void
783     */
784    public function registerKey($key)
785    {
786        $_SESSION['cartKey'] = $key;
787    }
788
789    /**
790     * カートに設定された現在のキー(商品種別ID)を削除する.
791     *
792     * @return void
793     */
794    public function unsetKey()
795    {
796        unset($_SESSION['cartKey']);
797    }
798
799    /**
800     * カートに設定された現在のキー(商品種別ID)を取得する.
801     *
802     * @return integer 商品種別ID
803     */
804    public function getKey()
805    {
806        return $_SESSION['cartKey'];
807    }
808
809    /**
810     * 複数商品種別かどうか.
811     *
812     * @return boolean カートが複数商品種別の場合 true
813     */
814    public function isMultiple()
815    {
816        return count($this->getKeys()) > 1;
817    }
818
819    /**
820     * 引数の商品種別の商品がカートに含まれるかどうか.
821     *
822     * @param  integer $product_type_id 商品種別ID
823     * @return boolean 指定の商品種別がカートに含まれる場合 true
824     */
825    public function hasProductType($product_type_id)
826    {
827        return in_array($product_type_id, $this->getKeys());
828    }
829}
Note: See TracBrowser for help on using the repository browser.