source: branches/comu-ver2/data/class/helper/SC_Helper_DB.php @ 18052

Revision 18052, 66.0 KB checked in by Seasoft, 15 years ago (diff)

・店舗基本情報の取得処理にランタイムのキャッシュ機構を設け、店舗基本情報を深く渡し回す実装を改めた。
・SC_Utils 冒頭のコメントに従い、インスタンスを生成していた処理を、Helper クラスへ移す。計算処理のみ SC_Utils に残す。

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id Revision Date
  • 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-2007 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 * DB関連のヘルパークラス.
26 *
27 * @package Helper
28 * @author LOCKON CO.,LTD.
29 * @version $Id:SC_Helper_DB.php 15532 2007-08-31 14:39:46Z nanasess $
30 */
31class SC_Helper_DB {
32
33    // {{{ properties
34
35    /** ルートカテゴリ取得フラグ */
36    var $g_root_on;
37
38    /** ルートカテゴリID */
39    var $g_root_id;
40
41    /** 選択中カテゴリ取得フラグ */
42    var $g_category_on;
43
44    /** 選択中カテゴリID */
45    var $g_category_id;
46
47    // }}}
48    // {{{ functions
49
50    /**
51     * データベースのバージョンを所得する.
52     *
53     * @param string $dsn データソース名
54     * @return string データベースのバージョン
55     */
56    function sfGetDBVersion($dsn = "") {
57        $dbFactory = SC_DB_DBFactory_Ex::getInstance();
58        return $dbFactory->sfGetDBVersion($dsn);
59    }
60
61    /**
62     * テーブルの存在をチェックする.
63     *
64     * @param string $table_name チェック対象のテーブル名
65     * @param string $dsn データソース名
66     * @return テーブルが存在する場合 true
67     */
68    function sfTabaleExists($table_name, $dsn = "") {
69        $dbFactory = SC_DB_DBFactory_Ex::getInstance();
70        $dsn = $dbFactory->getDSN($dsn);
71
72        $objQuery = new SC_Query($dsn, true, true);
73        // 正常に接続されている場合
74        if(!$objQuery->isError()) {
75            list($db_type) = split(":", $dsn);
76            $sql = $dbFactory->getTableExistsSql();
77            $arrRet = $objQuery->getAll($sql, array($table_name));
78            if(count($arrRet) > 0) {
79                return true;
80            }
81        }
82        return false;
83    }
84
85    /**
86     * カラムの存在チェックと作成を行う.
87     *
88     * チェック対象のテーブルに, 該当のカラムが存在するかチェックする.
89     * 引数 $add が true の場合, 該当のカラムが存在しない場合は, カラムの生成を行う.
90     * カラムの生成も行う場合は, $col_type も必須となる.
91     *
92     * @param string $table_name テーブル名
93     * @param string $column_name カラム名
94     * @param string $col_type カラムのデータ型
95     * @param string $dsn データソース名
96     * @param bool $add カラムの作成も行う場合 true
97     * @return bool カラムが存在する場合とカラムの生成に成功した場合 true,
98     *               テーブルが存在しない場合 false,
99     *               引数 $add == false でカラムが存在しない場合 false
100     */
101    function sfColumnExists($table_name, $col_name, $col_type = "", $dsn = "", $add = false) {
102        $dbFactory = SC_DB_DBFactory_Ex::getInstance();
103        $dsn = $dbFactory->getDSN($dsn);
104
105        // テーブルが無ければエラー
106        if(!$this->sfTabaleExists($table_name, $dsn)) return false;
107
108        $objQuery = new SC_Query($dsn, true, true);
109        // 正常に接続されている場合
110        if(!$objQuery->isError()) {
111            list($db_type) = split(":", $dsn);
112
113            // カラムリストを取得
114            $arrRet = $dbFactory->sfGetColumnList($table_name);
115            if(count($arrRet) > 0) {
116                if(in_array($col_name, $arrRet)){
117                    return true;
118                }
119            }
120        }
121
122        // カラムを追加する
123        if($add){
124            $objQuery->query("ALTER TABLE $table_name ADD $col_name $col_type ");
125            return true;
126        }
127        return false;
128    }
129
130    /**
131     * インデックスの存在チェックと作成を行う.
132     *
133     * チェック対象のテーブルに, 該当のインデックスが存在するかチェックする.
134     * 引数 $add が true の場合, 該当のインデックスが存在しない場合は, インデックスの生成を行う.
135     * インデックスの生成も行う場合で, DB_TYPE が mysql の場合は, $length も必須となる.
136     *
137     * @param string $table_name テーブル名
138     * @param string $column_name カラム名
139     * @param string $index_name インデックス名
140     * @param integer|string $length インデックスを作成するデータ長
141     * @param string $dsn データソース名
142     * @param bool $add インデックスの生成もする場合 true
143     * @return bool インデックスが存在する場合とインデックスの生成に成功した場合 true,
144     *               テーブルが存在しない場合 false,
145     *               引数 $add == false でインデックスが存在しない場合 false
146     */
147    function sfIndexExists($table_name, $col_name, $index_name, $length = "", $dsn = "", $add = false) {
148        $dbFactory = SC_DB_DBFactory_Ex::getInstance();
149        $dsn = $dbFactory->getDSN($dsn);
150
151        // テーブルが無ければエラー
152        if (!$this->sfTabaleExists($table_name, $dsn)) return false;
153
154        $objQuery = new SC_Query($dsn, true, true);
155        $arrRet = $dbFactory->getTableIndex($index_name, $table_name);
156
157        // すでにインデックスが存在する場合
158        if(count($arrRet) > 0) {
159            return true;
160        }
161
162        // インデックスを作成する
163        if($add){
164            $dbFactory->createTableIndex($index_name, $table_name, $col_name, $length());
165            return true;
166        }
167        return false;
168    }
169
170    /**
171     * データの存在チェックを行う.
172     *
173     * @param string $table_name テーブル名
174     * @param string $where データを検索する WHERE 句
175     * @param string $dsn データソース名
176     * @param string $sql データの追加を行う場合の SQL文
177     * @param bool $add データの追加も行う場合 true
178     * @return bool データが存在する場合 true, データの追加に成功した場合 true,
179     *               $add == false で, データが存在しない場合 false
180     */
181    function sfDataExists($table_name, $where, $arrval, $dsn = "", $sql = "", $add = false) {
182        $dbFactory = SC_DB_DBFactory_Ex::getInstance();
183        $dsn = $dbFactory->getDSN($dsn);
184
185        $objQuery = new SC_Query($dsn, true, true);
186        $count = $objQuery->count($table_name, $where, $arrval);
187
188        if($count > 0) {
189            $ret = true;
190        } else {
191            $ret = false;
192        }
193        // データを追加する
194        if(!$ret && $add) {
195            $objQuery->exec($sql);
196        }
197        return $ret;
198    }
199
200    /**
201     * 店舗基本情報を取得する.
202     *
203     * @param boolean $force 強制的にDB取得するか
204     * @return array 店舗基本情報の配列
205     */
206    function sf_getBasisData($force = false) {
207        static $data;
208       
209        if ($force || !isset($data)) {
210            $objQuery = new SC_Query();
211            $arrRet = $objQuery->select('*', 'dtb_baseinfo');
212           
213            if (isset($arrRet[0])) {
214                $data = $arrRet[0];
215            } else {
216                $data = array();
217            }
218        }
219       
220        return $data;
221    }
222
223    /* 選択中のアイテムのルートカテゴリIDを取得する */
224    function sfGetRootId() {
225
226        if(!$this->g_root_on)   {
227            $this->g_root_on = true;
228            $objQuery = new SC_Query();
229
230            if (!isset($_GET['product_id'])) $_GET['product_id'] = "";
231            if (!isset($_GET['category_id'])) $_GET['category_id'] = "";
232
233            if(!empty($_GET['product_id']) || !empty($_GET['category_id'])) {
234                // 選択中のカテゴリIDを判定する
235                $category_id = $this->sfGetCategoryId($_GET['product_id'], $_GET['category_id']);
236                // ROOTカテゴリIDの取得
237                $arrRet = $this->sfGetParents($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $category_id);
238                $root_id = isset($arrRet[0]) ? $arrRet[0] : "";
239            } else {
240                // ROOTカテゴリIDをなしに設定する
241                $root_id = "";
242            }
243            $this->g_root_id = $root_id;
244        }
245        return $this->g_root_id;
246    }
247
248    /**
249     * 商品規格情報を取得する.
250     *
251     * @param array $arrID 規格ID
252     * @return array 規格情報の配列
253     */
254    function sfGetProductsClass($arrID) {
255        list($product_id, $classcategory_id1, $classcategory_id2) = $arrID;
256
257        if($classcategory_id1 == "") {
258            $classcategory_id1 = '0';
259        }
260        if($classcategory_id2 == "") {
261            $classcategory_id2 = '0';
262        }
263
264        // 商品規格取得
265        $objQuery = new SC_Query();
266        $col = "product_id, deliv_fee, name, product_code, main_list_image, main_image, price01, price02, point_rate, product_class_id, classcategory_id1, classcategory_id2, class_id1, class_id2, stock, stock_unlimited, sale_limit, sale_unlimited";
267        $table = "vw_product_class AS prdcls";
268        $where = "product_id = ? AND classcategory_id1 = ? AND classcategory_id2 = ?";
269        $objQuery->setorder("rank1 DESC, rank2 DESC");
270        $arrRet = $objQuery->select($col, $table, $where, array($product_id, $classcategory_id1, $classcategory_id2));
271        return $arrRet[0];
272    }
273
274    /**
275     * 支払い方法を取得する.
276     *
277     * @return void
278     */
279    function sfGetPayment() {
280        $objQuery = new SC_Query();
281        // 購入金額が条件額以下の項目を取得
282        $where = "del_flg = 0";
283        $objQuery->setorder("fix, rank DESC");
284        $arrRet = $objQuery->select("payment_id, payment_method, rule", "dtb_payment", $where);
285        return $arrRet;
286    }
287
288    /**
289     * カート内商品の集計処理を行う.
290     *
291     * @param LC_Page $objPage ページクラスのインスタンス
292     * @param SC_CartSession $objCartSess カートセッションのインスタンス
293     * @return LC_Page 集計処理後のページクラスインスタンス
294     */
295    function sfTotalCart(&$objPage, $objCartSess) {
296
297        // 規格名一覧
298        $arrClassName = $this->sfGetIDValueList("dtb_class", "class_id", "name");
299        // 規格分類名一覧
300        $arrClassCatName = $this->sfGetIDValueList("dtb_classcategory", "classcategory_id", "name");
301
302        $objPage->tpl_total_pretax = 0;     // 費用合計(税込み)
303        $objPage->tpl_total_tax = 0;        // 消費税合計
304        $objPage->tpl_total_point = 0;      // ポイント合計
305
306        // カート内情報の取得
307        $arrQuantityInfo_by_product = array();
308        $cnt = 0;
309        foreach ($objCartSess->getCartList() as $arrCart) {
310            // 商品規格情報の取得
311            $arrData = $this->sfGetProductsClass($arrCart['id']);
312            $limit = "";
313            // DBに存在する商品
314            if (count($arrData) > 0) {
315
316                // 購入制限数を求める。
317                if ($arrData['stock_unlimited'] != '1' && $arrData['sale_unlimited'] != '1') {
318                    $limit = min($arrData['sale_limit'], $arrData['stock']);
319                } elseif ($arrData['sale_unlimited'] != '1') {
320                    $limit = $arrData['sale_limit'];
321                } elseif ($arrData['stock_unlimited'] != '1') {
322                    $limit = $arrData['stock'];
323                }
324
325                if($limit != "" && $limit < $arrCart['quantity']) {
326                    // カート内商品数を制限に合わせる
327                    $objCartSess->setProductValue($arrCart['id'], 'quantity', $limit);
328                    $quantity = $limit;
329                    $objPage->tpl_message = "※「" . $arrData['name'] . "」は販売制限(または在庫が不足)しております。一度にこれ以上の購入はできません。\n";
330                } else {
331                    $quantity = $arrCart['quantity'];
332                }
333               
334                // (商品規格単位でなく)商品単位での評価のための準備
335                $product_id = $arrCart['id'][0];
336                $arrQuantityInfo_by_product[$product_id]['product_id'] = $product_id;
337                $arrQuantityInfo_by_product[$product_id]['quantity'] += $quantity;
338                $arrQuantityInfo_by_product[$product_id]['sale_unlimited'] = $arrData['sale_unlimited'];
339                $arrQuantityInfo_by_product[$product_id]['sale_limit'] = $arrData['sale_limit'];
340               
341                $objPage->arrProductsClass[$cnt] = $arrData;
342                $objPage->arrProductsClass[$cnt]['quantity'] = $quantity;
343                $objPage->arrProductsClass[$cnt]['cart_no'] = $arrCart['cart_no'];
344                $objPage->arrProductsClass[$cnt]['class_name1'] =
345                    isset($arrClassName[$arrData['class_id1']])
346                        ? $arrClassName[$arrData['class_id1']] : "";
347
348                $objPage->arrProductsClass[$cnt]['class_name2'] =
349                    isset($arrClassName[$arrData['class_id2']])
350                        ? $arrClassName[$arrData['class_id2']] : "";
351
352                $objPage->arrProductsClass[$cnt]['classcategory_name1'] =
353                    $arrClassCatName[$arrData['classcategory_id1']];
354
355                $objPage->arrProductsClass[$cnt]['classcategory_name2'] =
356                    $arrClassCatName[$arrData['classcategory_id2']];
357
358                // 画像サイズ
359                $main_image_path = IMAGE_SAVE_DIR . basename($objPage->arrProductsClass[$cnt]["main_image"]);
360                if(file_exists($main_image_path)) {
361                    list($image_width, $image_height) = getimagesize($main_image_path);
362                } else {
363                    $image_width = 0;
364                    $image_height = 0;
365                }
366
367                $objPage->arrProductsClass[$cnt]["tpl_image_width"] = $image_width + 60;
368                $objPage->arrProductsClass[$cnt]["tpl_image_height"] = $image_height + 80;
369                // 価格の登録
370                if ($arrData['price02'] != "") {
371                    $objCartSess->setProductValue($arrCart['id'], 'price', $arrData['price02']);
372                    $objPage->arrProductsClass[$cnt]['uniq_price'] = $arrData['price02'];
373                } else {
374                    $objCartSess->setProductValue($arrCart['id'], 'price', $arrData['price01']);
375                    $objPage->arrProductsClass[$cnt]['uniq_price'] = $arrData['price01'];
376                }
377                // ポイント付与率の登録
378                if (USE_POINT !== false) {
379                    $objCartSess->setProductValue($arrCart['id'], 'point_rate', $arrData['point_rate']);
380                }
381                // 商品ごとの合計金額
382                $objPage->arrProductsClass[$cnt]['total_pretax'] = $objCartSess->getProductTotal($arrCart['id']);
383                // 送料の合計を計算する
384                $objPage->tpl_total_deliv_fee+= ($arrData['deliv_fee'] * $arrCart['quantity']);
385                $cnt++;
386            } else {
387                // DBに商品が見つからない場合はカート商品の削除
388                $objCartSess->delProductKey('id', $arrCart['id']);
389            }
390        }
391       
392        foreach ($arrQuantityInfo_by_product as $QuantityInfo) {
393            if($QuantityInfo['sale_unlimited'] != '1' && $QuantityInfo['sale_limit'] != '' && $QuantityInfo['sale_limit'] < $QuantityInfo['quantity']) {
394                // カート内商品数を制限に合わせる
395                $objPage->tpl_error = "※「" . $arrData['name'] . "」は個数「{$QuantityInfo['sale_limit']}」以下に販売制限しております。一度にこれ以上の購入はできません。\n";
396                foreach (array_keys($objPage->arrProductsClass) as $key) {
397                    $ProductsClass =& $objPage->arrProductsClass[$key];
398                    $ProductsClass['error'] = true;
399                }
400            }
401        }
402       
403        // 全商品合計金額(税込み)
404        $objPage->tpl_total_pretax = $objCartSess->getAllProductsTotal();
405        // 全商品合計消費税
406        $objPage->tpl_total_tax = $objCartSess->getAllProductsTax();
407        // 全商品合計ポイント
408        if (USE_POINT !== false) {
409            $objPage->tpl_total_point = $objCartSess->getAllProductsPoint();
410        }
411
412        return $objPage;
413    }
414
415    /**
416     * 受注一時テーブルへの書き込み処理を行う.
417     *
418     * @param string $uniqid ユニークID
419     * @param array $sqlval SQLの値の配列
420     * @return void
421     */
422    function sfRegistTempOrder($uniqid, $sqlval) {
423        if($uniqid != "") {
424            // 既存データのチェック
425            $objQuery = new SC_Query();
426            $where = "order_temp_id = ?";
427            $cnt = $objQuery->count("dtb_order_temp", $where, array($uniqid));
428            // 既存データがない場合
429            if ($cnt == 0) {
430                // 初回書き込み時に会員の登録済み情報を取り込む
431                $sqlval = $this->sfGetCustomerSqlVal($uniqid, $sqlval);
432                $sqlval['create_date'] = "now()";
433                $objQuery->insert("dtb_order_temp", $sqlval);
434            } else {
435                $objQuery->update("dtb_order_temp", $sqlval, $where, array($uniqid));
436            }
437           
438            // 受注_Tempテーブルの名称列を更新
439            $this->sfUpdateOrderNameCol($uniqid, true);
440        }
441    }
442
443    /**
444     * 会員情報から SQL文の値を生成する.
445     *
446     * @param string $uniqid ユニークID
447     * @param array $sqlval SQL の値の配列
448     * @return array 会員情報を含んだ SQL の値の配列
449     */
450    function sfGetCustomerSqlVal($uniqid, $sqlval) {
451        $objCustomer = new SC_Customer();
452        // 会員情報登録処理
453        if ($objCustomer->isLoginSuccess(true)) {
454            // 登録データの作成
455            $sqlval['order_temp_id'] = $uniqid;
456            $sqlval['update_date'] = 'Now()';
457            $sqlval['customer_id'] = $objCustomer->getValue('customer_id');
458            $sqlval['order_name01'] = $objCustomer->getValue('name01');
459            $sqlval['order_name02'] = $objCustomer->getValue('name02');
460            $sqlval['order_kana01'] = $objCustomer->getValue('kana01');
461            $sqlval['order_kana02'] = $objCustomer->getValue('kana02');
462            $sqlval['order_sex'] = $objCustomer->getValue('sex');
463            $sqlval['order_zip01'] = $objCustomer->getValue('zip01');
464            $sqlval['order_zip02'] = $objCustomer->getValue('zip02');
465            $sqlval['order_pref'] = $objCustomer->getValue('pref');
466            $sqlval['order_addr01'] = $objCustomer->getValue('addr01');
467            $sqlval['order_addr02'] = $objCustomer->getValue('addr02');
468            $sqlval['order_tel01'] = $objCustomer->getValue('tel01');
469            $sqlval['order_tel02'] = $objCustomer->getValue('tel02');
470            $sqlval['order_tel03'] = $objCustomer->getValue('tel03');
471            if (defined('MOBILE_SITE')) {
472                $email_mobile = $objCustomer->getValue('email_mobile');
473                if (empty($email_mobile)) {
474                    $sqlval['order_email'] = $objCustomer->getValue('email');
475                } else {
476                    $sqlval['order_email'] = $email_mobile;
477                }
478            } else {
479                $sqlval['order_email'] = $objCustomer->getValue('email');
480            }
481            $sqlval['order_job'] = $objCustomer->getValue('job');
482            $sqlval['order_birth'] = $objCustomer->getValue('birth');
483        }
484        return $sqlval;
485    }
486
487    /**
488     * 会員編集登録処理を行う.
489     *
490     * @param array $array パラメータの配列
491     * @param array $arrRegistColumn 登録するカラムの配列
492     * @return void
493     */
494    function sfEditCustomerData($array, $arrRegistColumn) {
495        $objQuery = new SC_Query();
496
497        foreach ($arrRegistColumn as $data) {
498            if ($data["column"] != "password") {
499                if($array[ $data['column'] ] != "") {
500                    $arrRegist[ $data["column"] ] = $array[ $data["column"] ];
501                } else {
502                    $arrRegist[ $data['column'] ] = NULL;
503                }
504            }
505        }
506        if (strlen($array["year"]) > 0 && strlen($array["month"]) > 0 && strlen($array["day"]) > 0) {
507            $arrRegist["birth"] = $array["year"] ."/". $array["month"] ."/". $array["day"] ." 00:00:00";
508        } else {
509            $arrRegist["birth"] = NULL;
510        }
511
512        //-- パスワードの更新がある場合は暗号化。(更新がない場合はUPDATE文を構成しない)
513        if ($array["password"] != DEFAULT_PASSWORD) $arrRegist["password"] = sha1($array["password"] . ":" . AUTH_MAGIC);
514        $arrRegist["update_date"] = "NOW()";
515
516        //-- 編集登録実行
517        $objQuery->begin();
518        $objQuery->update("dtb_customer", $arrRegist, "customer_id = ? ", array($array['customer_id']));
519        $objQuery->commit();
520    }
521
522    /**
523     * 注文番号、利用ポイント、加算ポイントから最終ポイントを取得する.
524     *
525     * @param integer $order_id 注文番号
526     * @param integer $use_point 利用ポイント
527     * @param integer $add_point 加算ポイント
528     * @return array 最終ポイントの配列
529     */
530    function sfGetCustomerPoint($order_id, $use_point, $add_point) {
531        $objQuery = new SC_Query();
532        $arrRet = $objQuery->select("customer_id", "dtb_order", "order_id = ?", array($order_id));
533        $customer_id = $arrRet[0]['customer_id'];
534        if($customer_id != "" && $customer_id >= 1) {
535    if (USE_POINT !== false) {
536            $arrRet = $objQuery->select("point", "dtb_customer", "customer_id = ?", array($customer_id));
537            $point = $arrRet[0]['point'];
538            $total_point = $arrRet[0]['point'] - $use_point + $add_point;
539    } else {
540        $total_point = 0;
541            $point = 0;
542    }
543        } else {
544            $total_point = "";
545            $point = "";
546        }
547        return array($point, $total_point);
548    }
549
550    /**
551     * カテゴリツリーの取得を行う.
552     *
553     * @param integer $parent_category_id 親カテゴリID
554     * @param bool $count_check 登録商品数のチェックを行う場合 true
555     * @return array カテゴリツリーの配列
556     */
557    function sfGetCatTree($parent_category_id, $count_check = false) {
558        $objQuery = new SC_Query();
559        $col = "";
560        $col .= " cat.category_id,";
561        $col .= " cat.category_name,";
562        $col .= " cat.parent_category_id,";
563        $col .= " cat.level,";
564        $col .= " cat.rank,";
565        $col .= " cat.creator_id,";
566        $col .= " cat.create_date,";
567        $col .= " cat.update_date,";
568        $col .= " cat.del_flg, ";
569        $col .= " ttl.product_count";
570        $from = "dtb_category as cat left join dtb_category_total_count as ttl on ttl.category_id = cat.category_id";
571        // 登録商品数のチェック
572        if($count_check) {
573            $where = "del_flg = 0 AND product_count > 0";
574        } else {
575            $where = "del_flg = 0";
576        }
577        $objQuery->setoption("ORDER BY rank DESC");
578        $arrRet = $objQuery->select($col, $from, $where);
579
580        $arrParentID = $this->sfGetParents($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $parent_category_id);
581
582        foreach($arrRet as $key => $array) {
583            foreach($arrParentID as $val) {
584                if($array['category_id'] == $val) {
585                    $arrRet[$key]['display'] = 1;
586                    break;
587                }
588            }
589        }
590
591        return $arrRet;
592    }
593
594    /**
595     * カテゴリツリーの取得を複数カテゴリーで行う.
596     *
597     * @param integer $product_id 商品ID
598     * @param bool $count_check 登録商品数のチェックを行う場合 true
599     * @return array カテゴリツリーの配列
600     */
601    function sfGetMultiCatTree($product_id, $count_check = false) {
602        $objQuery = new SC_Query();
603        $col = "";
604        $col .= " cat.category_id,";
605        $col .= " cat.category_name,";
606        $col .= " cat.parent_category_id,";
607        $col .= " cat.level,";
608        $col .= " cat.rank,";
609        $col .= " cat.creator_id,";
610        $col .= " cat.create_date,";
611        $col .= " cat.update_date,";
612        $col .= " cat.del_flg, ";
613        $col .= " ttl.product_count";
614        $from = "dtb_category as cat left join dtb_category_total_count as ttl on ttl.category_id = cat.category_id";
615        // 登録商品数のチェック
616        if($count_check) {
617            $where = "del_flg = 0 AND product_count > 0";
618        } else {
619            $where = "del_flg = 0";
620        }
621        $objQuery->setoption("ORDER BY rank DESC");
622        $arrRet = $objQuery->select($col, $from, $where);
623
624        $arrCategory_id = $this->sfGetCategoryId($product_id, $status);
625
626        $arrCatTree = array();
627        foreach ($arrCategory_id as $pkey => $parent_category_id) {
628            $arrParentID = $this->sfGetParents($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $parent_category_id);
629
630            foreach($arrParentID as $pid) {
631                foreach($arrRet as $key => $array) {
632                    if($array['category_id'] == $pid) {
633                        $arrCatTree[$pkey][] = $arrRet[$key];
634                        break;
635                    }
636                }
637            }
638        }
639
640        return $arrCatTree;
641    }
642
643    /**
644     * 親カテゴリーを連結した文字列を取得する.
645     *
646     * @param integer $category_id カテゴリID
647     * @return string 親カテゴリーを連結した文字列
648     */
649    function sfGetCatCombName($category_id){
650        // 商品が属するカテゴリIDを縦に取得
651        $objQuery = new SC_Query();
652        $arrCatID = $this->sfGetParents($objQuery, "dtb_category", "parent_category_id", "category_id", $category_id);
653        $ConbName = "";
654
655        // カテゴリー名称を取得する
656        foreach($arrCatID as $key => $val){
657            $sql = "SELECT category_name FROM dtb_category WHERE category_id = ?";
658            $arrVal = array($val);
659            $CatName = $objQuery->getOne($sql,$arrVal);
660            $ConbName .= $CatName . ' | ';
661        }
662        // 最後の | をカットする
663        $ConbName = substr_replace($ConbName, "", strlen($ConbName) - 2, 2);
664
665        return $ConbName;
666    }
667
668    /**
669     * 指定したカテゴリーIDのカテゴリーを取得する.
670     *
671     * @param integer $category_id カテゴリID
672     * @return array 指定したカテゴリーIDのカテゴリー
673     */
674    function sfGetCat($category_id){
675        $objQuery = new SC_Query();
676
677        // カテゴリーを取得する
678        $arrVal = array($category_id);
679        $res = $objQuery->select('category_id AS id, category_name AS name', 'dtb_category', 'category_id = ?', $arrVal);
680
681        return $res[0];
682    }
683
684    /**
685     * 指定したカテゴリーIDの大カテゴリーを取得する.
686     *
687     * @param integer $category_id カテゴリID
688     * @return array 指定したカテゴリーIDの大カテゴリー
689     */
690    function sfGetFirstCat($category_id){
691        // 商品が属するカテゴリIDを縦に取得
692        $objQuery = new SC_Query();
693        $arrRet = array();
694        $arrCatID = $this->sfGetParents($objQuery, "dtb_category", "parent_category_id", "category_id", $category_id);
695        $arrRet['id'] = $arrCatID[0];
696
697        // カテゴリー名称を取得する
698        $sql = "SELECT category_name FROM dtb_category WHERE category_id = ?";
699        $arrVal = array($arrRet['id']);
700        $arrRet['name'] = $objQuery->getOne($sql,$arrVal);
701
702        return $arrRet;
703    }
704
705    /**
706     * カテゴリツリーの取得を行う.
707     *
708     * $products_check:true商品登録済みのものだけ取得する
709     *
710     * @param string $addwhere 追加する WHERE 句
711     * @param bool $products_check 商品の存在するカテゴリのみ取得する場合 true
712     * @param string $head カテゴリ名のプレフィックス文字列
713     * @return array カテゴリツリーの配列
714     */
715    function sfGetCategoryList($addwhere = "", $products_check = false, $head = CATEGORY_HEAD) {
716        $objQuery = new SC_Query();
717        $where = "del_flg = 0";
718
719        if($addwhere != "") {
720            $where.= " AND $addwhere";
721        }
722
723        $objQuery->setoption("ORDER BY rank DESC");
724
725        if($products_check) {
726            $col = "T1.category_id, category_name, level";
727            $from = "dtb_category AS T1 LEFT JOIN dtb_category_total_count AS T2 ON T1.category_id = T2.category_id";
728            $where .= " AND product_count > 0";
729        } else {
730            $col = "category_id, category_name, level";
731            $from = "dtb_category";
732        }
733
734        $arrRet = $objQuery->select($col, $from, $where);
735
736        $max = count($arrRet);
737        for($cnt = 0; $cnt < $max; $cnt++) {
738            $id = $arrRet[$cnt]['category_id'];
739            $name = $arrRet[$cnt]['category_name'];
740            $arrList[$id] = str_repeat($head, $arrRet[$cnt]['level']) . $name;
741        }
742        return $arrList;
743    }
744
745    /**
746     * カテゴリーツリーの取得を行う.
747     *
748     * 親カテゴリの Value=0 を対象とする
749     *
750     * @param bool $parent_zero 親カテゴリの Value=0 の場合 true
751     * @return array カテゴリツリーの配列
752     */
753    function sfGetLevelCatList($parent_zero = true) {
754        $objQuery = new SC_Query();
755
756        // カテゴリ名リストを取得
757        $col = "category_id, parent_category_id, category_name";
758        $where = "del_flg = 0";
759        $objQuery->setoption("ORDER BY level");
760        $arrRet = $objQuery->select($col, "dtb_category", $where);
761        $arrCatName = array();
762        foreach ($arrRet as $arrTmp) {
763            $arrCatName[$arrTmp['category_id']] =
764                (($arrTmp['parent_category_id'] > 0)?
765                    $arrCatName[$arrTmp['parent_category_id']] : "")
766                . CATEGORY_HEAD . $arrTmp['category_name'];
767        }
768
769        $col = "category_id, parent_category_id, category_name, level";
770        $where = "del_flg = 0";
771        $objQuery->setoption("ORDER BY rank DESC");
772        $arrRet = $objQuery->select($col, "dtb_category", $where);
773        $max = count($arrRet);
774
775        for($cnt = 0; $cnt < $max; $cnt++) {
776            if($parent_zero) {
777                if($arrRet[$cnt]['level'] == LEVEL_MAX) {
778                    $arrValue[$cnt] = $arrRet[$cnt]['category_id'];
779                } else {
780                    $arrValue[$cnt] = "";
781                }
782            } else {
783                $arrValue[$cnt] = $arrRet[$cnt]['category_id'];
784            }
785
786            $arrOutput[$cnt] = $arrCatName[$arrRet[$cnt]['category_id']];
787        }
788
789        return array($arrValue, $arrOutput);
790    }
791
792    /**
793     * 選択中の商品のカテゴリを取得する.
794     *
795     * @param integer $product_id プロダクトID
796     * @param integer $category_id カテゴリID
797     * @return array 選択中の商品のカテゴリIDの配列
798     *
799     */
800    function sfGetCategoryId($product_id, $category_id = 0, $closed = false) {
801        if ($closed) {
802            $status = "";
803        } else {
804            $status = "status = 1";
805        }
806
807        if(!$this->g_category_on) {
808            $this->g_category_on = true;
809            $category_id = (int) $category_id;
810            $product_id = (int) $product_id;
811            if(SC_Utils_Ex::sfIsInt($category_id) && $this->sfIsRecord("dtb_category","category_id", $category_id)) {
812                $this->g_category_id = array($category_id);
813            } else if (SC_Utils_Ex::sfIsInt($product_id) && $this->sfIsRecord("dtb_products","product_id", $product_id, $status)) {
814                $objQuery = new SC_Query();
815                $where = "product_id = ?";
816                $category_id = $objQuery->getCol("dtb_product_categories", "category_id", "product_id = ?", array($product_id));
817                $this->g_category_id = $category_id;
818            } else {
819                // 不正な場合は、空の配列を返す。
820                $this->g_category_id = array();
821            }
822        }
823        return $this->g_category_id;
824    }
825
826    /**
827     * 商品をカテゴリの先頭に追加する.
828     *
829     * @param integer $category_id カテゴリID
830     * @param integer $product_id プロダクトID
831     * @return void
832     */
833    function addProductBeforCategories($category_id, $product_id) {
834
835        $sqlval = array("category_id" => $category_id,
836                        "product_id" => $product_id);
837
838        $objQuery = new SC_Query();
839
840        // 現在の商品カテゴリを取得
841        $arrCat = $objQuery->select("product_id, category_id, rank",
842                                    "dtb_product_categories",
843                                    "category_id = ?",
844                                    array($category_id));
845
846        $max = "0";
847        foreach ($arrCat as $val) {
848            // 同一商品が存在する場合は登録しない
849            if ($val["product_id"] == $product_id) {
850                return;
851            }
852            // 最上位ランクを取得
853            $max = ($max < $val["rank"]) ? $val["rank"] : $max;
854        }
855        $sqlval["rank"] = $max + 1;
856        $objQuery->insert("dtb_product_categories", $sqlval);
857    }
858
859    /**
860     * 商品をカテゴリの末尾に追加する.
861     *
862     * @param integer $category_id カテゴリID
863     * @param integer $product_id プロダクトID
864     * @return void
865     */
866    function addProductAfterCategories($category_id, $product_id) {
867        $sqlval = array("category_id" => $category_id,
868                        "product_id" => $product_id);
869
870        $objQuery = new SC_Query();
871
872        // 現在の商品カテゴリを取得
873        $arrCat = $objQuery->select("product_id, category_id, rank",
874                                    "dtb_product_categories",
875                                    "category_id = ?",
876                                    array($category_id));
877
878        $min = 0;
879        foreach ($arrCat as $val) {
880            // 同一商品が存在する場合は登録しない
881            if ($val["product_id"] == $product_id) {
882                return;
883            }
884            // 最下位ランクを取得
885            $min = ($min < $val["rank"]) ? $val["rank"] : $min;
886        }
887        $sqlval["rank"] = $min;
888        $objQuery->insert("dtb_product_categories", $sqlval);
889    }
890
891    /**
892     * 商品をカテゴリから削除する.
893     *
894     * @param integer $category_id カテゴリID
895     * @param integer $product_id プロダクトID
896     * @return void
897     */
898    function removeProductByCategories($category_id, $product_id) {
899        $sqlval = array("category_id" => $category_id,
900                        "product_id" => $product_id);
901        $objQuery = new SC_Query();
902        $objQuery->delete("dtb_product_categories",
903                          "category_id = ? AND product_id = ?", $sqlval);
904    }
905
906    /**
907     * 商品カテゴリを更新する.
908     *
909     * @param array $arrCategory_id 登録するカテゴリIDの配列
910     * @param integer $product_id プロダクトID
911     * @return void
912     */
913    function updateProductCategories($arrCategory_id, $product_id) {
914        $objQuery = new SC_Query();
915
916        // 現在のカテゴリ情報を取得
917        $arrCurrentCat = $objQuery->select("product_id, category_id, rank",
918                                           "dtb_product_categories",
919                                           "product_id = ?",
920                                           array($product_id));
921
922        // 登録するカテゴリ情報と比較
923        foreach ($arrCurrentCat as $val) {
924
925            // 登録しないカテゴリを削除
926            if (!in_array($val["category_id"], $arrCategory_id)) {
927                $this->removeProductByCategories($val["category_id"], $product_id);
928            }
929        }
930
931        // カテゴリを登録
932        foreach ($arrCategory_id as $category_id) {
933            $this->addProductBeforCategories($category_id, $product_id);
934        }
935    }
936
937    /**
938     * カテゴリ数の登録を行う.
939     *
940     * @param SC_Query $objQuery SC_Query インスタンス
941     * @return void
942     */
943    function sfCategory_Count($objQuery){
944
945        //テーブル内容の削除
946        $objQuery->query("DELETE FROM dtb_category_count");
947        $objQuery->query("DELETE FROM dtb_category_total_count");
948
949        $sql_where .= 'alldtl.del_flg = 0 AND alldtl.status = 1';
950        // 在庫無し商品の非表示
951        if (NOSTOCK_HIDDEN === true) {
952            $sql_where .= ' AND (alldtl.stock_max >= 1 OR alldtl.stock_unlimited_max = 1)';
953        }
954
955        //各カテゴリ内の商品数を数えて格納
956        $sql = <<< __EOS__
957            INSERT INTO dtb_category_count(category_id, product_count, create_date)
958            SELECT T1.category_id, count(T2.category_id), now()
959            FROM dtb_category AS T1
960                LEFT JOIN dtb_product_categories AS T2
961                    ON T1.category_id = T2.category_id
962                LEFT JOIN vw_products_allclass_detail AS alldtl
963                    ON T2.product_id = alldtl.product_id
964            WHERE $sql_where
965            GROUP BY T1.category_id, T2.category_id
966__EOS__;
967       
968        $objQuery->query($sql);
969
970        //子カテゴリ内の商品数を集計する
971       
972        // カテゴリ情報を取得
973        $arrCat = $objQuery->select('category_id', 'dtb_category');
974       
975        foreach ($arrCat as $row) {
976            $category_id = $row['category_id'];
977            $arrval = array();
978           
979            $arrval[] = $category_id;
980           
981            list($tmp_where, $tmp_arrval) = $this->sfGetCatWhere($category_id);
982            if ($tmp_where != "") {
983                $sql_where_product_ids = "alldtl.product_id IN (SELECT product_id FROM dtb_product_categories WHERE " . $tmp_where . ")";
984                $arrval = array_merge((array)$arrval, (array)$tmp_arrval);
985            } else {
986                $sql_where_product_ids = '0<>0'; // 一致させない
987            }
988           
989            $sql = <<< __EOS__
990                INSERT INTO dtb_category_total_count (category_id, product_count, create_date)
991                SELECT
992                    ?
993                    ,count(*)
994                    ,now()
995                FROM vw_products_allclass_detail AS alldtl
996                WHERE ($sql_where) AND ($sql_where_product_ids)
997__EOS__;
998           
999            $objQuery->query($sql, $arrval);
1000        }
1001    }
1002
1003    /**
1004     * 子IDの配列を返す.
1005     *
1006     * @param string $table テーブル名
1007     * @param string $pid_name 親ID名
1008     * @param string $id_name ID名
1009     * @param integer $id ID
1010     * @param array 子ID の配列
1011     */
1012    function sfGetChildsID($table, $pid_name, $id_name, $id) {
1013        $arrRet = $this->sfGetChildrenArray($table, $pid_name, $id_name, $id);
1014        return $arrRet;
1015    }
1016
1017    /**
1018     * 階層構造のテーブルから子ID配列を取得する.
1019     *
1020     * @param string $table テーブル名
1021     * @param string $pid_name 親ID名
1022     * @param string $id_name ID名
1023     * @param integer $id ID番号
1024     * @return array 子IDの配列
1025     */
1026    function sfGetChildrenArray($table, $pid_name, $id_name, $id) {
1027        $objQuery = new SC_Query();
1028        $col = $pid_name . "," . $id_name;
1029         $arrData = $objQuery->select($col, $table);
1030
1031        $arrPID = array();
1032        $arrPID[] = $id;
1033        $arrChildren = array();
1034        $arrChildren[] = $id;
1035
1036        $arrRet = $this->sfGetChildrenArraySub($arrData, $pid_name, $id_name, $arrPID);
1037
1038        while(count($arrRet) > 0) {
1039            $arrChildren = array_merge($arrChildren, $arrRet);
1040            $arrRet = $this->sfGetChildrenArraySub($arrData, $pid_name, $id_name, $arrRet);
1041        }
1042
1043        return $arrChildren;
1044    }
1045
1046    /**
1047     * 親ID直下の子IDをすべて取得する.
1048     *
1049     * @param array $arrData 親カテゴリの配列
1050     * @param string $pid_name 親ID名
1051     * @param string $id_name ID名
1052     * @param array $arrPID 親IDの配列
1053     * @return array 子IDの配列
1054     */
1055    function sfGetChildrenArraySub($arrData, $pid_name, $id_name, $arrPID) {
1056        $arrChildren = array();
1057        $max = count($arrData);
1058
1059        for($i = 0; $i < $max; $i++) {
1060            foreach($arrPID as $val) {
1061                if($arrData[$i][$pid_name] == $val) {
1062                    $arrChildren[] = $arrData[$i][$id_name];
1063                }
1064            }
1065        }
1066        return $arrChildren;
1067    }
1068
1069    /**
1070     * 所属するすべての階層の親IDを配列で返す.
1071     *
1072     * @param SC_Query $objQuery SC_Query インスタンス
1073     * @param string $table テーブル名
1074     * @param string $pid_name 親ID名
1075     * @param string $id_name ID名
1076     * @param integer $id ID
1077     * @return array 親IDの配列
1078     */
1079    function sfGetParents($objQuery, $table, $pid_name, $id_name, $id) {
1080        $arrRet = $this->sfGetParentsArray($table, $pid_name, $id_name, $id);
1081        // 配列の先頭1つを削除する。
1082        array_shift($arrRet);
1083        return $arrRet;
1084    }
1085
1086    /**
1087     * 階層構造のテーブルから親ID配列を取得する.
1088     *
1089     * @param string $table テーブル名
1090     * @param string $pid_name 親ID名
1091     * @param string $id_name ID名
1092     * @param integer $id ID
1093     * @return array 親IDの配列
1094     */
1095    function sfGetParentsArray($table, $pid_name, $id_name, $id) {
1096        $objQuery = new SC_Query();
1097        $col = $pid_name . "," . $id_name;
1098        $arrData = $objQuery->select($col, $table);
1099
1100        $arrParents = array();
1101        $arrParents[] = $id;
1102        $child = $id;
1103
1104        $ret = SC_Utils::sfGetParentsArraySub($arrData, $pid_name, $id_name, $child);
1105
1106        while($ret != "") {
1107            $arrParents[] = $ret;
1108            $ret = SC_Utils::sfGetParentsArraySub($arrData, $pid_name, $id_name, $ret);
1109        }
1110
1111        $arrParents = array_reverse($arrParents);
1112
1113        return $arrParents;
1114    }
1115
1116    /**
1117     * カテゴリから商品を検索する場合のWHERE文と値を返す.
1118     *
1119     * @param integer $category_id カテゴリID
1120     * @return array 商品を検索する場合の配列
1121     */
1122    function sfGetCatWhere($category_id) {
1123        // 子カテゴリIDの取得
1124        $arrRet = $this->sfGetChildsID("dtb_category", "parent_category_id", "category_id", $category_id);
1125        $tmp_where = "";
1126        foreach ($arrRet as $val) {
1127            if($tmp_where == "") {
1128                $tmp_where.= " category_id IN ( ?";
1129            } else {
1130                $tmp_where.= ",? ";
1131            }
1132            $arrval[] = $val;
1133        }
1134        $tmp_where.= " ) ";
1135        return array($tmp_where, $arrval);
1136    }
1137
1138    /**
1139     * 受注一時テーブルから情報を取得する.
1140     *
1141     * @param integer $order_temp_id 受注一時ID
1142     * @return array 受注一時情報の配列
1143     */
1144    function sfGetOrderTemp($order_temp_id) {
1145        $objQuery = new SC_Query();
1146        $where = "order_temp_id = ?";
1147        $arrRet = $objQuery->select("*", "dtb_order_temp", $where, array($order_temp_id));
1148        return $arrRet[0];
1149    }
1150
1151    /**
1152     * SELECTボックス用リストを作成する.
1153     *
1154     * @param string $table テーブル名
1155     * @param string $keyname プライマリーキーのカラム名
1156     * @param string $valname データ内容のカラム名
1157     * @return array SELECT ボックス用リストの配列
1158     */
1159    function sfGetIDValueList($table, $keyname, $valname) {
1160        $objQuery = new SC_Query();
1161        $col = "$keyname, $valname";
1162        $objQuery->setwhere("del_flg = 0");
1163        $objQuery->setorder("rank DESC");
1164        $arrList = $objQuery->select($col, $table);
1165        $count = count($arrList);
1166        for($cnt = 0; $cnt < $count; $cnt++) {
1167            $key = $arrList[$cnt][$keyname];
1168            $val = $arrList[$cnt][$valname];
1169            $arrRet[$key] = $val;
1170        }
1171        return $arrRet;
1172    }
1173
1174    /**
1175     * ランキングを上げる.
1176     *
1177     * @param string $table テーブル名
1178     * @param string $colname カラム名
1179     * @param string|integer $id テーブルのキー
1180     * @param string $andwhere SQL の AND 条件である WHERE 句
1181     * @return void
1182     */
1183    function sfRankUp($table, $colname, $id, $andwhere = "") {
1184        $objQuery = new SC_Query();
1185        $objQuery->begin();
1186        $where = "$colname = ?";
1187        if($andwhere != "") {
1188            $where.= " AND $andwhere";
1189        }
1190        // 対象項目のランクを取得
1191        $rank = $objQuery->get($table, "rank", $where, array($id));
1192        // ランクの最大値を取得
1193        $maxrank = $objQuery->max($table, "rank", $andwhere);
1194        // ランクが最大値よりも小さい場合に実行する。
1195        if($rank < $maxrank) {
1196            // ランクが一つ上のIDを取得する。
1197            $where = "rank = ?";
1198            if($andwhere != "") {
1199                $where.= " AND $andwhere";
1200            }
1201            $uprank = $rank + 1;
1202            $up_id = $objQuery->get($table, $colname, $where, array($uprank));
1203            // ランク入れ替えの実行
1204            $sqlup = "UPDATE $table SET rank = ? WHERE $colname = ?";
1205            if($andwhere != "") {
1206                $sqlup.= " AND $andwhere";
1207            }
1208            $objQuery->exec($sqlup, array($rank + 1, $id));
1209            $objQuery->exec($sqlup, array($rank, $up_id));
1210        }
1211        $objQuery->commit();
1212    }
1213
1214    /**
1215     * ランキングを下げる.
1216     *
1217     * @param string $table テーブル名
1218     * @param string $colname カラム名
1219     * @param string|integer $id テーブルのキー
1220     * @param string $andwhere SQL の AND 条件である WHERE 句
1221     * @return void
1222     */
1223    function sfRankDown($table, $colname, $id, $andwhere = "") {
1224        $objQuery = new SC_Query();
1225        $objQuery->begin();
1226        $where = "$colname = ?";
1227        if($andwhere != "") {
1228            $where.= " AND $andwhere";
1229        }
1230        // 対象項目のランクを取得
1231        $rank = $objQuery->get($table, "rank", $where, array($id));
1232
1233        // ランクが1(最小値)よりも大きい場合に実行する。
1234        if($rank > 1) {
1235            // ランクが一つ下のIDを取得する。
1236            $where = "rank = ?";
1237            if($andwhere != "") {
1238                $where.= " AND $andwhere";
1239            }
1240            $downrank = $rank - 1;
1241            $down_id = $objQuery->get($table, $colname, $where, array($downrank));
1242            // ランク入れ替えの実行
1243            $sqlup = "UPDATE $table SET rank = ? WHERE $colname = ?";
1244            if($andwhere != "") {
1245                $sqlup.= " AND $andwhere";
1246            }
1247            $objQuery->exec($sqlup, array($rank - 1, $id));
1248            $objQuery->exec($sqlup, array($rank, $down_id));
1249        }
1250        $objQuery->commit();
1251    }
1252
1253    /**
1254     * 指定順位へ移動する.
1255     *
1256     * @param string $tableName テーブル名
1257     * @param string $keyIdColumn キーを保持するカラム名
1258     * @param string|integer $keyId キーの値
1259     * @param integer $pos 指定順位
1260     * @param string $where SQL の AND 条件である WHERE 句
1261     * @return void
1262     */
1263    function sfMoveRank($tableName, $keyIdColumn, $keyId, $pos, $where = "") {
1264        $objQuery = new SC_Query();
1265        $objQuery->begin();
1266
1267        // 自身のランクを取得する
1268        $rank = $objQuery->get($tableName, "rank", "$keyIdColumn = ?", array($keyId));
1269
1270        $max = $objQuery->max($tableName, "rank", $where);
1271
1272        // 値の調整(逆順)
1273        if($pos > $max) {
1274            $position = 1;
1275        } else if($pos < 1) {
1276            $position = $max;
1277        } else {
1278            $position = $max - $pos + 1;
1279        }
1280
1281        //入れ替え先の順位が入れ換え元の順位より大きい場合
1282        if( $position > $rank ) $term = "rank - 1";
1283
1284        //入れ替え先の順位が入れ換え元の順位より小さい場合
1285        if( $position < $rank ) $term = "rank + 1";
1286
1287        // XXX 入れ替え先の順位が入れ替え元の順位と同じ場合
1288        if (!isset($term)) $term = "rank";
1289
1290        // 指定した順位の商品から移動させる商品までのrankを1つずらす
1291        $sql = "UPDATE $tableName SET rank = $term WHERE rank BETWEEN ? AND ?";
1292        if($where != "") {
1293            $sql.= " AND $where";
1294        }
1295
1296        if( $position > $rank ) $objQuery->exec( $sql, array( $rank + 1, $position ));
1297        if( $position < $rank ) $objQuery->exec( $sql, array( $position, $rank - 1 ));
1298
1299        // 指定した順位へrankを書き換える。
1300        $sql  = "UPDATE $tableName SET rank = ? WHERE $keyIdColumn = ? ";
1301        if($where != "") {
1302            $sql.= " AND $where";
1303        }
1304
1305        $objQuery->exec( $sql, array( $position, $keyId ) );
1306        $objQuery->commit();
1307    }
1308
1309    /**
1310     * ランクを含むレコードを削除する.
1311     *
1312     * レコードごと削除する場合は、$deleteをtrueにする
1313     *
1314     * @param string $table テーブル名
1315     * @param string $colname カラム名
1316     * @param string|integer $id テーブルのキー
1317     * @param string $andwhere SQL の AND 条件である WHERE 句
1318     * @param bool $delete レコードごと削除する場合 true,
1319     *                     レコードごと削除しない場合 false
1320     * @return void
1321     */
1322    function sfDeleteRankRecord($table, $colname, $id, $andwhere = "",
1323                                $delete = false) {
1324        $objQuery = new SC_Query();
1325        $objQuery->begin();
1326        // 削除レコードのランクを取得する。
1327        $where = "$colname = ?";
1328        if($andwhere != "") {
1329            $where.= " AND $andwhere";
1330        }
1331        $rank = $objQuery->get($table, "rank", $where, array($id));
1332
1333        if(!$delete) {
1334            // ランクを最下位にする、DELフラグON
1335            $sqlup = "UPDATE $table SET rank = 0, del_flg = 1 ";
1336            $sqlup.= "WHERE $colname = ?";
1337            // UPDATEの実行
1338            $objQuery->exec($sqlup, array($id));
1339        } else {
1340            $objQuery->delete($table, "$colname = ?", array($id));
1341        }
1342
1343        // 追加レコードのランクより上のレコードを一つずらす。
1344        $where = "rank > ?";
1345        if($andwhere != "") {
1346            $where.= " AND $andwhere";
1347        }
1348        $sqlup = "UPDATE $table SET rank = (rank - 1) WHERE $where";
1349        $objQuery->exec($sqlup, array($rank));
1350        $objQuery->commit();
1351    }
1352
1353    /**
1354     * 親IDの配列を元に特定のカラムを取得する.
1355     *
1356     * @param SC_Query $objQuery SC_Query インスタンス
1357     * @param string $table テーブル名
1358     * @param string $id_name ID名
1359     * @param string $col_name カラム名
1360     * @param array $arrId IDの配列
1361     * @return array 特定のカラムの配列
1362     */
1363    function sfGetParentsCol($objQuery, $table, $id_name, $col_name, $arrId ) {
1364        $col = $col_name;
1365        $len = count($arrId);
1366        $where = "";
1367
1368        for($cnt = 0; $cnt < $len; $cnt++) {
1369            if($where == "") {
1370                $where = "$id_name = ?";
1371            } else {
1372                $where.= " OR $id_name = ?";
1373            }
1374        }
1375
1376        $objQuery->setorder("level");
1377        $arrRet = $objQuery->select($col, $table, $where, $arrId);
1378        return $arrRet;
1379    }
1380
1381    /**
1382     * カテゴリ変更時の移動処理を行う.
1383     *
1384     * @param SC_Query $objQuery SC_Query インスタンス
1385     * @param string $table テーブル名
1386     * @param string $id_name ID名
1387     * @param string $cat_name カテゴリ名
1388     * @param integer $old_catid 旧カテゴリID
1389     * @param integer $new_catid 新カテゴリID
1390     * @param integer $id ID
1391     * @return void
1392     */
1393    function sfMoveCatRank($objQuery, $table, $id_name, $cat_name, $old_catid, $new_catid, $id) {
1394        if ($old_catid == $new_catid) {
1395            return;
1396        }
1397        // 旧カテゴリでのランク削除処理
1398        // 移動レコードのランクを取得する。
1399        $where = "$id_name = ?";
1400        $rank = $objQuery->get($table, "rank", $where, array($id));
1401        // 削除レコードのランクより上のレコードを一つ下にずらす。
1402        $where = "rank > ? AND $cat_name = ?";
1403        $sqlup = "UPDATE $table SET rank = (rank - 1) WHERE $where";
1404        $objQuery->exec($sqlup, array($rank, $old_catid));
1405        // 新カテゴリでの登録処理
1406        // 新カテゴリの最大ランクを取得する。
1407        $max_rank = $objQuery->max($table, "rank", "$cat_name = ?", array($new_catid)) + 1;
1408        $where = "$id_name = ?";
1409        $sqlup = "UPDATE $table SET rank = ? WHERE $where";
1410        $objQuery->exec($sqlup, array($max_rank, $id));
1411    }
1412
1413    /**
1414     * 配送時間を取得する.
1415     *
1416     * @param integer $payment_id 支払い方法ID
1417     * @return array 配送時間の配列
1418     */
1419    function sfGetDelivTime($payment_id = "") {
1420        $objQuery = new SC_Query();
1421
1422        $deliv_id = "";
1423        $arrRet = array();
1424
1425        if($payment_id != "") {
1426            $where = "del_flg = 0 AND payment_id = ?";
1427            $arrRet = $objQuery->select("deliv_id", "dtb_payment", $where, array($payment_id));
1428            $deliv_id = $arrRet[0]['deliv_id'];
1429        }
1430
1431        if($deliv_id != "") {
1432            $objQuery->setorder("time_id");
1433            $where = "deliv_id = ?";
1434            $arrRet= $objQuery->select("time_id, deliv_time", "dtb_delivtime", $where, array($deliv_id));
1435        }
1436
1437        return $arrRet;
1438    }
1439
1440    /**
1441     * 都道府県、支払い方法から配送料金を取得する.
1442     *
1443     * @param integer $pref 都道府県ID
1444     * @param integer $payment_id 支払い方法ID
1445     * @return string 指定の都道府県, 支払い方法の配送料金
1446     */
1447    function sfGetDelivFee($arrData) {
1448        $pref = $arrData['deliv_pref'];
1449        $payment_id = isset($arrData['payment_id']) ? $arrData['payment_id'] : "";
1450
1451        $objQuery = new SC_Query();
1452
1453        $deliv_id = "";
1454
1455        // 支払い方法が指定されている場合は、対応した配送業者を取得する
1456        if($payment_id != "") {
1457            $where = "del_flg = 0 AND payment_id = ?";
1458            $arrRet = $objQuery->select("deliv_id", "dtb_payment", $where, array($payment_id));
1459            $deliv_id = $arrRet[0]['deliv_id'];
1460        // 支払い方法が指定されていない場合は、先頭の配送業者を取得する
1461        } else {
1462            $where = "del_flg = 0";
1463            $objQuery->setOrder("rank DESC");
1464            $objQuery->setLimitOffset(1);
1465            $arrRet = $objQuery->select("deliv_id", "dtb_deliv", $where);
1466            $deliv_id = $arrRet[0]['deliv_id'];
1467        }
1468
1469        // 配送業者から配送料を取得
1470        if($deliv_id != "") {
1471
1472            // 都道府県が指定されていない場合は、東京都の番号を指定しておく
1473            if($pref == "") {
1474                $pref = 13;
1475            }
1476
1477            $objQuery = new SC_Query();
1478            $where = "deliv_id = ? AND pref = ?";
1479            $arrRet= $objQuery->select("fee", "dtb_delivfee", $where, array($deliv_id, $pref));
1480        }
1481        return $arrRet[0]['fee'];
1482    }
1483
1484    /**
1485     * 集計情報を元に最終計算を行う.
1486     *
1487     * @param array $arrData 各種情報
1488     * @param LC_Page $objPage LC_Page インスタンス
1489     * @param SC_CartSession $objCartSess SC_CartSession インスタンス
1490     * @param SC_Customer $objCustomer SC_Customer インスタンス
1491     * @return array 最終計算後の配列
1492     */
1493    function sfTotalConfirm($arrData, &$objPage, &$objCartSess, $objCustomer = "") {
1494        // 店舗基本情報を取得する
1495        $arrInfo = SC_Helper_DB_Ex::sf_getBasisData();
1496       
1497        // 未定義変数を定義
1498        if (!isset($arrData['deliv_pref'])) $arrData['deliv_pref'] = "";
1499        if (!isset($arrData['payment_id'])) $arrData['payment_id'] = "";
1500        if (!isset($arrData['charge'])) $arrData['charge'] = "";
1501        if (!isset($arrData['use_point'])) $arrData['use_point'] = "";
1502        if (!isset($arrData['add_point'])) $arrData['add_point'] = 0;
1503
1504        // 税金の取得
1505        $arrData['tax'] = $objPage->tpl_total_tax;
1506        // 小計の取得
1507        $arrData['subtotal'] = $objPage->tpl_total_pretax;
1508
1509        // 合計送料の取得
1510        $arrData['deliv_fee'] = 0;
1511
1512        // 商品ごとの送料が有効の場合
1513        if (OPTION_PRODUCT_DELIV_FEE == 1) {
1514            // 全商品の合計送料を加算する
1515            $this->lfAddAllProductsDelivFee($arrData, $objPage, $objCartSess);
1516        }
1517
1518        // 配送業者の送料が有効の場合
1519        if (OPTION_DELIV_FEE == 1) {
1520            // 都道府県、支払い方法から配送料金を加算する
1521            $this->lfAddDelivFee($arrData);
1522        }
1523
1524        // 送料無料の購入数が設定されている場合
1525        if (DELIV_FREE_AMOUNT > 0) {
1526            // 商品の合計数量
1527            $total_quantity = $objCartSess->getTotalQuantity(true);
1528           
1529            if($total_quantity >= DELIV_FREE_AMOUNT) {
1530                $arrData['deliv_fee'] = 0;
1531            }
1532        }
1533
1534        // 送料無料条件が設定されている場合
1535        if($arrInfo['free_rule'] > 0) {
1536            // 小計が無料条件を超えている場合
1537            if($arrData['subtotal'] >= $arrInfo['free_rule']) {
1538                $arrData['deliv_fee'] = 0;
1539            }
1540        }
1541
1542        // 合計の計算
1543        $arrData['total'] = $objPage->tpl_total_pretax; // 商品合計
1544        $arrData['total']+= $arrData['deliv_fee'];      // 送料
1545        $arrData['total']+= $arrData['charge'];         // 手数料
1546        // お支払い合計
1547        $arrData['payment_total'] = $arrData['total'] - ($arrData['use_point'] * POINT_VALUE);
1548        // 加算ポイントの計算
1549        if (USE_POINT !== false) {
1550            $arrData['add_point'] = SC_Helper_DB_Ex::sfGetAddPoint($objPage->tpl_total_point, $arrData['use_point']);
1551               
1552            if($objCustomer != "") {
1553                // 誕生日月であった場合
1554                if($objCustomer->isBirthMonth()) {
1555                    $arrData['birth_point'] = BIRTH_MONTH_POINT;
1556                    $arrData['add_point'] += $arrData['birth_point'];
1557                }
1558            }
1559        }
1560
1561        if($arrData['add_point'] < 0) {
1562            $arrData['add_point'] = 0;
1563        }
1564        return $arrData;
1565    }
1566
1567    /**
1568     * レコードの存在チェックを行う.
1569     *
1570     * @param string $table テーブル名
1571     * @param string $col カラム名
1572     * @param array $arrval 要素の配列
1573     * @param array $addwhere SQL の AND 条件である WHERE 句
1574     * @return bool レコードが存在する場合 true
1575     */
1576    function sfIsRecord($table, $col, $arrval, $addwhere = "") {
1577        $objQuery = new SC_Query();
1578        $arrCol = split("[, ]", $col);
1579
1580        $where = "del_flg = 0";
1581
1582        if($addwhere != "") {
1583            $where.= " AND $addwhere";
1584        }
1585
1586        foreach($arrCol as $val) {
1587            if($val != "") {
1588                if($where == "") {
1589                    $where = "$val = ?";
1590                } else {
1591                    $where.= " AND $val = ?";
1592                }
1593            }
1594        }
1595        $ret = $objQuery->get($table, $col, $where, $arrval);
1596
1597        if($ret != "") {
1598            return true;
1599        }
1600        return false;
1601    }
1602
1603    /**
1604     * メーカー商品数数の登録を行う.
1605     *
1606     * @param SC_Query $objQuery SC_Query インスタンス
1607     * @return void
1608     */
1609    function sfMaker_Count($objQuery){
1610        $sql = "";
1611
1612        //テーブル内容の削除
1613        $objQuery->query("DELETE FROM dtb_maker_count");
1614
1615        //各メーカーの商品数を数えて格納
1616        $sql = " INSERT INTO dtb_maker_count(maker_id, product_count, create_date) ";
1617        $sql .= " SELECT T1.maker_id, count(T2.maker_id), now() ";
1618        $sql .= " FROM dtb_maker AS T1 LEFT JOIN dtb_products AS T2";
1619        $sql .= " ON T1.maker_id = T2.maker_id ";
1620        $sql .= " WHERE T2.del_flg = 0 AND T2.status = 1 ";
1621        $sql .= " GROUP BY T1.maker_id, T2.maker_id ";
1622        $objQuery->query($sql);
1623    }
1624
1625    /**
1626     * 選択中の商品のメーカーを取得する.
1627     *
1628     * @param integer $product_id プロダクトID
1629     * @param integer $maker_id メーカーID
1630     * @return array 選択中の商品のメーカーIDの配列
1631     *
1632     */
1633    function sfGetMakerId($product_id, $maker_id = 0, $closed = false) {
1634        if ($closed) {
1635            $status = "";
1636        } else {
1637            $status = "status = 1";
1638        }
1639
1640        if(!$this->g_maker_on) {
1641            $this->g_maker_on = true;
1642            $maker_id = (int) $maker_id;
1643            $product_id = (int) $product_id;
1644            if(SC_Utils_Ex::sfIsInt($maker_id) && $this->sfIsRecord("dtb_maker","maker_id", $maker_id)) {
1645                $this->g_maker_id = array($maker_id);
1646            } else if (SC_Utils_Ex::sfIsInt($product_id) && $this->sfIsRecord("dtb_products","product_id", $product_id, $status)) {
1647                $objQuery = new SC_Query();
1648                $where = "product_id = ?";
1649                $maker_id = $objQuery->getCol("dtb_products", "maker_id", "product_id = ?", array($product_id));
1650                $this->g_maker_id = $maker_id;
1651            } else {
1652                // 不正な場合は、空の配列を返す。
1653                $this->g_maker_id = array();
1654            }
1655        }
1656        return $this->g_maker_id;
1657    }
1658
1659    /**
1660     * メーカーの取得を行う.
1661     *
1662     * $products_check:true商品登録済みのものだけ取得する
1663     *
1664     * @param string $addwhere 追加する WHERE 句
1665     * @param bool $products_check 商品の存在するカテゴリのみ取得する場合 true
1666     * @return array カテゴリツリーの配列
1667     */
1668    function sfGetMakerList($addwhere = "", $products_check = false) {
1669        $objQuery = new SC_Query();
1670        $where = "del_flg = 0";
1671
1672        if($addwhere != "") {
1673            $where.= " AND $addwhere";
1674        }
1675
1676        $objQuery->setoption("ORDER BY rank DESC");
1677
1678        if($products_check) {
1679            $col = "T1.maker_id, name";
1680            $from = "dtb_maker AS T1 LEFT JOIN dtb_maker_count AS T2 ON T1.maker_id = T2.maker_id";
1681            $where .= " AND product_count > 0";
1682        } else {
1683            $col = "maker_id, name";
1684            $from = "dtb_maker";
1685        }
1686
1687        $arrRet = $objQuery->select($col, $from, $where);
1688
1689        $max = count($arrRet);
1690        for($cnt = 0; $cnt < $max; $cnt++) {
1691            $id = $arrRet[$cnt]['maker_id'];
1692            $name = $arrRet[$cnt]['name'];
1693            $arrList[$id].= $name;
1694        }
1695        return $arrList;
1696    }
1697
1698    /**
1699     * 全商品の合計送料を加算する
1700     */
1701    function lfAddAllProductsDelivFee(&$arrData, &$objPage, &$objCartSess) {
1702        $arrData['deliv_fee'] += $this->lfCalcAllProductsDelivFee($arrData, $objCartSess);
1703    }
1704
1705    /**
1706     * 全商品の合計送料を計算する
1707     */
1708    function lfCalcAllProductsDelivFee(&$arrData, &$objCartSess) {
1709        $objQuery = new SC_Query();
1710        $deliv_fee_total = 0;
1711        $max = $objCartSess->getMax();
1712        for ($i = 0; $i <= $max; $i++) {
1713            // 商品送料
1714            $deliv_fee = $objQuery->getOne('SELECT deliv_fee FROM dtb_products WHERE product_id = ?', array($_SESSION[$objCartSess->key][$i]['id'][0]));
1715            // 数量
1716            $quantity = $_SESSION[$objCartSess->key][$i]['quantity'];
1717            // 累積
1718            $deliv_fee_total += $deliv_fee * $quantity;
1719        }
1720        return $deliv_fee_total;
1721    }
1722
1723    /**
1724     * 都道府県、支払い方法から配送料金を加算する.
1725     *
1726     * @param array $arrData
1727     */
1728    function lfAddDelivFee(&$arrData) {
1729        $arrData['deliv_fee'] += $this->sfGetDelivFee($arrRet);
1730    }
1731
1732    /**
1733     * 受注の名称列を更新する
1734     *
1735     * @param integer $order_id 更新対象の注文番号
1736     * @param boolean $temp_table 更新対象は「受注_Temp」か
1737     */
1738    function sfUpdateOrderNameCol($order_id, $temp_table = false) {
1739        $objQuery = new SC_Query();
1740       
1741        if ($temp_table) {
1742            $table = 'dtb_order_temp';
1743            $sql_where = 'WHERE order_temp_id = ?';
1744        } else {
1745            $table = 'dtb_order';
1746            $sql_where = 'WHERE order_id = ?';
1747        }
1748       
1749        $sql = <<< __EOS__
1750            UPDATE
1751                $table tgt
1752            SET
1753                 payment_method = (SELECT payment_method FROM dtb_payment WHERE payment_id = tgt.payment_id)
1754                ,deliv_time = (SELECT deliv_time FROM dtb_delivtime WHERE time_id = tgt.deliv_time_id AND deliv_id = tgt.deliv_id)
1755            $sql_where
1756__EOS__;
1757       
1758        $objQuery->query($sql, array($order_id));
1759    }
1760
1761    /**
1762     * 店舗基本情報に基づいて税金額を返す
1763     *
1764     * @param integer $price 計算対象の金額
1765     * @return integer 税金額
1766     */
1767    function sfTax($price) {
1768        // 店舗基本情報を取得
1769        $CONF = SC_Helper_DB_Ex::sf_getBasisData();
1770       
1771        return SC_Utils_Ex::sfTax($price, $CONF['tax'], $CONF['tax_rule']);
1772    }
1773
1774    /**
1775     * 店舗基本情報に基づいて税金付与した金額を返す
1776     *
1777     * @param integer $price 計算対象の金額
1778     * @return integer 税金付与した金額
1779     */
1780    function sfPreTax($price, $tax = null, $tax_rule = null) {
1781        // 店舗基本情報を取得
1782        $CONF = SC_Helper_DB_Ex::sf_getBasisData();
1783       
1784        return SC_Utils_Ex::sfPreTax($price, $CONF['tax'], $CONF['tax_rule']);
1785    }
1786
1787    /**
1788     * 店舗基本情報に基づいて加算ポイントを返す
1789     *
1790     * @param integer $totalpoint
1791     * @param integer $use_point
1792     * @return integer 加算ポイント
1793     */
1794    function sfGetAddPoint($totalpoint, $use_point) {
1795        // 店舗基本情報を取得
1796        $CONF = SC_Helper_DB_Ex::sf_getBasisData();
1797       
1798        return SC_Utils_Ex::sfGetAddPoint($totalpoint, $use_point, $CONF['point_rate']);
1799    }
1800}
1801?>
Note: See TracBrowser for help on using the repository browser.