Hook.class.php
4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2013 http://topthink.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace Think;
/**
* ThinkPHP系统钩子实现
*/
class Hook
{
private static $tags = array();
/**
* 动态添加插件到某个标签
*
* @param string $tag
* 标签名称
* @param mixed $name
* 插件名称
* @return void
*/
static public function add($tag, $name)
{
if (! isset(self::$tags[$tag])) {
self::$tags[$tag] = array();
}
if (is_array($name)) {
self::$tags[$tag] = array_merge(self::$tags[$tag], $name);
} else {
self::$tags[$tag][] = $name;
}
}
/**
* 批量导入插件
*
* @param array $data
* 插件信息
* @param boolean $recursive
* 是否递归合并
* @return void
*/
static public function import($data, $recursive = true)
{
if (! $recursive) { // 覆盖导入
self::$tags = array_merge(self::$tags, $data);
} else { // 合并导入
foreach ($data as $tag => $val) {
// by zhuxun begin. 键值转成小写
// $tag = rstrtolower($tag);
// end.
if (! isset(self::$tags[$tag])) {
self::$tags[$tag] = array();
}
if (! empty($val['_overlay'])) {
// 可以针对某个标签指定覆盖模式
unset($val['_overlay']);
self::$tags[$tag] = $val;
} else {
// 合并模式
self::$tags[$tag] = array_merge(self::$tags[$tag], $val);
}
}
}
}
/**
* 获取插件信息
*
* @param string $tag
* 插件位置 留空获取全部
* @return array
*/
static public function get($tag = '')
{
if (empty($tag)) {
// 获取全部的插件信息
return self::$tags;
} else {
return self::$tags[$tag];
}
}
/**
* 监听标签的插件
*
* @param string $tag
* 标签名称
* @param mixed $params
* 传入参数
* @return void
*/
static public function listen($tag, &$params = null)
{
if (isset(self::$tags[$tag])) {
if (APP_DEBUG) {
G($tag . 'Start');
trace('[ ' . $tag . ' ] --START--', '', 'INFO');
}
foreach (self::$tags[$tag] as $name) {
APP_DEBUG && G($name . '_start');
$result = self::exec($name, $tag, $params);
if (APP_DEBUG) {
G($name . '_end');
trace('Run ' . $name . ' [ RunTime:' . G($name . '_start', $name . '_end', 6) . 's ]', '', 'INFO');
}
if (false === $result) {
// 如果返回false 则中断插件执行
return;
}
}
if (APP_DEBUG) { // 记录行为的执行日志
trace('[ ' . $tag . ' ] --END-- [ RunTime:' . G($tag . 'Start', $tag . 'End', 6) . 's ]', '', 'INFO');
}
}
return;
}
/**
* 执行某个插件
*
* @param string $name
* 插件名称
* @param string $tag
* 方法名(标签名)
* @param Mixed $params
* 传入的参数
* @return void
*/
static public function exec($name, $tag, &$params = null)
{
if ('Behavior' == substr($name, - 8)) {
// 行为扩展必须用run入口方法
$tag = 'run';
}
$addon = new $name();
return $addon->$tag($params);
}
}