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

Revision 21884, 42.4 KB checked in by Yammy, 9 years ago (diff)

バージョン毎のプラグイン利用に必要なモジュールのチェック機構

refs #1845

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