source: branches/version-2_13-dev/data/class/helper/SC_Helper_DB.php @ 22960

Revision 22960, 55.8 KB checked in by Seasoft, 9 years ago (diff)

#2043 (typo修正・ソース整形・ソースコメントの改善 for 2.13.0)

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