Hook.class.php 4.0 KB

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