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

Revision 23605, 44.5 KB checked in by kimoto, 10 years ago (diff)

#2448 typo修正・ソース整形・ソースコメントの改善 for 2.13.3

Scrutinizer Auto-Fixes

This patch was automatically generated as part of the following inspection:
 https://scrutinizer-ci.com/g/nobuhiko/EC-CUBE/inspections/d8722894-69a6-4b1b-898d-43618035c60d

Enabled analysis tools:

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