Index: branches/version-2_13-dev/data/class/plugin/SC_Plugin_Base.php
===================================================================
--- branches/version-2_13-dev/data/class/plugin/SC_Plugin_Base.php	(revision 22857)
+++ branches/version-2_13-dev/data/class/plugin/SC_Plugin_Base.php	(revision 22978)
@@ -53,5 +53,7 @@
      * @return void
      */
-    abstract function install($arrPlugin);
+    function install($arrPlugin, $objPluginInstaller = null) {
+        
+    }
 
     /**
@@ -63,5 +65,7 @@
      * @return void
      */
-    abstract function uninstall($arrPlugin);
+    function uninstall($arrPlugin, $objPluginInstaller = null) {
+        
+    }
 
     /**
@@ -73,5 +77,7 @@
      * @return void
      */
-    abstract function enable($arrPlugin);
+    function enable($arrPlugin, $objPluginInstaller = null) {
+        
+    }
 
     /**
@@ -83,5 +89,7 @@
      * @return void
      */
-    abstract function disable($arrPlugin);
+    function disable($arrPlugin, $objPluginInstaller = null) {
+        
+    }
 
     /**
Index: branches/version-2_13-dev/data/class/plugin/SC_Plugin_Installer.php
===================================================================
--- branches/version-2_13-dev/data/class/plugin/SC_Plugin_Installer.php	(revision 22978)
+++ branches/version-2_13-dev/data/class/plugin/SC_Plugin_Installer.php	(revision 22978)
@@ -0,0 +1,247 @@
+<?php
+/*
+ * This file is part of EC-CUBE
+ *
+ * Copyright(c) 2000-2013 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.
+ */
+class SC_Plugin_Installer {
+    
+    protected $exec_func;
+    
+    protected $plugin_code;
+    
+    protected $arrPlugin;
+    
+    protected $arrInstallData;
+    
+    public function __construct($exec_func, $arrPlugin) {
+        $this->exec_func   = $exec_func;
+        $this->plugin_code = $arrPlugin['plugin_code'];
+        $this->arrPlugin   = $arrPlugin;
+        $this->arrInstallData = array();
+        $this->arrInstallData['sql'] = array();
+        $this->arrInstallData['copy_file'] = array();
+        $this->arrInstallData['copy_direcrtory'] = array();
+        $this->arrInstallData['insert'] = array();
+        $this->arrInstallData['update'] = array();
+        $this->arrInstallData['remove_file'] = array();
+        $this->arrInstallData['remove_directory'] = array();
+    }
+    
+    public function execPlugin() {
+        $this->log("start");
+        
+        $plugin_code = $this->arrPlugin['plugin_code'];
+
+
+        // テーブル作成SQLなどを実行
+        $arrSql = $this->arrInstallData['sql'];
+        $arrErr = array();
+
+        // SQLの検証
+        foreach ($arrSql as $sql) {
+            $this->log("verify sql: " . $sql['sql']);
+            $error_message = $this->verifySql($sql['sql'], $sql['params']);
+            if (!is_null($error_message)) {
+                $this->log("verify sql: invalid sql " . $sql['sql']);
+                $this->log("verify sql: $error_message");
+                $arrErr[] = $error_message;
+            }
+        }
+        
+        if (count($arrErr) > 0) {
+            return $arrErr;
+        }
+        
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+        
+        // SQLの実行
+        foreach ($arrSql as $sql) {
+            $this->log("exec sql: " . $sql['sql']);
+            $objQuery->query($sql['sql'], $sql['params']);
+        }
+        
+        $arrInsertQuery = $this->arrInstallData['insert'];
+        foreach ($arrInsertQuery as $query) {
+            $objQuery->insert(
+                    $query['table'],
+                    $query['arrVal'],
+                    $query['arrSql'],
+                    $query['arrSqlVal'],
+                    $query['form'],
+                    $query['arrFromVal']
+            );
+        }
+        
+        $arrUpdateQuery = $this->arrInstallData['update'];
+        foreach ($arrUpdateQuery as $query) {
+            $objQuery->update(
+                    $query['table'],
+                    $query['arrVal'],
+                    $query['where'],
+                    $query['arrWhereVal'],
+                    $query['arrRawSql'],
+                    $query['arrRawSqlVal']
+            );
+        }
+        
+        // プラグインのディレクトリコピー
+        $arrCopyDirectories = $this->arrInstallData['copy_directory'];
+
+        foreach ($arrCopyDirectories as $directory) {
+            $this->log("exec dir copy: " . $directory['src'] . ' -> ' . $directory['dist']);
+            // ディレクトリコピー -> HTML配下とDATA配下を別関数にする
+            SC_Utils::copyDirectory(
+                    PLUGIN_UPLOAD_REALDIR . $plugin_code . DIRECTORY_SEPARATOR . $directory['src'],
+                    PLUGIN_HTML_REALDIR   . $plugin_code . DIRECTORY_SEPARATOR . $directory['dist']);
+        }
+
+        // プラグインのファイルコピー
+        $arrCopyFiles = $this->arrInstallData['copy_file'];
+
+        foreach ($arrCopyFiles as $file) {
+            $this->log("exec file copy: " . $file['src'] . ' -> ' . $file['dist']);
+            // ファイルコピー
+            copy(PLUGIN_UPLOAD_REALDIR . $plugin_code . DIRECTORY_SEPARATOR . $file['src'],
+                 PLUGIN_HTML_REALDIR   . $plugin_code . DIRECTORY_SEPARATOR . $file['dist']);
+        }
+        
+        $this->log("end");         
+    }
+
+    public function copyFile($src, $dist) {
+        $this->arrInstallData['copy_file'][] = array(
+            'src'  => $src,
+            'dist' => $dist
+        );
+    }
+ 
+    public function copyDirectory($src, $dist) {
+        $this->arrInstallData['copy_directory'][] = array(
+            'src'  => $src,
+            'dist' => $dist
+        );        
+    }
+    
+    public function removeFile($dist) {
+        $this->arrInstallData['remove_file'][] = array(
+            'dist' => $dist
+        );
+    }
+    
+    public function removeDirectory($dist) {
+       $this->arrInstallData['remove_file'][] = array(
+            'dist' => $dist
+        );     
+    }
+
+    public function sql($sql, array $params = array()) {
+        $this->arrInstallData['sql'][] = array(
+            'sql'    => $sql,
+            'params' => $params
+        );
+    }
+    
+    protected function log($msg) {
+        $msg = sprintf("%s %s: %s", $this->plugin_code, $this->exec_func, $msg);
+        GC_Utils::gfPrintLog($msg, PLUGIN_LOG_REALFILE);
+    }
+    
+    /**
+     * カラム追加クエリの追加
+     * 
+     * @param type $table
+     * @param type $col
+     * @param type $type 
+     */
+    function sqlAterTableAddColumn($table_name, $col_name, $col_type) {
+        $sql = "ALTER TABLE $table_name ADD $col_name $col_type ";
+        $this->sql($sql);
+    }
+    
+    /**
+     * カラム削除クエリの追加
+     * 
+     * @param type $table
+     * @param type $col
+     * @param type $type 
+     */
+    function sqlAterTableDropColumn($table_name, $col_name) {
+        $sql = "ALTER TABLE $table_name DROP $col_name";
+        $this->sql($sql);
+    }
+    
+    
+    function sqlInsert($table, $arrVal, $arrSql = array(), $arrSqlVal = array(), $from = '', $arrFromVal = array()) {
+        $this->arrInstallData['insert'][] = array(
+            'table' => $table,
+            'arrVal' => $arrVal, 
+            'arrSql' => $arrSql, 
+            'arrSqlVal' => $arrSqlVal, 
+            'form' =>$from,
+            'arrFromVal' => $arrFromVal
+        );
+    }
+    
+    function sqlUpdate($table, $arrVal, $where = '', $arrWhereVal = array(), $arrRawSql = array(), $arrRawSqlVal = array()) {
+        $this->arrInstallData['update'][] = array(
+            'table' => $table,
+            'arrVal' => $arrVal, 
+            'where' => $where, 
+            'arrWhereVal' => $arrWhereVal, 
+            'arrRawSql' =>$arrRawSql,
+            'arrRawSqlVal' => $arrRawSqlVal
+        );
+    }
+    
+    /**
+     * 
+     * @param string $sql
+     * @param type $params
+     */
+    protected function verifySql($sql, $params) {
+        // FIXME $paramsのチェックも行いたい.
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+        
+        // force runを有効にし, システムエラーを回避する
+        $objQuery->force_run = true;
+
+        // prepareでSQLを検証
+        $sth = $objQuery->prepare($sql);
+
+        if (PEAR::isError($sth)) {
+            $error_message = $sth->message . ":" . $sth->userinfo;
+            $objQuery->force_run = false;
+            return $error_message;
+        }
+        
+        //$ret = $sth->execute($params);
+        //if (PEAR::isError($ret)) {
+        //    $error_message = $ret->message . ":" . $ret->userinfo;
+        //    $objQuery->force_run = false;
+        //    return $error_message;            
+        //}
+        
+        $sth->free();
+        // force_runをもとに戻す.
+        $objQuery->force_run = false;
+        
+        return $error_message;
+    }
+}
Index: branches/version-2_13-dev/data/class/plugin/SC_Plugin_Util.php
===================================================================
--- branches/version-2_13-dev/data/class/plugin/SC_Plugin_Util.php	(revision 22856)
+++ branches/version-2_13-dev/data/class/plugin/SC_Plugin_Util.php	(revision 22978)
@@ -144,7 +144,8 @@
      *
      * @param integer $plugin_id
