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

Revision 22567, 42.6 KB checked in by shutta, 11 years ago (diff)

#2043 (typo修正・ソース整形・ソースコメントの改善 for 2.12.4)
Zend Framework PHP 標準コーディング規約のコーディングスタイルへ準拠。
classおよびfunctionの開始波括弧「{」のスタイルを修正。

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