Index: /branches/version-2_5-dev/data/class/helper/SC_Helper_DB.php
===================================================================
--- /branches/version-2_5-dev/data/class/helper/SC_Helper_DB.php	(revision 18790)
+++ /branches/version-2_5-dev/data/class/helper/SC_Helper_DB.php	(revision 18815)
@@ -185,4 +185,6 @@
      * 商品規格情報を取得する.
      *
+     * TODO SC_Product クラスへ移動
+     *
      * @param array $arrID 規格ID
      * @param boolean $includePrivateProducts 非公開商品を含むか
@@ -193,20 +195,28 @@
 
         if (strlen($classcategory_id1) == 0) {
-            $classcategory_id1 = '0';
+            $classcategory_id1 = null;
         }
         if (strlen($classcategory_id2) == 0) {
-            $classcategory_id2 = '0';
+            $classcategory_id2 = null;
         }
 
         // 商品規格取得
-        $objQuery =& SC_Query::getSingletonInstance();
-        $col = 'product_id, deliv_fee, name, product_code, main_list_image, main_image, price01, price02, point_rate, product_class_id, classcategory_id1, classcategory_id2, class_id1, class_id2, stock, stock_unlimited, sale_limit';
-        $table = 'vw_product_class AS prdcls';
-        $where = 'product_id = ? AND classcategory_id1 = ? AND classcategory_id2 = ?';
-        if (!$includePrivateProducts) {
-             $where .= ' AND status = 1';
-        }
-        $arrRet = $objQuery->select($col, $table, $where, array($product_id, $classcategory_id1, $classcategory_id2));
-        return $arrRet[0];
+        $objProduct = new SC_Product();
+        $detail = $objProduct->getDetail($product_id);
+        $productsClass = $objProduct->getProductsClassFullByProductId($product_id);
+        foreach ($productsClass as $val) {
+
+            if ($val['classcategory_id1'] == $classcategory_id1
+                && $val['classcategory_id2'] == $classcategory_id2) {
+
+                $detail = array_merge($val, $detail);
+                if (!$includePrivateProducts) {
+                    if ($detail['status'] == 1) {
+                        return $detail;
+                    }
+                }
+                return $detail;
+            }
+        }
     }
 
@@ -912,23 +922,10 @@
         }
 
-        //各カテゴリ内の商品数を数えて格納
-        $sql = <<< __EOS__
-            INSERT INTO dtb_category_count(category_id, product_count, create_date)
-            SELECT T1.category_id, count(T2.category_id), now()
-            FROM dtb_category AS T1
-                LEFT JOIN dtb_product_categories AS T2
-                    ON T1.category_id = T2.category_id
-                LEFT JOIN vw_products_allclass_detail AS alldtl
-                    ON T2.product_id = alldtl.product_id
-            WHERE $sql_where
-            GROUP BY T1.category_id, T2.category_id
-__EOS__;
-
-        $objQuery->query($sql);
-
         //子カテゴリ内の商品数を集計する
 
         // カテゴリ情報を取得
         $arrCat = $objQuery->select('category_id', 'dtb_category');
