source: branches/version-2_12-dev/data/class/pages/admin/ownersstore/LC_Page_Admin_OwnersStore.php @ 21848

Revision 21848, 40.6 KB checked in by h_yoshimoto, 12 years ago (diff)

#1819 プラグインインストール・アップデート時にtmp/plugin_install・plugin_update以下の削除を先に行なう

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