+     * @param integer $use_type 1=有効のみ 2=無効のみ 3=全て
      * @return array フックポイントの一覧
      */
-    function getPluginHookPoint($plugin_id)
+    function getPluginHookPoint($plugin_id, $use_type = 1)
     {
         $objQuery =& SC_Query_Ex::getSingletonInstance();
@@ -152,6 +153,52 @@
         $from = 'dtb_plugin_hookpoint';
         $where = 'plugin_id = ?';
-
+        switch ($use_type) {
+            case 1:
+                $where .= ' AND use_flg = true';
+            break;
+
+            case 2:
+                $where .= ' AND use_flg = false';
+            break;
+
+            case 3:
+            default:
+            break;
+        }
         return $objQuery->select($cols, $from, $where, array($plugin_id));
+    }
+
+    /**
+     *  プラグインフックポイントを取得する.
+     *
+     * @param integer $use_type 1=有効のみ 2=無効のみ 3=全て
+     * @return array フックポイントの一覧
+     */
+    function getPluginHookPointList($use_type = 3)
+    {
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+        $objQuery->setOrder('hook_point ASC, priority DESC');
+        $cols = 'dtb_plugin_hookpoint.*, dtb_plugin.priority, dtb_plugin.plugin_name';
+        $from = 'dtb_plugin_hookpoint LEFT JOIN dtb_plugin USING(plugin_id)';
+        switch ($use_type) {
+            case 1:
+                $where = 'enable = 1 AND use_flg = true';
+            break;
+
+            case 2:
+                $where = 'enable = 1 AND use_flg = false';
+            break;
+
+            case 3:
+            default:
+                $where = '';
+            break;
+        }
+        return $objQuery->select($cols, $from, $where);
+        //$arrList = array();
+        //foreach ($arrRet AS $key=>$val) {
+        //    $arrList[$val['hook_point']][$val['plugin_id']] = $val;
+        //}
+        //return $arrList;
     }
 