+
+        $objProduct = new SC_Product();
 
         foreach ($arrCat as $row) {
@@ -940,10 +937,12 @@
             list($tmp_where, $tmp_arrval) = $this->sfGetCatWhere($category_id);
             if ($tmp_where != "") {
-                $sql_where_product_ids = "alldtl.product_id IN (SELECT product_id FROM dtb_product_categories WHERE " . $tmp_where . ")";
-                $arrval = array_merge((array)$arrval, (array)$tmp_arrval);
+                $sql_where_product_ids = "product_id IN (SELECT product_id FROM dtb_product_categories WHERE " . $tmp_where . ")";
+                $arrval = array_merge((array)$arrval, (array)$tmp_arrval, (array)$tmp_arrval);
             } else {
                 $sql_where_product_ids = '0<>0'; // 一致させない
             }
-
+            $where = "($sql_where) AND ($sql_where_product_ids)";
+
+            $from = $objProduct->alldtlSQL($sql_where_product_ids);
             $sql = <<< __EOS__
                 INSERT INTO dtb_category_total_count (category_id, product_count, create_date)
@@ -952,6 +951,6 @@
                     ,count(*)
                     ,now()
-                FROM vw_products_allclass_detail AS alldtl
-                WHERE ($sql_where) AND ($sql_where_product_ids)
+                FROM $from
+               WHERE $where
 __EOS__;
 
@@ -986,5 +985,5 @@
         $objQuery =& SC_Query::getSingletonInstance();
         $col = $pid_name . "," . $id_name;
-         $arrData = $objQuery->select($col, $table);
+        $arrData = $objQuery->select($col, $table);
 
         $arrPID = array();
@@ -1910,5 +1909,5 @@
 
         $objQuery =& SC_Query::getSingletonInstance();
-        $where = 'product_id = ? AND (classcategory_id1 <> 0 OR classcategory_id2 <> 0)';
+        $where = 'product_id = ? AND class_combination_id IS NOT NULL';
         $count = $objQuery->count('dtb_products_class', $where, array($product_id));
 
Index: /branches/version-2_5-dev/data/class/helper/SC_Helper_CSV.php
===================================================================
--- /branches/version-2_5-dev/data/class/helper/SC_Helper_CSV.php	(revision 18791)
+++ /branches/version-2_5-dev/data/class/helper/SC_Helper_CSV.php	(revision 18815)
@@ -132,4 +132,9 @@
         $objQuery->setOrder($order);
 
+        /*
+         * FIXME
+         * パフォーマンスが出ないため,
+         * SC_Product::getProductsClassByProductIds() を使用した実装に変更
+         */
         $dataRows = $objQuery->select(
              SC_Utils_Ex::sfGetCommaList($arrOutputCols, true, array('category_id'))
Index: /branches/version-2_5-dev/data/class/SC_Product.php
===================================================================
--- /branches/version-2_5-dev/data/class/SC_Product.php	(revision 18701)
+++ /branches/version-2_5-dev/data/class/SC_Product.php	(revision 18815)
@@ -42,51 +42,121 @@
     var $classCat2_find;
     var $classCats1;
-    
-    function SC_Product($arrProductId = null) {
-        $objDb = new SC_Helper_DB_Ex();
-        
-        // 規格名一覧
-        $this->arrClassName = $objDb->sfGetIDValueList("dtb_class", "class_id", "name");
-        // 規格分類名一覧
-        $this->arrClassCatName = $objDb->sfGetIDValueList("dtb_classcategory", "classcategory_id", "name");
-        $this->arrClassCatName[''] = '選択してください';
-        
-        if (!is_null($arrProductId)) {
-            $this->setProductId($arrProductId);
-        }
-    }
-
-    function setProductId($arrProductId) {
-        
-        // 商品規格情報の取得
-        $rows = $this->lfGetProductsClass($arrProductId);
-        
+
+    /**
+     * SC_Queryインスタンスに設定された検索条件をもとに商品IDの配列を取得する.
+     *
+     * 検索条件は, SC_Query::getWhere() 関数で設定しておく必要があります.
+     *
+     * @param SC_Query $objQuery SC_Query インスタンス
+     * @param array $arrVal 検索パラメータの配列
+     * @return array 商品IDの配列
+     */
+    function findProductIds(&$objQuery, $arrVal = array()) {
+        $table = <<< __EOS__
+                 dtb_products AS alldtl
+            JOIN dtb_product_categories AS T2
+              ON alldtl.product_id = T2.product_id
+            JOIN dtb_category
+              ON T2.category_id = dtb_category.category_id
+__EOS__;
+        // SC_Query::getCol() ではパフォーマンスが出ない
+        $results = $objQuery->select('alldtl.product_id', $table, "", $arrVal,
+                                     MDB2_FETCHMODE_ORDERED);
+        foreach ($results as $val) {
+            $resultValues[] = $val[0];
+        }
+        return array_unique($resultValues);
+    }
+
+    /**
+     * SC_Queryインスタンスに設定された検索条件をもとに商品一覧の配列を取得する.
+     *
+     * 主に SC_Product::findProductIds() で取得した商品IDを検索条件にし,
+     * SC_Query::setOrder() や SC_Query::setLimitOffset() を設定して, 商品一覧
+     * の配列を取得する.
+     *
+     * @param SC_Query $objQuery SC_Query インスタンス
+     * @param array $arrVal 検索パラメータ(ソート条件)の配列
+     * @return array 商品一覧の配列
+     */
+    function lists(&$objQuery, $arrVal = array()) {
+        $col = <<< __EOS__
+             product_id
+            ,product_code_min
+            ,product_code_max
+            ,name
+            ,comment1
+            ,comment2
+            ,comment3
+            ,main_list_comment
+            ,main_image
+            ,main_list_image
+            ,price01_min
+            ,price01_max
+            ,price02_min
+            ,price02_max
+            ,stock_min
+            ,stock_max
+            ,stock_unlimited_min
+            ,stock_unlimited_max
+            ,deliv_date_id
+            ,status
+            ,del_flg
+            ,update_date
+__EOS__;
+        return $objQuery->select($col, $this->alldtlSQL($objQuery->where),
+                                 "", $arrVal);
+    }
+
+    /**
+     * 商品詳細を取得する.
+     *
+     * @param integer $productId 商品ID
+     * @return array 商品詳細情報の配列
+     */
+    function getDetail($productId) {
+        $objQuery =& SC_Query::getSingletonInstance();
+        $result = $objQuery->select("*", $this->alldtlSQL("product_id = ?"),
+                                    "product_id = ?",
+                                    array($productId, $productId));
+        return $result[0];
+    }
+
+    /**
+     * 商品IDに紐づく商品規格を自分自身に設定する.
+     *
+     * 引数の商品IDの配列に紐づく商品規格を取得し, 自分自身のフィールドに
+     * 設定する.
+     *
+     * @param array $arrProductId 商品ID の配列
+     * @return void
+     */
+    function setProductsClassByProductIds($arrProductId) {
+
+        foreach ($arrProductId as $productId) {
+            $rows[$productId] = $this->getProductsClassFullByProductId($productId);
+        }
+
         $arrProductsClass = array();
-        foreach ($rows as $row) {
-            $productId = $row['product_id'];
-            $arrProductsClass[$productId][] = $row;
-        }
-        unset($rows);
-        
-        foreach ($arrProductsClass as $productId => $arrProductClass) {
+        foreach ($rows as $productId => $arrProductClass) {
             $classCats1 = array();
             $classCats1[''] = '選択してください';
-            
+
             // 規格1クラス名
             $this->className1[$productId] =
-                isset($this->arrClassName[$arrProductClass[0]['class_id1']])
-                ? $this->arrClassName[$arrProductClass[0]['class_id1']]
+                isset($arrProductClass[0]['class_name1'])
+                ? $arrProductClass[0]['class_name1']
                 : '';
 
             // 規格2クラス名
             $this->className2[$productId] =
-                isset($this->arrClassName[$arrProductClass[0]['class_id2']])
-                ? $this->arrClassName[$arrProductClass[0]['class_id2']]
+                isset($arrProductClass[0]['class_name2'])
+                ? $arrProductClass[0]['class_name2']
                 : '';
-            
+
             // 規格1が設定されている
-            $this->classCat1_find[$productId] = ($arrProductClass[0]['classcategory_id1'] != '0');
+            $this->classCat1_find[$productId] = (!SC_Utils_Ex::isBlank($arrProductClass[0]['classcategory_id1']));
             // 規格2が設定されている
-            $this->classCat2_find[$productId] = ($arrProductClass[0]['classcategory_id2'] != '0');
+            $this->classCat2_find[$productId] = (!SC_Utils_Ex::isBlank($arrProductClass[0]['classcategory_id2']));
 
             $this->stock_find[$productId] = false;
@@ -97,13 +167,11 @@
                 $productsClass2 = $productsClass['classcategory_id2'];
                 $classCategories[$productsClass1]['']['name'] = '選択してください';
-
                 // 在庫
                 $stock_find_class = ($productsClass['stock_unlimited'] || $productsClass['stock'] > 0);
-                
-                $classCategories[$productsClass1][$productsClass2]['name'] = $this->arrClassCatName[$productsClass2]
-                    . ($stock_find_class ? '' : ' (品切れ中)');
-                
+
+                $classCategories[$productsClass1][$productsClass2]['name'] = $productsClass['name2'] . ($stock_find_class ? '' : ' (品切れ中)');
+
                 $classCategories[$productsClass1][$productsClass2]['stock_find'] = $stock_find_class;
-                
+
                 if ($stock_find_class) {
                     $this->stock_find[$productId] = true;
@@ -111,8 +179,8 @@
 
                 if (!in_array($classcat_id1, $classCats1)) {
-                    $classCats1[$productsClass1] = $this->arrClassCatName[$productsClass1]
+                    $classCats1[$productsClass1] = $productsClass['name1']
                         . ($productsClass2 == 0 && !$stock_find_class ? ' (品切れ中)' : '');
                 }
-                
+
                 // 価格
                 $classCategories[$productsClass1][$productsClass2]['price01']
@@ -120,21 +188,21 @@
                     ? number_format(SC_Helper_DB_Ex::sfPreTax($productsClass['price01']))
                     : '';
-                
+
                 $classCategories[$productsClass1][$productsClass2]['price02']
                     = strlen($productsClass['price02'])
                     ? number_format(SC_Helper_DB_Ex::sfPreTax($productsClass['price02']))
                     : '';
-                
+
                 // ポイント
                 // XXX sfPrePoint() の第4パラメータは、処理にバグがあるため現状省略している。(http://xoops.ec-cube.net/modules/newbb/viewtopic.php?topic_id=3540&forum=1&post_id=13853#forumpost13853)
                 $classCategories[$productsClass1][$productsClass2]['point']
                     = SC_Utils_Ex::sfPrePoint($productsClass['price02'], $productsClass['point_rate']);
-                
+
                 // 商品コード
                 $classCategories[$productsClass1][$productsClass2]['product_code'] = $productsClass['product_code'];
             }
-            
+
             $this->classCategories[$productId] = $classCategories;
-            
+
             // 規格1
             $this->classCats1[$productId] = $classCats1;
@@ -142,21 +210,244 @@
     }
 
-    /* 商品規格情報の取得 */
-    function lfGetProductsClass($arrProductId) {
-        $arrProductId = (Array) $arrProductId;
-        
-        if (empty($arrProductId)) {
+    /**
+     * 複数の商品IDに紐づいた, 商品規格を取得する.
+     *
+     * @param array $productIds 商品IDの配列
+     * @return array 商品規格の配列
+     */
+    function getProductsClassByProductIds($productIds = array()) {
+        if (empty($productIds)) {
             return array();
         }
-        
-        // 商品規格取得
-        $objQuery = new SC_Query();
-        $col = 'product_id, classcategory_id1, classcategory_id2, class_id1, class_id2, stock, stock_unlimited, price01, price02, point_rate, product_code';
-        $table = 'vw_product_class AS prdcls';
-        $where = 'product_id IN (' . implode(', ', array_pad(array(), count($arrProductId), '?')) . ')';
-        $objQuery->setOrder("product_id, rank1 DESC, rank2 DESC");
-        $arrRet = $objQuery->select($col, $table, $where, $arrProductId);
-        
-        return $arrRet;
+        $objQuery =& SC_Query::getSingletonInstance();
+        $objQuery->setWhere('product_id IN (' . implode(', ', array_pad(array(), count($productIds), '?')) . ')');
+        $objQuery->setOrder("T2.level DESC");
+        // 末端の規格を取得
+        $col = <<< __EOS__
+            T1.product_id,
+            T1.stock,
+            T1.stock_unlimited,
+            T1.price01,
+            T1.price02,
+            T1.point_rate,
+            T1.product_code,
+            T1.product_class_id,
+            T1.del_flg,
+            T2.class_combination_id,
+            T2.parent_class_combination_id,
+            T2.classcategory_id,
+            T2.level,
+            T3.name,
+            T4.name AS class_name,
+            T4.class_id
+__EOS__;
+        $table = <<< __EOS__
+                      dtb_products_class T1
+            LEFT JOIN dtb_class_combination T2
+                   ON T1.class_combination_id = T2.class_combination_id
+            LEFT JOIN dtb_classcategory T3
+                   ON T2.classcategory_id = T3.classcategory_id
+            LEFT JOIN dtb_class T4
+                   ON T3.class_id = T4.class_id
+__EOS__;
+        $arrRet = $objQuery->select($col, $table, "", $productIds);
+        $levels = array();
+        $parents = array();
+
+        foreach ($arrRet as $rows) {
+            $levels[] = $rows['level'];
+            $parents[] = $rows['parent_class_combination_id'];
+        }
+        $level = max($levels);
+        $parentsClass = array();
+        // 階層分の親を取得
+        for ($i = 0; $i < $level -1; $i++) {
+            $objQuery =& SC_Query::getSingletonInstance();
+            $objQuery->setWhere('T1.class_combination_id IN (' . implode(', ', array_pad(array(), count($parents), '?')) . ')');
+
+            $col = <<< __EOS__
+                T1.class_combination_id,
+                T1.classcategory_id,
+                T1.parent_class_combination_id,
+                T1.level,
+                T2.name,
+                T3.name AS class_name,
+                T3.class_id
+__EOS__;
+            $table = <<< __EOS__
+                          dtb_class_combination T1
+                LEFT JOIN dtb_classcategory T2
+                       ON T1.classcategory_id = T2.classcategory_id
+                LEFT JOIN dtb_class T3
+                       ON T2.class_id = T3.class_id
+__EOS__;
+
+            $arrParents = $objQuery->select($col, $table, "", $parents);
+
+            unset($parents);
+            foreach ($arrParents as $rows) {
+                $parents[] = $rows['parent_class_combination_id'];
+
+                foreach ($arrRet as $child) {
+                    if ($child['parent_class_combination_id']
+                        == $rows['class_combination_id']) {
+                        $rows['product_id'] = $child['product_id'];
+                    }
+                }
+                $tmpParents[] = $rows;
+            }
+            $parentsClass = array_merge($parentsClass, $tmpParents);
+        }
+
+        // 末端から枝を作成
+        $tmpClass = array_merge($arrRet, $parentsClass);
+
+        foreach ($tmpClass as $val) {
+            $val['class_id' . $val['level']] = $val['class_id'];
+            $val['class_name' . $val['level']] = $val['class_name'];
+            $val['name' . $val['level']] = $val['name'];
+            $val['classcategory_id' . $val['level']] = $val['classcategory_id'];
+            $arrProductsClass[] = $val;
+        }
+
+        return $arrProductsClass;
+    }
+
+    /**
+     * 商品IDに紐づいた, 商品規格を階層ごとに取得する.
+     *
+     * @param array $productId 商品IDの配列
+     * @return array 階層ごとの商品規格の配列
+     */
+    function getProductsClassLevelByProductId($productId) {
+        $results = $this->getProductsClassByProductIds(array($productId));
+        foreach ($results as $row) {
+            $productsClassLevel["level" . $row['level']][] = $row;
+        }
+        return $productsClassLevel;
+    }
+
+    /**
+     * 商品IDに紐づいた, 商品規格をすべての組み合わせごとに取得する.
+     *
+     * @param array $productId 商品IDの配列
+     * @return array すべての組み合わせの商品規格の配列
+     */
+    function getProductsClassFullByProductId($productId) {
+        $results = $this->getProductsClassLevelByProductId($productId);
+        $productsClass = array();
+        foreach ($results["level1"] as $level1) {
+            foreach ($results["level2"] as $level2) {
+                if ($level2['parent_class_combination_id'] == $level1['class_combination_id']) {
+                    $level1 = array_merge($level1, $level2);
+                }
+            }
+            $productsClass[] = $level1;
+        }
+        return $productsClass;
+    }
+
+    /**
+     * 商品詳細の SQL を取得する.
+     *
+     * @param string $where 商品詳細の WHERE 句
+     * @return string 商品詳細の SQL
+     */
+    function alldtlSQL($where = "") {
+        $whereCause = "";
+        if (!SC_Utils_Ex::isBlank($where)) {
+            $whereCause = " WHERE " . $where;
+        }
+
+        $sql = <<< __EOS__
+            (
+             SELECT dtb_products.product_id,
+                    dtb_products.name,
+                    dtb_products.maker_id,
+                    dtb_products.rank,
+                    dtb_products.status,
+                    dtb_products.comment1,
+                    dtb_products.comment2,
+                    dtb_products.comment3,
+                    dtb_products.comment4,
+                    dtb_products.comment5,
+                    dtb_products.comment6,
+                    dtb_products.note,
+                    dtb_products.file1,
+                    dtb_products.file2,
+                    dtb_products.file3,
+                    dtb_products.file4,
+                    dtb_products.file5,
+                    dtb_products.file6,
+                    dtb_products.main_list_comment,
+                    dtb_products.main_list_image,
+                    dtb_products.main_comment,
+                    dtb_products.main_image,
+                    dtb_products.main_large_image,
+                    dtb_products.sub_title1,
+                    dtb_products.sub_comment1,
+                    dtb_products.sub_image1,
+                    dtb_products.sub_large_image1,
+                    dtb_products.sub_title2,
+                    dtb_products.sub_comment2,
+                    dtb_products.sub_image2,
+                    dtb_products.sub_large_image2,
+                    dtb_products.sub_title3,
+                    dtb_products.sub_comment3,
+                    dtb_products.sub_image3,
+                    dtb_products.sub_large_image3,
+                    dtb_products.sub_title4,
+                    dtb_products.sub_comment4,
+                    dtb_products.sub_image4,
+                    dtb_products.sub_large_image4,
+                    dtb_products.sub_title5,
+                    dtb_products.sub_comment5,
+                    dtb_products.sub_image5,
+                    dtb_products.sub_large_image5,
+                    dtb_products.sub_title6,
+                    dtb_products.sub_comment6,
+                    dtb_products.sub_image6,
+                    dtb_products.sub_large_image6,
+                    dtb_products.del_flg,
+                    dtb_products.creator_id,
+                    dtb_products.create_date,
+                    dtb_products.update_date,
+                    dtb_products.deliv_date_id,
+                    dtb_products.down,
+                    dtb_products.down_filename,
+                    dtb_products.down_realfilename,
+                    T4.product_code_min,
+                    T4.product_code_max,
+                    T4.price01_min,
+                    T4.price01_max,
+                    T4.price02_min,
+                    T4.price02_max,
+                    T4.stock_min,
+                    T4.stock_max,
+                    T4.stock_unlimited_min,
+                    T4.stock_unlimited_max,
+                    T4.class_count
+               FROM dtb_products
+               JOIN (
+                       SELECT product_id,
+                              MIN(product_code) AS product_code_min,
+                              MAX(product_code) AS product_code_max,
+                              MIN(price01) AS price01_min,
+                              MAX(price01) AS price01_max,
+                              MIN(price02) AS price02_min,
+                              MAX(price02) AS price02_max,
+                              MIN(stock) AS stock_min,
+                              MAX(stock) AS stock_max,
+                              MIN(stock_unlimited) AS stock_unlimited_min,
+                              MAX(stock_unlimited) AS stock_unlimited_max,
+                              COUNT(*) as class_count
+                         FROM dtb_products_class
+                       $whereCause
+                     GROUP BY product_id
+                     ) AS T4
+                 ON dtb_products.product_id = T4.product_id
+        ) AS alldtl
+__EOS__;
+        return $sql;
     }
 }
Index: /branches/version-2_5-dev/data/class/pages/products/LC_Page_Products_Detail.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/products/LC_Page_Products_Detail.php	(revision 18770)
+++ /branches/version-2_5-dev/data/class/pages/products/LC_Page_Products_Detail.php	(revision 18815)
@@ -151,6 +151,7 @@
         $this->lfMakeSelect($product_id);
 
-        require_once CLASS_PATH . 'SC_Product.php';
-        $objProduct = new SC_Product($product_id);
+        $objProduct = new SC_Product();
+        $objProduct->setProductsClassByProductIds(array($product_id));
+
         // 規格1クラス名
         $this->tpl_class_name1 = $objProduct->className1[$product_id];
@@ -227,7 +228,6 @@
         $this->arrErr = $arrErr;
 
-        // DBから商品情報を取得する。
-        $arrRet = $objQuery->select("*, (SELECT count(*) FROM dtb_customer_favorite_products WHERE product_id = alldtl.product_id AND customer_id = ?) AS favorite_count", "vw_products_allclass_detail AS alldtl", "product_id = ?", array($objCustomer->getValue('customer_id'), $product_id));
-        $this->arrProduct = $arrRet[0];
+        // 商品詳細を取得
+        $this->arrProduct = $objProduct->getDetail($product_id);
 
         // サブタイトルを取得
@@ -421,8 +421,7 @@
         }
 
-        $objQuery = new SC_Query();
-        // DBから商品情報を取得する。
-        $arrRet = $objQuery->select("*", "vw_products_allclass_detail AS alldtl", "product_id = ?", array($product_id));
-        $this->arrProduct = $arrRet[0];
+        // 商品詳細を取得
+        $objProduct = new SC_Product();
+        $this->arrProduct = $objProduct->getDetail($product_id);
 
         // サブタイトルを取得
@@ -531,4 +530,9 @@
         // 規格分類名一覧
         $arrClassCatName = $objDb->sfGetIDValueList("dtb_classcategory", "classcategory_id", "name");
+        /*
+         * FIXME
+         * パフォーマンスが出ないため,
+         * SC_Product::getProductsClassByProductIds() を使用した実装に変更
+         */
         // 商品規格情報の取得
         $arrProductsClass = $this->lfGetProductsClass($product_id);
@@ -617,4 +621,5 @@
         $max = count($arrRet);
         $no = 0;
+        // FIXME SC_Product クラスを使用した実装
         $from = "vw_products_allclass AS T1 "
                 . " JOIN ("
@@ -626,5 +631,5 @@
         for($i = 0; $i < $max; $i++) {
             $where = "del_flg = 0 AND T3.product_id = ? AND status = 1";
-            $arrProductInfo = $objQuery->select("DISTINCT main_list_image, price02_min, price02_max, price01_min, price01_max, name, point_rate, T3.product_rank", $from, $where, array($arrRet[$i]['recommend_product_id']));
+            $arrProductInfo = $objQuery->select("DISTINCT main_list_image, price02_min, price02_max, price01_min, price01_max, name, T3.product_rank", $from, $where, array($arrRet[$i]['recommend_product_id']));
 
             if(count($arrProductInfo) > 0) {
Index: /branches/version-2_5-dev/data/class/pages/products/LC_Page_Products_List.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/products/LC_Page_Products_List.php	(revision 18792)
+++ /branches/version-2_5-dev/data/class/pages/products/LC_Page_Products_List.php	(revision 18815)
@@ -310,5 +310,4 @@
     function lfDispProductsList() {
 
-        $objQuery = new SC_Query();
         $objDb = new SC_Helper_DB_Ex();
         $arrval = array();
@@ -324,4 +323,5 @@
         // 商品検索条件の作成（未削除、表示）
         $where = "del_flg = 0 AND status = 1 ";
+        $where1 = "alldtl.del_flg = 0 AND alldtl.status = 1 ";
         
         // 在庫無し商品の非表示
@@ -332,4 +332,5 @@
         if (strlen($where_category) >= 1) {
             $where.= " AND $where_category";
+            $where1 .= " AND T2.$where_category";
             $arrval = array_merge($arrval, $arrval_category);
         }
@@ -346,4 +347,5 @@
             if ( strlen($val) > 0 ) {
                 $where .= " AND ( name ILIKE ? OR comment3 ILIKE ?) ";
+                $where1 .= " AND ( alldtl.name ILIKE ? OR alldtl.comment3 ILIKE ?) ";
                 $arrval[] = "%$val%";
                 $arrval[] = "%$val%";
@@ -354,9 +356,14 @@
         if ($this->arrSearchData['maker_id']) {
             $where .= " AND maker_id = ? ";
+            $where1 .= " AND alldtl.maker_id = ? ";
             $arrval[] = $this->arrSearchData['maker_id'];
         }
-        
-        // 対象商品IDの抽出
-        $arrProduct_id = array_unique($objQuery->getCol('vw_products_allclass AS allcls', 'product_id', $where, $arrval));
+
+        // 一覧表示する商品IDを取得
+        $objQuery =& SC_Query::getSingletonInstance();
+        $objQuery->setWhere($where1);
+        $objProduct = new SC_Product();
+        $arrProduct_id = $objProduct->findProductIds($objQuery, $arrval);
+
         // 行数の取得
         $linemax = count($arrProduct_id);
@@ -373,35 +380,4 @@
         $startno = $this->objNavi->start_row;                 // 開始行
         
-        // ▼商品詳細取得
-        $col = <<< __EOS__
-             product_id
-            ,product_code_min
-            ,product_code_max
-            ,name
-            ,comment1
-            ,comment2
-            ,comment3
-            ,main_list_comment
-            ,main_image
-            ,main_list_image
-            ,price01_min
-            ,price01_max
-            ,price02_min
-            ,price02_max
-            ,stock_min
-            ,stock_max
-            ,stock_unlimited_min
-            ,stock_unlimited_max
-            ,point_rate
-            ,sale_limit
-            ,deliv_date_id
-            ,deliv_fee
-            ,status
-            ,product_flag
-            ,del_flg
-__EOS__;
-        
-        $from = "vw_products_allclass_detail AS alldtl";
-        
         // WHERE 句
         $where = '0=0';
@@ -412,5 +388,5 @@
             $where .= ' AND 0<>0';
         }
-        
+
         // 表示順序
         switch ($this->orderby) {
@@ -462,11 +438,13 @@
         
         // 取得範囲の指定(開始行番号、行数のセット)
-        $objQuery->setLimitOffset($this->disp_number, $startno);
-        // 表示順序
-        $objQuery->setOrder($order);
-        
+        $objQuery =& SC_Query::getSingletonInstance();
+        $objQuery->setLimitOffset($this->disp_number, $startno)
+                 ->setOrder($order)
+                 ->setWhere($where);
+
         // 検索結果の取得
-        $this->arrProducts = $objQuery->select($col, $from, $where, $arrval_order);
-        // ▲商品詳細取得
+        $objProduct = new SC_Product();
+        $this->arrProducts = $objProduct->lists($objQuery, $arrval_order);
+
         
         $arrProductId = array();
@@ -476,6 +454,6 @@
         }
         
-        require_once CLASS_PATH . 'SC_Product.php';
-        $objProduct = new SC_Product($arrProductId);
+        // 規格を設定
+        $objProduct->setProductsClassByProductIds($arrProductId);
         
         // 規格1クラス名
Index: /branches/version-2_5-dev/data/class/pages/rss/LC_Page_Rss_Products.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/rss/LC_Page_Rss_Products.php	(revision 18701)
+++ /branches/version-2_5-dev/data/class/pages/rss/LC_Page_Rss_Products.php	(revision 18815)
@@ -194,4 +194,5 @@
      */
     function lfGetProductsAllclass($objQuery){
+        // FIXME SC_Product クラスを使用した実装
         $sql = "";
         $sql .= "SELECT
Index: /branches/version-2_5-dev/data/class/pages/mypage/LC_Page_Mypage_Favorite.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/mypage/LC_Page_Mypage_Favorite.php	(revision 18770)
+++ /branches/version-2_5-dev/data/class/pages/mypage/LC_Page_Mypage_Favorite.php	(revision 18815)
@@ -94,4 +94,5 @@
         }
 
+        // FIXME SC_Product クラスを使用した実装
         $col = "alldtl.*";
         $from = "dtb_customer_favorite_products AS dcfp LEFT JOIN vw_products_allclass_detail AS alldtl USING(product_id)";
Index: /branches/version-2_5-dev/data/class/pages/shopping/LC_Page_Shopping_Complete.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/shopping/LC_Page_Shopping_Complete.php	(revision 18788)
+++ /branches/version-2_5-dev/data/class/pages/shopping/LC_Page_Shopping_Complete.php	(revision 18815)
@@ -665,18 +665,25 @@
         }
         
-        $where = "product_id = ? AND classcategory_id1 = ? AND classcategory_id2 = ?";
-        $arrRet = $objQuery->select("stock, stock_unlimited", "dtb_products_class", $where, $arrID);
-
-        if (($arrRet[0]['stock_unlimited'] != '1' && $arrRet[0]['stock'] < $quantity) || $quantity == 0) {
-            // 売り切れエラー
-            $objQuery->rollback();
-            SC_Utils_Ex::sfDispSiteError(SOLD_OUT, "", true);
-        }
+        $objProduct = new SC_Product();
+        $productsClass = $objProduct->getProductsClassFullByProductId($arrID[0]);
+    
+        foreach ($productsClass as $val) {
+            if ($val['classcategory_id1'] == $arrID[1]
+                && $val['classcategory_id2'] == $arrID[2]) {
+
+                if (($val['stock_unlimited'] != '1' && $val['stock'] < $quantity) || $quantity == 0) {
+                    // 売り切れエラー
+                    $objQuery->rollback();
+                    SC_Utils_Ex::sfDispSiteError(SOLD_OUT, "", true);
+                }
         
-        // 在庫を減らす
-        $arrRawSql = array();
-        $arrRawSql['stock'] = 'stock - ?';
-        $arrRawSqlVal[] = $quantity;
-        $objQuery->update('dtb_products_class', array(), $where, $arrID, $arrRawSql, $arrRawSqlVal);
+                // 在庫を減らす
+                $arrRawSql = array();
+                $arrRawSql['stock'] = 'stock - ?';
+                $arrRawSqlVal[] = $quantity;
+                $objQuery->update('dtb_products_class', array(), "product_class_id = ?", array($val['product_class_id']), $arrRawSql, $arrRawSqlVal);
+                break;
+            }
+        }
         
         // 在庫無し商品の非表示対応
Index: /branches/version-2_5-dev/data/class/pages/admin/mail/LC_Page_Admin_Mail.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/admin/mail/LC_Page_Admin_Mail.php	(revision 18798)
+++ /branches/version-2_5-dev/data/class/pages/admin/mail/LC_Page_Admin_Mail.php	(revision 18815)
@@ -535,4 +535,5 @@
 
         // メイン商品の情報取得
+        // FIXME SC_Product クラスを使用した実装
         $sql = "SELECT name, main_image, point_rate, deliv_fee, price01_min, price01_max, price02_min, price02_max FROM vw_products_allclass AS allcls WHERE product_id = ?";
         $main = $objQuery->getAll($sql, array($list_data["sub_product_id" .$j]));
Index: /branches/version-2_5-dev/data/class/pages/admin/mail/LC_Page_Admin_Mail_Preview.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/admin/mail/LC_Page_Admin_Mail_Preview.php	(revision 18772)
+++ /branches/version-2_5-dev/data/class/pages/admin/mail/LC_Page_Admin_Mail_Preview.php	(revision 18815)
@@ -85,4 +85,5 @@
 
             // メイン商品の情報取得
+            // FIXME SC_Product クラスを使用した実装
             $sql = "SELECT name, main_image, point_rate, deliv_fee, price01_min, price01_max, price02_min, price02_max FROM vw_products_allclass AS allcls WHERE product_id = ?";
             $main = $objQuery->getAll($sql, array($this->list_data["main_product_id"]));
@@ -90,4 +91,5 @@
 
             // サブ商品の情報取得
+            // FIXME SC_Product クラスを使用した実装
             $sql = "SELECT product_id, name, main_list_image, price01_min, price01_max, price02_min, price02_max FROM vw_products_allclass WHERE product_id = ?";
             $k = 0;
Index: /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_ProductClass.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_ProductClass.php	(revision 18788)
+++ /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_ProductClass.php	(revision 18815)
@@ -49,125 +49,44 @@
         $this->tpl_subno = 'product';
         $this->tpl_subtitle = '商品登録(商品規格)';
-
-        $masterData = new SC_DB_MasterData_Ex();
-        $this->arrSRANK = $masterData->getMasterData("mtb_srank");
-        $this->arrDISP = $masterData->getMasterData("mtb_disp");
-        $this->arrCLASS = $masterData->getMasterData("mtb_class");
-        $this->arrSTATUS = $masterData->getMasterData("mtb_status");
-        $this->tpl_onload = "";
-    }
-
-    /**
-     * Page のプロセス.
-     *
-     * @return void
-     */
+    }
+
     function process() {
-        $objView = new SC_AdminView();
-        // 認証可否の判定
-        $objSess = new SC_Session();
-        SC_Utils_Ex::sfIsSuccess($objSess);
-
-        // 検索パラメータの引き継ぎ
-        foreach ($_POST as $key => $val) {
-            if (ereg("^search_", $key)) {
-                $this->arrSearchHidden[$key] = $val;
-            }
-        }
+        $this->authorization();
+
+        $this->arrSearchHidden = $this->createSearchParams($_POST);
 
         $this->tpl_product_id =
             isset($_POST['product_id']) ? $_POST['product_id'] : "" ;
-
         $this->tpl_pageno = isset($_POST['pageno']) ? $_POST['pageno'] : "";
-
         if (!isset($_POST['mode'])) $_POST['mode'] = "";
 
-        switch($_POST['mode']) {
-        // 規格削除要求
-        case 'delete':
-            $objQuery = new SC_Query();
-            $objDb = new SC_Helper_DB_Ex();
-
-            $objQuery->setLimitOffset(1);
-            $where = "product_id = ? AND NOT (classcategory_id1 = 0 AND classcategory_id2 = 0)";
-            $objQuery->setOrder("rank1 DESC, rank2 DESC");
-            $arrRet = $objQuery->select("*", "vw_cross_products_class AS crs_prd", $where, array($_POST['product_id']));
-
-            if(count($arrRet) > 0) {
-
-                $sqlval['product_id'] = $arrRet[0]['product_id'];
-                $sqlval['classcategory_id1'] = '0';
-                $sqlval['classcategory_id2'] = '0';
-                $sqlval['product_code'] = $arrRet[0]['product_code'];
-                $sqlval['stock'] = $arrRet[0]['stock'];
-                $sqlval['price01'] = $arrRet[0]['price01'];
-                $sqlval['price02'] = $arrRet[0]['price02'];
-                $sqlval['creator_id'] = $_SESSION['member_id'];
-                $sqlval['create_date'] = "now()";
-                $sqlval['update_date'] = "now()";
-
-                $objQuery->begin();
-                $where = "product_id = ?";
-                $objQuery->delete("dtb_products_class", $where, array($_POST['product_id']));
-                $sqlval['product_class_id'] = $objQuery->nextVal('dtb_products_class_product_class_id');
-                $objQuery->insert("dtb_products_class", $sqlval);
-
-                $objQuery->commit();
-            }
-            
-	        // 在庫無し商品の非表示対応
-	        if (NOSTOCK_HIDDEN === true) {
-	            // 件数カウントバッチ実行
-	            $objDb->sfCategory_Count($objQuery);
-	        }
-            
-            $this->lfProductClassPage();   // 規格登録ページ
-            break;
-
-        // 編集要求
-        case 'pre_edit':
-            $objQuery = new SC_Query();
-            $where = "product_id = ? AND NOT(classcategory_id1 = 0 AND classcategory_id2 = 0) ";
-            $ret = $objQuery->count("dtb_products_class", $where, array($_POST['product_id']));
-
-            if($ret > 0) {
-                // 規格組み合わせ一覧の取得(DBの値を優先する。)
-                $this->arrClassCat = $this->lfGetClassCatListEdit($_POST['product_id']);
-            }
-            $this->lfProductClassPage();   // 規格登録ページ
-            break;
-            
-        // 規格組み合わせ表示
-        case 'disp':
-            $this->arrForm['select_class_id1'] = $_POST['select_class_id1'];
-            $this->arrForm['select_class_id2'] = $_POST['select_class_id2'];
-
-            $this->arrErr = $this->lfClassError();
-            if (count($this->arrErr) == 0) {
-                // 規格組み合わせ一覧の取得
-                $this->arrClassCat = $this->lfGetClassCatListDisp($_POST['select_class_id1'], $_POST['select_class_id2']);
-            }
-            $this->lfProductClassPage();   // 規格登録ページ
-            break;
-            
-        // 規格登録要求
+        switch ($_POST['mode']) {
         case 'edit':
             // 入力値の変換
             $this->arrForm = $this->lfConvertParam($_POST);
+
             // エラーチェック
             $this->arrErr = $this->lfProductClassError($this->arrForm);
-
-            if(count($this->arrErr) == 0) {
-                // 確認ページ設定
+            if (SC_Utils_Ex::isBlank($this->arrErr)) {
                 $this->tpl_mainpage = 'products/product_class_confirm.tpl';
                 $this->lfProductConfirmPage(); // 確認ページ表示
+
             } else {
-                // 規格組み合わせ一覧の取得
-                $this->arrClassCat = $this->lfGetClassCatListDisp($_POST['class_id1'], $_POST['class_id2'], false);
-                $this->lfProductClassPage();   // 規格登録ページ
+                $this->doPreEdit(false);
             }
             break;
-            
-        // 確認ページからの戻り
+
+        case 'delete':
+            $this->doDelete();
+            break;
+
+        case 'pre_edit':
+            $this->doPreEdit();
+            break;
+
+        case 'disp':
+            $this->doDisp();
+            break;
+
         case 'confirm_return':
             // フォームパラメータの引き継ぎ
@@ -176,23 +95,20 @@
             $this->arrForm['select_class_id1'] = "";
             $this->arrForm['select_class_id2'] = "";
-            // 規格組み合わせ一覧の取得(デフォルト値は出力しない)
-            $this->arrClassCat = $this->lfGetClassCatListDisp($_POST['class_id1'], $_POST['class_id2'], false);
-            $this->lfProductClassPage();   // 規格登録ページ
+            $this->doPreEdit(false);
             break;
-            
+
         case 'complete':
             // 完了ページ設定
             $this->tpl_mainpage = 'products/product_class_complete.tpl';
             // 商品規格の登録
-            $this->lfInsertProductClass($_POST, $_POST['product_id']);
+            $this->registerProductClass($_POST, $_POST['product_id']);
             break;
-            
+
         default:
-            $this->lfProductClassPage();   // 規格登録ページ
-            break;
-        }
-
-        $objView->assignobj($this);
-        $objView->display(MAIN_FRAME);
+        }
+
+        $this->arrClass = $this->getAllClass();
+        $this->arrForm['product_name'] = $this->getProductName($_POST['product_id']);
+        $this->assignView();
     }
 
@@ -206,181 +122,105 @@
     }
 
-    /* 規格登録ページ表示用 */
-    function lfProductClassPage() {
+    /**
+     * 規格の登録または更新を行う.
+     *
+     * TODO dtb_class_combination は, dtb_product_categories に倣って,
+     *      DELETE to INSERT だが, UPDATE を検討する.
+     *
+     * @param array $arrList 入力フォームの内容
+     * @param integer $product_id 登録を行う商品ID
+     */
+    function registerProductClass($arrList, $product_id) {
+        $objQuery =& SC_Query::getSingletonInstance();
         $objDb = new SC_Helper_DB_Ex();
 
-        $this->arrHidden = $_POST;
-        $this->arrHidden['select_class_id1'] = "";
-        $this->arrHidden['select_class_id2'] = "";
-        $arrClass = $objDb->sfGetIDValueList("dtb_class", 'class_id', 'name');
-
-        // 規格分類が登録されていない規格は表示しないようにする。
-        $arrClassCatCount = SC_Utils_Ex::sfGetClassCatCount();
-        if (count($arrClass) > 0) {
-            foreach($arrClass as $key => $val) {
-                if($arrClassCatCount[$key] > 0) {
-                    $this->arrClass[$key] = $arrClass[$key];
-                }
-            }
-        }
-        // 商品名を取得
-        $objQuery = new SC_Query();
-        $product_name = $objQuery->getOne("SELECT name FROM dtb_products WHERE product_id = ?", array($_POST['product_id']));
-        $this->arrForm['product_name'] = $product_name;
-    }
-    
-    /**
-     * デフォルトの表示
-     *
-     * @param object $objQuery
-     * @param integer $product_id 製品のID
-     * @param integer $max 表示される最大値
-     */
-    function lfSetDefaultClassCat($objQuery, $product_id, $max) {
-
-        // デフォルト値の読込
-        $col = "product_class_id, product_code, price01, price02, stock, stock_unlimited";
-        $arrRet = $objQuery->select($col, "dtb_products_class", "product_id = ? AND classcategory_id1 = 0 AND classcategory_id2 = 0", array($product_id));;
-
-        if(count($arrRet) > 0) {
-            $no = 1;
-            for($cnt = 0; $cnt < $max; $cnt++) {
-                $this->arrForm["product_class_id:".$no] = $arrRet[0]['product_class_id'];
-                $this->arrForm["product_code:".$no] = $arrRet[0]['product_code'];
-                $this->arrForm['stock:'.$no] = $arrRet[0]['stock'];
-                $this->arrForm['price01:'.$no] = $arrRet[0]['price01'];
-                $this->arrForm['price02:'.$no] = $arrRet[0]['price02'];
-                $this->arrForm['stock_unlimited:'.$no] = $arrRet[0]['stock_unlimited'];
-                $no++;
-            }
-        }
-    }
-
-    /* 規格組み合わせ一覧の取得 */
-    function lfGetClassCatListDisp($class_id1, $class_id2, $default = true) {
-        $objQuery = new SC_Query();
-
-        if($class_id2 != "") {
-            // 規格1と規格2
-            $sql = "SELECT * ";
-            $sql.= "FROM vw_cross_class AS crs_cls ";
-            $sql.= "WHERE class_id1 = ? AND class_id2 = ? ORDER BY rank1 DESC, rank2 DESC;";
-            $arrRet = $objQuery->getAll($sql, array($class_id1, $class_id2));
-        } else {
-            // 規格1のみ
-            $sql = "SELECT * ";
-            $sql.= "FROM vw_cross_class AS crs_cls ";
-            $sql.= "WHERE class_id1 = ? AND class_id2 = 0 ORDER BY rank1 DESC;";
-            $arrRet = $objQuery->getAll($sql, array($class_id1));
-            
-        }
-
-        $max = count($arrRet);
-
-        if($default) {
-            // デフォルト値を設定
-            $this->lfSetDefaultClassCat($objQuery, $_POST['product_id'], $max);
-        }
-
-        $this->arrForm["class_id1"] = $arrRet[0]['class_id1'];
-        $this->arrForm["class_id2"] = $arrRet[0]['class_id2'];
-        $this->tpl_onload.= "fnCheckAllStockLimit('$max', '" . DISABLED_RGB . "');";
-
-        return $arrRet;
-    }
-
-    /* 規格組み合わせ一覧の取得(編集画面) */
-    function lfGetClassCatListEdit($product_id) {
-        // 既存編集の場合
-        $objQuery = new SC_Query();
-
-        $col = "class_id1, class_id2, name1, name2, rank1, rank2, ";
-        $col.= "product_class_id, product_id, T1_classcategory_id AS classcategory_id1, T2_classcategory_id AS classcategory_id2, ";
-        $col.= "product_code, stock, stock_unlimited, sale_limit, price01, price02, status";
-
-        $sql = "SELECT $col FROM ";
-        $sql.= "( ";
-        $sql.= "SELECT T1.class_id AS class_id1, T2.class_id AS class_id2, T1.classcategory_id AS T1_classcategory_id, T2.classcategory_id AS T2_classcategory_id, T1.name AS name1, T2.name AS name2, T1.rank AS rank1, T2.rank AS rank2 ";
-        $sql.= "FROM dtb_classcategory AS T1, dtb_classcategory AS T2 ";
-        $sql.= "WHERE T1.class_id IN (SELECT class_id1 FROM vw_cross_products_class AS crs_prd WHERE product_id = ? GROUP BY class_id1, class_id2) AND T2.class_id IN (SELECT class_id2 FROM vw_cross_products_class AS crs_prd WHERE product_id = ? GROUP BY class_id1, class_id2)";
-        $sql.= ") AS T1 ";
-
-        $sql.= "LEFT JOIN (SELECT * FROM dtb_products_class WHERE product_id = ?) AS T3 ";
-        $sql.= "ON T1_classcategory_id = T3.classcategory_id1 AND T2_classcategory_id = T3.classcategory_id2 ";
-        $sql.= "ORDER BY rank1 DESC, rank2 DESC";
-
-        $arrList =  $objQuery->getAll($sql, array($product_id, $product_id, $product_id));
-
-        $this->arrForm["class_id1"] = $arrList[0]['class_id1'];
-        $this->arrForm["class_id2"] = $arrList[0]['class_id2'];
-
-        $max = count($arrList);
-
-        // デフォルト値を設定
-        $this->lfSetDefaultClassCat($objQuery, $product_id, $max);
-        $no = 1;
-        for($cnt = 0; $cnt < $max; $cnt++) {
-            $this->arrForm["classcategory_id1:".$no] = $arrList[$cnt]['classcategory_id1'];
-            $this->arrForm["classcategory_id2:".$no] = $arrList[$cnt]['classcategory_id2'];
-            $this->arrForm["product_class_id:".$no] = $arrList[$cnt]['product_class_id'];
-            if($arrList[$cnt]['product_id'] != "") {
-                $this->arrForm["product_code:".$no] = $arrList[$cnt]['product_code'];
-                $this->arrForm['stock:'.$no] = $arrList[$cnt]['stock'];
-                $this->arrForm['stock_unlimited:'.$no] = $arrList[$cnt]['stock_unlimited'];
-                $this->arrForm['price01:'.$no] = $arrList[$cnt]['price01'];
-                $this->arrForm['price02:'.$no] = $arrList[$cnt]['price02'];
-                // JavaScript初期化用文字列
-                $line.= "'check:".$no."',";
-            }
-            $no++;
-        }
-
-        $line = ereg_replace(",$", "", $line);
-        $this->tpl_javascript = "list = new Array($line);";
-        $color = DISABLED_RGB;
-        $this->tpl_onload.= "fnListCheck(list); fnCheckAllStockLimit('$max', '$color');";
-
-        return $arrList;
-    }
-
-    /* 規格の登録 */
-    function lfInsertProductClass($arrList, $product_id) {
-        $objQuery = new SC_Query();
-        $objDb = new SC_Helper_DB_Ex();
-
         $objQuery->begin();
 
-        // 既存規格の削除
-        $where = "product_id = ?";
-        $objQuery->delete("dtb_products_class", $where, array($product_id));
-
-        $cnt = 1;
-        // すべての規格を登録する。
-        while($arrList["classcategory_id1:".$cnt] != "") {
-            if($arrList["check:".$cnt] == 1) {
-                $sqlval = array();
-                $sqlval['product_id'] = $product_id;
-                $sqlval['classcategory_id1'] = $arrList["classcategory_id1:".$cnt];
-                $sqlval['classcategory_id2'] = $arrList["classcategory_id2:".$cnt];
-                if( strlen($arrList["product_class_id:".$cnt]) > 0 ){
-                    $sqlval['product_class_id'] = $arrList["product_class_id:".$cnt];
-                }
-                $sqlval['product_code'] = $arrList["product_code:".$cnt];
-                $sqlval['stock'] = $arrList["stock:".$cnt];
-                $sqlval['stock_unlimited'] = ($arrList["stock_unlimited:".$cnt]) ? '1' : '0';
-                $sqlval['price01'] = $arrList['price01:'.$cnt];
-                $sqlval['price02'] = $arrList['price02:'.$cnt];
-                $sqlval['creator_id'] = $_SESSION['member_id'];
-                $sqlval['create_date'] = "now()";
-                $sqlval['update_date'] = "now()";
-                // INSERTの実行
-                $objQuery->insert("dtb_products_class", $sqlval);
-            }
-            $cnt++;
-        }
-        
+        $productsClass = $objQuery->select("*", "dtb_products_class", "product_id = ?", array($product_id));
+
+        $exists = array();
+        foreach ($productsClass as $val) {
+            $exists[$val['product_class_id']] = $val;
+        }
+
+        $i = 1;
+        while (isset($arrList['classcategory_id1:' . $i])) {
+            $pVal = array();
+            $pVal['product_id'] = $product_id;;
+            $pVal['product_code'] = $arrList["product_code:".$i];
+            $pVal['stock'] = $arrList["stock:".$i];
+            $pVal['stock_unlimited'] = ($arrList["stock_unlimited:".$i]) ? '1' : '0';
+            $pVal['price01'] = $arrList['price01:'.$i];
+            $pVal['price02'] = $arrList['price02:'.$i];
+            $pVal['creator_id'] = $_SESSION['member_id'];
+            $pVal['update_date'] = "now()";
+
+            if($arrList["check:".$i] == 1) {
+                $pVal['del_flg'] = 0;
+            } else {
+                $pVal['del_flg'] = 1;
+            }
+
+            // 更新 or 登録
+            $isUpdate = false;
+            if (!SC_Utils_Ex::isBlank($arrList["product_class_id:".$i])) {
+                $isUpdate = true;
+                // 更新の場合は規格組み合わせを検索し, 削除しておく
+                $class_combination_id = $exists[$arrList["product_class_id:".$i]]['class_combination_id'];
+                $existsCombi = $objQuery->getRow("dtb_class_combination",
+                                                 "*", "class_combination_id = ?",
+                                                 array($class_combination_id));
+
+                $objQuery->delete("dtb_class_combination",
+                                  "class_combination_id IN (?, ?)",
+                                  array($existsCombi['class_combination_id'],
+                                        $existsCombi['parent_class_combination_id']));
+            }
+
+            // 規格組み合わせを登録
+            $cVal1['class_combination_id'] = $objQuery->nextVal('dtb_class_combination_class_combination_id');
+
+            $cVal1['classcategory_id'] = $arrList["classcategory_id1:".$i];
+            $cVal1['level'] = 1;
+            $objQuery->insert("dtb_class_combination", $cVal1);
+
+            $pVal['class_combination_id'] = $cVal1['class_combination_id'];
+
+            // 規格2も登録する場合
+            if (!SC_Utils_Ex::isBlank($arrList["classcategory_id2:".$i])) {
+                $cVal2['class_combination_id'] = $objQuery->nextVal('dtb_class_combination_class_combination_id');
+                $cVal2['classcategory_id'] = $arrList["classcategory_id2:".$i];
+                $cVal2['parent_class_combination_id'] = $cVal1['class_combination_id'];
+                $cVal2['level'] = 2;
+                $objQuery->insert("dtb_class_combination", $cVal2);
+
+                $pVal['class_combination_id'] = $cVal2['class_combination_id'];
+            }
+
+            // 更新
+            if ($isUpdate) {
+                $pVal['product_class_id'] = $arrList["product_class_id:".$i];
+                $objQuery->update("dtb_products_class", $pVal,
+                                  "product_class_id = ?",
+                                  array($pVal['product_class_id']));
+            }
+            // 新規登録
+            else {
+                $pVal['create_date'] = "now()";
+                $pVal['product_class_id'] = $objQuery->nextVal('dtb_products_class_product_class_id');
+                $objQuery->insert("dtb_products_class", $pVal);
+            }
+            $i++;
+        }
+
+        // 規格無し用の商品規格を非表示に
+        $bVal['del_flg'] = 1;
+        $bVal['update_date'] = 'now()';
+        $objQuery->update("dtb_products_class", $bVal,
+                          "product_class_id = ? AND class_combination_id IS NULL",
+                          array($pVal['product_class_id']));
+
         // 件数カウントバッチ実行
         $objDb->sfCategory_Count($objQuery);
-        
         $objQuery->commit();
     }
@@ -467,4 +307,213 @@
         $this->tpl_count = $cnt;
     }
+
+    /**
+     * 規格の組み合わせ一覧を表示する.
+     *
+     * 1. 規格1, 規格2を組み合わせた場合の妥当性を検証する.
+     * 2. 規格1, 規格2における規格分類のすべての組み合わせを取得し,
+     *    該当商品の商品規格の内容を取得し, フォームに設定する.
+     */
+    function doDisp() {
+        $this->arrForm['select_class_id1'] = $_POST['select_class_id1'];
+        $this->arrForm['select_class_id2'] = $_POST['select_class_id2'];
+
+        $this->arrErr = $this->lfClassError();
+        if (SC_Utils_Ex::isBlank($this->arrErr)) {
+            $this->arrClassCat = $this->getAllClassCategory($_POST['select_class_id1'], $_POST['select_class_id2']);
+
+            $productsClass = $this->getProductsClass($_POST['product_id']);
+
+            $total = count($this->arrClassCat);
+            for ($i = 1; $i <= $total; $i++) {
+                foreach ($productsClass as $key => $val) {
+                    $this->arrForm[$key . ":" . $i] = $val;
+                }
+            }
+        }
+        $this->tpl_onload.= "fnCheckAllStockLimit('$total', '" . DISABLED_RGB . "');";
+    }
+
+    /**
+     * 規格編集画面を表示する.
+     */
+    function doPreEdit($existsValue = true) {
+        $existsProductsClass = $this->getProductsClassAndClasscategory($_POST['product_id']);
+        $productsClass = $this->getProductsClass($_POST['product_id']);
+        $this->arrForm["class_id1"] = $existsProductsClass[0]['class_id1'];
+        $this->arrForm["class_id2"] = $existsProductsClass[0]['class_id2'];
+        $this->arrForm['select_class_id1'] = $this->arrForm["class_id1"];
+        $this->arrForm['select_class_id2'] = $this->arrForm["class_id2"];
+
+        $this->arrClassCat = $this->getAllClassCategory($this->arrForm["class_id1"], $this->arrForm["class_id2"]);
+        $total = count($this->arrClassCat);
+        for ($i = 1; $i <= $total; $i++) {
+            if ($existsValue) {
+                foreach ($productsClass as $key => $val) {
+                    $this->arrForm[$key . ":" . $i] = $val;
+                }
+            }
+            foreach ($existsProductsClass[$i] as $key => $val) {
+                $this->arrForm[$key . ":" . $i] = $val;
+            }
+            if (!SC_Utils_Ex::isBlank($this->arrForm['product_id:' . $i])
+                && $this->arrForm["del_flg:" . $i] == 0) {
+                $line .= "'check:" . $i . "',";
+            }
+        }
+
+        $line = preg_replace("/,$/", "", $line);
+        $this->tpl_javascript = "list = new Array($line);";
+        $color = DISABLED_RGB;
+        $this->tpl_onload.= "fnListCheck(list); fnCheckAllStockLimit('$total', '$color');";
+    }
+
+    function doDelete() {
+        $objQuery =& SC_Query::getSingletonInstance();
+
+        $objQuery->begin();
+        $val['del_flg'] = 0;
+        $objQuery->update("dtb_products_class", $val, "product_id = ? AND class_combination_id IS NULL", array($_POST['product_id']));
+
+        $val['del_flg'] = 1;
+        $objQuery->update("dtb_products_class", $val, "product_id = ? AND class_combination_id IS NOT NULL", array($_POST['product_id']));
+
+        $objQuery->commit();
+
+        // 在庫無し商品の非表示対応
+        if (NOSTOCK_HIDDEN === true) {
+            // 件数カウントバッチ実行
+            //$objDb->sfCategory_Count($objQuery);
+        }
+    }
+
+    /**
+     * 規格ID1, 規格ID2の規格分類すべてを取得する.
+     *
+     * @param integer $class_id1 規格ID1
+     * @param integer $class_id2 規格ID2
+     * @return array 規格と規格分類の配列
+     */
+    function getAllClassCategory($class_id1, $class_id2 = null) {
+        $objQuery =& SC_Query::getSingletonInstance();
+
+        $col = "T1.class_id AS class_id1, "
+            . " T1.classcategory_id AS classcategory_id1, "
+            . " T1.name AS name1, "
+            . " T1.rank AS rank1 ";
+
+        if(SC_Utils_Ex::isBlank($class_id2)) {
+            $table = "dtb_classcategory T1 ";
+            $objQuery->setWhere("T1.class_id = ?")
+                     ->setOrder("T1.rank DESC");
+            $val = array($class_id1);
+        } else {
+            $col .= ","
+                . "T2.class_id AS class_id2,"
+                . "T2.classcategory_id AS classcategory_id2,"
+                . "T2.name AS name2,"
+                . "T2.rank AS rank2";
+            $table = "dtb_classcategory AS T1, dtb_classcategory AS T2";
+            $objQuery->setWhere("T1.class_id = ? AND T2.class_id = ?")
+                     ->setOrder("T1.rank DESC, T2.rank DESC");
+            $val = array($class_id1, $class_id2);
+        }
+        return $objQuery->select($col, $table, "", $val);
+    }
+
+    /**
+     * 商品名を取得する.
+     *
+     * @access private
+     * @param integer $product_id 商品ID
+     * @return string 商品名の文字列
+     */
+    function getProductName($product_id) {
+        $objQuery =& SC_Query::getSingletonInstance();
+        return $objQuery->getOne("SELECT name FROM dtb_products WHERE product_id = ?", array($product_id));
+    }
+
+    /**
+     * 検索パラメータを生成する.
+     *
+     * "search_" で始まるパラメータのみを生成して返す.
+     *
+     * TODO パラメータの妥当性検証
+     *
+     * @access private
+     * @param array $params 生成元の POST パラメータ
+     * @return array View にアサインするパラメータの配列
+     */
+    function createSearchParams($params) {
+        $results = array();
+        foreach ($params as $key => $val) {
+            if (substr($key, 0, 7) == "search_") {
+                $results[$key] = $val;
+            }
+        }
+        return $results;
+    }
+
+    /**
+     * 規格分類の登録された, すべての規格を取得する.
+     *
+     * @access private
+     * @return array 規格分類の登録された, すべての規格
+     */
+    function getAllClass() {
+        $objDb = new SC_Helper_DB_Ex();
+        $arrClass = $objDb->sfGetIDValueList("dtb_class", 'class_id', 'name');
+
+        // 規格分類が登録されていない規格は表示しないようにする。
+        $arrClassCatCount = SC_Utils_Ex::sfGetClassCatCount();
+
+        $results = array();
+        if (!SC_Utils_Ex::isBlank($arrClass)) {
+            foreach($arrClass as $key => $val) {
+                if($arrClassCatCount[$key] > 0) {
+                    $results[$key] = $arrClass[$key];
+                }
+            }
+        }
+        return $results;
+    }
+
+    /**
+     * 商品IDをキーにして, 商品規格を取得する.
+     *
+     * @param integer $product_id 商品ID
+     * @return array 商品規格の配列
+     */
+    function getProductsClass($product_id) {
+        $objQuery =& SC_Query::getSingletonInstance();
+        return $objQuery->getRow("dtb_products_class", "*", "product_id = ?", array($product_id));
+    }
+
+    /**
+     * 登録済みの商品規格, 規格, 規格分類を取得する.
+     *
+     * @param integer $product_id 商品ID
+     * @return array 商品規格, 規格, 規格分類の配列
+     */
+    function getProductsClassAndClasscategory($productId) {
+        $objProduct = new SC_Product();
+        return $objProduct->getProductsClassFullByProductId($productId);
+    }
+
+    /**
+     * @access private
+     */
+    function authorization() {
+        SC_Utils_Ex::sfIsSuccess(new SC_Session());
+    }
+
+    /**
+     * @access private
+     */
+    function assignView() {
+        $objView = new SC_AdminView();
+        $objView->assignobj($this);
+        $objView->display(MAIN_FRAME);
+    }
 }
 ?>
Index: /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_ProductRank.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_ProductRank.php	(revision 18701)
+++ /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_ProductRank.php	(revision 18815)
@@ -139,4 +139,5 @@
     /* 商品読み込み */
     function lfGetProduct($category_id) {
+        // FIXME SC_Product クラスを使用した実装
         $objQuery = new SC_Query();
         $col = "product_id, name, main_list_image, product_code_min, product_code_max, status";
Index: /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products.php	(revision 18792)
+++ /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products.php	(revision 18815)
@@ -244,5 +244,5 @@
                 $order = "update_date DESC, product_id DESC";
                 $objQuery = new SC_Query();
-
+                $objProduct = new SC_Product();
                 switch($_POST['mode']) {
                     case 'csv':
@@ -253,9 +253,9 @@
                         // CSVを送信する。正常終了の場合、終了。
                         $objCSV->sfDownloadProductsCsv($where, $arrval, $order) && exit;
-                        
                         break;
                     case 'delete_all':
                         // 検索結果をすべて削除
-                        $where = "product_id IN (SELECT product_id FROM vw_products_allclass_detail AS alldtl WHERE $where)";
+                        $where = "product_id IN (SELECT product_id FROM "
+                            . $objProduct->alldtlSQL() . " WHERE $where)";
                         $sqlval['del_flg'] = 1;
                         $objQuery->update("dtb_products", $sqlval, $where, $arrval);
@@ -269,5 +269,5 @@
                         // 読み込む列とテーブルの指定
                         $col = "product_id, name, main_list_image, status, product_code_min, product_code_max, price02_min, price02_max, stock_min, stock_max, stock_unlimited_min, stock_unlimited_max, update_date";
-                        $from = "vw_products_allclass_detail AS alldtl ";
+                        $from = $objProduct->alldtlSQL();
 
                         // 行数の取得
Index: /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_Product.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_Product.php	(revision 18788)
+++ /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_Product.php	(revision 18815)
@@ -66,5 +66,4 @@
 
         $masterData = new SC_DB_MasterData_Ex();
-        $this->arrSRANK = $masterData->getMasterData("mtb_srank");
         $this->arrDISP = $masterData->getMasterData("mtb_disp");
         $this->arrCLASS = $masterData->getMasterData("mtb_class");
@@ -292,6 +291,6 @@
 
             if((isset($this->arrForm[$keyname]) && !empty($this->arrForm[$keyname])) && $this->arrForm[$delkey] != 1) {
-                $arrRet = $objQuery->select("main_list_image, product_code_min, name", "vw_products_allclass AS allcls", "product_id = ?", array($this->arrForm[$keyname]));
-                $arrRecommend[$i] = $arrRet[0];
+                $objProduct = new SC_Product();
+                $arrRecommend[$i] = $objProduct->getDetail($this->arrForm[$keyname]);
                 $arrRecommend[$i]['product_id'] = $this->arrForm[$keyname];
                 $arrRecommend[$i]['comment'] = $this->arrForm[$commentkey];
@@ -352,5 +351,21 @@
 
         $col = "*";
-        $table = "vw_products_nonclass AS noncls ";
+        $table = <<< __EOF__
+                      dtb_products AS T1
+            LEFT JOIN (
+                       SELECT product_id AS product_id_sub,
+                              product_code,
+                              price01,
+                              price02,
+                              stock,
+                              stock_unlimited,
+                              sale_limit,
+                              sale_unlimited,
+                              point_rate
+                         FROM dtb_products_class
+                        WHERE class_combination_id IS NULL
+                       ) AS T2
+                     ON T1.product_id = T2.product_id_sub
+__EOF__;
         $where = "product_id = ?";
 
@@ -431,6 +446,6 @@
 
         // 配列の添字を定義
-        $checkArray = array("name", "status", "product_flag",
-                            "main_list_comment", "main_comment", "point_rate",
+        $checkArray = array("name", "status",
+                            "main_list_comment", "main_comment",
                             "deliv_fee", "comment1", "comment2", "comment3",
                             "comment4", "comment5", "comment6", "main_list_comment",
@@ -441,9 +456,6 @@
         $sqlval['name'] = $arrList['name'];
         $sqlval['status'] = $arrList['status'];
-        $sqlval['product_flag'] = $arrList['product_flag'];
         $sqlval['main_list_comment'] = $arrList['main_list_comment'];
         $sqlval['main_comment'] = $arrList['main_comment'];
-        $sqlval['point_rate'] = $arrList['point_rate'];
-        $sqlval['deliv_fee'] = $arrList['deliv_fee'];
         $sqlval['comment1'] = $arrList['comment1'];
         $sqlval['comment2'] = $arrList['comment2'];
@@ -453,5 +465,4 @@
         $sqlval['comment6'] = $arrList['comment6'];
         $sqlval['main_list_comment'] = $arrList['main_list_comment'];
-        $sqlval['sale_limit'] = $arrList['sale_limit'];
         $sqlval['deliv_date_id'] = $arrList['deliv_date_id'];
         $sqlval['maker_id'] = $arrList['maker_id'];
@@ -843,25 +854,26 @@
         if ($objDb->sfHasProductClass($product_id)) return;
 
-        // 既存規格の削除
-        $where = 'product_id = ?';
-        $objQuery->delete('dtb_products_class', $where, array($product_id));
-
         // 配列の添字を定義
-        $checkArray = array('product_class_id', 'product_id', 'product_code', 'stock', 'stock_unlimited', 'price01', 'price02');
+        $checkArray = array('product_class_id', 'product_id', 'product_code', 'stock', 'stock_unlimited', 'price01', 'price02', 'sale_limit', 'sale_unlimited', 'deliv_fee', 'point_rate', 'del_flg');
         $sqlval = SC_Utils_Ex::sfArrayIntersectKeys($arrList, $checkArray);
         $sqlval = SC_Utils_Ex::arrayDefineIndexes($sqlval, $checkArray);
 
+        $sqlval['stock_unlimited'] = $sqlval['stock_unlimited'] ? '1' : '0';
+        $sqlval['creator_id'] = strlen($_SESSION['member_id']) >= 1 ? $_SESSION['member_id'] : '0';
+
         if (strlen($sqlval['product_class_id']) == 0) {
             $sqlval['product_class_id'] = $objQuery->nextVal('dtb_products_class_product_class_id');
-        }
-        $sqlval['classcategory_id1'] = '0';
-        $sqlval['classcategory_id2'] = '0';
-        $sqlval['stock_unlimited'] = $sqlval['stock_unlimited'] ? '1' : '0';
-        $sqlval['creator_id'] = strlen($_SESSION['member_id']) >= 1 ? $_SESSION['member_id'] : '0';
-        $sqlval['create_date'] = 'now()';
-
-        // INSERTの実行
-        $objQuery->insert('dtb_products_class', $sqlval);
-    }
+            $sqlval['create_date'] = 'now()';
+            $sqlval['update_date'] = 'now()';
+            // INSERTの実行
+            $objQuery->insert('dtb_products_class', $sqlval);
+        } else {
+            $sqlval['update_date'] = 'now()';
+            // UPDATEの実行
+            $objQuery->update('dtb_products_class', $sqlval, "product_class_id = ?", array($sqlval['product_class_id']));
+
+        }
+    }
+
     /* ダウンロードファイル情報の初期化 */
     function lfInitDownFile() {
Index: /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_ProductSelect.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_ProductSelect.php	(revision 18789)
+++ /branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_ProductSelect.php	(revision 18815)
@@ -105,8 +105,4 @@
             $order = "update_date DESC, product_id DESC ";
 
-            // 読み込む列とテーブルの指定
-            $col = "product_id, name, category_id, main_list_image, status, product_code, price01, stock, stock_unlimited";
-            $from = "vw_products_nonclass AS noncls ";
-
             $objQuery = new SC_Query();
             // 行数の取得
@@ -135,9 +131,7 @@
             $objQuery->setOrder($order);
 
-            // viewも絞込みをかける(mysql用)
-            //sfViewWhere("&&noncls_where&&", $where, $arrval, $objQuery->order . " " .  $objQuery->setLimitOffset($page_max, $startno, true));
-
             // 検索結果の取得
-            $this->arrProducts = $objQuery->select($col, $from, $where, $arrval);
+            // FIXME 商品コードの表示
+            $this->arrProducts = $objQuery->select("*", SC_Product::alldtlSQL(), $where, $arrval);
         }
 
Index: /branches/version-2_5-dev/data/class/pages/admin/order/LC_Page_Admin_Order_ProductSelect.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/admin/order/LC_Page_Admin_Order_ProductSelect.php	(revision 18789)
+++ /branches/version-2_5-dev/data/class/pages/admin/order/LC_Page_Admin_Order_ProductSelect.php	(revision 18815)
@@ -109,4 +109,7 @@
             }
 
+            /*
+             * FIXME パフォーマンスに問題があるため SC_Product::lists() を使用する
+             */
             // 読み込む列とテーブルの指定
             $col = "DISTINCT T1.product_id, product_code_min, product_code_max,"
@@ -115,5 +118,5 @@
                 . " stock_unlimited_max, del_flg, status, name, comment1,"
                 . " comment2, comment3, main_list_comment, main_image,"
-                . " main_list_image, product_flag, deliv_date_id, sale_limit,"
+                . " main_list_image, deliv_date_id, sale_limit,"
                 . " point_rate, create_date, deliv_fee, "
                 . " T4.product_rank, T4.category_rank";
@@ -153,7 +156,4 @@
             $objQuery->setOrder($order);
 
-            // viewも絞込みをかける(mysql用)
-            //sfViewWhere("&&noncls_where&&", $where, $arrval, $objQuery->order . " " .  $objQuery->setLimitOffset($page_max, $startno, true));
-
             // 検索結果の取得
             $this->arrProducts = $objQuery->select($col, $from, $where, $arrval);
@@ -209,4 +209,5 @@
     }
 
+    // FIXME SC_Product クラスを使用する
     /* 規格セレクトボックスの作成 */
     function lfMakeSelect($product_id, $arrClassName, $arrClassCatName) {
Index: /branches/version-2_5-dev/data/class/pages/admin/contents/LC_Page_Admin_Contents_RecommendSearch.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/admin/contents/LC_Page_Admin_Contents_RecommendSearch.php	(revision 18772)
+++ /branches/version-2_5-dev/data/class/pages/admin/contents/LC_Page_Admin_Contents_RecommendSearch.php	(revision 18815)
@@ -103,8 +103,4 @@
             $order = "update_date DESC, product_id DESC";
 
-            // 読み込む列とテーブルの指定
-            $col = "product_id, name, category_id, main_list_image, status, product_code, price01, stock, stock_unlimited";
-            $from = "vw_products_nonclass AS noncls ";
-
             $objQuery = new SC_Query();
             // 行数の取得
@@ -131,6 +127,7 @@
             $objQuery->setOrder($order);
 
+            // FIXME 商品コードの表示
             // 検索結果の取得
-            $this->arrProducts = $objQuery->select($col, $from, $where, $arrval);
+            $this->arrProducts = $objQuery->select("*", SC_Product::alldtlSQL(), $where, $arrval);
         }
 
Index: /branches/version-2_5-dev/data/class/pages/admin/customer/LC_Page_Admin_Customer.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/admin/customer/LC_Page_Admin_Customer.php	(revision 18772)
+++ /branches/version-2_5-dev/data/class/pages/admin/customer/LC_Page_Admin_Customer.php	(revision 18815)
@@ -335,5 +335,5 @@
                 case 'delete_all':
                     // 検索結果をすべて削除
-                    $where = "product_id IN (SELECT product_id FROM vw_products_nonclass AS noncls WHERE $where)";
+                    $where = "product_id IN (SELECT product_id FROM SC_Product::alldtlSQL() WHERE $where)";
                     $sqlval['del_flg'] = 1;
                     $objQuery->update("dtb_products", $sqlval, $where, $arrval);
Index: /branches/version-2_5-dev/data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Best5.php
===================================================================
--- /branches/version-2_5-dev/data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Best5.php	(revision 18701)
+++ /branches/version-2_5-dev/data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Best5.php	(revision 18815)
@@ -105,5 +105,5 @@
     function lfGetRanking(){
         $objQuery = new SC_Query();
-
+        // FIXME SC_Product クラスを使用した実装
         $col = "DISTINCT A.*, name, price02_min, price01_min, main_list_image ";
         $from = "dtb_best_products AS A INNER JOIN vw_products_allclass AS allcls using(product_id)";
Index: /branches/version-2_5-dev/data/class/util/SC_Utils.php
===================================================================
--- /branches/version-2_5-dev/data/class/util/SC_Utils.php	(revision 18812)
+++ /branches/version-2_5-dev/data/class/util/SC_Utils.php	(revision 18815)
@@ -806,5 +806,5 @@
             $objQuery->setOrder('update_date DESC');
             //キャンペーンポイントの取得
-            $arrRet = $objQuery->select("campaign_name, campaign_point_rate", "dtb_campaign", $where, array($product_id));
+            //$arrRet = $objQuery->select("campaign_name, campaign_point_rate", "dtb_campaign", $where, array($product_id));
         }
         //複数のキャンペーンに登録されている商品は、最新のキャンペーンからポイントを取得
@@ -858,7 +858,9 @@
 
     function sfGetProductClassId($product_id, $classcategory_id1, $classcategory_id2) {
-        $where = "product_id = ? AND classcategory_id1 = ? AND classcategory_id2 = ?";
+        // $where = "product_id = ? AND classcategory_id1 = ? AND classcategory_id2 = ?";
+        $where = "product_id = ?";
         $objQuery = new SC_Query();
-        $ret = $objQuery->get("dtb_products_class", "product_class_id", $where, Array($product_id, $classcategory_id1, $classcategory_id2));
+        // $ret = $objQuery->get("dtb_products_class", "product_class_id", $where, Array($product_id, $classcategory_id1, $classcategory_id2));
+        $ret = $objQuery->get("dtb_products_class", "product_class_id", $where, Array($product_id));
         return $ret;
     }
Index: /branches/version-2_5-dev/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php
===================================================================
--- /branches/version-2_5-dev/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php	(revision 18793)
+++ /branches/version-2_5-dev/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php	(revision 18815)
@@ -307,69 +307,4 @@
         if (empty($sql)) {
 
-            $sql['vw_cross_class'] = <<< __EOS__
-                (
-                    SELECT
-                        T1.class_id AS class_id1,
-                        T2.class_id AS class_id2,
-                        T1.classcategory_id AS classcategory_id1,
-                        T2.classcategory_id AS classcategory_id2,
-                        T1.name AS name1,
-                        T2.name AS name2,
-                        T1.rank AS rank1,
-                        T2.rank AS rank2
-                    FROM
-                        dtb_classcategory AS T1,
-                        dtb_classcategory AS T2
-                )
-__EOS__;
-
-            $sql['vw_cross_products_class'] = <<< __EOS__
-                (
-                    SELECT
-                        T1.class_id1,
-                        T1.class_id2,
-                        T1.classcategory_id1,
-                        T1.classcategory_id2,
-                        T2.product_id,
-                        T1.name1,
-                        T1.name2,
-                        T2.product_code,
-                        T2.stock,
-                        T2.price01,
-                        T2.price02,
-                        T1.rank1,
-                        T1.rank2
-                    FROM
-                        {$sql['vw_cross_class']} AS T1
-                        LEFT JOIN dtb_products_class AS T2
-                            ON T1.classcategory_id1 = T2.classcategory_id1
-                            AND T1.classcategory_id2 = T2.classcategory_id2
-                )
-__EOS__;
-
-            $sql['vw_products_nonclass'] = <<< __EOS__
-                (
-                    SELECT *
-                    FROM
-                        dtb_products AS T1
-                        LEFT JOIN
-                        (
-                            SELECT
-                                product_id AS product_id_sub,
-                                product_code,
-                                price01,
-                                price02,
-                                stock,
-                                stock_unlimited,
-                                classcategory_id1,
-                                classcategory_id2
-                            FROM dtb_products_class
-                            WHERE
-                                classcategory_id1 = 0
-                                AND classcategory_id2 = 0
-                        ) AS T2
-                        ON T1.product_id = T2.product_id_sub
-                )
-__EOS__;
 
             $sql['vw_products_allclass_detail'] = <<< __EOS__
@@ -378,11 +313,7 @@
                         dtb_products.product_id,
                         dtb_products.name,
-                        dtb_products.deliv_fee,
-                        dtb_products.sale_limit,
                         dtb_products.maker_id,
                         dtb_products.rank,
                         dtb_products.status,
-                        dtb_products.product_flag,
-                        dtb_products.point_rate,
                         dtb_products.comment1,
                         dtb_products.comment2,
@@ -448,5 +379,5 @@
                     FROM
                         dtb_products
-                        LEFT JOIN
+                    JOIN
                             (
                                 SELECT
@@ -488,39 +419,4 @@
 __EOS__;
 
-            $sql['vw_product_class'] = <<< __EOS__
-                (SELECT * FROM
-                (SELECT T3.product_class_id, T3.product_id AS product_id_sub, classcategory_id1, classcategory_id2,
-                T3.rank AS rank1, T4.rank AS rank2, T3.class_id AS class_id1, T4.class_id AS class_id2,
-                stock, price01, price02, stock_unlimited, product_code
-                FROM ( SELECT
-                        T1.product_class_id,
-                        T1.product_id,
-                        classcategory_id1,
-                        classcategory_id2,
-                        T2.rank,
-                        T2.class_id,
-                        stock,
-                        price01,
-                        price02,
-                        stock_unlimited,
-                        product_code
-                 FROM (dtb_products_class AS T1 LEFT JOIN dtb_classcategory AS T2
-                ON T1.classcategory_id1 = T2.classcategory_id))
-                AS T3 LEFT JOIN dtb_classcategory AS T4
-                ON T3.classcategory_id2 = T4.classcategory_id) AS T5 LEFT JOIN dtb_products AS T6
-                ON product_id_sub = T6.product_id)
-__EOS__;
-
-            $sql['vw_category_count'] = <<< __EOS__
-                (SELECT T1.category_id, T1.category_name, T1.parent_category_id, T1.level, T1.rank, T2.product_count
-                FROM dtb_category AS T1 LEFT JOIN dtb_category_total_count AS T2
-                ON T1.category_id = T2.category_id)
-__EOS__;
-
-            $sql['vw_download_class'] = <<< __EOS__
-                (SELECT p.product_id AS product_id, p.down_realfilename AS down_realfilename , p.down_filename AS down_filename, od.order_id AS order_id, o.customer_id AS customer_id, o.commit_date AS commit_date, o.status AS status FROM
-                    dtb_products p, dtb_order_detail od, dtb_order o
-                WHERE p.product_id = od.product_id AND od.order_id = o.order_id)
-__EOS__;
         }
 
Index: /branches/version-2_5-dev/data/require_classes.php
===================================================================
--- /branches/version-2_5-dev/data/require_classes.php	(revision 18773)
+++ /branches/version-2_5-dev/data/require_classes.php	(revision 18815)
@@ -47,4 +47,5 @@
 require_once(CLASS_PATH . "SC_MobileEmoji.php");
 require_once(CLASS_PATH . "SC_MobileImage.php");
+require_once(CLASS_PATH . "SC_Product.php");
 require_once(CLASS_EX_PATH . "helper_extends/SC_Helper_PageLayout_Ex.php");
 require_once(CLASS_EX_PATH . "helper_extends/SC_Helper_DB_Ex.php");
Index: /branches/version-2_5-dev/data/Smarty/templates/default/admin/products/product_class.tpl
===================================================================
--- /branches/version-2_5-dev/data/Smarty/templates/default/admin/products/product_class.tpl	(revision 18700)
+++ /branches/version-2_5-dev/data/Smarty/templates/default/admin/products/product_class.tpl	(revision 18815)
@@ -108,9 +108,10 @@
       <!--{assign var=key value="check:`$smarty.section.cnt.iteration`"}-->
       <td align="center">
+				<!--{assign var=id value="product_class_id:`$smarty.section.cnt.iteration`"}-->
         <input type="hidden" name="classcategory_id1:<!--{$smarty.section.cnt.iteration}-->" value="<!--{$arrClassCat[cnt].classcategory_id1}-->" />
         <input type="hidden" name="classcategory_id2:<!--{$smarty.section.cnt.iteration}-->" value="<!--{$arrClassCat[cnt].classcategory_id2}-->" />
         <input type="hidden" name="name1:<!--{$smarty.section.cnt.iteration}-->" value="<!--{$arrClassCat[cnt].name1}-->" />
         <input type="hidden" name="name2:<!--{$smarty.section.cnt.iteration}-->" value="<!--{$arrClassCat[cnt].name2}-->" />
-        <input type="hidden" name="product_class_id:<!--{$smarty.section.cnt.iteration}-->" value="<!--{$arrClassCat[cnt].product_class_id}-->" />
+        <input type="hidden" name="product_class_id:<!--{$smarty.section.cnt.iteration}-->" value="<!--{$arrForm[$id]}-->" />
         <input type="checkbox" name="check:<!--{$smarty.section.cnt.iteration}-->" value="1" <!--{if $arrForm[$key] == 1}-->checked="checked"<!--{/if}-->>
       </td>
Index: /branches/version-2_5-dev/test/class/page/LC_Page_Admin_Products_ProductClass_Test.php
===================================================================
--- /branches/version-2_5-dev/test/class/page/LC_Page_Admin_Products_ProductClass_Test.php	(revision 18815)
+++ /branches/version-2_5-dev/test/class/page/LC_Page_Admin_Products_ProductClass_Test.php	(revision 18815)
@@ -0,0 +1,412 @@
+<?php
+/*
+ * This file is part of EC-CUBE
+ *
+ * Copyright(c) 2000-2010 LOCKON CO.,LTD. All Rights Reserved.
+ *
+ * http://www.lockon.co.jp/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+// {{{ requires
+require_once(realpath(dirname(__FILE__)) . '/../../require.php');
+require_once(realpath(dirname(__FILE__)) . '/../../../data/class/pages/admin/products/LC_Page_Admin_Products_ProductClass.php');
+
+/**
+ * LC_Page_Admin_Products_ProductClass のテストケース.
+ *
+ * @package Page
+ * @author Kentaro Ohkouchi
+ * @version $Id$
+ */
+class LC_Page_Admin_Products_ProductClass_Test extends PHPUnit_Framework_TestCase {
+
+    function setUp() {
+        $this->objQuery =& SC_Query::getSingletonInstance();
+        $this->objQuery->begin();
+
+        $this->objPage = new LC_Page_Admin_Products_ProductClass_Mock();
+        $this->objPage->init();
+        $this->now = "2010-01-01 00:00:00";
+    }
+
+    function tearDown() {
+        $this->objQuery->rollback();
+        $this->objQuery = null;
+        $this->objPage = null;
+    }
+
+    function testInit() {
+
+        $this->assertEquals('products/product_class.tpl',
+                            $this->objPage->tpl_mainpage);
+        $this->assertEquals('products/subnavi.tpl',
+                            $this->objPage->tpl_subnavi);
+        $this->assertEquals('products',
+                            $this->objPage->tpl_mainno);
+        $this->assertEquals('product',
+                            $this->objPage->tpl_subno);
+        $this->assertEquals('商品登録(商品規格)',
+                            $this->objPage->tpl_subtitle);
+    }
+
+    function testProcess() {
+        $this->objPage->process();
+    }
+
+    function testCreateSearchParams() {
+        $keys = array('search_product_id',
+                      'search_product_code',
+                      'search_category_id',
+                      'search_product_class_name',
+                      'search_name',
+                      'search_startyear',
+                      'search_startmonth',
+                      'search_startday',
+                      'search_endyear',
+                      'search_endmonth',
+                      'search_endday',
+                      'search_page_max',
+                      'search_pageno',
+                      'mode');
+        foreach ($keys as $key) {
+            $_POST[$key] = $key . " in value.";
+        }
+
+        $this->expected = array('search_product_id' => 'search_product_id in value.',
+                                'search_product_code' => 'search_product_code in value.',
+                                'search_category_id' => 'search_category_id in value.',
+                                'search_product_class_name' => 'search_product_class_name in value.',
+                                'search_name' => 'search_name in value.',
+                                'search_startyear' => 'search_startyear in value.',
+                                'search_startmonth' => 'search_startmonth in value.',
+                                'search_startday' => 'search_startday in value.',
+                                'search_endyear' => 'search_endyear in value.',
+                                'search_endmonth' => 'search_endmonth in value.',
+                                'search_endday' => 'search_endday in value.',
+                                'search_page_max' => 'search_page_max in value.',
+                                'search_pageno' => 'search_pageno in value.');
+
+        $this->actual = $this->objPage->createSearchParams($_POST);
+
+        $this->verify();
+    }
+
+    function testGetProductName() {
+        $product_id = 10000000;
+        $this->expected = "テスト商品";
+        $this->setProduct($product_id, $this->expected);
+
+        $this->actual = $this->objPage->getProductName($product_id);
+
+        $this->verify();
+    }
+
+    function testGetProductsClass() {
+        $product_id = 10000000;
+        $product_class_id = 10000;
+        $this->setProductsClass($product_id, $product_class_id);
+        $this->expected = array('product_class_id' => $product_class_id,
+                                'product_id' => $product_id,
+                                'class_combination_id' => null,
+                                'product_code' => 'product_code' . $product_class_id,
+                                'stock' => null,
+                                'stock_unlimited' => 0,
+                                'sale_unlimited' => 0,
+                                'sale_limit' => null,
+                                'price01' => 10000,
+                                'price02' => null,
+                                'deliv_fee' => null,
+                                'point_rate' => null,
+                                'status' => null,
+                                'creator_id' => 1,
+                                'create_date' => $this->now,
+                                'update_date' => null,
+                                'del_flg' => 0
+                                );
+
+        $this->actual = $this->objPage->getProductsClass($product_id);
+
+        $this->verify();
+    }
+
+    function testGetAllClass() {
+        $this->clearClass();
+        $this->setClass(1000, "大きさ", 1, array("S", "M", "L", "LL"));
+        $this->setClass(2, "色", 2, array("赤", "青", "黄", "緑"));
+        $this->setClass(3, "味", 3, array());
+
+        $this->expected = array("1000" => "大きさ",
+                                "2" => "色");
+        $this->actual = $this->objPage->getAllClass();
+
+        $this->verify();
+    }
+
+    function testGetAllClassCategory規格1のみ() {
+        $this->clearClass();
+        $this->setClass(1000, "大きさ", 1, array("S", "M", "L", "LL"));
+        $this->setClass(2, "色", 2, array("赤", "青", "黄", "緑"));
+        $this->setClass(3, "味", 3, array("甘口", "中辛", "辛口"));
+
+        $this->expected = array(
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000004,
+                                      "name1" => "LL",
+                                      "rank1" => 4),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000003,
+                                      "name1" => "L",
+                                      "rank1" => 3),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000002,
+                                      "name1" => "M",
+                                      "rank1" => 2),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000001,
+                                      "name1" => "S",
+                                      "rank1" => 1));
+
+        $this->actual = $this->objPage->getAllClassCategory(1000);
+        $this->verify();
+    }
+
+    function testGetAllClassCategory規格1と3() {
+        $this->clearClass();
+        $this->setClass(1000, "大きさ", 1, array("S", "M", "L", "LL"));
+        $this->setClass(2, "色", 2, array("赤", "青", "黄", "緑"));
+        $this->setClass(3, "味", 3, array("甘口", "中辛", "辛口"));
+
+        $this->expected = array(
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000004,
+                                      "name1" => "LL",
+                                      "rank1" => 4,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000003,
+                                      "name2" => "辛口",
+                                      "rank2" => 3),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000004,
+                                      "name1" => "LL",
+                                      "rank1" => 4,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000002,
+                                      "name2" => "中辛",
+                                      "rank2" => 2),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000004,
+                                      "name1" => "LL",
+                                      "rank1" => 4,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000001,
+                                      "name2" => "甘口",
+                                      "rank2" => 1),
+
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000003,
+                                      "name1" => "L",
+                                      "rank1" => 3,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000003,
+                                      "name2" => "辛口",
+                                      "rank2" => 3),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000003,
+                                      "name1" => "L",
+                                      "rank1" => 3,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000002,
+                                      "name2" => "中辛",
+                                      "rank2" => 2),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000003,
+                                      "name1" => "L",
+                                      "rank1" => 3,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000001,
+                                      "name2" => "甘口",
+                                      "rank2" => 1),
+
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000002,
+                                      "name1" => "M",
+                                      "rank1" => 2,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000003,
+                                      "name2" => "辛口",
+                                      "rank2" => 3),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000002,
+                                      "name1" => "M",
+                                      "rank1" => 2,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000002,
+                                      "name2" => "中辛",
+                                      "rank2" => 2),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000002,
+                                      "name1" => "M",
+                                      "rank1" => 2,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000001,
+                                      "name2" => "甘口",
+                                      "rank2" => 1),
+
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000001,
+                                      "name1" => "S",
+                                      "rank1" => 1,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000003,
+                                      "name2" => "辛口",
+                                      "rank2" => 3),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000001,
+                                      "name1" => "S",
+                                      "rank1" => 1,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000002,
+                                      "name2" => "中辛",
+                                      "rank2" => 2),
+                                array("class_id1" => 1000,
+                                      "classcategory_id1" => 1000000001,
+                                      "name1" => "S",
+                                      "rank1" => 1,
+                                      "class_id2" => 3,
+                                      "classcategory_id2" => 3000001,
+                                      "name2" => "甘口",
+                                      "rank2" => 1),
+                                );
+
+        $this->actual = $this->objPage->getAllClassCategory(1000, 3);
+        $this->verify();
+    }
+
+    function testGetProductsClassAndClasscategory() {
+        $product_id = 10000;
+        $product_class_id = 1000;
+        $class_combination_id = 200;
+        $this->clearClass();
+        $this->setClass(1000, "大きさ", 1, array("S", "M", "L", "LL"));
+        $this->setClass(2, "色", 2, array("赤", "青", "黄", "緑"));
+        $this->setClass(3, "味", 3, array("甘口", "中辛", "辛口"));
+        $this->setProductsClass($product_id, $product_class_id,
+                                $class_combination_id);
+        $this->setClassCombination($class_combination_id, 100, 3000001, 2);
+        $this->setClassCombination(100, null, 2000001, 1);
+
+
+        $this->expected = array(
+                                array("class_id1" => 2,
+                                      "class_id2" => 3,
+                                      "name1" => "赤",
+                                      "name2" => "甘口",
+                                      "rank1" => 1,
+                                      "rank2" => 1,
+                                      "product_class_id" => 1000,
+                                      "product_id" => 10000,
+                                      "classcategory_id1" => 2000001,
+                                      "classcategory_id2" => 3000001,
+                                      "product_code" => "product_code1000",
+                                      "stock" => null,
+                                      "stock_unlimited" => 0,
+                                      "sale_limit" => null,
+                                      "price01" => 10000,
+                                      "price02" => null));
+
+        $this->actual = $this->objPage->getProductsClassAndClasscategory($product_id);
+
+        $this->verify();
+    }
+
+    function verify() {
+        $this->assertEquals($this->expected, $this->actual);
+    }
+
+    function setProduct($product_id, $name) {
+        $val['product_id'] = $product_id;
+        $val['name'] = $name;
+        $val['creator_id'] = 1;
+        $val['deliv_date_id'] = 1;
+        $this->objQuery->insert("dtb_products", $val);
+    }
+
+    function setProductsClass($product_id, $product_class_id, $class_combination_id = null) {
+        $val['product_class_id'] = $product_class_id;
+        $val['product_id'] = $product_id;
+        $val['class_combination_id'] = $class_combination_id;
+        $val['product_code'] = 'product_code' . $product_class_id;
+        $val['price01'] = 10000;
+        $val['creator_id'] = 1;
+        $val['create_date'] = $this->now;
+        $val['del_flg'] = 0;
+        $this->objQuery->insert("dtb_products_class", $val);
+    }
+
+    function setClassCombination($class_combination_id,
+                                 $parent_class_combination_id, $classcategory_id,
+                                 $level) {
+        $val['class_combination_id'] = $class_combination_id;
+        $val['parent_class_combination_id'] = $parent_class_combination_id;
+        $val['classcategory_id'] = $classcategory_id;
+        $val['level'] = $level;
+        $this->objQuery->insert("dtb_class_combination", $val);
+    }
+
+    function clearClass() {
+        $this->objQuery->delete("dtb_class");
+        $this->objQuery->delete("dtb_classcategory");
+    }
+
+    /**
+     * 規格と規格分類を生成する.
+     *
+     * @param integer $class_id 規格ID
+     * @param string $class_name 規格名
+     * @param integer $rank 規格の表示順
+     * @param array $classcategory 規格分類名の配列
+     */
+    function setClass($class_id, $class_name, $rank, $classcategory) {
+        $val['class_id'] = $class_id;
+        $val['name'] = $class_name;
+        $val['creator_id'] = 1;
+        $val['del_flg'] = 0;
+        $val['rank'] = $rank;
+
+        $this->objQuery->insert("dtb_class", $val);
+        $i = 1;
+        foreach ($classcategory as $name) {
+            $val['classcategory_id'] = $class_id . "00000" . $i;
+            $val['name'] = $name;
+            $val['rank'] = $i;
+            $this->objQuery->insert("dtb_classcategory", $val);
+            $i++;
+        }
+    }
+}
+
+class LC_Page_Admin_Products_ProductClass_Mock extends LC_Page_Admin_Products_ProductClass {
+
+    function authorization() {
+        // quiet.
+    }
+
+    function assignView() {
+        // quiet.
+    }
+}
+?>
Index: /branches/version-2_5-dev/html/install/sql/create_view.sql
===================================================================
--- /branches/version-2_5-dev/html/install/sql/create_view.sql	(revision 18777)
+++ /branches/version-2_5-dev/html/install/sql/create_view.sql	(revision 18815)
@@ -1,73 +1,9 @@
-CREATE VIEW vw_cross_class as
-    SELECT
-        T1.class_id AS class_id1,
-        T2.class_id AS class_id2,
-        T1.classcategory_id AS classcategory_id1,
-        T2.classcategory_id AS classcategory_id2,
-        T1.name AS name1,
-        T2.name AS name2,
-        T1.rank AS rank1,
-        T2.rank AS rank2
-    FROM
-        dtb_classcategory AS T1,
-        dtb_classcategory AS T2
-;
-
-CREATE VIEW vw_cross_products_class AS
-    SELECT
-        T1.class_id1,
-        T1.class_id2,
-        T1.classcategory_id1,
-        T1.classcategory_id2,
-        T2.product_id,
-        T1.name1,
-        T1.name2,
-        T2.product_code,
-        T2.stock,
-        T2.price01,
-        T2.price02,
-        T1.rank1,
-        T1.rank2
-    FROM
-        vw_cross_class AS T1
-        LEFT JOIN dtb_products_class AS T2
-            ON T1.classcategory_id1 = T2.classcategory_id1
-            AND T1.classcategory_id2 = T2.classcategory_id2
-;
-
-CREATE VIEW vw_products_nonclass AS
-    SELECT *
-    FROM
-        dtb_products AS T1
-        LEFT JOIN
-        (
-            SELECT
-                product_id AS product_id_sub,
-                product_code,
-                price01,
-                price02,
-                stock,
-                stock_unlimited,
-                classcategory_id1,
-                classcategory_id2
-            FROM dtb_products_class
-            WHERE
-                classcategory_id1 = 0
-                AND classcategory_id2 = 0
-        ) AS T2
-        ON T1.product_id = T2.product_id_sub
-;
-
 CREATE VIEW vw_products_allclass_detail AS
     SELECT
         dtb_products.product_id,
         dtb_products."name",
