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

Revision 23613, 29.9 KB checked in by undertree, 10 years ago (diff)

#2475 SC_CartSession.phpについて カート商品削除操作getMaxを使用するように修正

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