@@ -183,3 +230,67 @@
         return $arrErr;
     }
+
+    /**
+     * フックポイントのON/OFF変更
+     *
+     * @param intger $plugin_hookpoint_id  フックポイントID
+     * @return bolean $use_flg：ture=ON、false=OFF
+     */
+    function setPluginHookPointChangeUse($plugin_hookpoint_id, $use_flg = false) {
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+        $sqlval['use_flg'] = $use_flg;
+        $objQuery->update('dtb_plugin_hookpoint', $sqlval, 'plugin_hookpoint_id = ?', array($plugin_hookpoint_id));
+    }
+
+    /**
+     * フックポイントで衝突する可能性のあるプラグインを判定.メッセージを返します.
+     *
+     * @param int $plugin_id プラグインID
+     * @return string $conflict_alert_message メッセージ
+     */
+    function checkConflictPlugin($plugin_id = '')
+    {
+        // フックポイントを取得します.
+        $where = 'T1.hook_point = ? AND NOT T1.plugin_id = ? AND T2.enable = ?';
+        if ($plugin_id > 0) {
+            $hookPoints = SC_Plugin_Util::getPluginHookPoint($plugin_id, '');
+        } else {
+            $hookPoints = SC_Plugin_Util::getPluginHookPointList(1);
+            $where .= ' AND T1.use_flg = true';
+        }
+
+        $conflict_alert_message = '';
+        $arrConflictPluginName = array();
+        $arrConflictHookPoint = array();
+        $objQuery =& SC_Query_Ex::getSingletonInstance();
+        $objQuery->setGroupBy('T1.hook_point, T1.plugin_id, T2.plugin_name');
+        $table = 'dtb_plugin_hookpoint AS T1 LEFT JOIN dtb_plugin AS T2 ON T1.plugin_id = T2.plugin_id';
+        foreach ($hookPoints as $hookPoint) {
+            // 競合するプラグインを取得する,
+            $conflictPlugins = $objQuery->select('T1.hook_point, T1.plugin_id, T2.plugin_name', $table, $where, array($hookPoint['hook_point'], $hookPoint['plugin_id'], PLUGIN_ENABLE_TRUE));
+
+            // プラグイン名重複を削除する為、専用の配列に格納し直す.
+            foreach ($conflictPlugins as $conflictPlugin) {
+                // プラグイン名が見つからなければ配列に格納
+                if (!in_array($conflictPlugin['plugin_name'], $arrConflictPluginName)) {
+                    $arrConflictPluginName[] = $conflictPlugin['plugin_name'];
+                }
+                // プラグイン名が見つからなければ配列に格納
+                if (!in_array($conflictPlugin['hook_point'], $arrConflictHookPoint)) {
+                    $arrConflictHookPoint[] = $conflictPlugin['hook_point'];
+                }
+            }
+        }
+
+        if ($plugin_id > 0) {
+            // メッセージをセットします.
+            foreach ($arrConflictPluginName as $conflictPluginName) {
+                $conflict_alert_message .= '* ' .  $conflictPluginName . 'と競合する可能性があります。<br/>';
+            }
+            return $conflict_alert_message;
+        } else {
+            return $arrConflictHookPoint;
+        }
+    }
+
 }