-        dtb_products.deliv_fee,
-        dtb_products.sale_limit,
         dtb_products.maker_id,
         dtb_products.rank,
         dtb_products.status,
-        dtb_products.product_flag,
-        dtb_products.point_rate,
         dtb_products.comment1,
         dtb_products.comment2,
@@ -169,55 +105,2 @@
             ON T2.category_id = dtb_category.category_id
 ;
-
-CREATE VIEW vw_product_class AS
-     SELECT *
-       FROM
-      (SELECT T3.product_class_id,
-              T3.product_id AS product_id_sub,
-              classcategory_id1,
-              classcategory_id2,
-              T3.rank AS rank1,
-              T4.rank AS rank2,
-              T3.class_id AS class_id1,
-              T4.class_id AS class_id2,
-              stock,
-              price01,
-              price02,
-              stock_unlimited,
-              product_code
-         FROM (dtb_products_class AS T1
-    LEFT JOIN dtb_classcategory AS T2
-           ON T1.classcategory_id1 = T2.classcategory_id) AS T3
-  LEFT JOIN dtb_classcategory AS T4
-         ON T3.classcategory_id2 = T4.classcategory_id) AS T5
-  LEFT JOIN dtb_products AS T6
-         ON product_id_sub = T6.product_id;
-
-CREATE VIEW vw_category_count AS
-     SELECT T1.category_id,
-            T1.category_name,
-            T1.parent_category_id,
-            T1.level,
-            T1.rank,
-            T2.product_count
-       FROM dtb_category AS T1
-  LEFT JOIN dtb_category_total_count AS T2
-         ON T1.category_id = T2.category_id
-;
-
-CREATE VIEW vw_download_class as
-     SELECT
-          p.product_id AS product_id,
-          p.down_realfilename AS down_realfilename,
-          p.down_filename AS down_filename,
-          od.order_id AS order_id,
-          o.customer_id AS customer_id,
-          o.commit_date AS commit_date,
-          o.status AS status
-     FROM
-          dtb_products p,
-          dtb_order_detail od,
-          dtb_order o
-     WHERE
-          p.product_id = od.product_id AND
-          od.order_id = o.order_id;
Index: /branches/version-2_5-dev/html/install/sql/insert_data.sql
===================================================================
--- /branches/version-2_5-dev/html/install/sql/insert_data.sql	(revision 18791)
+++ /branches/version-2_5-dev/html/install/sql/insert_data.sql	(revision 18815)
@@ -37,6 +37,6 @@
 INSERT INTO dtb_category_total_count (category_id, product_count, create_date) VALUES (4, 1, CURRENT_TIMESTAMP);
 
