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

Revision 22856, 42.5 KB checked in by Seasoft, 11 years ago (diff)

#2043 (typo修正・ソース整形・ソースコメントの改善 for 2.13.0)

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