source: branches/version-2_12-dev/data/class/helper/SC_Helper_DB.php @ 22487

Revision 22487, 55.4 KB checked in by undertree, 8 years ago (diff)

#1358(PC・スマートフォンのエラー画面でフッタにサイト名が表示されない。)
「基本設定>SHOPマスター」更新時にdtb_baseinfoのキャッシュファイルをdata/cacheに生成。
エラーページではarrSiteInfoにキャッシュファイルの値を入れる(ファイルが無い場合の「DB参照→生成」は行わない)

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2013 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24/**
25 * 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     * チェック対象のテーブルに, 該当のカラムが存在するかチェックする.
54     * 引数 $add が true の場合, 該当のカラムが存在しない場合は, カラムの生成を行う.
55     * カラムの生成も行う場合は, $col_type も必須となる.
56     *
57     * @param string $table_name テーブル名
58     * @param string $column_name カラム名
59     * @param string $col_type カラムのデータ型
60     * @param string $dsn データソース名
61     * @param bool $add カラムの作成も行う場合 true
62     * @return bool カラムが存在する場合とカラムの生成に成功した場合 true,
63     *               テーブルが存在しない場合 false,
64     *               引数 $add == false でカラムが存在しない場合 false
65     */
66    function sfColumnExists($table_name, $col_name, $col_type = '', $dsn = '', $add = false) {
67        $dbFactory = SC_DB_DBFactory_Ex::getInstance();
68        $dsn = $dbFactory->getDSN($dsn);
69
70        $objQuery =& SC_Query_Ex::getSingletonInstance($dsn);
71
72        // テーブルが無ければエラー
73        if (!in_array($table_name, $objQuery->listTables())) return false;
74
75        // 正常に接続されている場合
76        if (!$objQuery->isError()) {
77            // カラムリストを取得
78            $columns = $objQuery->listTableFields($table_name);
79
80            if (in_array($col_name, $columns)) {
81                return true;
82            }
83        }
84
85        // カラムを追加する
86        if ($add) {
87            $objQuery->query("ALTER TABLE $table_name ADD $col_name $col_type ");
88            return true;
89        }
90        return false;
91    }
92
93    /**
94     * データの存在チェックを行う.
95     *
96     * @param string $table_name テーブル名
97     * @param string $where データを検索する WHERE 句
98     * @param string $dsn データソース名
99     * @param string $sql @deprecated データの追加を行う場合の SQL文
100     * @param bool $add @deprecated データの追加も行う場合 true
101     * @return bool データが存在する場合 true, データの追加に成功した場合 true,
102     *               $add == false で, データが存在しない場合 false
103     */
104    function sfDataExists($table_name, $where, $arrWhereVal, $dsn = '', $sql = '', $add = false) {
105        $dbFactory = SC_DB_DBFactory_Ex::getInstance();
106        $dsn = $dbFactory->getDSN($dsn);
107
108        $objQuery =& SC_Query_Ex::getSingletonInstance();
109        $exists = $objQuery->exists($table_name, $where, $arrWhereVal);
110
111        // データが存在する場合 TRUE
112        if ($exists) {
113            return TRUE;
114        // $add が TRUE の場合はデータを追加する
115        } elseif ($add) {
116            return $objQuery->exec($sql);
117        // $add が FALSE で、データが存在しない場合 FALSE
118        } else {
119            return FALSE;
120        }
121    }
122
123    /**
124     * 店舗基本情報を取得する.
125     *
126     * 引数 $force が false の場合は, 初回のみ DB 接続し,
127     * 2回目以降はキャッシュされた結果を使用する.
128     *
129     * @param boolean $force 強制的にDB取得するか
130     * @param string $col 取得カラムを指定する
131     * @return array 店舗基本情報の配列
132     */
133    function sfGetBasisData($force = false, $col = '') {
134        static $data = array();
135
136        if ($force || empty($data)) {
137            $objQuery =& SC_Query_Ex::getSingletonInstance();
138
139            if ($col === '') {
140                $arrRet = $objQuery->select('*', 'dtb_baseinfo');
141            } else {
142                $arrRet = $objQuery->select($col, 'dtb_baseinfo');
143            }
144
145            if (isset($arrRet[0])) {
146                $data = $arrRet[0];
147            } else {
148                $data = array();
149            }
150        }
151        return $data;
152    }
153
154    /**
155     * 基本情報のキャッシュデータを取得する
156     *
157     * @param boolean $generate キャッシュファイルが無い時、DBのデータを基にキャッシュを生成するか
158     * @return array 店舗基本情報の配列
159     */
160    function sfGetBasisDataCache($generate = false){
161        // テーブル名
162        $name = 'dtb_baseinfo';
163        // キャッシュファイルパス
164        $filepath = MASTER_DATA_REALDIR . $name . '.serial';
165        // ファイル存在確認
166        if (!file_exists($filepath) && $generate) {
167            // 存在していなければキャッシュ生成
168            $this->sfCreateBasisDataCache();
169        }
170        // 戻り値初期化
171        $cacheData = array();
172        // キャッシュファイルが存在すれば読み込む
173        if (file_exists($filepath)) {
174            // キャッシュデータファイルを読み込みアンシリアライズした配列を取得
175            $cacheData = unserialize(file_get_contents($filepath));
176        }
177        // return
178        return $cacheData;
179    }
180
181    /**
182     * 基本情報のキャッシュデータファイルを生成する
183     * データはsfGetBasisDataより取得。
184     *
185     * このメソッドが直接呼ばれるのは、
186     *「基本情報管理>SHOPマスター」の更新完了後。
187     * sfGetBasisDataCacheでは、
188     * キャッシュデータファイルが無い場合に呼ばれます。
189     *
190     * @return bool キャッシュデータファイル生成結果
191     */
192    function sfCreateBasisDataCache() {
193        // テーブル名
194        $name = 'dtb_baseinfo';
195        // キャッシュファイルパス
196        $filepath = MASTER_DATA_REALDIR . $name . '.serial';
197        // データ取得
198        $arrData = $this->sfGetBasisData(true);
199        // シリアライズ
200        $data = serialize($arrData);
201        // ファイルを書き出しモードで開く
202        $handle = fopen($filepath, 'w');
203        if (!$handle) {
204            // ファイル生成失敗
205            return false;
206        }
207        // ファイルの内容を書き出す.
208        $res = fwrite($handle, $data);
209        // ファイルを閉じる
210        fclose($handle);
211        if ( $res === false) {
212            // ファイル生成失敗
213            return false;
214        }
215        // ファイル生成成功
216        return true;
217    }
218
219    /**
220     * 基本情報の登録数を取得する
221     *
222     * @return int
223     * @deprecated
224     */
225    function sfGetBasisCount() {
226        $objQuery =& SC_Query_Ex::getSingletonInstance();
227
228        return $objQuery->count('dtb_baseinfo');
229    }
230
231    /**
232     * 基本情報の登録有無を取得する
233     *
234     * @return boolean 有無
235     */
236    function sfGetBasisExists() {
237        $objQuery =& SC_Query_Ex::getSingletonInstance();
238
239        return $objQuery->exists('dtb_baseinfo');
240    }
241
242    /* 選択中のアイテムのルートカテゴリIDを取得する */
243    function sfGetRootId() {
244
245        if (!$this->g_root_on) {
246            $this->g_root_on = true;
247
248            if (!isset($_GET['product_id'])) $_GET['product_id'] = '';
249            if (!isset($_GET['category_id'])) $_GET['category_id'] = '';
250
251            if (!empty($_GET['product_id']) || !empty($_GET['category_id'])) {
252                // 選択中のカテゴリIDを判定する
253                $category_id = $this->sfGetCategoryId($_GET['product_id'], $_GET['category_id']);
254                // ROOTカテゴリIDの取得
255                if (count($category_id) > 0) {
256                    $arrRet = $this->sfGetParents('dtb_category', 'parent_category_id', 'category_id', $category_id);
257                    $root_id = isset($arrRet[0]) ? $arrRet[0] : '';
258                } else {
259                    $root_id = '';
260                }
261            } else {
262                // ROOTカテゴリIDをなしに設定する
263                $root_id = '';
264            }
265            $this->g_root_id = $root_id;
266        }
267        return $this->g_root_id;
268    }
269
270    /**
271     * 受注番号、最終ポイント、加算ポイント、利用ポイントから「オーダー前ポイント」を取得する
272     *
273     * @param integer $order_id 受注番号
274     * @param integer $use_point 利用ポイント
275     * @param integer $add_point 加算ポイント
276     * @param integer $order_status 対応状況
277     * @return array オーダー前ポイントの配列
278     */
279    function sfGetRollbackPoint($order_id, $use_point, $add_point, $order_status) {
280        $objQuery =& SC_Query_Ex::getSingletonInstance();
281        $arrRet = $objQuery->select('customer_id', 'dtb_order', 'order_id = ?', array($order_id));
282        $customer_id = $arrRet[0]['customer_id'];
283        if ($customer_id != '' && $customer_id >= 1) {
284            $arrRet = $objQuery->select('point', 'dtb_customer', 'customer_id = ?', array($customer_id));
285            $point = $arrRet[0]['point'];
286            $rollback_point = $arrRet[0]['point'];
287
288            // 対応状況がポイント利用対象の場合、使用ポイント分を戻す
289            if (SC_Helper_Purchase_Ex::isUsePoint($order_status)) {
290                $rollback_point += $use_point;
291            }
292
293            // 対応状況がポイント加算対象の場合、加算ポイント分を戻す
294            if (SC_Helper_Purchase_Ex::isAddPoint($order_status)) {
295                $rollback_point -= $add_point;
296            }
297        } else {
298            $rollback_point = '';
299            $point = '';
300        }
301        return array($point, $rollback_point);
302    }
303
304    /**
305     * カテゴリツリーの取得を行う.
306     *
307     * @param integer $parent_category_id 親カテゴリID
308     * @param bool $count_check 登録商品数のチェックを行う場合 true
309     * @return array カテゴリツリーの配列
310     */
311    function sfGetCatTree($parent_category_id, $count_check = false) {
312        $objQuery =& SC_Query_Ex::getSingletonInstance();
313        $col = '';
314        $col .= ' cat.category_id,';
315        $col .= ' cat.category_name,';
316        $col .= ' cat.parent_category_id,';
317        $col .= ' cat.level,';
318        $col .= ' cat.rank,';
319        $col .= ' cat.creator_id,';
320        $col .= ' cat.create_date,';
321        $col .= ' cat.update_date,';
322        $col .= ' cat.del_flg, ';
323        $col .= ' ttl.product_count';
324        $from = 'dtb_category as cat left join dtb_category_total_count as ttl on ttl.category_id = cat.category_id';
325        // 登録商品数のチェック
326        if ($count_check) {
327            $where = 'del_flg = 0 AND product_count > 0';
328        } else {
329            $where = 'del_flg = 0';
330        }
331        $objQuery->setOption('ORDER BY rank DESC');
332        $arrRet = $objQuery->select($col, $from, $where);
333
334        $arrParentID = SC_Helper_DB_Ex::sfGetParents('dtb_category', 'parent_category_id', 'category_id', $parent_category_id);
335
336        foreach ($arrRet as $key => $array) {
337            foreach ($arrParentID as $val) {
338                if ($array['category_id'] == $val) {
339                    $arrRet[$key]['display'] = 1;
340                    break;
341                }
342            }
343        }
344
345        return $arrRet;
346    }
347
348    /**
349     * カテゴリツリーを走査し, パンくずリスト用の配列を生成する.
350     *
351     * @param array カテゴリの配列
352     * @param integer $parent 上位カテゴリID
353     * @param array パンくずリスト用の配列
354     * @result void
355     * @see sfGetCatTree()
356     */
357    function findTree(&$arrTree, $parent, &$result) {
358        if ($result[count($result) - 1]['parent_category_id'] === 0) {
359            return;
360        } else {
361            foreach ($arrTree as $val) {
362                if ($val['category_id'] == $parent) {
363                    $result[] = array(
364                        'category_id' => $val['category_id'],
365                        'parent_category_id' => (int) $val['parent_category_id'],
366                        'category_name' => $val['category_name'],
367                    );
368                    $this->findTree($arrTree, $val['parent_category_id'], $result);
369                }
370            }
371        }
372    }
373
374    /**
375     * カテゴリツリーの取得を複数カテゴリで行う.
376     *
377     * @param integer $product_id 商品ID
378     * @param bool $count_check 登録商品数のチェックを行う場合 true
379     * @return array カテゴリツリーの配列
380     */
381    function sfGetMultiCatTree($product_id, $count_check = false) {
382        $objQuery =& SC_Query_Ex::getSingletonInstance();
383        $col = '';
384        $col .= ' cat.category_id,';
385        $col .= ' cat.category_name,';
386        $col .= ' cat.parent_category_id,';
387        $col .= ' cat.level,';
388        $col .= ' cat.rank,';
389        $col .= ' cat.creator_id,';
390        $col .= ' cat.create_date,';
391        $col .= ' cat.update_date,';
392        $col .= ' cat.del_flg, ';
393        $col .= ' ttl.product_count';
394        $from = 'dtb_category as cat left join dtb_category_total_count as ttl on ttl.category_id = cat.category_id';
395        // 登録商品数のチェック
396        if ($count_check) {
397            $where = 'del_flg = 0 AND product_count > 0';
398        } else {
399            $where = 'del_flg = 0';
400        }
401        $objQuery->setOption('ORDER BY rank DESC');
402        $arrRet = $objQuery->select($col, $from, $where);
403
404        $arrCategory_id = SC_Helper_DB_Ex::sfGetCategoryId($product_id);
405
406        $arrCatTree = array();
407        foreach ($arrCategory_id as $pkey => $parent_category_id) {
408            $arrParentID = SC_Helper_DB_Ex::sfGetParents('dtb_category', 'parent_category_id', 'category_id', $parent_category_id);
409
410            foreach ($arrParentID as $pid) {
411                foreach ($arrRet as $key => $array) {
412                    if ($array['category_id'] == $pid) {
413                        $arrCatTree[$pkey][] = $arrRet[$key];
414                        break;
415                    }
416                }
417            }
418        }
419
420        return $arrCatTree;
421    }
422
423    /**
424     * 親カテゴリを連結した文字列を取得する.
425     *
426     * @param integer $category_id カテゴリID
427     * @return string 親カテゴリを連結した文字列
428     */
429    function sfGetCatCombName($category_id) {
430        // 商品が属するカテゴリIDを縦に取得
431        $objQuery =& SC_Query_Ex::getSingletonInstance();
432        $arrCatID = $this->sfGetParents('dtb_category', 'parent_category_id', 'category_id', $category_id);
433        $ConbName = '';
434
435        // カテゴリ名称を取得する
436        foreach ($arrCatID as $val) {
437            $sql = 'SELECT category_name FROM dtb_category WHERE category_id = ?';
438            $arrVal = array($val);
439            $CatName = $objQuery->getOne($sql,$arrVal);
440            $ConbName .= $CatName . ' | ';
441        }
442        // 最後の | をカットする
443        $ConbName = substr_replace($ConbName, '', strlen($ConbName) - 2, 2);
444
445        return $ConbName;
446    }
447
448    /**
449     * 指定したカテゴリIDのカテゴリを取得する.
450     *
451     * @param integer $category_id カテゴリID
452     * @return array 指定したカテゴリIDのカテゴリ
453     */
454    function sfGetCat($category_id) {
455        $objQuery =& SC_Query_Ex::getSingletonInstance();
456
457        // カテゴリを取得する
458        $arrVal = array($category_id);
459        $res = $objQuery->select('category_id AS id, category_name AS name', 'dtb_category', 'category_id = ?', $arrVal);
460
461        return $res[0];
462    }
463
464    /**
465     * 指定したカテゴリIDの大カテゴリを取得する.
466     *
467     * @param integer $category_id カテゴリID
468     * @return array 指定したカテゴリIDの大カテゴリ
469     */
470    function sfGetFirstCat($category_id) {
471        // 商品が属するカテゴリIDを縦に取得
472        $objQuery =& SC_Query_Ex::getSingletonInstance();
473        $arrRet = array();
474        $arrCatID = $this->sfGetParents('dtb_category', 'parent_category_id', 'category_id', $category_id);
475        $arrRet['id'] = $arrCatID[0];
476
477        // カテゴリ名称を取得する
478        $sql = 'SELECT category_name FROM dtb_category WHERE category_id = ?';
479        $arrVal = array($arrRet['id']);
480        $arrRet['name'] = $objQuery->getOne($sql,$arrVal);
481
482        return $arrRet;
483    }
484
485    /**
486     * カテゴリツリーの取得を行う.
487     *
488     * $products_check:true商品登録済みのものだけ取得する
489     *
490     * @param string $addwhere 追加する WHERE 句
491     * @param bool $products_check 商品の存在するカテゴリのみ取得する場合 true
492     * @param string $head カテゴリ名のプレフィックス文字列
493     * @return array カテゴリツリーの配列
494     */
495    function sfGetCategoryList($addwhere = '', $products_check = false, $head = CATEGORY_HEAD) {
496        $objQuery =& SC_Query_Ex::getSingletonInstance();
497        $where = 'del_flg = 0';
498
499        if ($addwhere != '') {
500            $where.= " AND $addwhere";
501        }
502
503        $objQuery->setOption('ORDER BY rank DESC');
504
505        if ($products_check) {
506            $col = 'T1.category_id, category_name, level';
507            $from = 'dtb_category AS T1 LEFT JOIN dtb_category_total_count AS T2 ON T1.category_id = T2.category_id';
508            $where .= ' AND product_count > 0';
509        } else {
510            $col = 'category_id, category_name, level';
511            $from = 'dtb_category';
512        }
513
514        $arrRet = $objQuery->select($col, $from, $where);
515
516        $max = count($arrRet);
517        $arrList = array();
518        for ($cnt = 0; $cnt < $max; $cnt++) {
519            $id = $arrRet[$cnt]['category_id'];
520            $name = $arrRet[$cnt]['category_name'];
521            $arrList[$id] = str_repeat($head, $arrRet[$cnt]['level']) . $name;
522        }
523        return $arrList;
524    }
525
526    /**
527     * カテゴリツリーの取得を行う.
528     *
529     * 親カテゴリの Value=0 を対象とする
530     *
531     * @param bool $parent_zero 親カテゴリの Value=0 の場合 true
532     * @return array カテゴリツリーの配列
533     */
534    function sfGetLevelCatList($parent_zero = true) {
535        $objQuery =& SC_Query_Ex::getSingletonInstance();
536
537        // カテゴリ名リストを取得
538        $col = 'category_id, parent_category_id, category_name';
539        $where = 'del_flg = 0';
540        $objQuery->setOption('ORDER BY level');
541        $arrRet = $objQuery->select($col, 'dtb_category', $where);
542        $arrCatName = array();
543        foreach ($arrRet as $arrTmp) {
544            $arrCatName[$arrTmp['category_id']] =
545                (($arrTmp['parent_category_id'] > 0)?
546                    $arrCatName[$arrTmp['parent_category_id']] : '')
547                . CATEGORY_HEAD . $arrTmp['category_name'];
548        }
549
550        $col = 'category_id, parent_category_id, category_name, level';
551        $where = 'del_flg = 0';
552        $objQuery->setOption('ORDER BY rank DESC');
553        $arrRet = $objQuery->select($col, 'dtb_category', $where);
554        $max = count($arrRet);
555
556        $arrValue = array();
557        $arrOutput = array();
558        for ($cnt = 0; $cnt < $max; $cnt++) {
559            if ($parent_zero) {
560                if ($arrRet[$cnt]['level'] == LEVEL_MAX) {
561                    $arrValue[$cnt] = $arrRet[$cnt]['category_id'];
562                } else {
563                    $arrValue[$cnt] = '';
564                }
565            } else {
566                $arrValue[$cnt] = $arrRet[$cnt]['category_id'];
567            }
568
569            $arrOutput[$cnt] = $arrCatName[$arrRet[$cnt]['category_id']];
570        }
571
572        return array($arrValue, $arrOutput);
573    }
574
575    /**
576     * 選択中の商品のカテゴリを取得する.
577     *
578     * @param integer $product_id プロダクトID
579     * @param integer $category_id カテゴリID
580     * @return array 選択中の商品のカテゴリIDの配列
581     *
582     */
583    function sfGetCategoryId($product_id, $category_id = 0, $closed = false) {
584        if ($closed) {
585            $status = '';
586        } else {
587            $status = 'status = 1';
588        }
589        $category_id = (int) $category_id;
590        $product_id = (int) $product_id;
591        if (SC_Utils_Ex::sfIsInt($category_id) && $category_id != 0 && SC_Helper_DB_Ex::sfIsRecord('dtb_category','category_id', $category_id)) {
592            $category_id = array($category_id);
593        } else if (SC_Utils_Ex::sfIsInt($product_id) && $product_id != 0 && SC_Helper_DB_Ex::sfIsRecord('dtb_products','product_id', $product_id, $status)) {
594            $objQuery =& SC_Query_Ex::getSingletonInstance();
595            $category_id = $objQuery->getCol('category_id', 'dtb_product_categories', 'product_id = ?', array($product_id));
596        } else {
597            // 不正な場合は、空の配列を返す。
598            $category_id = array();
599        }
600        return $category_id;
601    }
602
603    /**
604     * 商品をカテゴリの先頭に追加する.
605     *
606     * @param integer $category_id カテゴリID
607     * @param integer $product_id プロダクトID
608     * @return void
609     */
610    function addProductBeforCategories($category_id, $product_id) {
611        $objQuery =& SC_Query_Ex::getSingletonInstance();
612
613        $sqlval = array('category_id' => $category_id,
614                        'product_id' => $product_id);
615
616        $arrSql = array();
617        $arrSql['rank'] = '(SELECT COALESCE(MAX(rank), 0) FROM dtb_product_categories sub WHERE category_id = ?) + 1';
618
619        $from_and_where = $objQuery->dbFactory->getDummyFromClauseSql();
620        $from_and_where .= ' WHERE NOT EXISTS(SELECT * FROM dtb_product_categories WHERE category_id = ? AND product_id = ?)';
621        $objQuery->insert('dtb_product_categories', $sqlval, $arrSql, array($category_id), $from_and_where, array($category_id, $product_id));
622    }
623
624    /**
625     * 商品をカテゴリの末尾に追加する.
626     *
627     * @param integer $category_id カテゴリID
628     * @param integer $product_id プロダクトID
629     * @return void
630     */
631    function addProductAfterCategories($category_id, $product_id) {
632        $sqlval = array('category_id' => $category_id,
633                        'product_id' => $product_id);
634
635        $objQuery =& SC_Query_Ex::getSingletonInstance();
636
637        // 現在の商品カテゴリを取得
638        $arrCat = $objQuery->select('product_id, category_id, rank',
639                                    'dtb_product_categories',
640                                    'category_id = ?',
641                                    array($category_id));
642
643        $min = 0;
644        foreach ($arrCat as $val) {
645            // 同一商品が存在する場合は登録しない
646            if ($val['product_id'] == $product_id) {
647                return;
648            }
649            // 最下位ランクを取得
650            $min = ($min < $val['rank']) ? $val['rank'] : $min;
651        }
652        $sqlval['rank'] = $min;
653        $objQuery->insert('dtb_product_categories', $sqlval);
654    }
655
656    /**
657     * 商品をカテゴリから削除する.
658     *
659     * @param integer $category_id カテゴリID
660     * @param integer $product_id プロダクトID
661     * @return void
662     */
663    function removeProductByCategories($category_id, $product_id) {
664        $objQuery =& SC_Query_Ex::getSingletonInstance();
665        $objQuery->delete('dtb_product_categories',
666                          'category_id = ? AND product_id = ?', array($category_id, $product_id));
667    }
668
669    /**
670     * 商品カテゴリを更新する.
671     *
672     * @param array $arrCategory_id 登録するカテゴリIDの配列
673     * @param integer $product_id プロダクトID
674     * @return void
675     */
676    function updateProductCategories($arrCategory_id, $product_id) {
677        $objQuery =& SC_Query_Ex::getSingletonInstance();
678
679        // 現在のカテゴリ情報を取得
680        $arrCurrentCat = $objQuery->getCol('category_id',
681                                           'dtb_product_categories',
682                                           'product_id = ?',
683                                           array($product_id));
684
685        // 登録するカテゴリ情報と比較
686        foreach ($arrCurrentCat as $category_id) {
687
688            // 登録しないカテゴリを削除
689            if (!in_array($category_id, $arrCategory_id)) {
690                $this->removeProductByCategories($category_id, $product_id);
691            }
692        }
693
694        // カテゴリを登録
695        foreach ($arrCategory_id as $category_id) {
696            $this->addProductBeforCategories($category_id, $product_id);
697            SC_Utils_Ex::extendTimeOut();
698        }
699    }
700
701    /**
702     * カテゴリ数の登録を行う.
703     *
704     *
705     * @param SC_Query $objQuery SC_Query インスタンス
706     * @param boolean $is_force_all_count 全カテゴリの集計を強制する場合 true
707     * @return void
708     */
709    function sfCountCategory($objQuery = NULL, $is_force_all_count = false) {
710        $objProduct = new SC_Product_Ex();
711
712        if ($objQuery == NULL) {
713            $objQuery =& SC_Query_Ex::getSingletonInstance();
714        }
715
716        $is_out_trans = false;
717        if (!$objQuery->inTransaction()) {
718            $objQuery->begin();
719            $is_out_trans = true;
720        }
721
722        //共通のfrom/where文の構築
723        $sql_where = 'alldtl.del_flg = 0 AND alldtl.status = 1';
724        // 在庫無し商品の非表示
725        if (NOSTOCK_HIDDEN) {
726            $where_products_class = '(stock >= 1 OR stock_unlimited = 1)';
727            $from = $objProduct->alldtlSQL($where_products_class);
728        } else {
729            $from = 'dtb_products as alldtl';
730        }
731
732        //dtb_category_countの構成
733        // 各カテゴリに所属する商品の数を集計。集計対象には子カテゴリを含まない。
734
735        //まずテーブル内容の元を取得
736        if (!$is_force_all_count) {
737            $arrCategoryCountOld = $objQuery->select('category_id,product_count','dtb_category_count');
738        } else {
739            $arrCategoryCountOld = array();
740        }
741
742        //各カテゴリ内の商品数を数えて取得
743        $sql = <<< __EOS__
744            SELECT T1.category_id, count(T2.category_id) as product_count
745            FROM dtb_category AS T1
746                LEFT JOIN dtb_product_categories AS T2
747                    ON T1.category_id = T2.category_id
748                LEFT JOIN $from
749                    ON T2.product_id = alldtl.product_id
750            WHERE $sql_where
751            GROUP BY T1.category_id, T2.category_id
752__EOS__;
753
754        $arrCategoryCountNew = $objQuery->getAll($sql);
755        // 各カテゴリに所属する商品の数を集計。集計対象には子カテゴリを「含む」。
756        //差分を取得して、更新対象カテゴリだけを確認する。
757
758        //各カテゴリ毎のデータ値において以前との差を見る
759        //古いデータの構造入れ替え
760        $arrOld = array();
761        foreach ($arrCategoryCountOld as $item) {
762            $arrOld[$item['category_id']] = $item['product_count'];
763        }
764        //新しいデータの構造入れ替え
765        $arrNew = array();
766        foreach ($arrCategoryCountNew as $item) {
767            $arrNew[$item['category_id']] = $item['product_count'];
768        }
769
770        unset($arrCategoryCountOld);
771        unset($arrCategoryCountNew);
772
773        $arrDiffCategory_id = array();
774        //新しいカテゴリ一覧から見て商品数が異なるデータが無いか確認
775        foreach ($arrNew as $cid => $count) {
776            if ($arrOld[$cid] != $count) {
777                $arrDiffCategory_id[] = $cid;
778            }
779        }
780        //削除カテゴリを想定して、古いカテゴリ一覧から見て商品数が異なるデータが無いか確認。
781        foreach ($arrOld as $cid => $count) {
782            if ($arrNew[$cid] != $count && $count > 0) {
783                $arrDiffCategory_id[] = $cid;
784            }
785        }
786
787        //対象IDが無ければ終了
788        if (count($arrDiffCategory_id) == 0) {
789            if ($is_out_trans) {
790                $objQuery->commit();
791            }
792            return;
793        }
794
795        //差分対象カテゴリIDの重複を除去
796        $arrDiffCategory_id = array_unique($arrDiffCategory_id);
797
798        //dtb_category_countの更新 差分のあったカテゴリだけ更新する。
799        foreach ($arrDiffCategory_id as $cid) {
800            $sqlval = array();
801            $sqlval['create_date'] = 'CURRENT_TIMESTAMP';
802            $sqlval['product_count'] = (string)$arrNew[$cid];
803            if ($sqlval['product_count'] =='') {
804                $sqlval['product_count'] = (string)'0';
805            }
806            if (isset($arrOld[$cid])) {
807                $objQuery->update('dtb_category_count', $sqlval, 'category_id = ?', array($cid));
808            } else {
809                if ($is_force_all_count) {
810                    $ret = $objQuery->update('dtb_category_count', $sqlval, 'category_id = ?', array($cid));
811                    if ($ret > 0) {
812                        continue;
813                    }
814                }
815                $sqlval['category_id'] = $cid;
816                $objQuery->insert('dtb_category_count', $sqlval);
817            }
818        }
819
820        unset($arrOld);
821        unset($arrNew);
822
823        //差分があったIDとその親カテゴリIDのリストを取得する
824        $arrTgtCategory_id = array();
825        foreach ($arrDiffCategory_id as $parent_category_id) {
826            $arrTgtCategory_id[] = $parent_category_id;
827            $arrParentID = $this->sfGetParents('dtb_category', 'parent_category_id', 'category_id', $parent_category_id);
828            $arrTgtCategory_id = array_unique(array_merge($arrTgtCategory_id, $arrParentID));
829        }
830
831        unset($arrDiffCategory_id);
832
833        //dtb_category_total_count 集計処理開始
834        //更新対象カテゴリIDだけ集計しなおす。
835        $arrUpdateData = array();
836        $where_products_class = '';
837        if (NOSTOCK_HIDDEN) {
838            $where_products_class .= '(stock >= 1 OR stock_unlimited = 1)';
839        }
840        $from = $objProduct->alldtlSQL($where_products_class);
841        foreach ($arrTgtCategory_id as $category_id) {
842            $arrWhereVal = array();
843            list($tmp_where, $arrTmpVal) = $this->sfGetCatWhere($category_id);
844            if ($tmp_where != '') {
845                $sql_where_product_ids = 'product_id IN (SELECT product_id FROM dtb_product_categories WHERE ' . $tmp_where . ')';
846                $arrWhereVal = $arrTmpVal;
847            } else {
848                $sql_where_product_ids = '0<>0'; // 一致させない
849            }
850            $where = "($sql_where) AND ($sql_where_product_ids)";
851
852            $arrUpdateData[$category_id] = $objQuery->count($from, $where, $arrWhereVal);
853        }
854
855        unset($arrTgtCategory_id);
856
857        // 更新対象だけを更新。
858        foreach ($arrUpdateData as $cid => $count) {
859            $sqlval = array();
860            $sqlval['create_date'] = 'CURRENT_TIMESTAMP';
861            $sqlval['product_count'] = $count;
862            if ($sqlval['product_count'] =='') {
863                $sqlval['product_count'] = (string)'0';
864            }
865            $ret = $objQuery->update('dtb_category_total_count', $sqlval, 'category_id = ?', array($cid));
866            if (!$ret) {
867                $sqlval['category_id'] = $cid;
868                $ret = $objQuery->insert('dtb_category_total_count', $sqlval);
869            }
870        }
871        // トランザクション終了処理
872        if ($is_out_trans) {
873            $objQuery->commit();
874        }
875    }
876
877    /**
878     * 子IDの配列を返す.
879     *
880     * @param string $table テーブル名
881     * @param string $pid_name 親ID名
882     * @param string $id_name ID名
883     * @param integer $id ID
884     * @param array 子ID の配列
885     */
886    function sfGetChildsID($table, $pid_name, $id_name, $id) {
887        $arrRet = $this->sfGetChildrenArray($table, $pid_name, $id_name, $id);
888        return $arrRet;
889    }
890
891    /**
892     * 階層構造のテーブルから子ID配列を取得する.
893     *
894     * @param string $table テーブル名
895     * @param string $pid_name 親ID名
896     * @param string $id_name ID名
897     * @param integer $id ID番号
898     * @return array 子IDの配列
899     */
900    function sfGetChildrenArray($table, $pid_name, $id_name, $id) {
901        $arrChildren = array();
902        $arrRet = array($id);
903
904        while (count($arrRet) > 0) {
905            $arrChildren = array_merge($arrChildren, $arrRet);
906            $arrRet = SC_Helper_DB_Ex::sfGetChildrenArraySub($table, $pid_name, $id_name, $arrRet);
907        }
908
909        return $arrChildren;
910    }
911
912    /**
913     * 親ID直下の子IDをすべて取得する.
914     *
915     * @param array $arrData 親カテゴリの配列
916     * @param string $pid_name 親ID名
917     * @param string $id_name ID名
918     * @param array $arrPID 親IDの配列
919     * @return array 子IDの配列
920     */
921    function sfGetChildrenArraySub($table, $pid_name, $id_name, $arrPID) {
922        $objQuery =& SC_Query_Ex::getSingletonInstance();
923
924        $where = "$pid_name IN (" . SC_Utils_Ex::repeatStrWithSeparator('?', count($arrPID)) . ')';
925
926        $return = $objQuery->getCol($id_name, $table, $where, $arrPID);
927
928        return $return;
929    }
930
931    /**
932     * 所属するすべての階層の親IDを配列で返す.
933     *
934     * @param SC_Query $objQuery SC_Query インスタンス
935     * @param string $table テーブル名
936     * @param string $pid_name 親ID名
937     * @param string $id_name ID名
938     * @param integer $id ID
939     * @return array 親IDの配列
940     */
941    function sfGetParents($table, $pid_name, $id_name, $id) {
942        $arrRet = SC_Helper_DB_Ex::sfGetParentsArray($table, $pid_name, $id_name, $id);
943        return $arrRet;
944    }
945
946    /**
947     * 階層構造のテーブルから親ID配列を取得する.
948     *
949     * @param string $table テーブル名
950     * @param string $pid_name 親ID名
951     * @param string $id_name ID名
952     * @param integer $id ID
953     * @return array 親IDの配列
954     */
955    function sfGetParentsArray($table, $pid_name, $id_name, $id) {
956        $arrParents = array();
957        $ret = $id;
958
959        while ($ret != '0' && !SC_Utils_Ex::isBlank($ret)) {
960            $arrParents[] = $ret;
961            $ret = SC_Helper_DB_Ex::sfGetParentsArraySub($table, $pid_name, $id_name, $ret);
962        }
963
964        $arrParents = array_reverse($arrParents);
965
966        return $arrParents;
967    }
968
969    /* 子ID所属する親IDを取得する */
970    function sfGetParentsArraySub($table, $pid_name, $id_name, $child) {
971        if (SC_Utils_Ex::isBlank($child)) {
972            return false;
973        }
974        $objQuery =& SC_Query_Ex::getSingletonInstance();
975        if (!is_array($child)) {
976            $child = array($child);
977        }
978        $parent = $objQuery->get($pid_name, $table, "$id_name = ?", $child);
979        return $parent;
980    }
981
982    /**
983     * カテゴリから商品を検索する場合のWHERE文と値を返す.
984     *
985     * @param integer $category_id カテゴリID
986     * @return array 商品を検索する場合の配列
987     */
988    function sfGetCatWhere($category_id) {
989        // 子カテゴリIDの取得
990        $arrRet = SC_Helper_DB_Ex::sfGetChildrenArray('dtb_category', 'parent_category_id', 'category_id', $category_id);
991
992        $where = 'category_id IN (' . SC_Utils_Ex::repeatStrWithSeparator('?', count($arrRet)) . ')';
993
994        return array($where, $arrRet);
995    }
996
997    /**
998     * SELECTボックス用リストを作成する.
999     *
1000     * @param string $table テーブル名
1001     * @param string $keyname プライマリーキーのカラム名
1002     * @param string $valname データ内容のカラム名
1003     * @param string $where WHERE句
1004     * @param array $arrWhereVal プレースホルダ
1005     * @return array SELECT ボックス用リストの配列
1006     */
1007    function sfGetIDValueList($table, $keyname, $valname, $where = '', $arrVal = array()) {
1008        $objQuery =& SC_Query_Ex::getSingletonInstance();
1009        $col = "$keyname, $valname";
1010        $objQuery->setWhere('del_flg = 0');
1011        $objQuery->setOrder('rank DESC');
1012        $arrList = $objQuery->select($col, $table, $where, $arrVal);
1013        $count = count($arrList);
1014        $arrRet = array();
1015        for ($cnt = 0; $cnt < $count; $cnt++) {
1016            $key = $arrList[$cnt][$keyname];
1017            $val = $arrList[$cnt][$valname];
1018            $arrRet[$key] = $val;
1019        }
1020        return $arrRet;
1021    }
1022
1023    /**
1024     * ランキングを上げる.
1025     *
1026     * @param string $table テーブル名
1027     * @param string $colname カラム名
1028     * @param string|integer $id テーブルのキー
1029     * @param string $andwhere SQL の AND 条件である WHERE 句
1030     * @return void
1031     */
1032    function sfRankUp($table, $colname, $id, $andwhere = '') {
1033        $objQuery =& SC_Query_Ex::getSingletonInstance();
1034        $objQuery->begin();
1035        $where = "$colname = ?";
1036        if ($andwhere != '') {
1037            $where.= " AND $andwhere";
1038        }
1039        // 対象項目のランクを取得
1040        $rank = $objQuery->get('rank', $table, $where, array($id));
1041        // ランクの最大値を取得
1042        $maxrank = $objQuery->max('rank', $table, $andwhere);
1043        // ランクが最大値よりも小さい場合に実行する。
1044        if ($rank < $maxrank) {
1045            // ランクが一つ上のIDを取得する。
1046            $where = 'rank = ?';
1047            if ($andwhere != '') {
1048                $where.= " AND $andwhere";
1049            }
1050            $uprank = $rank + 1;
1051            $up_id = $objQuery->get($colname, $table, $where, array($uprank));
1052
1053            // ランク入れ替えの実行
1054            $where = "$colname = ?";
1055            if ($andwhere != '') {
1056                $where .= " AND $andwhere";
1057            }
1058
1059            $sqlval = array(
1060                'rank' => $rank + 1,
1061            );
1062            $arrWhereVal = array($id);
1063            $objQuery->update($table, $sqlval, $where, $arrWhereVal);
1064
1065            $sqlval = array(
1066                'rank' => $rank,
1067            );
1068            $arrWhereVal = array($up_id);
1069            $objQuery->update($table, $sqlval, $where, $arrWhereVal);
1070        }
1071        $objQuery->commit();
1072    }
1073
1074    /**
1075     * ランキングを下げる.
1076     *
1077     * @param string $table テーブル名
1078     * @param string $colname カラム名
1079     * @param string|integer $id テーブルのキー
1080     * @param string $andwhere SQL の AND 条件である WHERE 句
1081     * @return void
1082     */
1083    function sfRankDown($table, $colname, $id, $andwhere = '') {
1084        $objQuery =& SC_Query_Ex::getSingletonInstance();
1085        $objQuery->begin();
1086        $where = "$colname = ?";
1087        if ($andwhere != '') {
1088            $where.= " AND $andwhere";
1089        }
1090        // 対象項目のランクを取得
1091        $rank = $objQuery->get('rank', $table, $where, array($id));
1092
1093        // ランクが1(最小値)よりも大きい場合に実行する。
1094        if ($rank > 1) {
1095            // ランクが一つ下のIDを取得する。
1096            $where = 'rank = ?';
1097            if ($andwhere != '') {
1098                $where.= " AND $andwhere";
1099            }
1100            $downrank = $rank - 1;
1101            $down_id = $objQuery->get($colname, $table, $where, array($downrank));
1102
1103            // ランク入れ替えの実行
1104            $where = "$colname = ?";
1105            if ($andwhere != '') {
1106                $where .= " AND $andwhere";
1107            }
1108
1109            $sqlval = array(
1110                'rank' => $rank - 1,
1111            );
1112            $arrWhereVal = array($id);
1113            $objQuery->update($table, $sqlval, $where, $arrWhereVal);
1114
1115            $sqlval = array(
1116                'rank' => $rank,
1117            );
1118            $arrWhereVal = array($down_id);
1119            $objQuery->update($table, $sqlval, $where, $arrWhereVal);
1120        }
1121        $objQuery->commit();
1122    }
1123
1124    /**
1125     * 指定順位へ移動する.
1126     *
1127     * @param string $tableName テーブル名
1128     * @param string $keyIdColumn キーを保持するカラム名
1129     * @param string|integer $keyId キーの値
1130     * @param integer $pos 指定順位
1131     * @param string $where SQL の AND 条件である WHERE 句
1132     * @return void
1133     */
1134    function sfMoveRank($tableName, $keyIdColumn, $keyId, $pos, $where = '') {
1135        $objQuery =& SC_Query_Ex::getSingletonInstance();
1136        $objQuery->begin();
1137
1138        // 自身のランクを取得する
1139        if ($where != '') {
1140            $getWhere = "$keyIdColumn = ? AND " . $where;
1141        } else {
1142            $getWhere = "$keyIdColumn = ?";
1143        }
1144        $rank = $objQuery->get('rank', $tableName, $getWhere, array($keyId));
1145
1146        $max = $objQuery->max('rank', $tableName, $where);
1147
1148        // 値の調整(逆順)
1149        if ($pos > $max) {
1150            $position = 1;
1151        } else if ($pos < 1) {
1152            $position = $max;
1153        } else {
1154            $position = $max - $pos + 1;
1155        }
1156
1157        //入れ替え先の順位が入れ換え元の順位より大きい場合
1158        if ($position > $rank) $term = 'rank - 1';
1159
1160        //入れ替え先の順位が入れ換え元の順位より小さい場合
1161        if ($position < $rank) $term = 'rank + 1';
1162
1163        // XXX 入れ替え先の順位が入れ替え元の順位と同じ場合
1164        if (!isset($term)) $term = 'rank';
1165
1166        // 指定した順位の商品から移動させる商品までのrankを1つずらす
1167        $sqlval = array();
1168        $arrRawSql = array(
1169            'rank' => $term,
1170        );
1171        $str_where = 'rank BETWEEN ? AND ?';
1172        if ($where != '') {
1173            $str_where .= " AND $where";
1174        }
1175
1176        if ($position > $rank) {
1177            $arrWhereVal = array($rank + 1, $position);
1178            $objQuery->update($tableName, $sqlval, $str_where, $arrWhereVal, $arrRawSql);
1179        }
1180        if ($position < $rank) {
1181            $arrWhereVal = array($position, $rank - 1);
1182            $objQuery->update($tableName, $sqlval, $str_where, $arrWhereVal, $arrRawSql);
1183        }
1184
1185        // 指定した順位へrankを書き換える。
1186        $sqlval = array(
1187            'rank' => $position,
1188        );
1189        $str_where = "$keyIdColumn = ?";
1190        if ($where != '') {
1191            $str_where .= " AND $where";
1192        }
1193        $arrWhereVal = array($keyId);
1194        $objQuery->update($tableName, $sqlval, $str_where, $arrWhereVal);
1195
1196        $objQuery->commit();
1197    }
1198
1199    /**
1200     * ランクを含むレコードを削除する.
1201     *
1202     * レコードごと削除する場合は、$deleteをtrueにする
1203     *
1204     * @param string $table テーブル名
1205     * @param string $colname カラム名
1206     * @param string|integer $id テーブルのキー
1207     * @param string $andwhere SQL の AND 条件である WHERE 句
1208     * @param bool $delete レコードごと削除する場合 true,
1209     *                     レコードごと削除しない場合 false
1210     * @return void
1211     */
1212    function sfDeleteRankRecord($table, $colname, $id, $andwhere = '',
1213                                $delete = false) {
1214        $objQuery =& SC_Query_Ex::getSingletonInstance();
1215        $objQuery->begin();
1216        // 削除レコードのランクを取得する。
1217        $where = "$colname = ?";
1218        if ($andwhere != '') {
1219            $where.= " AND $andwhere";
1220        }
1221        $rank = $objQuery->get('rank', $table, $where, array($id));
1222
1223        if (!$delete) {
1224            // ランクを最下位にする、DELフラグON
1225            $sqlval = array(
1226                'rank'      => 0,
1227                'del_flg'   => 1,
1228            );
1229            $where = "$colname = ?";
1230            $arrWhereVal = array($id);
1231            $objQuery->update($table, $sqlval, $where, $arrWhereVal);
1232        } else {
1233            $objQuery->delete($table, "$colname = ?", array($id));
1234        }
1235
1236        // 追加レコードのランクより上のレコードを一つずらす。
1237        $sqlval = array();
1238        $where = 'rank > ?';
1239        if ($andwhere != '') {
1240            $where .= " AND $andwhere";
1241        }
1242        $arrWhereVal = array($rank);
1243        $arrRawSql = array(
1244            'rank' => '(rank - 1)',
1245        );
1246        $objQuery->update($table, $sqlval, $where, $arrWhereVal, $arrRawSql);
1247
1248        $objQuery->commit();
1249    }
1250
1251    /**
1252     * 親IDの配列を元に特定のカラムを取得する.
1253     *
1254     * @param SC_Query $objQuery SC_Query インスタンス
1255     * @param string $table テーブル名
1256     * @param string $id_name ID名
1257     * @param string $col_name カラム名
1258     * @param array $arrId IDの配列
1259     * @return array 特定のカラムの配列
1260     */
1261    function sfGetParentsCol($objQuery, $table, $id_name, $col_name, $arrId) {
1262        $col = $col_name;
1263        $len = count($arrId);
1264        $where = '';
1265
1266        for ($cnt = 0; $cnt < $len; $cnt++) {
1267            if ($where == '') {
1268                $where = "$id_name = ?";
1269            } else {
1270                $where.= " OR $id_name = ?";
1271            }
1272        }
1273
1274        $objQuery->setOrder('level');
1275        $arrRet = $objQuery->select($col, $table, $where, $arrId);
1276        return $arrRet;
1277    }
1278
1279    /**
1280     * カテゴリ変更時の移動処理を行う.
1281     *
1282     * ※この関数って、どこからも呼ばれていないのでは??
1283     *
1284     * @param SC_Query $objQuery SC_Query インスタンス
1285     * @param string $table テーブル名
1286     * @param string $id_name ID名
1287     * @param string $cat_name カテゴリ名
1288     * @param integer $old_catid 旧カテゴリID
1289     * @param integer $new_catid 新カテゴリID
1290     * @param integer $id ID
1291     * @return void
1292     */
1293    function sfMoveCatRank($objQuery, $table, $id_name, $cat_name, $old_catid, $new_catid, $id) {
1294        if ($old_catid == $new_catid) {
1295            return;
1296        }
1297        // 旧カテゴリでのランク削除処理
1298        // 移動レコードのランクを取得する。
1299        $sqlval = array();
1300        $where = "$id_name = ?";
1301        $rank = $objQuery->get('rank', $table, $where, array($id));
1302        // 削除レコードのランクより上のレコードを一つ下にずらす。
1303        $where = "rank > ? AND $cat_name = ?";
1304        $arrWhereVal = array($rank, $old_catid);
1305        $arrRawSql = array(
1306            'rank' => '(rank - 1)',
1307        );
1308        $objQuery->update($table, $sqlval, $where, $arrWhereVal, $arrRawSql);
1309
1310        // 新カテゴリでの登録処理
1311        // 新カテゴリの最大ランクを取得する。
1312        $max_rank = $objQuery->max('rank', $table, "$cat_name = ?", array($new_catid)) + 1;
1313        $sqlval = array(
1314            'rank' => $max_rank,
1315        );
1316        $where = "$id_name = ?";
1317        $arrWhereVal = array($id);
1318        $objQuery->update($table, $sqlval, $where, $arrWhereVal);
1319    }
1320
1321    /**
1322     * レコードの存在チェックを行う.
1323     *
1324     * TODO SC_Query に移行するべきか?
1325     *
1326     * @param string $table テーブル名
1327     * @param string $col カラム名
1328     * @param array $arrVal 要素の配列
1329     * @param array $addwhere SQL の AND 条件である WHERE 句
1330     * @return bool レコードが存在する場合 true
1331     */
1332    function sfIsRecord($table, $col, $arrVal, $addwhere = '') {
1333        $objQuery =& SC_Query_Ex::getSingletonInstance();
1334        $arrCol = preg_split('/[, ]/', $col);
1335
1336        $where = 'del_flg = 0';
1337
1338        if ($addwhere != '') {
1339            $where.= " AND $addwhere";
1340        }
1341
1342        foreach ($arrCol as $val) {
1343            if ($val != '') {
1344                if ($where == '') {
1345                    $where = "$val = ?";
1346                } else {
1347                    $where.= " AND $val = ?";
1348                }
1349            }
1350        }
1351        $ret = $objQuery->get($col, $table, $where, $arrVal);
1352
1353        if ($ret != '') {
1354            return true;
1355        }
1356        return false;
1357    }
1358
1359    /**
1360     * メーカー商品数数の登録を行う.
1361     *
1362     * @param SC_Query $objQuery SC_Query インスタンス
1363     * @return void
1364     */
1365    function sfCountMaker($objQuery) {
1366        $sql = '';
1367
1368        //テーブル内容の削除
1369        $objQuery->query('DELETE FROM dtb_maker_count');
1370
1371        //各メーカーの商品数を数えて格納
1372        $sql = ' INSERT INTO dtb_maker_count(maker_id, product_count, create_date) ';
1373        $sql .= ' SELECT T1.maker_id, count(T2.maker_id), CURRENT_TIMESTAMP ';
1374        $sql .= ' FROM dtb_maker AS T1 LEFT JOIN dtb_products AS T2';
1375        $sql .= ' ON T1.maker_id = T2.maker_id ';
1376        $sql .= ' WHERE T2.del_flg = 0 AND T2.status = 1 ';
1377        $sql .= ' GROUP BY T1.maker_id, T2.maker_id ';
1378        $objQuery->query($sql);
1379    }
1380
1381    /**
1382     * 選択中の商品のメーカーを取得する.
1383     *
1384     * @param integer $product_id プロダクトID
1385     * @param integer $maker_id メーカーID
1386     * @return array 選択中の商品のメーカーIDの配列
1387     *
1388     */
1389    function sfGetMakerId($product_id, $maker_id = 0, $closed = false) {
1390        if ($closed) {
1391            $status = '';
1392        } else {
1393            $status = 'status = 1';
1394        }
1395
1396        if (!$this->g_maker_on) {
1397            $this->g_maker_on = true;
1398            $maker_id = (int) $maker_id;
1399            $product_id = (int) $product_id;
1400            if (SC_Utils_Ex::sfIsInt($maker_id) && $maker_id != 0 && $this->sfIsRecord('dtb_maker','maker_id', $maker_id)) {
1401                $this->g_maker_id = array($maker_id);
1402            } else if (SC_Utils_Ex::sfIsInt($product_id) && $product_id != 0 && $this->sfIsRecord('dtb_products','product_id', $product_id, $status)) {
1403                $objQuery =& SC_Query_Ex::getSingletonInstance();
1404                $maker_id = $objQuery->getCol('maker_id', 'dtb_products', 'product_id = ?', array($product_id));
1405                $this->g_maker_id = $maker_id;
1406            } else {
1407                // 不正な場合は、空の配列を返す。
1408                $this->g_maker_id = array();
1409            }
1410        }
1411        return $this->g_maker_id;
1412    }
1413
1414    /**
1415     * メーカーの取得を行う.
1416     *
1417     * $products_check:true商品登録済みのものだけ取得する
1418     *
1419     * @param string $addwhere 追加する WHERE 句
1420     * @param bool $products_check 商品の存在するカテゴリのみ取得する場合 true
1421     * @return array カテゴリツリーの配列
1422     */
1423    function sfGetMakerList($addwhere = '', $products_check = false) {
1424        $objQuery =& SC_Query_Ex::getSingletonInstance();
1425        $where = 'del_flg = 0';
1426
1427        if ($addwhere != '') {
1428            $where.= " AND $addwhere";
1429        }
1430
1431        $objQuery->setOption('ORDER BY rank DESC');
1432
1433        if ($products_check) {
1434            $col = 'T1.maker_id, name';
1435            $from = 'dtb_maker AS T1 LEFT JOIN dtb_maker_count AS T2 ON T1.maker_id = T2.maker_id';
1436            $where .= ' AND product_count > 0';
1437        } else {
1438            $col = 'maker_id, name';
1439            $from = 'dtb_maker';
1440        }
1441
1442        $arrRet = $objQuery->select($col, $from, $where);
1443
1444        $max = count($arrRet);
1445        $arrList = array();
1446        for ($cnt = 0; $cnt < $max; $cnt++) {
1447            $id = $arrRet[$cnt]['maker_id'];
1448            $name = $arrRet[$cnt]['name'];
1449            $arrList[$id] = $name;
1450        }
1451        return $arrList;
1452    }
1453
1454    /**
1455     * 店舗基本情報に基づいて税金額を返す
1456     *
1457     * @param integer $price 計算対象の金額
1458     * @return integer 税金額
1459     */
1460    function sfTax($price) {
1461        // 店舗基本情報を取得
1462        $CONF = SC_Helper_DB_Ex::sfGetBasisData();
1463
1464        return SC_Utils_Ex::sfTax($price, $CONF['tax'], $CONF['tax_rule']);
1465    }
1466
1467    /**
1468     * 店舗基本情報に基づいて税金付与した金額を返す
1469     * SC_Utils_Ex::sfCalcIncTax とどちらか統一したほうが良い
1470     *
1471     * @param integer $price 計算対象の金額
1472     * @return integer 税金付与した金額
1473     */
1474    function sfCalcIncTax($price, $tax = null, $tax_rule = null) {
1475        // 店舗基本情報を取得
1476        $CONF = SC_Helper_DB_Ex::sfGetBasisData();
1477        $tax      = $tax      === null ? $CONF['tax']      : $tax;
1478        $tax_rule = $tax_rule === null ? $CONF['tax_rule'] : $tax_rule;
1479
1480        return SC_Utils_Ex::sfCalcIncTax($price, $tax, $tax_rule);
1481    }
1482
1483    /**
1484     * 店舗基本情報に基づいて加算ポイントを返す
1485     *
1486     * @param integer $totalpoint
1487     * @param integer $use_point
1488     * @return integer 加算ポイント
1489     */
1490    function sfGetAddPoint($totalpoint, $use_point) {
1491        // 店舗基本情報を取得
1492        $CONF = SC_Helper_DB_Ex::sfGetBasisData();
1493
1494        return SC_Utils_Ex::sfGetAddPoint($totalpoint, $use_point, $CONF['point_rate']);
1495    }
1496
1497    /**
1498     * 指定ファイルが存在する場合 SQL として実行
1499     *
1500     * XXX プラグイン用に追加。将来消すかも。
1501     *
1502     * @param string $sqlFilePath SQL ファイルのパス
1503     * @return void
1504     */
1505    function sfExecSqlByFile($sqlFilePath) {
1506        if (file_exists($sqlFilePath)) {
1507            $objQuery =& SC_Query_Ex::getSingletonInstance();
1508
1509            $sqls = file_get_contents($sqlFilePath);
1510            if ($sqls === false) trigger_error('ファイルは存在するが読み込めない', E_USER_ERROR);
1511
1512            foreach (explode(';', $sqls) as $sql) {
1513                $sql = trim($sql);
1514                if (strlen($sql) == 0) continue;
1515                $objQuery->query($sql);
1516            }
1517        }
1518    }
1519
1520    /**
1521     * 商品規格を設定しているか
1522     *
1523     * @param integer $product_id 商品ID
1524     * @return bool 商品規格が存在する場合:true, それ以外:false
1525     */
1526    function sfHasProductClass($product_id) {
1527        if (!SC_Utils_Ex::sfIsInt($product_id)) return false;
1528
1529        $objQuery =& SC_Query_Ex::getSingletonInstance();
1530        $where = 'product_id = ? AND del_flg = 0 AND (classcategory_id1 != 0 OR classcategory_id2 != 0)';
1531        $exists = $objQuery->exists('dtb_products_class', $where, array($product_id));
1532
1533        return $exists;
1534    }
1535
1536    /**
1537     * 店舗基本情報を登録する
1538     *
1539     * @param array $arrData 登録するデータ
1540     * @return void
1541     */
1542    static function registerBasisData($arrData) {
1543        $objQuery =& SC_Query_Ex::getSingletonInstance();
1544
1545        $arrData = $objQuery->extractOnlyColsOf('dtb_baseinfo', $arrData);
1546
1547        if (isset($arrData['regular_holiday_ids']) && is_array($arrData['regular_holiday_ids'])) {
1548            // 定休日をパイプ区切りの文字列に変換
1549            $arrData['regular_holiday_ids'] = implode('|', $arrData['regular_holiday_ids']);
1550        }
1551
1552        $arrData['update_date'] = 'CURRENT_TIMESTAMP';
1553
1554        // UPDATEの実行
1555        $ret = $objQuery->update('dtb_baseinfo', $arrData);
1556        GC_Utils_Ex::gfPrintLog('dtb_baseinfo に UPDATE を実行しました。');
1557
1558        // UPDATE できなかった場合、INSERT
1559        if ($ret == 0) {
1560            $arrData['id'] = 1;
1561            $ret = $objQuery->insert('dtb_baseinfo', $arrData);
1562            GC_Utils_Ex::gfPrintLog('dtb_baseinfo に INSERT を実行しました。');
1563        }
1564    }
1565}
Note: See TracBrowser for help on using the repository browser.