-INSERT INTO dtb_class (class_id, name, status, rank, creator_id, create_date, update_date, del_flg, product_id) VALUES (1, '味', NULL, 1, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0, NULL);
-INSERT INTO dtb_class (class_id, name, status, rank, creator_id, create_date, update_date, del_flg, product_id) VALUES (2, '大きさ', NULL, 2, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0, NULL);
+INSERT INTO dtb_class (class_id, name, status, rank, creator_id, create_date, update_date, del_flg) VALUES (1, '味', NULL, 1, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+INSERT INTO dtb_class (class_id, name, status, rank, creator_id, create_date, update_date, del_flg) VALUES (2, '大きさ', NULL, 2, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
 
 INSERT INTO dtb_classcategory (classcategory_id, name, class_id, status, rank, creator_id, create_date, update_date, del_flg) VALUES (1, 'バニラ', 1, NULL, 1, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
@@ -392,17 +392,38 @@
 INSERT INTO dtb_product_categories (product_id, category_id, rank) VALUES (2, 4, 1);
 
-INSERT INTO dtb_products (product_id, name, deliv_fee, sale_limit, category_id, maker_id, rank, status, product_flag, point_rate, comment1, comment2, comment3, comment4, comment5, comment6, note, file1, file2, file3, file4, file5, file6, main_list_comment, main_list_image, main_comment, main_image, main_large_image, sub_title1, sub_comment1, sub_image1, sub_large_image1, sub_title2, sub_comment2, sub_image2, sub_large_image2, sub_title3, sub_comment3, sub_image3, sub_large_image3, sub_title4, sub_comment4, sub_image4, sub_large_image4, sub_title5, sub_comment5, sub_image5, sub_large_image5, sub_title6, sub_comment6, sub_image6, sub_large_image6, del_flg, creator_id, create_date, update_date, deliv_date_id, down, down_filename, down_realfilename) VALUES (1, 'アイスクリーム', NULL, NULL, 5, NULL, 1, 1, '10010', 10, NULL, NULL, 'アイス,バニラ,チョコ,抹茶', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '暑い夏にどうぞ。', '08311201_44f65122ee5fe.jpg', '冷たいものはいかがですか？', '08311202_44f6515906a41.jpg', '08311203_44f651959bcb5.jpg', NULL, '<b>おいしいよ<b>', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 2, 1, NULL, NULL);
-INSERT INTO dtb_products (product_id, name, deliv_fee, sale_limit, category_id, maker_id, rank, status, product_flag, point_rate, comment1, comment2, comment3, comment4, comment5, comment6, note, file1, file2, file3, file4, file5, file6, main_list_comment, main_list_image, main_comment, main_image, main_large_image, sub_title1, sub_comment1, sub_image1, sub_large_image1, sub_title2, sub_comment2, sub_image2, sub_large_image2, sub_title3, sub_comment3, sub_image3, sub_large_image3, sub_title4, sub_comment4, sub_image4, sub_large_image4, sub_title5, sub_comment5, sub_image5, sub_large_image5, sub_title6, sub_comment6, sub_image6, sub_large_image6, del_flg, creator_id, create_date, update_date, deliv_date_id, down, down_filename, down_realfilename) VALUES (2, 'おなべ', NULL, 5, NULL, NULL, 1, 1, '11001', 5, NULL, NULL, '鍋,なべ,ナベ', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '一人用からあります。', '08311311_44f661811fec0.jpg', 'たまには鍋でもどうでしょう。', '08311313_44f661dc649fb.jpg', '08311313_44f661e5698a6.jpg', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 3, 1, NULL, NULL);
-
-INSERT INTO dtb_products_class (product_class_id, product_id, classcategory_id1, classcategory_id2, product_code, stock, stock_unlimited, sale_limit, price01, price02, status, creator_id, create_date, update_date) VALUES (1, 1, 3, 6, 'ice-01', NULL, 1, NULL, 150, 120, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
-INSERT INTO dtb_products_class (product_class_id, product_id, classcategory_id1, classcategory_id2, product_code, stock, stock_unlimited, sale_limit, price01, price02, status, creator_id, create_date, update_date) VALUES (2, 1, 3, 5, 'ice-01', NULL, 1, NULL, 150, 120, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
-INSERT INTO dtb_products_class (product_class_id, product_id, classcategory_id1, classcategory_id2, product_code, stock, stock_unlimited, sale_limit, price01, price02, status, creator_id, create_date, update_date) VALUES (3, 1, 3, 4, 'ice-01', NULL, 1, NULL, 150, 120, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
-INSERT INTO dtb_products_class (product_class_id, product_id, classcategory_id1, classcategory_id2, product_code, stock, stock_unlimited, sale_limit, price01, price02, status, creator_id, create_date, update_date) VALUES (4, 1, 2, 6, 'ice-01', NULL, 1, NULL, 150, 120, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
-INSERT INTO dtb_products_class (product_class_id, product_id, classcategory_id1, classcategory_id2, product_code, stock, stock_unlimited, sale_limit, price01, price02, status, creator_id, create_date, update_date) VALUES (5, 1, 2, 5, 'ice-01', NULL, 1, NULL, 150, 120, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
-INSERT INTO dtb_products_class (product_class_id, product_id, classcategory_id1, classcategory_id2, product_code, stock, stock_unlimited, sale_limit, price01, price02, status, creator_id, create_date, update_date) VALUES (6, 1, 2, 4, 'ice-01', NULL, 1, NULL, 150, 120, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
-INSERT INTO dtb_products_class (product_class_id, product_id, classcategory_id1, classcategory_id2, product_code, stock, stock_unlimited, sale_limit, price01, price02, status, creator_id, create_date, update_date) VALUES (7, 1, 1, 6, 'ice-01', NULL, 1, NULL, 150, 120, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
-INSERT INTO dtb_products_class (product_class_id, product_id, classcategory_id1, classcategory_id2, product_code, stock, stock_unlimited, sale_limit, price01, price02, status, creator_id, create_date, update_date) VALUES (8, 1, 1, 5, 'ice-01', NULL, 1, NULL, 150, 120, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
-INSERT INTO dtb_products_class (product_class_id, product_id, classcategory_id1, classcategory_id2, product_code, stock, stock_unlimited, sale_limit, price01, price02, status, creator_id, create_date, update_date) VALUES (9, 1, 1, 4, 'ice-01', NULL, 1, NULL, 150, 120, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
-INSERT INTO dtb_products_class (product_class_id, product_id, classcategory_id1, classcategory_id2, product_code, stock, stock_unlimited, sale_limit, price01, price02, status, creator_id, create_date, update_date) VALUES (10, 2, 0, 0, 'nabe-01', 100, 0, NULL, 1700, 1650, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
+INSERT INTO dtb_products (product_id, name, maker_id, rank, status, comment1, comment2, comment3, comment4, comment5, comment6, note, file1, file2, file3, file4, file5, file6, main_list_comment, main_list_image, main_comment, main_image, main_large_image, sub_title1, sub_comment1, sub_image1, sub_large_image1, sub_title2, sub_comment2, sub_image2, sub_large_image2, sub_title3, sub_comment3, sub_image3, sub_large_image3, sub_title4, sub_comment4, sub_image4, sub_large_image4, sub_title5, sub_comment5, sub_image5, sub_large_image5, sub_title6, sub_comment6, sub_image6, sub_large_image6, del_flg, creator_id, create_date, update_date, deliv_date_id) VALUES (1, 'アイスクリーム', NULL, 1, 1, NULL, NULL, 'アイス,バニラ,チョコ,抹茶', NULL, 'NULL', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'NULL', '暑い夏にどうぞ。', '08311201_44f65122ee5fe.jpg', '冷たいものはいかがですか?', '08311202_44f6515906a41.jpg', '08311203_44f651959bcb5.jpg', '', '<b>おいしいよ<b>', 'NULL', NULL, 'NULL', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'NULL', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'NULL', NULL, NULL, NULL, 0, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 2);
+INSERT INTO dtb_products (product_id, name, maker_id, rank, status, comment1, comment2, comment3, comment4, comment5, comment6, note, file1, file2, file3, file4, file5, file6, main_list_comment, main_list_image, main_comment, main_image, main_large_image, sub_title1, sub_comment1, sub_image1, sub_large_image1, sub_title2, sub_comment2, sub_image2, sub_large_image2, sub_title3, sub_comment3, sub_image3, sub_large_image3, sub_title4, sub_comment4, sub_image4, sub_large_image4, sub_title5, sub_comment5, sub_image5, sub_large_image5, sub_title6, sub_comment6, sub_image6, sub_large_image6, del_flg, creator_id, create_date, update_date, deliv_date_id) VALUES (2, 'おなべ', NULL, 1, 1, NULL, NULL, '鍋,なべ,ナベ', NULL, 'NULL', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'NULL', '一人用からあります。', '08311311_44f661811fec0.jpg', 'たまには鍋でもどうでしょう。', '08311313_44f661dc649fb.jpg', '08311313_44f661e5698a6.jpg', '', 'NULL', 'NULL', NULL, 'NULL', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'NULL', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'NULL', NULL, NULL, NULL, 0, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 3);
+
+INSERT INTO dtb_products_class (product_class_id, product_id, class_combination_id, product_code, stock, stock_unlimited, sale_limit, sale_unlimited, price01, price02, deliv_fee, point_rate, status, creator_id, create_date, update_date, del_flg) VALUES(1, 1, 10, 'ice-01', NULL, 1, NULL, 0, 150, 120, NULL, 10, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+INSERT INTO dtb_products_class (product_class_id, product_id, class_combination_id, product_code, stock, stock_unlimited, sale_limit, sale_unlimited, price01, price02, deliv_fee, point_rate, status, creator_id, create_date, update_date, del_flg) VALUES(2, 1, 11, 'ice-01', NULL, 1, NULL, 0, 150, 120, NULL, 5, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+INSERT INTO dtb_products_class (product_class_id, product_id, class_combination_id, product_code, stock, stock_unlimited, sale_limit, sale_unlimited, price01, price02, deliv_fee, point_rate, status, creator_id, create_date, update_date, del_flg) VALUES(3, 1, 12, 'ice-01', NULL, 1, NULL, 0, 150, 120, NULL, NULL, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+INSERT INTO dtb_products_class (product_class_id, product_id, class_combination_id, product_code, stock, stock_unlimited, sale_limit, sale_unlimited, price01, price02, deliv_fee, point_rate, status, creator_id, create_date, update_date, del_flg) VALUES(4, 1, 13, 'ice-01', NULL, 1, NULL, 0, 150, 120, NULL, NULL, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+INSERT INTO dtb_products_class (product_class_id, product_id, class_combination_id, product_code, stock, stock_unlimited, sale_limit, sale_unlimited, price01, price02, deliv_fee, point_rate, status, creator_id, create_date, update_date, del_flg) VALUES(5, 1, 14, 'ice-01', NULL, 1, NULL, 0, 150, 120, NULL, NULL, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+INSERT INTO dtb_products_class (product_class_id, product_id, class_combination_id, product_code, stock, stock_unlimited, sale_limit, sale_unlimited, price01, price02, deliv_fee, point_rate, status, creator_id, create_date, update_date, del_flg) VALUES(6, 1, 15, 'ice-01', NULL, 1, NULL, 0, 150, 120, NULL, NULL, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+INSERT INTO dtb_products_class (product_class_id, product_id, class_combination_id, product_code, stock, stock_unlimited, sale_limit, sale_unlimited, price01, price02, deliv_fee, point_rate, status, creator_id, create_date, update_date, del_flg) VALUES(7, 1, 16, 'ice-01', NULL, 1, NULL, 0, 150, 120, NULL, NULL, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+INSERT INTO dtb_products_class (product_class_id, product_id, class_combination_id, product_code, stock, stock_unlimited, sale_limit, sale_unlimited, price01, price02, deliv_fee, point_rate, status, creator_id, create_date, update_date, del_flg) VALUES(8, 1, 17, 'ice-01', NULL, 1, NULL, 0, 150, 120, NULL, NULL, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+INSERT INTO dtb_products_class (product_class_id, product_id, class_combination_id, product_code, stock, stock_unlimited, sale_limit, sale_unlimited, price01, price02, deliv_fee, point_rate, status, creator_id, create_date, update_date, del_flg) VALUES(9, 1, 18, 'ice-01', NULL, 1, NULL, 0, 150, 120, NULL, NULL, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+INSERT INTO dtb_products_class (product_class_id, product_id, class_combination_id, product_code, stock, stock_unlimited, sale_limit, sale_unlimited, price01, price02, deliv_fee, point_rate, status, creator_id, create_date, update_date, del_flg) VALUES(10, 2, NULL, 'nabe-01', 100, 0, 5, 0, 1700, 1650, NULL, NULL, NULL, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0);
+
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(1, NULL, 3, 1);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(2, NULL, 3, 1);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(3, NULL, 3, 1);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(4, NULL, 2, 1);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(5, NULL, 2, 1);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(6, NULL, 2, 1);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(7, NULL, 1, 1);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(8, NULL, 1, 1);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(9, NULL, 1, 1);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(10, 1, 6, 2);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(11, 2, 5, 2);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(12, 3, 4, 2);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(13, 4, 6, 2);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(14, 5, 5, 2);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(15, 6, 4, 2);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(16, 7, 6, 2);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(17, 8, 5, 2);
+INSERT INTO dtb_class_combination (class_combination_id, parent_class_combination_id, classcategory_id, level) VALUES(18, 9, 4, 2);
+
+INSERT INTO dtb_product_status (product_status_id, product_id, creator_id, create_date, update_date, del_flg) VALUES (1, 1, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 2);
 
 INSERT INTO dtb_recommend_products (product_id, recommend_product_id, rank, comment, status, creator_id, create_date, update_date) VALUES (2, 1, 4, 'お口直しに。', 0, 2, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
Index: /branches/version-2_5-dev/html/install/sql/drop_view.sql
===================================================================
--- /branches/version-2_5-dev/html/install/sql/drop_view.sql	(revision 18787)
+++ /branches/version-2_5-dev/html/install/sql/drop_view.sql	(revision 18815)
@@ -1,8 +1,2 @@
-DROP VIEW vw_category_count;
-DROP VIEW vw_product_class;
 DROP VIEW vw_products_allclass;
 DROP VIEW vw_products_allclass_detail;
-DROP VIEW vw_products_nonclass;
-DROP VIEW vw_cross_products_class;
-DROP VIEW vw_cross_class;
-DROP VIEW vw_download_class;
Index: /branches/version-2_5-dev/html/install/sql/create_table_mysql.sql
===================================================================
--- /branches/version-2_5-dev/html/install/sql/create_table_mysql.sql	(revision 18791)
+++ /branches/version-2_5-dev/html/install/sql/create_table_mysql.sql	(revision 18815)
@@ -256,13 +256,8 @@
 CREATE TABLE dtb_products (
     product_id int  NOT NULL,
-    name text,
-    deliv_fee numeric,
-    sale_limit numeric,
-    category_id int,
+    name text NOT NULL,
     maker_id int,
     rank int,
     status smallint NOT NULL DEFAULT 2,
-    product_flag text,
-    point_rate numeric,
     comment1 text,
     comment2 text,
@@ -312,5 +307,5 @@
     update_date datetime,
     deliv_date_id int,
-    down smallint NOT NULL ,
+    down smallint NOT NULL DEFAULT 0,
     down_filename text,
     down_realfilename text,
@@ -321,16 +316,19 @@
     product_class_id int  NOT NULL,
     product_id int NOT NULL,
-    classcategory_id1 int NOT NULL DEFAULT 0,
-    classcategory_id2 int NOT NULL DEFAULT 0,
+    class_combination_id int,
     product_code text,
     stock numeric,
     stock_unlimited smallint NOT NULL DEFAULT 0,
     sale_limit numeric,
+    sale_unlimited smallint NOT NULL DEFAULT 0,
     price01 numeric,
     price02 numeric,
+    deliv_fee numeric,
+    point_rate numeric,
     status smallint,
     creator_id int NOT NULL,
     create_date datetime NOT NULL,
     update_date datetime,
+    del_flg smallint NOT NULL DEFAULT 0,
     PRIMARY KEY (product_class_id)
 ) TYPE=InnoDB;
@@ -345,5 +343,4 @@
     update_date datetime,
     del_flg smallint NOT NULL DEFAULT 0,
-    product_id int,
     PRIMARY KEY (class_id)
 ) TYPE=InnoDB;
@@ -360,4 +357,12 @@
     del_flg smallint NOT NULL DEFAULT 0,
     PRIMARY KEY (classcategory_id)
+) TYPE=InnoDB;
+
+CREATE TABLE dtb_class_combination (
+    class_combination_id int NOT NULL,
+    parent_class_combination_id int,
+    classcategory_id int NOT NULL,
+    level int,
+    PRIMARY KEY(class_combination_id)
 ) TYPE=InnoDB;
 
@@ -380,4 +385,14 @@
     rank int NOT NULL,
     PRIMARY KEY(product_id, category_id)
+) TYPE=InnoDB;
+
+CREATE TABLE dtb_product_status (
+    product_status_id smallint NOT NULL,
+    product_id int NOT NULL,
+    creator_id int NOT NULL,
+    create_date datetime NOT NULL,
+    update_date datetime,
+    del_flg smallint NOT NULL DEFAULT 0,
+    PRIMARY KEY(product_status_id, product_id)
 ) TYPE=InnoDB;
 
Index: /branches/version-2_5-dev/html/install/sql/create_table_pgsql.sql
===================================================================
--- /branches/version-2_5-dev/html/install/sql/create_table_pgsql.sql	(revision 18791)
+++ /branches/version-2_5-dev/html/install/sql/create_table_pgsql.sql	(revision 18815)
@@ -256,13 +256,8 @@
 CREATE TABLE dtb_products (
     product_id int NOT NULL,
-    name text,
-    deliv_fee numeric,
-    sale_limit numeric,
-    category_id int,
+    name text NOT NULL,
     maker_id int,
     rank int,
     status smallint NOT NULL DEFAULT 2,
-    product_flag text,
-    point_rate numeric,
     comment1 text,
     comment2 text,
@@ -312,5 +307,5 @@
     update_date timestamp,
     deliv_date_id int,
-    down int2 NOT NULL ,
+    down smallint NOT NULL DEFAULT 0,
     down_filename text,
     down_realfilename text,
@@ -321,16 +316,19 @@
     product_class_id int NOT NULL,
     product_id int NOT NULL,
-    classcategory_id1 int NOT NULL DEFAULT 0,
-    classcategory_id2 int NOT NULL DEFAULT 0,
+    class_combination_id int,
     product_code text,
     stock numeric,
     stock_unlimited smallint NOT NULL DEFAULT 0,
     sale_limit numeric,
+    sale_unlimited smallint NOT NULL DEFAULT 0,
     price01 numeric,
     price02 numeric,
+    deliv_fee numeric,
+    point_rate numeric,
     status smallint,
     creator_id int NOT NULL,
     create_date timestamp NOT NULL DEFAULT now(),
     update_date timestamp,
+    del_flg smallint NOT NULL DEFAULT 0,
     PRIMARY KEY (product_class_id)
 );
@@ -345,5 +343,4 @@
     update_date timestamp,
     del_flg smallint NOT NULL DEFAULT 0,
-    product_id int,
     PRIMARY KEY (class_id)
 );
@@ -360,4 +357,12 @@
     del_flg smallint NOT NULL DEFAULT 0,
     PRIMARY KEY (classcategory_id)
+);
+
+CREATE TABLE dtb_class_combination (
+    class_combination_id int NOT NULL,
+    parent_class_combination_id int,
+    classcategory_id int NOT NULL,
+    level int,
+    PRIMARY KEY (class_combination_id)
 );
 
@@ -381,4 +386,15 @@
     PRIMARY KEY(product_id, category_id)
 );
+
+CREATE TABLE dtb_product_status (
+    product_status_id smallint NOT NULL,
+    product_id int NOT NULL,
+    creator_id int NOT NULL,
+    create_date timestamp NOT NULL DEFAULT now(),
+    update_date timestamp,
+    del_flg smallint NOT NULL DEFAULT 0,
+    PRIMARY KEY (product_status_id, product_id)
+);
+
 
 CREATE TABLE dtb_bat_order_daily (
Index: /branches/version-2_5-dev/html/install/sql/drop_table.sql
===================================================================
--- /branches/version-2_5-dev/html/install/sql/drop_table.sql	(revision 18791)
+++ /branches/version-2_5-dev/html/install/sql/drop_table.sql	(revision 18815)
@@ -13,6 +13,8 @@
 DROP TABLE dtb_products;
 DROP TABLE dtb_products_class;
+DROP TABLE dtb_product_status;
 DROP TABLE dtb_class;
 DROP TABLE dtb_classcategory;
+DROP TABLE dtb_class_combination;
 DROP TABLE dtb_category;
 DROP TABLE dtb_product_categories;
Index: /branches/version-2_5-dev/html/install/index.php
===================================================================
--- /branches/version-2_5-dev/html/install/index.php	(revision 18794)
+++ /branches/version-2_5-dev/html/install/index.php	(revision 18815)
@@ -972,4 +972,5 @@
                  array("dtb_products_class", "product_class_id"),
                  array("dtb_products", "product_id"),
+                 array("dtb_class_combination", "class_combination_id"),
                  array("dtb_review", "review_id"),
                  array("dtb_send_history", "send_id"),
