Hook.class.php
4 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
<?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
*/
public static 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
*/
public static function import($data, $recursive = true)
{
if (!$recursive) {
// 覆盖导入
self::$tags = array_merge(self::$tags, $data);
} else {
// 合并导入
foreach ($data as $tag => $val) {
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
*/
public static function get($tag = '')
{
if (empty($tag)) {
// 获取全部的插件信息
return self::$tags;
} else {
return self::$tags[$tag];
}
}
/**
* 监听标签的插件
* @param string $tag 标签名称
* @param mixed $params 传入参数
* @return void
*/
public static 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
*/
public static function exec($name, $tag, &$params = null)
{
if ('Behavior' == substr($name, -8)) {
// 行为扩展必须用run入口方法
$tag = 'run';
}
$addon = new $name();
return $addon->$tag($params);
}
}