source: branches/version-2_12-dev/data/class/helper/SC_Helper_Plugin.php @ 21455

Revision 21455, 13.7 KB checked in by h_yoshimoto, 12 years ago (diff)

#1603 #1632 プラグインの管理画面を作成しました。それに伴うエンジン部分の修正。

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2012 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24/**
25 * プラグインのヘルパークラス.
26 *
27 * @package Helper
28 * @version $Id$
29 */
30class SC_Helper_Plugin {
31    // プラグインのインスタンスの配列.
32    var $arrPluginInstances = array();
33    // プラグインのアクションの配列.
34    var $arrRegistedPluginActions = array();
35    // プラグインのIDの配列.
36    var $arrPluginIds = array();
37
38    /**
39     * 有効なプラグインのロード. プラグインエンジンが有効になっていない場合は
40     * プラグインエンジン自身のインストール処理を起動する
41     *
42     * @return void
43     */
44    function load() {
45
46        if (!defined('CONFIG_REALFILE') || !file_exists(CONFIG_REALFILE)) return; // インストール前
47        if (SC_Utils_Ex::sfIsInstallFunction()) return; // インストール中
48
49        // 有効なプラグインを取得
50        $arrPluginDataList = $this->getEnablePlugin();
51        // pluginディレクトリを取得
52        $arrPluginDirectory = $this->getPluginDirectory();
53
54        foreach ($arrPluginDataList as $arrPluginData) {
55            // プラグイン本体ファイル名が取得したプラグインディレクトリ一覧にある事を確認
56            if (array_search($arrPluginData['plugin_code'], $arrPluginDirectory) !== false ) {
57                // プラグイン本体ファイルをrequire.
58                require_once(PLUGIN_UPLOAD_REALDIR . $arrPluginData['plugin_code'] . '/' . $arrPluginData['plugin_code'] . '.php');
59               
60                // プラグインのインスタンス生成.
61                $objPlugin = new $arrPluginData['plugin_code']($arrPluginData);
62                // メンバ変数にプラグインのインスタンスを登録.
63                $this->arrPluginInstances[$arrPluginData['plugin_id']] = $objPlugin;
64                $this->arrPluginIds[] = $arrPluginData['plugin_id'];
65                // ローカルフックポイントの登録.
66                $this->registLocalHookPoint($objPlugin, $arrPluginData['rank']);
67                // スーパーフックポイントの登録.
68                $this->registSuperHookPoint($objPlugin, HOOK_POINT_PREPROCESS, 'preProcess', $arrPluginData['rank']);
69                $this->registSuperHookPoint($objPlugin, HOOK_POINT_PROCESS, 'process', $arrPluginData['rank']);
70            }
71        }
72    }
73
74    /**
75     * SC_Helper_Plugin オブジェクトを返す(Singletonパターン)
76     *
77     * @return object SC_Helper_Pluginオブジェクト
78     */
79    function getSingletonInstance() {
80        if (!isset($GLOBALS['_SC_Helper_Plugin_instance']) || is_null($GLOBALS['_SC_Helper_Plugin_instance'])) {
81            $GLOBALS['_SC_Helper_Plugin_instance'] =& new SC_Helper_Plugin_Ex();
82            $GLOBALS['_SC_Helper_Plugin_instance']->load();
83        }
84        return $GLOBALS['_SC_Helper_Plugin_instance'];
85    }
86
87    /**
88     * プラグイン実行
89     *
90     * @param string $hook_point フックポイント
91     * @param array  $arrArgs    コールバック関数へ渡す引数
92     * @return void
93     */
94    function doAction($hook_point, $arrArgs = array()) {
95        if (is_array($arrArgs) === false) {
96            array(&$arrArgs);
97        }
98
99        if (array_key_exists($hook_point, $this->arrRegistedPluginActions)
100            && is_array($this->arrRegistedPluginActions[$hook_point])) {
101
102            ksort($this->arrRegistedPluginActions[$hook_point]);
103            foreach ($this->arrRegistedPluginActions[$hook_point] as $priority => $arrFuncs) {
104
105                foreach ($arrFuncs as $func) {
106                    if (!is_null($func['function'])) {
107                        call_user_func_array($func['function'], $arrArgs);
108                    }
109                }
110            }
111        }
112    }
113
114    /**
115     * 稼働中のプラグインを取得する。
116     */
117    function getEnablePlugin(){
118        $objQuery = new SC_Query_Ex();
119        $col = '*';
120        $table = 'dtb_plugin';
121        $where = 'enable = 1';
122        // XXX 2.11.0 互換のため
123        $arrCols = $objQuery->listTableFields($table);
124        if (in_array('rank', $arrCols)) {
125            $objQuery->setOrder('rank DESC');
126        }
127        $arrRet = $objQuery->select($col,$table,$where);
128        return $arrRet;
129    }
130
131    /**
132     * インストールされているプラグインを取得する。
133     *
134     * @return array $arrRet インストールされているプラグイン.
135     */
136    function getAllPlugin(){
137        $objQuery = new SC_Query_Ex();
138        $col = '*';
139        $table = 'dtb_plugin';
140        // XXX 2.11.0 互換のため
141        $arrCols = $objQuery->listTableFields($table);
142        if (in_array('rank', $arrCols)) {
143            $objQuery->setOrder('plugin_id ASC');
144        }
145        $arrRet = $objQuery->select($col,$table);
146        return $arrRet;
147    }
148
149    /**
150     * プラグインIDをキーにプラグインを取得する。
151     *
152     * @param int $plugin_id プラグインID.
153     * @return array プラグインの基本情報.
154     */
155    function getPluginByPluginId($plugin_id){
156        $objQuery = new SC_Query_Ex();
157        $col = '*';
158        $table = 'dtb_plugin';
159        $where = 'plugin_id = ?';
160        // XXX 2.11.0 互換のため
161        $arrCols = $objQuery->listTableFields($table);
162        if (in_array('rank', $arrCols)) {
163            $objQuery->setOrder('rank ASC');
164        }
165        $arrRet = $objQuery->select($col, $table, $where, array($plugin_id));
166        return $arrRet[0];
167    }
168   
169    /**
170     * プラグインコードをキーにプラグインを取得する。
171     *
172     * @param string $plugin_code プラグインコード.
173     * @return array プラグインの基本情報.
174     */
175    function getPluginByPluginCode($plugin_code){
176        $objQuery = new SC_Query_Ex();
177        $col = '*';
178        $table = 'dtb_plugin';
179        $where = 'plugin_code = ?';
180        // XXX 2.11.0 互換のため
181        $arrCols = $objQuery->listTableFields($table);
182        if (in_array('rank', $arrCols)) {
183            $objQuery->setOrder('rank ASC');
184        }
185        $arrRet = $objQuery->select($col, $table, $where, array($plugin_code));
186        return $arrRet[0];
187    }
188
189    /**
190     * プラグインディレクトリの取得
191     *
192     * @return array $arrPluginDirectory
193     */
194    function getPluginDirectory() {
195        $arrPluginDirectory = array();
196        if (is_dir(PLUGIN_UPLOAD_REALDIR)) {
197            if ($dh = opendir(PLUGIN_UPLOAD_REALDIR)) {
198                while (($pluginDirectory = readdir($dh)) !== false) {
199                    $arrPluginDirectory[] = $pluginDirectory;
200                }
201                closedir($dh);
202            }
203        }
204        return $arrPluginDirectory;
205    }
206
207    /**
208     * スーパーフックポイントを登録します.
209     *
210     * @param Object $objPlugin プラグインのインスタンス
211     * @param string $hook_point スーパーフックポイント
212     * @param string $function_name 実行する関数名
213     * @param string $priority 実行順
214     */
215    function registSuperHookPoint($objPlugin, $hook_point, $function_name, $priority) {
216        // スーパープラグイン関数を定義しているかを検証.
217        if (method_exists($objPlugin, $function_name) === true) {
218            // アクションの登録
219            $this->addAction($hook_point, array($objPlugin, $function_name), $priority);
220        }
221    }
222
223    /**
224     * ローカルフックポイントを登録します.
225     *
226     * @param Object $objPlugin プラグインのインスタンス
227     * @param string $priority 実行順
228     */
229    function registLocalHookPoint($objPlugin, $priority) {
230        // ローカルプラグイン関数を定義しているかを検証.
231        if (method_exists($objPlugin, 'regist') === true) {
232            // アクションの登録(プラグイン側に記述)
233            $objPluginHelper =& SC_Helper_Plugin::getSingletonInstance();
234            $objPlugin->regist($objPluginHelper, $priority);
235        }
236    }
237
238    /**
239     * プラグイン コールバック関数を追加する
240     *
241     * @param string   $hook_point フックポイント名
242     * @param callback $function   コールバック関数名
243     * @param string   $priority   同一フックポイント内での実行優先度
244     * @return boolean 成功すればtrue
245     */
246    function addAction($hook_point, $function, $priority) {
247        if (!is_callable($function)) {
248            // TODO エラー処理; コール可能な形式ではありません
249        }
250        $idx = $this->makeActionUniqueId($hook_point, $function, $priority);
251        $this->arrRegistedPluginActions[$hook_point][$priority][$idx] = array('function' => $function);
252        return true;
253    }
254
255    /**
256     * コールバック関数を一意に識別するIDの生成
257     *
258     * @param string   $hook_point フックポイント名
259     * @param callback $function   コールバック関数名
260     * @param integer  $priority   同一フックポイント内での実行優先度
261     * @return string コールバック関数を一意に識別するID
262     */
263    function makeActionUniqueId($hook_point, $function, $priority) {
264        static $filter_id_count = 0;
265
266        if (is_string($function)) {
267            return $function;
268        }
269
270        if (is_object($function)) {
271            $function = array($function, '');
272        } else {
273            $function = (array) $function;
274        }
275
276        if (is_object($function[0])) {
277            if (function_exists('spl_object_hash')) {
278                return spl_object_hash($function[0]) . $function[1];
279            } else {
280                $obj_idx = get_class($function[0]).$function[1];
281                if ( false === $priority)
282                    return false;
283                $obj_idx .= isset($this->arrRegistedPluginActions[$hook_point][$priority])
284                          ? count((array)$this->arrRegistedPluginActions[$hook_point][$priority])
285                          : $filter_id_count;
286                $function[0]->wp_filter_id = $filter_id_count;
287                ++$filter_id_count;
288
289                return $obj_idx;
290            }
291        } else if (is_string($function[0])) {
292            return $function[0].$function[1];
293        }
294    }
295
296    /**
297     * 全てのテンプレートを再生成する
298     *
299     * @param boolean $test_mode true の場合、validate のみを行い、実際にテンプレートの再生成は行わない
300     * @return void
301     */
302    function remakeAllTemplates($test_mode = false) {
303        $this->load(); // 最新のデータを読み込みなおす
304        if (!is_writable(PLUGIN_TMPL_CACHE_REALDIR)) {
305            // TODO エラー処理;
306            exit;
307        }
308        // キャッシュテンプレートを削除
309        if ($test_mode === false) {
310            SC_Utils_Ex::deleteFile(PLUGIN_TMPL_CACHE_REALDIR, false);
311        }
312        $objTemplateTransformList = SC_Plugin_Template_Transform_List::getSingletonInstance();
313        $objTemplateTransformList->init();
314        foreach ($this->arrPluginInstances as $objPlugin) {
315            // TODO 関数チェック;
316            $objPlugin->setTemplateTransformer();
317        }
318        // トランスフォーム実行
319        $objTemplateTransformList->transformAll($test_mode);
320    }
321
322    /**
323     * テンプレートキャッシュファイルのフルパスを返す.
324     *
325     * @param string $tpl_mainpage  返すキャッシュファイルのパスの対象となるテンプレート.
326     * @param object $objPage  ページオブジェクト.
327     */
328    function getPluginTemplateCachePath($objPage) {
329        // main_template の差し替え
330        if (strpos($objPage->tpl_mainpage, SMARTY_TEMPLATES_REALDIR) === 0) {
331            // フルパスで指定された
332            $dir = '';
333            $default_tpl_mainpage = str_replace(SMARTY_TEMPLATES_REALDIR, '', $objPage->tpl_mainpage);
334        } else {
335            // フロントページ or 管理画面を判定
336            $dir = ($objPage instanceof LC_Page_Admin) ? 'admin/' : TEMPLATE_NAME . '/';
337            $default_tpl_mainpage = $objPage->tpl_mainpage;
338        }
339        return PLUGIN_TMPL_CACHE_REALDIR . $dir . $default_tpl_mainpage;
340    }
341
342    /**
343     * ブロックの配列から有効でないpluginのブロックを除外して返します.
344     *
345     * @param array $arrBlocs プラグインのインストールディレクトリ
346     * @return array $arrBlocsサイトルートからメディアディレクトリへの相対パス
347     */
348    function getEnableBlocs($arrBlocs) {
349        foreach ($arrBlocs as $key => $value) {
350            // 有効なpluginのブロック以外.
351            if (!in_array($value['plugin_id'] , $this->arrPluginIds)) {
352                // 通常ブロック以外.
353                if ($value['plugin_id'] != "") {
354                    // ブロック配列から削除する
355                    unset ($arrBlocs[$key]);
356                }
357            }
358        }
359        return $arrBlocs;
360    }
361}
Note: See TracBrowser for help on using the repository browser.