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

Revision 22994, 43.1 KB checked in by adachi, 11 years ago (diff)

#2181 エラーメッセージ修正

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