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

Revision 22796, 11.5 KB checked in by h_yoshimoto, 11 years ago (diff)

#2236 2.12.3リリース以降の2.12-devへのコミット差し戻し

  • 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/**
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    // HeadNaviブロックの配列
38    var $arrHeadNaviBlocsByPlugin = array();
39
40    /**
41     * 有効なプラグインのロード. プラグインエンジンが有効になっていない場合は
42     * プラグインエンジン自身のインストール処理を起動する
43     *
44     * @return void
45     */
46    function load($plugin_activate_flg = true) {
47
48        if (!defined('CONFIG_REALFILE') || !file_exists(CONFIG_REALFILE)) return; // インストール前
49        if (GC_Utils_Ex::isInstallFunction()) return; // インストール中
50        if ($plugin_activate_flg === false) return;
51        // 有効なプラグインを取得
52        $arrPluginDataList = SC_Plugin_Util_Ex::getEnablePlugin();
53        // pluginディレクトリを取得
54        $arrPluginDirectory = SC_Plugin_Util_Ex::getPluginDirectory();
55        foreach ($arrPluginDataList as $arrPluginData) {
56            // プラグイン本体ファイル名が取得したプラグインディレクトリ一覧にある事を確認
57            if (array_search($arrPluginData['plugin_code'], $arrPluginDirectory) !== false) {
58                // プラグイン本体ファイルをrequire.
59                require_once PLUGIN_UPLOAD_REALDIR . $arrPluginData['plugin_code'] . '/' . $arrPluginData['class_name'] . '.php';
60
61                // プラグインのインスタンス生成.
62                $objPlugin = new $arrPluginData['class_name']($arrPluginData);
63                // メンバ変数にプラグインのインスタンスを登録.
64                $this->arrPluginInstances[$arrPluginData['plugin_id']] = $objPlugin;
65                $this->arrPluginIds[] = $arrPluginData['plugin_id'];
66                // ローカルフックポイントの登録.
67                $this->registerLocalHookPoint($objPlugin, $arrPluginData['priority']);
68                // スーパーフックポイントの登録.
69                $this->registerSuperHookPoint($objPlugin, HOOK_POINT_PREPROCESS, 'preProcess', $arrPluginData['priority']);
70                $this->registerSuperHookPoint($objPlugin, HOOK_POINT_PROCESS, 'process', $arrPluginData['priority']);
71            }
72        }
73    }
74
75    /**
76     * SC_Helper_Plugin オブジェクトを返す(Singletonパターン)
77     *
78     * @return object SC_Helper_Pluginオブジェクト
79     */
80    static function getSingletonInstance($plugin_activate_flg = true) {
81        if (!isset($GLOBALS['_SC_Helper_Plugin_instance'])) {
82            // プラグインのローダーがDB接続を必要とするため、
83            // SC_Queryインスタンス生成後のみオブジェクトを生成する。
84            require_once CLASS_EX_REALDIR . 'SC_Query_Ex.php';
85            if (is_null(SC_Query_Ex::getPoolInstance())) {
86                return false;
87            }
88
89            $GLOBALS['_SC_Helper_Plugin_instance'] = new SC_Helper_Plugin_Ex();
90            $GLOBALS['_SC_Helper_Plugin_instance']->load($plugin_activate_flg);
91        }
92        return $GLOBALS['_SC_Helper_Plugin_instance'];
93    }
94
95    /**
96     * プラグイン実行
97     *
98     * @param string $hook_point フックポイント
99     * @param array  $arrArgs    コールバック関数へ渡す引数
100     * @return void
101     */
102    function doAction($hook_point, $arrArgs = array()) {
103        if (is_array($arrArgs) === false) {
104            array(&$arrArgs);
105        }
106
107        if ($hook_point == 'loadClassFileChange') {
108            $arrSaveArgs = $arrArgs;
109            $arrClassName = array();
110            $arrClassPath = array();
111        }
112
113        if (array_key_exists($hook_point, $this->arrRegistedPluginActions)
114            && is_array($this->arrRegistedPluginActions[$hook_point])) {
115
116            krsort($this->arrRegistedPluginActions[$hook_point]);
117            foreach ($this->arrRegistedPluginActions[$hook_point] as $arrFuncs) {
118
119                foreach ($arrFuncs as $func) {
120                    if (!is_null($func['function'])) {
121                        if ($hook_point == 'loadClassFileChange') {
122                            $classname = $arrSaveArgs[0];
123                            $classpath = $arrSaveArgs[1];
124                            $arrTempArgs = array(&$classname, &$classpath);
125
126                            call_user_func_array($func['function'], $arrTempArgs);
127
128                            if ($classname !== $arrSaveArgs[0]) {
129                                $arrClassName[] = $classname;
130                                $arrClassPath[] = $classpath;
131                            }
132                        } else {
133                            call_user_func_array($func['function'], $arrArgs);
134                        }
135                    }
136                }
137            }
138
139            if ($hook_point == 'loadClassFileChange') {
140                if (count($arrClassName) > 0) {
141                    $arrArgs[0] = $arrClassName;
142                    $arrArgs[1] = $arrClassPath;
143                }
144            }
145        }
146    }
147
148    /**
149     * スーパーフックポイントを登録します.
150     *
151     * @param Object $objPlugin プラグインのインスタンス
152     * @param string $hook_point スーパーフックポイント
153     * @param string $function_name 実行する関数名
154     * @param string $priority 実行順
155     */
156    function registerSuperHookPoint($objPlugin, $hook_point, $function_name, $priority) {
157        // スーパープラグイン関数を定義しているかを検証.
158        if (method_exists($objPlugin, $function_name) === true) {
159            // アクションの登録
160            $this->addAction($hook_point, array($objPlugin, $function_name), $priority);
161        }
162    }
163
164    /**
165     * ローカルフックポイントを登録します.
166     *
167     * @param Object $objPlugin プラグインのインスタンス
168     * @param string $priority 実行順
169     */
170    function registerLocalHookPoint($objPlugin, $priority) {
171        // ローカルプラグイン関数を定義しているかを検証.
172        if (method_exists($objPlugin, 'register') === true) {
173            // アクションの登録(プラグイン側に記述)
174            $objPluginHelper =& SC_Helper_Plugin::getSingletonInstance();
175            $objPlugin->register($objPluginHelper, $priority);
176        }
177    }
178
179    /**
180     * プラグイン コールバック関数を追加する
181     *
182     * @param string   $hook_point フックポイント名
183     * @param callback $function   コールバック関数名
184     * @param string   $priority   同一フックポイント内での実行優先度
185     * @return boolean 成功すればtrue
186     */
187    function addAction($hook_point, $function, $priority = 0) {
188        if (!is_callable($function)) {
189            // TODO エラー処理; コール可能な形式ではありません
190        }
191        $idx = $this->makeActionUniqueId($hook_point, $function, $priority);
192        $this->arrRegistedPluginActions[$hook_point][$priority][$idx] = array('function' => $function);
193        return true;
194    }
195
196    /**
197     * コールバック関数を一意に識別するIDの生成
198     *
199     * @param string   $hook_point フックポイント名
200     * @param callback $function   コールバック関数名
201     * @param integer  $priority   同一フックポイント内での実行優先度
202     * @return string コールバック関数を一意に識別するID
203     */
204    function makeActionUniqueId($hook_point, $function, $priority) {
205        static $filter_id_count = 0;
206
207        if (is_string($function)) {
208            return $function;
209        }
210
211        if (is_object($function)) {
212            $function = array($function, '');
213        } else {
214            $function = (array) $function;
215        }
216
217        if (is_object($function[0])) {
218            if (function_exists('spl_object_hash')) {
219                return spl_object_hash($function[0]) . $function[1];
220            } else {
221                $obj_idx = get_class($function[0]).$function[1];
222                if ( false === $priority)
223                    return false;
224                $obj_idx .= isset($this->arrRegistedPluginActions[$hook_point][$priority])
225                         ? count((array)$this->arrRegistedPluginActions[$hook_point][$priority])
226                         : $filter_id_count;
227                $function[0]->wp_filter_id = $filter_id_count;
228                ++$filter_id_count;
229
230                return $obj_idx;
231            }
232        } else if (is_string($function[0])) {
233            return $function[0].$function[1];
234        }
235    }
236
237    /**
238     * ブロックの配列から有効でないpluginのブロックを除外して返します.
239     *
240     * @param array $arrBlocs プラグインのインストールディレクトリ
241     * @return array $arrBlocsサイトルートからメディアディレクトリへの相対パス
242     */
243    function getEnableBlocs($arrBlocs) {
244        foreach ($arrBlocs as $key => $value) {
245            // 有効なpluginのブロック以外.
246            if (!in_array($value['plugin_id'] , $this->arrPluginIds)) {
247                // 通常ブロック以外.
248                if ($value['plugin_id'] != '') {
249                    // ブロック配列から削除する
250                    unset ($arrBlocs[$key]);
251                }
252            }
253        }
254        return $arrBlocs;
255    }
256
257   /**
258     * テンプレートのヘッダに追加するPHPのURLをセットする
259     *
260     * @param string $url PHPファイルのURL
261     * @return void
262     */
263    function setHeadNavi($url) {
264        $this->arrHeadNaviBlocsByPlugin[$url] = TARGET_ID_HEAD;
265    }
266
267    /**
268     * PHPのURLをテンプレートのヘッダに追加する
269     *
270     * @param array|null $arrBlocs  配置情報を含めたブロックの配列
271     * @return void
272     */
273    function setHeadNaviBlocs(&$arrBlocs) {
274        foreach ($this->arrHeadNaviBlocsByPlugin as $key => $value) {
275            $arrBlocs[] = array(
276                'target_id' =>$value,
277                'php_path' => $key
278            );
279        }
280    }
281
282    /**
283     * Utility function to set a hook point.
284     *
285     * @param string    $hook_point  hook point
286     * @param array     $arrArgs     argument passing to callback function
287     * @param boolean   $plugin_activate_flg
288     * @return void
289     */
290    public static function hook($hook_point, $arrArgs = array(), $plugin_activate_flg = PLUGIN_ACTIVATE_FLAG) {
291        $objPlugin = SC_Helper_Plugin::getSingletonInstance($plugin_activate_flg);
292        $objPlugin->doAction($hook_point, $arrArgs);
293    }
294}
Note: See TracBrowser for help on using the repository browser.