source: branches/camp/camp-2_13-plugin/data/class/pages/admin/ownersstore/LC_Page_Admin_OwnersStore.php @ 22681

Revision 22681, 41.0 KB checked in by adachi, 11 years ago (diff)

#2181 SQLを検証し、問題ある場合はロールバック

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2013 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24// {{{ requires
25require_once CLASS_EX_REALDIR . 'page_extends/admin/LC_Page_Admin_Ex.php';
26
27/**
28 * オーナーズストア:プラグイン管理 のページクラス.
29 *
30 * @package Page
31 * @author LOCKON CO.,LTD.
32 * @version $Id$
33 */
34class LC_Page_Admin_OwnersStore extends LC_Page_Admin_Ex
35{
36
37    // }}}
38    // {{{ functions
39
40    /**
41     * Page を初期化する.
42     *
43     * @return void
44     */
45    function init()
46    {
47        parent::init();
48        $this->tpl_mainpage = 'ownersstore/plugin.tpl';
49        $this->tpl_subno    = 'index';
50        $this->tpl_mainno   = 'ownersstore';
51        $this->tpl_maintitle = 'オーナーズストア';
52        $this->tpl_subtitle = 'プラグイン管理';
53    }
54
55    /**
56     * Page のプロセス.
57     *
58     * @return void
59     */
60    function process()
61    {
62        $this->action();
63        $this->sendResponse();
64    }
65
66    /**
67     * Page のアクション.
68     *
69     * @return void
70     */
71    function action()
72    {
73        // パラメーター管理クラス
74        $objFormParam = new SC_FormParam_Ex();
75        $mode = $this->getMode();
76        // パラメーター情報の初期化
77        $this->initParam($objFormParam, $mode);
78        $objFormParam->setParam($_POST);
79
80        switch ($mode) {
81            // インストール
82            case 'install':
83                $file_key = 'plugin_file';
84                $this->arrErr = $this->checkUploadFile($file_key);
85                if ($this->isError($this->arrErr) === false) {
86                    $archive_file_name = $_FILES[$file_key]['name'];
87                    // インストール処理.
88                    $this->arrErr = $this->installPlugin($archive_file_name, 'plugin_file');
89                    if ($this->isError($this->arrErr) === false) {
90                        // コンパイルファイルのクリア処理
91                        SC_Utils_Ex::clearCompliedTemplate();
92                        $this->tpl_onload = "alert('プラグインをインストールしました。');";
93                    }
94                }
95                break;
96            // 削除
97            case 'uninstall':
98                // エラーチェック
99                $this->arrErr = $objFormParam->checkError();
100                if ($this->isError($this->arrErr) === false) {
101                    $plugin_id = $objFormParam->getValue('plugin_id');
102                    $plugin = SC_Plugin_Util_Ex::getPluginByPluginId($plugin_id);
103                    $this->arrErr = $this->uninstallPlugin($plugin);
104                    if ($this->isError($this->arrErr) === false) {
105                        // TODO 全プラグインのインスタンスを保持したまま後続処理が実行されるので、全てのインスタンスを解放する。
106                        unset($GLOBALS['_SC_Helper_Plugin_instance']);
107                        // コンパイルファイルのクリア処理
108                        SC_Utils_Ex::clearCompliedTemplate();
109                        $this->tpl_onload = "alert('" . $plugin['plugin_name'] ."を削除しました。');";
110                    }
111                }
112                break;
113            // 有効化
114            case 'enable':
115                // エラーチェック
116                $this->arrErr = $objFormParam->checkError();
117                if ($this->isError($this->arrErr) === false) {
118                    $plugin_id = $objFormParam->getValue('plugin_id');
119                    // プラグイン取得.
120                    $plugin = SC_Plugin_Util_Ex::getPluginByPluginId($plugin_id);
121                    $this->arrErr = $this->enablePlugin($plugin);
122                    if ($this->isError($this->arrErr) === false) {
123                        // TODO 全プラグインのインスタンスを保持したまま後続処理が実行されるので、全てのインスタンスを解放する。
124                        unset($GLOBALS['_SC_Helper_Plugin_instance']);
125                        // コンパイルファイルのクリア処理
126                        SC_Utils_Ex::clearCompliedTemplate();
127                        $this->tpl_onload = "alert('" . $plugin['plugin_name'] . "を有効にしました。');";
128                    }
129                }
130                break;
131            // 無効化
132            case 'disable':
133                // エラーチェック
134                $this->arrErr = $objFormParam->checkError();
135                if ($this->isError($this->arrErr) === false) {
136                    $plugin_id = $objFormParam->getValue('plugin_id');
137                    // プラグイン取得.
138                    $plugin = SC_Plugin_Util_Ex::getPluginByPluginId($plugin_id);
139                    $this->arrErr = $this->disablePlugin($plugin);
140                    if ($this->isError($this->arrErr) === false) {
141                        // TODO 全プラグインのインスタンスを保持したまま後続処理が実行されるので、全てのインスタンスを解放する。
142                        unset($GLOBALS['_SC_Helper_Plugin_instance']);
143                        // コンパイルファイルのクリア処理
144                        SC_Utils_Ex::clearCompliedTemplate();
145                        $this->tpl_onload = "alert('" . $plugin['plugin_name'] . "を無効にしました。');";
146                    }
147                }
148                break;
149            // アップデート.
150            case 'update':
151                // エラーチェック
152                $this->arrErr = $objFormParam->checkError();
153                if ($this->isError($this->arrErr) === false) {
154                    $plugin_id = $objFormParam->getValue('plugin_id');
155                    $plugin = SC_Plugin_Util_Ex::getPluginByPluginId($plugin_id);
156                    $target_plugin_code = $plugin['plugin_code']; // アップデート対象のプラグインコード
157                    $this->arrErr = $this->checkUploadFile($target_plugin_code);
158
159                    if ($this->isError($this->arrErr) === false) {
160                        $update_plugin_file = $_FILES[$target_plugin_code];
161                        $update_plugin_file_name = $update_plugin_file['name']; // アップデートファイルのファイル名.
162                        // インストール処理.
163                        $target_plugin = SC_Plugin_Util_Ex::getPluginByPluginCode($target_plugin_code);
164                        $this->arrErr = $this->updatePlugin($target_plugin, $update_plugin_file_name, $target_plugin_code);
165                        if ($this->isError($this->arrErr) === false) {
166                            // コンパイルファイルのクリア処理
167                            SC_Utils_Ex::clearCompliedTemplate();
168                            $this->tpl_onload = "alert('プラグインをアップデートしました。');";
169                        }
170                    }
171                }
172                break;
173            // 優先度.
174            case 'priority':
175                // エラーチェック
176                $arrErr = $objFormParam->checkError();
177                $plugin_id = $objFormParam->getValue('plugin_id');
178                if ($this->isError($arrErr) === false) {
179                    // 優先度の更新
180                    $priority = $objFormParam->getValue('priority');
181                    $this->updatePriority($plugin_id, $priority);
182                    // コンパイルファイルのクリア処理
183                    SC_Utils_Ex::clearCompliedTemplate();
184                } else {
185                    // エラーメッセージを詰め直す.
186                    $this->arrErr['priority'][$plugin_id] = $arrErr['priority'];
187                }
188
189                break;
190            default:
191                break;
192        }
193        // DBからプラグイン情報を取得
194        $plugins = SC_Plugin_Util_Ex::getAllPlugin();
195
196        foreach ($plugins as $key => $plugin) {
197            // ロゴファイルへのパスを生成(ロゴが無い場合はNO_IMAGEを表示)
198            if (file_exists(PLUGIN_HTML_REALDIR . $plugins[$key]['plugin_code'] . '/logo.png') === true){
199                $plugins[$key]['logo'] = ROOT_URLPATH . 'plugin/' . $plugins[$key]['plugin_code'] . '/logo.png';
200            } else {
201                $plugins[$key]['logo'] = IMAGE_SAVE_URLPATH . 'noimage_plugin_list.png';
202            }
203
204            // 設定ファイルがあるかを判定.
205            $plugins[$key]['config_flg'] = $this->isContainsFile(PLUGIN_UPLOAD_REALDIR . $plugin['plugin_code'], 'config.php');
206            if ($plugins[$key]['enable'] === PLUGIN_ENABLE_TRUE) {
207                // 競合するプラグインがあるかを判定.
208                //$plugins[$key]['conflict_message']= $this->checkConflictPlugin($plugin['plugin_id']);
209                $plugins[$key]['conflict_message'] = SC_Plugin_Util_Ex::checkConflictPlugin($plugin['plugin_id']);
210            }
211        }
212        $this->plugins = $plugins;
213    }
214
215    /**
216     * デストラクタ.
217     *
218     * @return void
219     */
220    function destroy()
221    {
222        parent::destroy();
223    }
224
225    /**
226     * パラメーター初期化.
227     *
228     * @param SC_FormParam_Ex $objFormParam
229     * @param string $mode モード
230     * @return void
231     */
232    function initParam(&$objFormParam, $mode)
233    {
234        $objFormParam->addParam('mode', 'mode', INT_LEN, '', array('ALPHA_CHECK', 'MAX_LENGTH_CHECK'));
235        $objFormParam->addParam('plugin_id', 'plugin_id', INT_LEN, '', array('NUM_CHECK', 'MAX_LENGTH_CHECK'));
236        if ($mode === 'priority') {
237            $objFormParam->addParam('優先度', 'priority', INT_LEN, '', array('EXIST_CHECK', 'NUM_CHECK', 'MAX_LENGTH_CHECK'));
238        }
239    }
240
241    /**
242     * ファイルパラメーター初期化.
243     *
244     * @param SC_UploadFile_Ex $objUpFile SC_UploadFileのインスタンス.
245     * @param string $key 登録するキー.
246     * @return void
247     */
248    function initUploadFile(&$objUpFile, $key)
249    {
250        $objUpFile->addFile('プラグインファイル', $key, explode(',', PLUGIN_EXTENSION), FILE_SIZE, true, 0, 0, false);
251    }
252
253    /**
254     * ファイルが指定されている事をチェックします.
255     *
256     * @param string $file ファイル
257     * @param string $file_key ファイルキー
258     * @return array エラー情報を格納した連想配列.
259     */
260    function checkUploadFile($file_key)
261    {
262        $objErr = new SC_CheckError_Ex();
263        // 拡張子チェック
264        $objErr->doFunc(array('プラグインファイル', $file_key, explode(',', PLUGIN_EXTENSION)), array('FILE_EXT_CHECK'));
265        // ファイルサイズチェック
266        $objErr->doFunc(array('プラグインファイル', $file_key, FILE_SIZE), array('FILE_SIZE_CHECK'));
267        // ファイル名チェック
268        $objErr->doFunc(array('プラグインファイル', $file_key), array('FILE_NAME_CHECK'));
269
270        return $objErr->arrErr;
271    }
272
273    /**
274     * 既にインストールされているプラグインかを判定します.
275     *
276     * @param string $plugin_code プラグインコード
277     * @return boolean インストール済の場合true インストールされていない場合false
278     */
279    function isInstalledPlugin($plugin_code)
280    {
281        $plugin = SC_Plugin_Util_Ex::getPluginByPluginCode($plugin_code);
282        if (!empty($plugin)) {
283            return true;
284        }
285        return false;
286    }
287
288    /**
289     * ファイル名からプラグインコードを取得する.
290     *
291     * ファイル名を「.」で配列に分解.
292     * 配列内から拡張子として格納される可能性のある「tar」「gz」を除外すし、再度結合する.
293     *
294     * @param string $file_name ファイル名
295     * @return string $plugin_code プラグインコード.
296     */
297    function getPluginCode($file_name)
298    {
299        // 分解
300        $array_ext = explode('.', $file_name);
301        $array_file_name = array_diff($array_ext, array('tar','gz'));
302        // 結合
303        $plugin_code = implode('.', $array_file_name);
304        return $plugin_code;
305    }
306
307    /**
308     * プラグイン保存ディレクトリのパスを取得する.
309     *
310     * @param string $plugin_code プラグインコード
311     * @return string $plugin_dir_path プラグイン保存ディレクトリのパス.
312     */
313    function getPluginDir($plugin_code)
314    {
315        $plugin_dir_path = PLUGIN_UPLOAD_REALDIR . $plugin_code . '/';
316        return $plugin_dir_path;
317    }
318
319    /**
320     * プラグインHTMLディレクトリのパスを取得する.
321     *
322     * @param string $plugin_code プラグインコード
323     * @return string $plugin_dir_path プラグイン保存ディレクトリのパス.
324     */
325    function getHtmlPluginDir($plugin_code)
326    {
327        $plugin_html_dir_path = PLUGIN_HTML_REALDIR . $plugin_code . '/';
328        return $plugin_html_dir_path;
329    }
330
331    /**
332     * プラグインファイルのパスを取得する.
333     *
334     * @param string $plugin_code プラグインコード
335     * @param string $plugin_class プラグインクラス名
336     * @return string $plugin_file_path クラスファイルのパス.
337     */
338    function getPluginFilePath($plugin_code , $plugin_class)
339    {
340        $plugin_file_path = $this->getPluginDir($plugin_code) . $plugin_class . '.php';
341        return $plugin_file_path;
342    }
343
344    /**
345     * プラグインをインストールします.
346     *
347     * @param string $archive_file_name アーカイブファイル名.
348     * @param string $key キー.
349     * @return array エラー情報を格納した連想配列.
350     */
351    function installPlugin($archive_file_name, $key)
352    {
353        $objQuery =& SC_Query_Ex::getSingletonInstance();
354        $objQuery->begin();
355       
356        // 一時展開ディレクトリにファイルがある場合は事前に削除.
357        $arrFileHash = SC_Helper_FileManager_Ex::sfGetFileList(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR);
358        if (count($arrFileHash) > 0) {
359            SC_Helper_FileManager_Ex::deleteFile(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR, false);
360        }
361
362        //シンタックスエラーがあるtar.gzをアップ後、削除するとたまにディレクトリが消えるので追加
363        $this->makeDir(PLUGIN_UPLOAD_REALDIR);
364
365        $arrErr = array();
366        // 必須拡張モジュールのチェック
367        $arrErr = SC_Plugin_Util_Ex::checkExtension($key);
368        if ($this->isError($arrErr) === true) {
369            return $arrErr;
370        }
371        // ファイルをチェックし一時展開用ディレクトリに展開します.
372        $arrErr = $this->unpackPluginFile($archive_file_name, DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR, $key);
373        if ($this->isError($arrErr) === true) {
374            return $arrErr;
375        }
376        // plugin_infoを読み込み.
377        $arrErr = $this->requirePluginFile(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR . 'plugin_info.php', $key);
378        if ($this->isError($arrErr) === true) {
379            $this->rollBack(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR);
380            return $arrErr;
381        }
382
383        // リフレクションオブジェクトを生成.
384        $objReflection = new ReflectionClass('plugin_info');
385        $arrPluginInfo = $this->getPluginInfo($objReflection);
386        // プラグインクラスに必須となるパラメータが正常に定義されているかチェックします.
387        $arrErr = $this->checkPluginConstants($objReflection, DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR);
388        if ($this->isError($arrErr) === true) {
389            $this->rollBack(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR);
390            return $arrErr;
391        }
392
393        // 既にインストールされていないかを判定.
394        if ($this->isInstalledPlugin($arrPluginInfo['PLUGIN_CODE']) === true) {
395            $this->rollBack(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR);
396            $arrErr['plugin_file'] = '※ ' . $arrPluginInfo['PLUGIN_NAME'] . 'は既にインストールされています。<br/>';
397            return $arrErr;
398        }
399
400        // プラグイン情報をDB登録
401        if ($this->registerData($arrPluginInfo) === false) {
402            $this->rollBack(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR);
403            $arrErr['plugin_file'] = '※ DB登録に失敗しました。<br/>';
404            return $arrErr;
405        }
406
407        // プラグイン保存ディレクトリを作成し、一時展開用ディレクトリから移動します.
408        $plugin_dir_path = $this->getPluginDir($arrPluginInfo['PLUGIN_CODE']);
409        $this->makeDir($plugin_dir_path);
410        SC_Utils_Ex::copyDirectory(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR, $plugin_dir_path);
411
412        // プラグイン情報を取得
413        $plugin = SC_Plugin_Util_Ex::getPluginByPluginCode($arrPluginInfo['PLUGIN_CODE']);
414
415        // クラスファイルを読み込み.
416        $plugin_class_file_path = $this->getPluginFilePath($plugin['plugin_code'], $plugin['class_name']);
417        $arrErr = $this->requirePluginFile($plugin_class_file_path, $key);
418        if ($this->isError($arrErr) === true) {
419            $this->rollBack(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR, $plugin['plugin_id']);
420            return $arrErr;
421        }
422        // プラグインhtmlディレクトリ作成
423        $plugin_html_dir_path = $this->getHtmlPluginDir($plugin['plugin_code']);
424        $this->makeDir($plugin_html_dir_path);
425
426        $arrErr = $this->execPlugin($plugin, $plugin['class_name'], 'install');
427        if ($this->isError($arrErr) === true) {
428            var_dump($arrErr);
429            $objQuery->rollback();
430            //$objQuery->begin();
431            $this->rollBack(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR, $plugin['plugin_id'], $plugin_html_dir_path);
432            return $arrErr;
433        }
434
435        $objQuery->commit();
436       
437        // 不要なファイルの削除
438        SC_Helper_FileManager_Ex::deleteFile(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR, false);
439        return $arrErr;
440    }
441
442    /**
443     * ロールバック処理
444     * インストール失敗時などに不要な一時ファイルを削除します.
445     *
446     * @param string $temp_dir インストール・アップデート時の一時展開用ディレクトリのパス.
447     * @param string $plugin_id プラグインID.
448     * @param string $plugin_html_dir_path プラグイン毎に生成されるhtmlディレクトリのパス.
449     */
450    function rollBack($temp_dir, $plugin_id = '', $plugin_html_dir_path ='')
451    {
452        // 一時ディレクトリを削除.
453        SC_Helper_FileManager_Ex::deleteFile($temp_dir, false);
454        // DBからプラグイン情報を削除
455        if (empty($plugin_id) === false) {
456            SC_Plugin_Util_Ex::deletePluginByPluginId($plugin_id);
457        }
458        // htmlディレクトリを削除
459        if (empty($plugin_html_dir_path) === false) {
460            SC_Helper_FileManager_Ex::deleteFile($plugin_html_dir_path, true);
461        }
462    }
463
464    /**
465     * プラグイン情報を取得します.
466     *
467     * @param ReflectionClass $objReflection
468     * @return array プラグイン情報の配列
469     */
470    function getPluginInfo(ReflectionClass $objReflection)
471    {
472        $arrStaticProps = $objReflection->getStaticProperties();
473        $arrConstants   = $objReflection->getConstants();
474
475        $arrPluginInfoKey = array(
476            'PLUGIN_CODE',
477            'PLUGIN_NAME',
478            'CLASS_NAME',
479            'PLUGIN_VERSION',
480            'COMPLIANT_VERSION',
481            'AUTHOR',
482            'DESCRIPTION',
483            'PLUGIN_SITE_URL',
484            'AUTHOR_SITE_URL',
485            'HOOK_POINTS',
486        );
487        $arrPluginInfo = array();
488        foreach ($arrPluginInfoKey as $key) {
489            // クラス変数での定義を優先
490            if (isset($arrStaticProps[$key])) {
491                $arrPluginInfo[$key] = $arrStaticProps[$key];
492            // クラス変数定義がなければ, クラス定数での定義を読み込み.
493            } elseif ($arrConstants[$key]) {
494                $arrPluginInfo[$key] = $arrConstants[$key];
495            } else {
496                $arrPluginInfo[$key] = null;
497            }
498        }
499        return $arrPluginInfo;
500    }
501
502    /**
503     * プラグインクラス内の定数をチェックします.
504     *
505     * @param ReflectionClass $objReflection リフレクションオブジェクト
506     * @param string $dir_path チェックするプラグインディレクトリ
507     * @return array エラー情報を格納した連想配列.
508     */
509    function checkPluginConstants(ReflectionClass $objReflection, $dir_path)
510    {
511        $arrErr = array();
512        // プラグイン情報を取得
513        $arrPluginInfo = $this->getPluginInfo($objReflection);
514
515        if (!isset($arrPluginInfo['PLUGIN_CODE'])) {
516            $arrErr['plugin_file'] = '※ PLUGIN_CODEが定義されていません。<br/>';
517            return $arrErr;
518        }
519        if (!isset($arrPluginInfo['PLUGIN_NAME'])) {
520            $arrErr['plugin_file'] = '※ PLUGIN_NAMEが定義されていません。<br/>';
521            return $arrErr;
522        }
523        if (!isset($arrPluginInfo['CLASS_NAME'])) {
524            $arrErr['plugin_file'] = '※ CLASS_NAMEが定義されていません。<br/>';
525            return $arrErr;
526        }
527        $plugin_class_file_path = $dir_path . $arrPluginInfo['CLASS_NAME'] . '.php';
528        if (file_exists($plugin_class_file_path) === false) {
529            $arrErr['plugin_file'] = '※ CLASS_NAMEが正しく定義されていません。<br/>';
530            return $arrErr;
531        }
532        if (!isset($arrPluginInfo['PLUGIN_VERSION'])) {
533            $arrErr['plugin_file'] = '※ PLUGIN_VERSIONが定義されていません。<br/>';
534            return $arrErr;
535        }
536        if (!isset($arrPluginInfo['COMPLIANT_VERSION'])) {
537            $arrErr['plugin_file'] = '※ COMPLIANT_VERSIONが定義されていません。<br/>';
538            return $arrErr;
539        }
540        if (!isset($arrPluginInfo['AUTHOR'])) {
541            $arrErr['plugin_file'] = '※ AUTHORが定義されていません。<br/>';
542            return $arrErr;
543        }
544        if (!isset($arrPluginInfo['DESCRIPTION'])) {
545            $arrErr['plugin_file'] = '※ DESCRIPTIONが定義されていません。<br/>';
546            return $arrErr;
547        }
548        $objErr = new SC_CheckError_Ex($arrPluginInfo);
549        $objErr->doFunc(array('PLUGIN_CODE', 'PLUGIN_CODE', STEXT_LEN), array('MAX_LENGTH_CHECK','GRAPH_CHECK'));
550        $objErr->doFunc(array('PLUGIN_NAME', 'PLUGIN_NAME', STEXT_LEN), array('MAX_LENGTH_CHECK'));
551        $objErr->doFunc(array('CLASS_NAME', 'CLASS_NAME', STEXT_LEN), array('MAX_LENGTH_CHECK','GRAPH_CHECK'));
552        $objErr->doFunc(array('PLUGIN_VERSION', 'PLUGIN_VERSION', STEXT_LEN), array('MAX_LENGTH_CHECK'));
553        $objErr->doFunc(array('COMPLIANT_VERSION', 'COMPLIANT_VERSION', STEXT_LEN), array('MAX_LENGTH_CHECK'));
554        $objErr->doFunc(array('AUTHOR', 'AUTHOR', STEXT_LEN), array('MAX_LENGTH_CHECK'));
555        $objErr->doFunc(array('DESCRIPTION', 'DESCRIPTION', MTEXT_LEN), array('MAX_LENGTH_CHECK'));
556        if (isset($arrPluginInfo['PLUGIN_SITE_URL'])) {
557            $objErr->doFunc(array('PLUGIN_SITE_URL', 'PLUGIN_SITE_URL', URL_LEN), array('MAX_LENGTH_CHECK','GRAPH_CHECK'));
558        }
559        if (isset($arrPluginInfo['AUTHOR_SITE_URL'])) {
560            $objErr->doFunc(array('AUTHOR_SITE_URL', 'AUTHOR_SITE_URL', URL_LEN), array('MAX_LENGTH_CHECK','GRAPH_CHECK'));
561        }
562        // エラー内容を出力用の配列にセットします.
563        if ($this->isError($objErr->arrErr)) {
564            $arrErr['plugin_file'] = '';
565            foreach ($objErr->arrErr as $error) {
566                    $arrErr['plugin_file'] .= $error;
567            }
568        }
569        return $arrErr;
570    }
571
572    /**
573     * プラグインをアップデートします.
574     *
575     * @param array $target_plugin アップデートするプラグイン情報の配列.
576     * @param string $upload_file_name アップロードファイル名.
577     * @return array エラー情報を格納した連想配列.
578     */
579    function updatePlugin($target_plugin, $upload_file_name)
580    {
581        // アップデート前に不要なファイルを消しておきます.
582        SC_Helper_FileManager_Ex::deleteFile(DOWNLOADS_TEMP_PLUGIN_UPDATE_DIR, false);
583
584        $arrErr = array();
585
586        // ファイルをチェックし展開します.
587        $arrErr = $this->unpackPluginFile($upload_file_name, DOWNLOADS_TEMP_PLUGIN_UPDATE_DIR, $target_plugin['plugin_code']);
588        if ($this->isError($arrErr) === true) {
589            return $arrErr;
590        }
591        // plugin_infoを読み込み.
592        $arrErr = $this->requirePluginFile(DOWNLOADS_TEMP_PLUGIN_UPDATE_DIR . 'plugin_info.php', $target_plugin['plugin_code']);
593        if ($this->isError($arrErr) === true) {
594            $this->rollBack(DOWNLOADS_TEMP_PLUGIN_INSTALL_DIR);
595            return $arrErr;
596        }
597        // リフレクションオブジェクトを生成.
598        $objReflection = new ReflectionClass('plugin_info');
599        $arrPluginInfo = $this->getPluginInfo($objReflection);
600        if ($arrPluginInfo['PLUGIN_CODE'] != $target_plugin['plugin_code']) {
601            $arrErr[$target_plugin['plugin_code']] = '※ プラグインコードが一致しません。<br/>';
602            return $arrErr;
603        }
604
605        // plugin_update.phpを読み込み.
606        $arrErr = $this->requirePluginFile(DOWNLOADS_TEMP_PLUGIN_UPDATE_DIR . 'plugin_update.php', $target_plugin['plugin_code']);
607        if ($this->isError($arrErr) === true) {
608            $this->rollBack(DOWNLOADS_TEMP_PLUGIN_UPDATE_DIR);
609            return $arrErr;
610        }
611        // プラグインクラスファイルのUPDATE処理を実行.
612        $arrErr = $this->execPlugin($target_plugin, 'plugin_update', 'update');
613
614        // 保存ディレクトリの削除.
615        SC_Helper_FileManager_Ex::deleteFile(DOWNLOADS_TEMP_PLUGIN_UPDATE_DIR, false);
616
617        return $arrErr;
618    }
619
620    /**
621     * ファイルをアップロードし、解凍先のディレクトリに解凍します.
622     *
623     * @param string $unpack_file_name 解凍ファイル名
624     * @param string $unpack_dir_path 解凍先ディレクトリパス
625     * @param string $file_key ファイルキー
626     * @return array エラー情報を格納した連想配列.
627     */
628    function unpackPluginFile($unpack_file_name, $unpack_dir_path, $file_key)
629    {
630        $arrErr = array();
631        // 解凍ディレクトリディレクトリを作成し、一時ディレクトリからファイルを移動
632        $objUpFile = new SC_UploadFile_Ex(PLUGIN_TEMP_REALDIR, $unpack_dir_path);
633        $this->initUploadFile($objUpFile, $file_key);
634        $arrErr = $objUpFile->makeTempFile($file_key, false);
635        if ($this->isError($arrErr) === true) {
636            return $arrErr;
637        }
638
639        // 正常にアップロードされているかをチェック.
640        $arrErr = $objUpFile->checkExists($file_key);
641        if ($this->isError($arrErr) === true) {
642            return $arrErr;
643        }
644        $objUpFile->moveTempFile();
645        // 解凍
646        $unpack_file_path = $unpack_dir_path . $unpack_file_name;
647        if (!$this->unpackPluginArchive($unpack_file_path)) {
648            $arrErr['plugin_file'] = '※ 解凍に失敗しました。<br/>';
649            return $arrErr;
650        }
651        return $arrErr;
652    }
653
654    /**
655     * プラグインをアンインストールします.
656     *
657     * @param array $plugin プラグイン情報を確認した連想配列.
658     * @return array エラー情報を格納した連想配列.
659     */
660    function uninstallPlugin($plugin)
661    {
662        $arrErr = array();
663        // プラグインファイルを読み込みます.
664        $plugin_class_file_path = $this->getPluginFilePath($plugin['plugin_code'], $plugin['class_name']);
665        $arrErr = $this->requirePluginFile($plugin_class_file_path, 'plugin_error');
666        if ($this->isError($arrErr) === true) {
667            return $arrErr;
668        }
669
670        // プラグインが有効な場合に無効化処理を実行
671        if ($plugin['enable'] == PLUGIN_ENABLE_TRUE){
672            // 無効化処理を実行します.
673            $arrErr = $this->execPlugin($plugin, $plugin['class_name'], 'disable');
674            if ($this->isError($arrErr) === true) {
675                return $arrErr;
676            }
677            // プラグインを無効にします.
678            $this->updatePluginEnable($plugin['plugin_id'], PLUGIN_ENABLE_FALSE);
679        }
680
681        // アンインストール処理を実行します.
682        $arrErr = $this->execPlugin($plugin, $plugin['class_name'], 'uninstall');
683        // プラグインの削除処理.
684        $arrErr = $this->deletePlugin($plugin['plugin_id'], $plugin['plugin_code']);
685
686        return $arrErr;
687    }
688
689    /**
690     * プラグインを有効にします.
691     *
692     * @param array $plugin プラグイン情報を確認した連想配列.
693     * @return array $arrErr エラー情報を格納した連想配列.
694     */
695    function enablePlugin($plugin)
696    {
697        $arrErr = array();
698        // クラスファイルを読み込み.
699        $plugin_class_file_path = $this->getPluginFilePath($plugin['plugin_code'], $plugin['class_name']);
700        $arrErr = $this->requirePluginFile($plugin_class_file_path, 'plugin_error');
701        if ($this->isError($arrErr) === true) {
702            return $arrErr;
703        }
704        // 有効化処理を実行します.
705        $arrErr = $this->execPlugin($plugin, $plugin['class_name'], 'enable');
706        if ($this->isError($arrErr) === true) {
707            return $arrErr;
708        }
709        // プラグインを有効にします.
710        $this->updatePluginEnable($plugin['plugin_id'], PLUGIN_ENABLE_TRUE);
711
712        return $arrErr;
713    }
714
715    /**
716     * プラグインを無効にします.
717     *
718     * @param array $plugin プラグイン情報を確認した連想配列.
719     * @return array $arrErr エラー情報を格納した連想配列.
720     */
721    function disablePlugin($plugin)
722    {
723        $arrErr = array();
724        // クラスファイルを読み込み.
725        $plugin_class_file_path =$this->getPluginFilePath($plugin['plugin_code'], $plugin['class_name']);
726        $arrErr = $this->requirePluginFile($plugin_class_file_path, 'plugin_error');
727        if ($this->isError($arrErr) === true) {
728            return $arrErr;
729        }
730
731        // 無効化処理を実行します.
732        $arrErr = $this->execPlugin($plugin, $plugin['class_name'], 'disable');
733        if ($this->isError($arrErr) === true) {
734            return $arrErr;
735        }
736        // プラグインを無効にします.
737        $this->updatePluginEnable($plugin['plugin_id'], PLUGIN_ENABLE_FALSE);
738
739        return $arrErr;
740    }
741
742    /**
743     * 優先度を更新します.
744     *
745     * @param int $plugin_id プラグインID
746     * @param int $priority 優先度
747     * @return integer 更新件数
748     */
749    function updatePriority($plugin_id, $priority)
750    {
751        $objQuery =& SC_Query_Ex::getSingletonInstance();
752        // UPDATEする値を作成する。
753        $sqlval['priority'] = $priority;
754        $sqlval['update_date'] = 'CURRENT_TIMESTAMP';
755        $where = 'plugin_id = ?';
756        // UPDATEの実行
757        $ret = $objQuery->update('dtb_plugin', $sqlval, $where, array($plugin_id));
758        return $ret;
759    }
760
761    /**
762     * プラグイン情報をDB登録.
763     *
764     * @param array $arrPluginInfo プラグイン情報を格納した連想配列.
765     * @return array エラー情報を格納した連想配列.
766     */
767    function registerData($arrPluginInfo)
768    {
769
770        // プラグイン情報をDB登録.
771        $objQuery =& SC_Query_Ex::getSingletonInstance();
772        $arr_sqlval_plugin = array();
773        $plugin_id = $objQuery->nextVal('dtb_plugin_plugin_id');
774        $arr_sqlval_plugin['plugin_id'] = $plugin_id;
775        $arr_sqlval_plugin['plugin_name'] = $arrPluginInfo['PLUGIN_NAME'];
776        $arr_sqlval_plugin['plugin_code'] = $arrPluginInfo['PLUGIN_CODE'];
777        $arr_sqlval_plugin['class_name'] = $arrPluginInfo['CLASS_NAME'];
778        $arr_sqlval_plugin['author'] = $arrPluginInfo['AUTHOR'];
779        // AUTHOR_SITE_URLが定義されているか判定.
780        $author_site_url = $arrPluginInfo['AUTHOR_SITE_URL'];
781        if ($author_site_url !== null) {
782            $arr_sqlval_plugin['author_site_url'] = $arrPluginInfo['AUTHOR_SITE_URL'];
783        }
784        // PLUGIN_SITE_URLが定義されているか判定.
785        $plugin_site_url = $arrPluginInfo['PLUGIN_SITE_URL'];
786        if ($plugin_site_url !== null) {
787            $arr_sqlval_plugin['plugin_site_url'] = $plugin_site_url;
788        }
789        $arr_sqlval_plugin['plugin_version'] = $arrPluginInfo['PLUGIN_VERSION'];
790        $arr_sqlval_plugin['compliant_version'] = $arrPluginInfo['COMPLIANT_VERSION'];
791        $arr_sqlval_plugin['plugin_description'] = $arrPluginInfo['DESCRIPTION'];
792        $arr_sqlval_plugin['priority'] = 0;
793        $arr_sqlval_plugin['enable'] = PLUGIN_ENABLE_FALSE;
794        $arr_sqlval_plugin['update_date'] = 'CURRENT_TIMESTAMP';
795        $objQuery->insert('dtb_plugin', $arr_sqlval_plugin);
796
797        // フックポイントをDB登録.
798        $hook_point = $arrPluginInfo['HOOK_POINTS'];
799        if ($hook_point !== null) {
800            /**
801             * FIXME コードが重複しているため、要修正
802             */
803            // フックポイントが配列で定義されている場合
804            if (is_array($hook_point)) {
805                foreach ($hook_point as $h) {
806                    $arr_sqlval_plugin_hookpoint = array();
807                    $id = $objQuery->nextVal('dtb_plugin_hookpoint_plugin_hookpoint_id');
808                    $arr_sqlval_plugin_hookpoint['plugin_hookpoint_id'] = $id;
809                    $arr_sqlval_plugin_hookpoint['plugin_id'] = $plugin_id;
810                    $arr_sqlval_plugin_hookpoint['hook_point'] = $h[0];
811                    $arr_sqlval_plugin_hookpoint['callback'] = $h[1];
812                    $arr_sqlval_plugin_hookpoint['update_date'] = 'CURRENT_TIMESTAMP';
813                    $objQuery->insert('dtb_plugin_hookpoint', $arr_sqlval_plugin_hookpoint);
814                }
815            // 文字列定義の場合
816            } else {
817                $array_hook_point = explode(',', $hook_point);
818                foreach ($array_hook_point as $h) {
819                    $arr_sqlval_plugin_hookpoint = array();
820                    $id = $objQuery->nextVal('dtb_plugin_hookpoint_plugin_hookpoint_id');
821                    $arr_sqlval_plugin_hookpoint['plugin_hookpoint_id'] = $id;
822                    $arr_sqlval_plugin_hookpoint['plugin_id'] = $plugin_id;
823                    $arr_sqlval_plugin_hookpoint['hook_point'] = $h;
824                    $arr_sqlval_plugin_hookpoint['update_date'] = 'CURRENT_TIMESTAMP';
825                    $objQuery->insert('dtb_plugin_hookpoint', $arr_sqlval_plugin_hookpoint);
826                }
827            }
828        }
829    }
830
831    /**
832     * ファイルを読み込む.
833     *
834     * @param string $file_path クラスのpath
835     * @param string $key エラー情報のキー.
836     * @return array $arrErr エラー情報を格納した連想配列.
837     */
838    function requirePluginFile($file_path, $key)
839    {
840        $arrErr = array();
841        if (file_exists($file_path)) {
842            require_once $file_path;
843        } else {
844            $arrErr[$key] = '※ ' . $file_path .'の読み込みに失敗しました。<br/>';
845        }
846        return $arrErr;
847    }
848
849    /**
850     * インスタンスを生成し、指定のメソッドを実行する.
851     *
852     * @param object $obj インスタンス
853     * @param string $class_name クラス名
854     * @param string $exec_func 実行するメソッド名.
855     * @return array $arrErr エラー情報を格納した連想配列.
856     *
857     */
858    function execPlugin($obj, $class_name, $exec_func)
859    {
860        $objPluginInstaller = new SC_Plugin_Installer($exec_func, $obj);
861
862        $arrErr = array();
863        if (method_exists($class_name, $exec_func) === true) {
864            $ret = call_user_func_array(
865                    array($class_name, $exec_func),
866                    array($obj, $objPluginInstaller));
867            if (!(is_null($ret) || $ret === true)) {
868                $arrErr[$obj['plugin_code']] = $ret;
869            }
870            $arrInstallErr = $objPluginInstaller->execPlugin();
871            if ($arrInstallErr) {
872                $arrErr['plugin_file'] = "プラグインのインストールにしっぱいしました.<br/>";
873            }
874        } else {
875            $arrErr['plugin_file'] = '※ ' . $class_name . '.php に' . $exec_func . 'が見つかりません。<br/>';
876        }
877       
878        return $arrErr;
879    }
880
881    /**
882     * プラグインアーカイブを解凍する.
883     *
884     * @param string $path アーカイブパス
885     * @return boolean Archive_Tar::extractModify()のエラー
886     */
887    function unpackPluginArchive($path)
888    {
889        // 圧縮フラグTRUEはgzip解凍をおこなう
890        $tar = new Archive_Tar($path, true);
891
892        $dir = dirname($path);
893        $file_name = basename($path);
894
895        // 拡張子を切り取る
896        $unpacking_name = preg_replace("/(\.tar|\.tar\.gz)$/", '', $file_name);
897
898        // 指定されたフォルダ内に解凍する
899        $result = $tar->extractModify($dir. '/', $unpacking_name);
900        GC_Utils_Ex::gfPrintLog('解凍:' . $dir.'/'.$file_name.'->'.$dir.'/'.$unpacking_name);
901        // 解凍元のファイルを削除する.
902        unlink($path);
903
904        return $result;
905    }
906
907    /**
908     * plugin_idをキーにdtb_pluginのstatusを更新します.
909     *
910     * @param int $plugin_id プラグインID
911     * @param int $enable_flg 有効フラグ
912     * @return integer 更新件数
913     */
914    function updatePluginEnable($plugin_id, $enable_flg)
915    {
916        $objQuery =& SC_Query_Ex::getSingletonInstance();
917        // UPDATEする値を作成する。
918        $sqlval['enable'] = $enable_flg;
919        $sqlval['update_date'] = 'CURRENT_TIMESTAMP';
920        $where = 'plugin_id = ?';
921        // UPDATEの実行
922        $ret = $objQuery->update('dtb_plugin', $sqlval, $where, array($plugin_id));
923        return $ret;
924    }
925
926    /**
927     * plugin_idをキーにdtb_plugin, dtb_plugin_hookpointから物理削除します.
928     *
929     * @param int $plugin_id プラグインID.
930     * @param string $plugin_code プラグインコード.
931     * @return array $arrErr エラー情報を格納した連想配列.
932     */
933    function deletePlugin($plugin_id, $plugin_code)
934    {
935        $arrErr = array();
936        $objQuery =& SC_Query_Ex::getSingletonInstance();
937        $objQuery->begin();
938
939        SC_Plugin_Util_Ex::deletePluginByPluginId($plugin_id);
940
941        if (SC_Helper_FileManager_Ex::deleteFile($this->getPluginDir($plugin_code)) === false) {
942            // TODO エラー処理
943        }
944
945        if (SC_Helper_FileManager_Ex::deleteFile($this->getHtmlPluginDir($plugin_code)) === false) {
946            // TODO エラー処理
947        }
948
949        $objQuery->commit();
950
951        return $arrErr;
952    }
953
954    /**
955     * ファイルがあるかを判定します.
956     *
957     * @param string $plugin_dir 対象ディレクトリ.
958     * @param string $file_name ファイル名.
959     * @return boolean
960     */
961    function isContainsFile($plugin_dir, $file_name)
962    {
963        if (file_exists($plugin_dir) && is_dir($plugin_dir)) {
964            if ($handle = opendir($plugin_dir)) {
965                while (($item = readdir($handle)) !== false) {
966                    if ($item === $file_name) return true;
967                }
968            }
969            closedir($handle);
970        }
971        return false;
972    }
973
974    /**
975     * アーカイブ内に指定のファイルが存在するかを判定します.
976     *
977     * @param Archive_Tar $tar_obj
978     * @param string $file_path 判定するファイルパス
979     * @return boolean
980     */
981    function checkContainsFile($tar_obj, $file_path)
982    {
983        // ファイル一覧を取得
984        $arrayFile = $tar_obj->listContent();
985        foreach ($arrayFile as  $value) {
986            if ($value['filename'] === $file_path) return true;
987        }
988        return false;
989    }
990
991    /**
992     * ディレクトリを作成します.
993     *
994     * @param string $dir_path 作成するディレクトリのパス
995     * @return void
996     */
997    function makeDir($dir_path)
998    {
999        // ディレクトリ作成
1000        if (!file_exists($dir_path)) {
1001            mkdir($dir_path);
1002        }
1003    }
1004
1005    /**
1006     * エラー情報が格納されているか判定します.
1007     *
1008     * @param array $arrErr エラー情報を格納した連想配列.
1009     * @return boolean.
1010     */
1011    function isError($error)
1012    {
1013        if (is_array($error) && count($error) > 0) {
1014            return true;
1015        }
1016        return false;
1017    }
1018
1019}
Note: See TracBrowser for help on using the repository browser.