Index: /branches/version-2_13_3/data/class/helper/SC_Helper_Category.php
===================================================================
--- /branches/version-2_13_3/data/class/helper/SC_Helper_Category.php	(revision 23649)
+++ /branches/version-2_13_3/data/class/helper/SC_Helper_Category.php	(revision 23650)
@@ -67,16 +67,10 @@
      * カテゴリー一覧の取得.
      *
-     * @param bool $cid_to_key 配列のキーをカテゴリーIDにする場合はtrue
-     * @param bool $reset スタティック変数をリセットする場合はtrue
+     * @param  boolean $cid_to_key 配列のキーをカテゴリーIDにする場合はtrue
      * @return array   カテゴリー一覧の配列
      */
-    public function getList($cid_to_key = FALSE, $reset = FALSE)
+    public function getList($cid_to_key = FALSE)
     {
         static $arrCategory = array(), $cidIsKey = array();
-
-        if ($reset) {
-            $arrCategory = array();
-            $cidIsKey = array();
-        }
 
         if (!isset($arrCategory[$this->count_check])) {
@@ -111,17 +105,11 @@
      * カテゴリーツリーの取得.
      *
-     * @param bool $reset スタティック変数をリセットする場合はtrue
-     * @return array
+     * @return type
      */
-    public function getTree($reset = false)
+    public function getTree()
     {
         static $arrTree = array();
-
-        if ($reset) {
-            $arrTree = array();
-        }
-
         if (!isset($arrTree[$this->count_check])) {
-            $arrList = $this->getList(false, $reset);
+            $arrList = $this->getList();
             $arrTree[$this->count_check] = SC_Utils_Ex::buildTree('category_id', 'parent_category_id', LEVEL_MAX, $arrList);
         }
@@ -151,83 +139,20 @@
      * @return array
      */
-    public function getTreeBranch($category_id)
-    {
+    public function getTreeBranch($category_id) {
         $arrTree = $this->getTree();
         $arrTrail = $this->getTreeTrail($category_id, true);
 
-        // 指定カテゴリーがルートの場合は、ツリーをそのまま返す.
-        if ($category_id == 0) {
-            return $arrTree;
-        } else {
-            // ルートから指定カテゴリーまでたどる.
-            foreach ($arrTrail as $parent_id) {
-                $nextTree = array();
-                foreach ($arrTree as $branch) {
-                    if ($branch['category_id'] == $parent_id && isset($branch['children'])) {
-                        $nextTree = $branch['children'];
-                    }
+        // ルートから指定カテゴリーまでたどる.
+        foreach ($arrTrail as $parent_id) {
+            $nextTree = array();
+            foreach ($arrTree as $branch) {
+                if ($branch['category_id'] == $parent_id && isset($branch['children'])) {
+                    $nextTree = $branch['children'];
                 }
-                $arrTree = $nextTree;
             }
-            return $arrTree;
-        }
-    }
-
-    /**
-     * カテゴリーの登録.
-     *
-     * @param array $data
-     * @return void
-     */
-    public function save($data)
-    {
-        $objQuery =& SC_Query_Ex::getSingletonInstance();
-
-        $category_id = $data['category_id'];
-        $query = array('update_date' => 'CURRENT_TIMESTAMP');
-        $objQuery->begin();
-
-        if ($category_id == '') {
-            // 新規登録
-            $parent_category_id = $data['parent_category_id'];
-            $rank = null;
-            if ($parent_category_id == 0) {
-                // ROOT階層で最大のランクを取得する。
-                $where = 'parent_category_id = ?';
-                $rank = $objQuery->max('rank', 'dtb_category', $where, array($parent_category_id)) + 1;
-            } else {
-                // 親のランクを自分のランクとする。
-                $where = 'category_id = ?';
-                $rank = $objQuery->get('rank', 'dtb_category', $where, array($parent_category_id));
-                // 追加レコードのランク以上のレコードを一つあげる。
-                $where = 'rank >= ?';
-                $arrRawSql = array(
-                    'rank' => '(rank + 1)',
-                );
-                $objQuery->update('dtb_category', array(), $where, array($rank), $arrRawSql);
-            }
-
-            $where = 'category_id = ?';
-            // 自分のレベルを取得する(親のレベル + 1)
-            $level = $objQuery->get('level', 'dtb_category', $where, array($parent_category_id)) + 1;
-
-            $query['category_id'] = $objQuery->nextVal('dtb_category_category_id');
-            $query['category_name'] = $data['category_name'];
-            $query['parent_category_id'] = $data['parent_category_id'];
-            $query['create_date'] = 'CURRENT_TIMESTAMP';
-            $query['creator_id']  = $_SESSION['member_id'];
-            $query['rank']        = $rank;
-            $query['level']       = $level;
-
-            $objQuery->insert('dtb_category', $query);
-        } else {
-            // 既存編集
-            $query['parent_category_id'] = $data['parent_category_id'];
-            $query['category_name'] = $data['category_name'];
-            $where = 'category_id = ?';
-            $objQuery->update('dtb_category', $query, $where, array($category_id));
+            $arrTree = $nextTree;
         }
 
-        $objQuery->commit();
+        return $arrTree;
     }
 
@@ -238,158 +163,8 @@
      * @return void
      */
-    public function delete($category_id)
-    {
+    public function delete($category_id) {
         $objDb = new SC_Helper_DB_Ex();
         // ランク付きレコードの削除(※処理負荷を考慮してレコードごと削除する。)
         $objDb->sfDeleteRankRecord('dtb_category', 'category_id', $category_id, '', true);
-    }
-
-    /**
-     * カテゴリーの表示順をひとつ上げる.
-     *
-     * @param int $category_id カテゴリーID
-     * @return void
-     */
-    public function rankUp($category_id)
-    {
-        $objQuery =& SC_Query_Ex::getSingletonInstance();
-        $objQuery->begin();
-        $up_id = $this->getNeighborRankId('upper', $category_id);
-        if ($up_id != '') {
-            // 上のグループのrankから減算する数
-            $my_count = $this->countAllBranches($category_id);
-            // 自分のグループのrankに加算する数
-            $up_count = $this->countAllBranches($up_id);
-            if ($my_count > 0 && $up_count > 0) {
-                // 自分のグループに加算
-                $this->raiseBranchRank($objQuery, $category_id, $up_count);
-                // 上のグループから減算
-                $this->reduceBranchRank($objQuery, $up_id, $my_count);
-            }
-        }
-        $objQuery->commit();
-    }
-
-    /**
-     * カテゴリーの表示順をひとつ下げる.
-     *
-     * @param int $category_id カテゴリーID
-     * @return void
-     */
-    public function rankDown($category_id)
-    {
-        $objQuery =& SC_Query_Ex::getSingletonInstance();
-        $objQuery->begin();
-        $down_id = $this->getNeighborRankId('lower', $category_id);
-        if ($down_id != '') {
-            // 下のグループのrankに加算する数
-            $my_count = $this->countAllBranches($category_id);
-            // 自分のグループのrankから減算する数
-            $down_count = $this->countAllBranches($down_id);
-            if ($my_count > 0 && $down_count > 0) {
-                // 自分のグループから減算
-                $this->raiseBranchRank($objQuery, $down_id, $my_count);
-                // 下のグループに加算
-                $this->reduceBranchRank($objQuery, $category_id, $down_count);
-            }
-        }
-        $objQuery->commit();
-    }
-
-    /**
-     * 並びがとなりのIDを取得する。
-     *
-     * @param string $side 上 upper か下 down か
-     * @param int $category_id カテゴリーID
-     * @return int
-     */
-    private function getNeighborRankId($side, $category_id)
-    {
-        $arrCategory = $this->get($category_id);
-        $parent_id = $arrCategory['parent_category_id'];
-
-        if ($parent_id == 0) {
-            $arrBrother = $this->getTree();
-        } else {
-            $arrBrother = $this->getTreeBranch($parent_id);
-        }
-
-        // 全ての子を取得する。
-        $max = count($arrBrother);
-        $upper_id = '';
-        for ($cnt = 0; $cnt < $max; $cnt++) {
-            if ($arrBrother[$cnt]['category_id'] == $category_id) {
-                if ($side == 'upper') {
-                    $index = $cnt - 1;
-                } else {
-                    $index = $cnt + 1;
-                }
-                $upper_id = $arrBrother[$index]['category_id'];
-                break;
-            }
-        }
-
-        return $upper_id;
-    }
-
-    /**
-     * 指定カテゴリーを含めた子孫カテゴリーの数を取得する.
-     *
-     * @param int $category_id カテゴリーID
-     * @return int
-     */
-    private function countAllBranches($category_id)
-    {
-        $objDb = new SC_Helper_DB_Ex();
-        // 子ID一覧を取得
-        $arrRet = $objDb->sfGetChildrenArray('dtb_category', 'parent_category_id', 'category_id', $category_id);
-
-        return count($arrRet);
-    }
-
-    /**
-     * 子孫カテゴリーの表示順を一括して上げる.
-     *
-     * @param SC_Query $objQuery
-     * @param int $category_id
-     * @param int $count
-     * @return array|bool
-     */
-    private function raiseBranchRank(SC_Query $objQuery, $category_id, $count)
-    {
-        $table = 'dtb_category';
-        $objDb = new SC_Helper_DB_Ex();
-        // 子ID一覧を取得
-        $arrRet = $objDb->sfGetChildrenArray($table, 'parent_category_id', 'category_id', $category_id);
-        $line = SC_Utils_Ex::sfGetCommaList($arrRet);
-        $where = "category_id IN ($line) AND del_flg = 0";
-        $arrRawVal = array(
-            'rank' => "(rank + $count)",
-        );
-
-        return $objQuery->update($table, array(), $where, array(), $arrRawVal);
-    }
-
-    /**
-     * 子孫カテゴリーの表示順を一括して下げる.
-     *
-     * @param SC_Query $objQuery
-     * @param int $category_id
-     * @param int $count
-     * @return array|bool
-     */
-    private function reduceBranchRank(SC_Query $objQuery, $category_id, $count)
-    {
-        $table = 'dtb_category';
-        $objDb = new SC_Helper_DB_Ex();
-        // 子ID一覧を取得
-        $arrRet = $objDb->sfGetChildrenArray($table, 'parent_category_id', 'category_id', $category_id);
-        $line = SC_Utils_Ex::sfGetCommaList($arrRet);
-        $where = "category_id IN ($line) AND del_flg = 0";
-        $arrRawVal = array(
-            'rank' => "(rank - $count)",
-        );
-
-        return $objQuery->update($table, array(), $where, array(), $arrRawVal);
     }
 
Index: /branches/version-2_13_3/data/class/pages/admin/products/LC_Page_Admin_Products_Category.php
===================================================================
--- /branches/version-2_13_3/data/class/pages/admin/products/LC_Page_Admin_Products_Category.php	(revision 23605)
+++ /branches/version-2_13_3/data/class/pages/admin/products/LC_Page_Admin_Products_Category.php	(revision 23650)
@@ -172,9 +172,9 @@
         // 親カテゴリIDの保持
         $this->arrForm['parent_category_id'] = $parent_category_id;
+        // カテゴリ一覧を取得
+        $this->arrList = $this->findCategoiesByParentCategoryId($parent_category_id);
         // カテゴリツリーを取得
-        $this->arrTree = $objCategory->getTree(true);
+        $this->arrTree = $objCategory->getTree();
         $this->arrParentID = $objCategory->getTreeTrail($parent_category_id);
-        // カテゴリ一覧を取得
-        $this->arrList = $objCategory->getTreeBranch($parent_category_id);
         // ぱんくずの生成
         $arrBread = $objCategory->getTreeTrail($this->arrForm['parent_category_id'], FALSE);
@@ -249,12 +249,25 @@
     public function doEdit(&$objFormParam)
     {
+        $category_id = $objFormParam->getValue('category_id');
+
+        // 追加か
+        $add = strlen($category_id) === 0;
+
         // エラーチェック
-        $this->arrErr = $this->checkError($objFormParam);
+        $this->arrErr = $this->checkError($objFormParam, $add);
 
         // エラーがない場合、追加・更新処理
         if (empty($this->arrErr)) {
             $arrCategory = $objFormParam->getDbArray();
-            $objCategory = new SC_Helper_Category_Ex();
-            $objCategory->save($arrCategory);
+
+            // 追加
+            if ($add) {
+                $this->registerCategory($arrCategory);
+            }
+            // 更新
+            else {
+                unset($arrCategory['category_id']);
+                $this->updateCategory($category_id, $arrCategory);
+            }
         // エラーがある場合、入力値の再表示
         } else {
@@ -267,9 +280,10 @@
      *
      * @param  SC_FormParam $objFormParam
-     * @return array
-     */
-    public function checkError(&$objFormParam)
-    {
-        $objCategory = new SC_Helper_Category_Ex();
+     * @param  boolean      $add          追加か
+     * @return void
+     */
+    public function checkError(&$objFormParam, $add)
+    {
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
 
         // 入力項目チェック
@@ -284,7 +298,8 @@
 
         // 追加の場合に固有のチェック
-        if (!$category_id) {
+        if ($add) {
             // 登録数上限チェック
-            $count = count($objCategory->getList());
+            $where = 'del_flg = 0';
+            $count = $objQuery->count('dtb_category', $where);
             if ($count >= CATEGORY_MAX) {
                 $arrErr['category_name'] = '※ カテゴリの登録最大数を超えました。<br/>';
@@ -294,6 +309,5 @@
 
             // 階層上限チェック
-            $arrParent = $objCategory->get($parent_category_id);
-            if ($arrParent['level'] >= LEVEL_MAX) {
+            if ($this->isOverLevel($parent_category_id)) {
                 $arrErr['category_name'] = '※ ' . LEVEL_MAX . '階層以上の登録はできません。<br/>';
 
@@ -303,11 +317,14 @@
 
         // 重複チェック
-        $exists = false;
-        $arrBrother = $objCategory->getTreeBranch($parent_category_id);
-        foreach ($arrBrother as $brother) {
-            if ($brother['category_name'] == $category_name && $brother['category_id'] != $category_id) {
-                $exists = true;
-            }
-        }
+        $arrWhereVal = array();
+        $where = 'del_flg = 0 AND parent_category_id = ? AND category_name = ?';
+        $arrWhereVal[] = $parent_category_id;
+        $arrWhereVal[] = $category_name;
+        // 更新の場合、抽出対象から自己を除外する
+        if (!$add) {
+            $where .= ' AND category_id <> ?';
+            $arrWhereVal[] = $category_id;
+        }
+        $exists = $objQuery->exists('dtb_category', $where, $arrWhereVal);
         if ($exists) {
             $arrErr['category_name'] = '※ 既に同じ内容の登録が存在します。<br/>';
@@ -327,7 +344,22 @@
     public function doUp(&$objFormParam)
     {
-        $objCategory = new SC_Helper_Category_Ex(false);
         $category_id = $objFormParam->getValue('category_id');
-        $objCategory->rankUp($category_id);
+
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+        $objQuery->begin();
+        $up_id = $this->lfGetUpRankID($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $category_id);
+        if ($up_id != '') {
+            // 上のグループのrankから減算する数
+            $my_count = $this->lfCountChilds($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $category_id);
+                // 自分のグループのrankに加算する数
+                $up_count = $this->lfCountChilds($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $up_id);
+                if ($my_count > 0 && $up_count > 0) {
+                    // 自分のグループに加算
+                    $this->lfUpRankChilds($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $category_id, $up_count);
+                    // 上のグループから減算
+                    $this->lfDownRankChilds($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $up_id, $my_count);
+                }
+        }
+        $objQuery->commit();
     }
 
@@ -340,7 +372,22 @@
     public function doDown(&$objFormParam)
     {
-        $objCategory = new SC_Helper_Category_Ex(false);
         $category_id = $objFormParam->getValue('category_id');
-        $objCategory->rankDown($category_id);
+
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+        $objQuery->begin();
+        $down_id = $this->lfGetDownRankID($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $category_id);
+        if ($down_id != '') {
+            // 下のグループのrankに加算する数
+            $my_count = $this->lfCountChilds($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $category_id);
+            // 自分のグループのrankから減算する数
+            $down_count = $this->lfCountChilds($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $down_id);
+            if ($my_count > 0 && $down_count > 0) {
+                // 自分のグループから減算
+                $this->lfUpRankChilds($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $down_id, $my_count);
+                // 下のグループに加算
+                $this->lfDownRankChilds($objQuery, 'dtb_category', 'parent_category_id', 'category_id', $category_id, $down_count);
+            }
+        }
+        $objQuery->commit();
     }
 
@@ -359,9 +406,151 @@
 
     /**
-     * @param SC_Query $objQuery
-     * @param string $table
-     * @param string $pid_name
-     * @param string $id_name
-     */
+     * 親カテゴリIDでカテゴリを検索する.
+     *
+     * - 表示順の降順でソートする
+     * - 有効なカテゴリを返す(del_flag = 0)
+     *
+     * @param  SC_Query $objQuery
+     * @param  int      $parent_category_id 親カテゴリID
+     * @return array    カテゴリの配列
+     */
+    public function findCategoiesByParentCategoryId($parent_category_id)
+    {
+        if (!$parent_category_id) {
+            $parent_category_id = 0;
+        }
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+        $col   = 'category_id, category_name, level, rank';
+        $where = 'del_flg = 0 AND parent_category_id = ?';
+        $objQuery->setOption('ORDER BY rank DESC');
+
+        return $objQuery->select($col, 'dtb_category', $where, array($parent_category_id));
+    }
+
+    /**
+     * カテゴリを更新する
+     *
+     * @param  SC_FormParam $objFormParam SC_FormParam インスタンス
+     * @return void
+     */
+    public function updateCategory($category_id, $arrCategory)
+    {
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+
+        $arrCategory['update_date']   = 'CURRENT_TIMESTAMP';
+
+        $objQuery->begin();
+        $where = 'category_id = ?';
+        $objQuery->update('dtb_category', $arrCategory, $where, array($category_id));
+        $objQuery->commit();
+    }
+
+    /**
+     * カテゴリを登録する
+     *
+     * @param  SC_FormParam $objFormParam SC_FormParam インスタンス
+     * @return void
+     */
+    public function registerCategory($arrCategory)
+    {
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+
+        $parent_category_id = $arrCategory['parent_category_id'];
+
+        $objQuery->begin();
+
+        $rank = null;
+        if ($parent_category_id == 0) {
+            // ROOT階層で最大のランクを取得する。
+            $where = 'parent_category_id = ?';
+            $rank = $objQuery->max('rank', 'dtb_category', $where, array($parent_category_id)) + 1;
+        } else {
+            // 親のランクを自分のランクとする。
+            $where = 'category_id = ?';
+            $rank = $objQuery->get('rank', 'dtb_category', $where, array($parent_category_id));
+            // 追加レコードのランク以上のレコードを一つあげる。
+            $where = 'rank >= ?';
+            $arrRawSql = array(
+                'rank' => '(rank + 1)',
+            );
+            $objQuery->update('dtb_category', array(), $where, array($rank), $arrRawSql);
+        }
+
+        $where = 'category_id = ?';
+        // 自分のレベルを取得する(親のレベル + 1)
+        $level = $objQuery->get('level', 'dtb_category', $where, array($parent_category_id)) + 1;
+
+        $arrCategory['create_date'] = 'CURRENT_TIMESTAMP';
+        $arrCategory['update_date'] = 'CURRENT_TIMESTAMP';
+        $arrCategory['creator_id']  = $_SESSION['member_id'];
+        $arrCategory['rank']        = $rank;
+        $arrCategory['level']       = $level;
+        $arrCategory['category_id'] = $objQuery->nextVal('dtb_category_category_id');
+
+        $objQuery->insert('dtb_category', $arrCategory);
+
+        $objQuery->commit();    // トランザクションの終了
+    }
+
+    /**
+     * カテゴリの階層が上限を超えているかを判定する
+     *
+     * @param integer 親カテゴリID
+     * @param 超えている場合 true
+     */
+    public function isOverLevel($parent_category_id)
+    {
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+        $level = $objQuery->get('level', 'dtb_category', 'category_id = ?', array($parent_category_id));
+
+        return $level >= LEVEL_MAX;
+    }
+
+    // 並びが1つ下のIDを取得する。
+    public function lfGetDownRankID($objQuery, $table, $pid_name, $id_name, $id)
+    {
+        // 親IDを取得する。
+        $col = "$pid_name";
+        $where = "$id_name = ?";
+        $pid = $objQuery->get($col, $table, $where, $id);
+        // 全ての子を取得する。
+        $col = "$id_name";
+        $where = "del_flg = 0 AND $pid_name = ? ORDER BY rank DESC";
+        $arrRet = $objQuery->select($col, $table, $where, array($pid));
+        $max = count($arrRet);
+        $down_id = '';
+        for ($cnt = 0; $cnt < $max; $cnt++) {
+            if ($arrRet[$cnt][$id_name] == $id) {
+                $down_id = $arrRet[($cnt + 1)][$id_name];
+                break;
+            }
+        }
+
+        return $down_id;
+    }
+
+    // 並びが1つ上のIDを取得する。
+    public function lfGetUpRankID($objQuery, $table, $pid_name, $id_name, $id)
+    {
+        // 親IDを取得する。
+        $col = "$pid_name";
+        $where = "$id_name = ?";
+        $pid = $objQuery->get($col, $table, $where, $id);
+        // 全ての子を取得する。
+        $col = "$id_name";
+        $where = "del_flg = 0 AND $pid_name = ? ORDER BY rank DESC";
+        $arrRet = $objQuery->select($col, $table, $where, array($pid));
+        $max = count($arrRet);
+        $up_id = '';
+        for ($cnt = 0; $cnt < $max; $cnt++) {
+            if ($arrRet[$cnt][$id_name] == $id) {
+                $up_id = $arrRet[($cnt - 1)][$id_name];
+                break;
+            }
+        }
+
+        return $up_id;
+    }
+
     public function lfCountChilds($objQuery, $table, $pid_name, $id_name, $id)
     {
