source: branches/version-2_5-dev/data/class/helper/SC_Helper_DB.php @ 20167

Revision 20167, 56.6 KB checked in by nanasess, 11 years ago (diff)

#981([フロント]MYページ)

  • 受注取得処理を抽象化

#642(共通ロジックの機能向上)

  • SC_Query::extractOnlyColsOf() を追加

#628(未使用処理・定義などの削除)

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