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

Revision 21416, 13.5 KB checked in by h_yoshimoto, 12 years ago (diff)

#1603 mtb_constantsへのinsert処理追加、コメント・copyrightの修正、Plugin周りの定数名を修正

  • 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['class_name'], $arrPluginDirectory) !== false ) {
57                // プラグイン本体ファイルをrequire.
58                require_once(PLUGIN_UPLOAD_REALDIR . $arrPluginData['class_name'] . '/' . $arrPluginData['class_name'] . '.php');
59                // プラグインのインスタンス生成.
60                $objPlugin = new $arrPluginData['class_name']($arrPluginData);
61                // メンバ変数にプラグインのインスタンスを登録.
62                $this->arrPluginInstances[$arrPluginData['plugin_id']] = $objPlugin;
63                $this->arrPluginIds[] = $arrPluginData['plugin_id'];
64                // ローカルフックポイントの登録.
65                $this->registLocalHookPoint($objPlugin, $arrPluginData['rank']);
66                // スーパーフックポイントの登録.
67                $this->registSuperHookPoint($objPlugin, HOOK_POINT_PREPROCESS, 'preProcess', $arrPluginData['rank']);
68                $this->registSuperHookPoint($objPlugin, HOOK_POINT_PROCESS, 'process', $arrPluginData['rank']);
69            }
70        }
71    }
72
73    /**
74     * SC_Helper_Plugin オブジェクトを返す(Singletonパターン)
75     *
76     * @return object SC_Helper_Pluginオブジェクト
77     */
78    function getSingletonInstance() {
79        if (!isset($GLOBALS['_SC_Helper_Plugin_instance']) || is_null($GLOBALS['_SC_Helper_Plugin_instance'])) {
80            $GLOBALS['_SC_Helper_Plugin_instance'] =& new SC_Helper_Plugin_Ex();
81            $GLOBALS['_SC_Helper_Plugin_instance']->load();
82        }
83        return $GLOBALS['_SC_Helper_Plugin_instance'];
84    }
85
86    /**
87     * プラグイン実行
88     *
89     * @param string $hook_point フックポイント
90     * @param array  $arrArgs    コールバック関数へ渡す引数
91     * @return void
92     */
93    function doAction($hook_point, $arrArgs = array()) {
94        if(is_array($arrArgs) === false) {
95            array(&$arrArgs);
96        }
97
98        if (array_key_exists($hook_point, $this->arrRegistedPluginActions)
99            && is_array($this->arrRegistedPluginActions[$hook_point])) {
100
101            ksort($this->arrRegistedPluginActions[$hook_point]);
102            foreach ($this->arrRegistedPluginActions[$hook_point] as $priority => $arrFuncs) {
103               
104                foreach ($arrFuncs as $func) {
105                    if (!is_null($func['function'])) {
106                        call_user_func_array($func['function'], $arrArgs);
107                    }
108                }
109            }
110        }
111    }
112
113    /**
114     * 稼働中のプラグインを取得する。
115     */
116    function getEnablePlugin(){
117        $objQuery = new SC_Query_Ex();
118        $col = '*';
119        $table = 'dtb_plugin';
120        $where = 'enable = 1 AND del_flg = 0';
121        // XXX 2.11.0 互換のため
122        $arrCols = $objQuery->listTableFields($table);
123        if (in_array('rank', $arrCols)) {
124            $objQuery->setOrder('rank DESC');
125        }
126        $arrRet = $objQuery->select($col,$table,$where);
127        return $arrRet;
128    }
129
130    /**
131     * インストールされているプラグインを取得する。
132     */
133    function getAllPlugin(){
134        $objQuery = new SC_Query_Ex();
135        $col = '*';
136        $table = 'dtb_plugin';
137        $where = 'del_flg = 0';
138        // XXX 2.11.0 互換のため
139        $arrCols = $objQuery->listTableFields($table);
140        if (in_array('rank', $arrCols)) {
141            $objQuery->setOrder('rank DESC');
142        }
143        $arrRet = $objQuery->select($col,$table,$where);
144        return $arrRet;
145    }
146
147    /**
148     * プラグインディレクトリの取得
149     *
150     * @return array $arrPluginDirectory
151     */
152    function getPluginDirectory() {
153        $arrPluginDirectory = array();
154        if (is_dir(PLUGIN_UPLOAD_REALDIR)) {
155            if ($dh = opendir(PLUGIN_UPLOAD_REALDIR)) {
156                while (($pluginDirectory = readdir($dh)) !== false) {
157                    $arrPluginDirectory[] = $pluginDirectory;
158                }
159                closedir($dh);
160            }
161        }
162        return $arrPluginDirectory;
163    }
164
165    /**
166     * スーパーフックポイントを登録します.
167     *
168     * @param Object $objPlugin プラグインのインスタンス
169     * @param string $hook_point スーパーフックポイント
170     * @param string $function_name 実行する関数名
171     * @param string $priority 実行順
172     */
173    function registSuperHookPoint($objPlugin, $hook_point, $function_name, $priority) {
174        // スーパープラグイン関数を定義しているかを検証.
175        if(method_exists($objPlugin, $function_name) === true){
176            // アクションの登録
177            $this->addAction($hook_point, array($objPlugin, $function_name), $priority);
178        }
179    }
180
181    /**
182     * ローカルフックポイントを登録します.
183     *
184     * @param Object $objPlugin プラグインのインスタンス
185     * @param string $priority 実行順
186     */
187    function registLocalHookPoint($objPlugin, $priority) {
188        // ローカルプラグイン関数を定義しているかを検証.
189        if(method_exists($objPlugin, 'regist') === true){
190            // アクションの登録(プラグイン側に記述)
191            $objPluginHelper =& SC_Helper_Plugin::getSingletonInstance();
192            $objPlugin->regist($objPluginHelper, $priority);
193        }
194    }
195
196    /**
197     * プラグイン コールバック関数を追加する
198     *
199     * @param string   $hook_point フックポイント名
200     * @param callback $function   コールバック関数名
201     * @param string   $priority   同一フックポイント内での実行優先度
202     * @return boolean 成功すればtrue
203     */
204    function addAction($hook_point, $function, $priority) {
205        if (!is_callable($function)){
206            // TODO エラー処理; コール可能な形式ではありません
207        }
208        $idx = $this->makeActionUniqueId($hook_point, $function, $priority);
209        $this->arrRegistedPluginActions[$hook_point][$priority][$idx] = array('function' => $function);
210        return true;
211    }
212
213    /**
214     * コールバック関数を一意に識別するIDの生成
215     *
216     * @param string   $hook_point フックポイント名
217     * @param callback $function   コールバック関数名
218     * @param integer  $priority   同一フックポイント内での実行優先度
219     * @return string コールバック関数を一意に識別するID
220     */
221    function makeActionUniqueId($hook_point, $function, $priority) {
222        static $filter_id_count = 0;
223
224        if (is_string($function)) {
225            return $function;
226        }
227
228        if (is_object($function)) {
229            $function = array($function, '');
230        } else {
231            $function = (array) $function;
232        }
233
234        if (is_object($function[0])) {
235            if (function_exists('spl_object_hash')) {
236                return spl_object_hash($function[0]) . $function[1];
237            } else {
238                $obj_idx = get_class($function[0]).$function[1];
239                if ( false === $priority )
240                    return false;
241                $obj_idx .= isset($this->arrRegistedPluginActions[$hook_point][$priority])
242                          ? count((array)$this->arrRegistedPluginActions[$hook_point][$priority])
243                          : $filter_id_count;
244                $function[0]->wp_filter_id = $filter_id_count;
245                ++$filter_id_count;
246
247                return $obj_idx;
248            }
249        } else if ( is_string($function[0]) ) {
250            return $function[0].$function[1];
251        }
252    }
253
254    /**
255     * 全てのテンプレートを再生成する
256     *
257     * @param boolean $test_mode true の場合、validate のみを行い、実際にテンプレートの再生成は行わない
258     * @return void
259     */
260    function remakeAllTemplates($test_mode = false) {
261        $this->load(); // 最新のデータを読み込みなおす
262        if (!is_writable(PLUGIN_TMPL_CACHE_REALDIR)) {
263            // TODO エラー処理;
264            exit;
265        }
266        // キャッシュテンプレートを削除
267        if ($test_mode === false) {
268            $this->unlinkRecurse(PLUGIN_TMPL_CACHE_REALDIR, false);
269        }
270        $objTemplateTransformList = SC_Plugin_Template_Transform_List::getSingletonInstance();
271        $objTemplateTransformList->init();
272        foreach ($this->arrPluginInstances as $objPlugin) {
273            // TODO 関数チェック;
274            $objPlugin->setTemplateTransformer();
275        }
276        // トランスフォーム実行
277        $objTemplateTransformList->transformAll($test_mode);
278    }
279
280    /**
281     * 指定されたパスの配下を再帰的に unlink
282     *
283     * @param string  $path       削除対象のディレクトリまたはファイルのパス
284     * @param boolean $del_myself $pathそのものを削除するか. true なら削除する.
285     * @return void
286     */
287    function unlinkRecurse($path, $del_myself = true) {
288        if (!file_exists($path)) {
289            // TODO エラー処理; パスが存在しません
290        } elseif (is_dir($path)) {
291            // ディレクトリ
292            $handle = opendir($path);
293            if (!$handle) {
294                // TODO エラー処理; ディレクトリが開けませんでした
295            }
296
297            while (($item = readdir($handle)) !== false) {
298                if ($item === '.' || $item === '..') continue;
299                $cur_path = $path . '/' . $item;
300                if (is_dir($cur_path)) SC_Helper_Plugin::unlinkRecurse($cur_path);
301                else @unlink($cur_path);
302            }
303            closedir($handle);
304           
305            // ディレクトリを削除
306            if ($del_myself) @rmdir($path);
307        } else {
308            // ファイルが指定された
309            @unlink($path);
310        }
311    }
312
313    /**
314     * テンプレートキャッシュファイルのフルパスを返す.
315     *
316     * @param string $tpl_mainpage  返すキャッシュファイルのパスの対象となるテンプレート.
317     * @param object $objPage  ページオブジェクト.
318     */
319    function getPluginTemplateCachePath($objPage) {
320        // main_template の差し替え
321        if (strpos($objPage->tpl_mainpage, SMARTY_TEMPLATES_REALDIR) === 0) {
322            // フルパスで指定された
323            $dir = '';
324            $default_tpl_mainpage = str_replace(SMARTY_TEMPLATES_REALDIR, '', $objPage->tpl_mainpage);
325        } else {
326            // フロントページ or 管理画面を判定
327            $dir = ($objPage instanceof LC_Page_Admin) ? 'admin/' : TEMPLATE_NAME . '/';
328            $default_tpl_mainpage = $objPage->tpl_mainpage;
329        }
330        return PLUGIN_TMPL_CACHE_REALDIR . $dir . $default_tpl_mainpage;
331    }
332
333    /**
334     * ブロックの配列から有効でないpluginのブロックを除外して返します.
335     *
336     * @param array $arrBlocs プラグインのインストールディレクトリ
337     * @return array $arrBlocsサイトルートからメディアディレクトリへの相対パス
338     */
339    function getEnableBlocs($arrBlocs) {
340        foreach ($arrBlocs as $key => $value) {
341            // 有効なpluginのブロック以外.
342            if(!in_array($value['plugin_id'] , $this->arrPluginIds)) {
343                // 通常ブロック以外.
344                if($value['plugin_id'] != ""){
345                    // ブロック配列から削除する
346                    unset ($arrBlocs[$key]);
347                }
348            }
349        }
350        return $arrBlocs;
351    }
352}
Note: See TracBrowser for help on using the repository browser.