Hook.class.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. static private $tags = array();
  17. /**
  18. * 动态添加插件到某个标签
  19. * @param string $tag 标签名称
  20. * @param mixed $name 插件名称
  21. * @return void
  22. */
  23. static public function add($tag,$name) {
  24. if(!isset(self::$tags[$tag])){
  25. self::$tags[$tag] = array();
  26. }
  27. if(is_array($name)){
  28. self::$tags[$tag] = array_merge(self::$tags[$tag],$name);
  29. }else{
  30. self::$tags[$tag][] = $name;
  31. }
  32. }
  33. /**
  34. * 批量导入插件
  35. * @param array $data 插件信息
  36. * @param boolean $recursive 是否递归合并
  37. * @return void
  38. */
  39. static public function import($data,$recursive=true) {
  40. if(!$recursive){ // 覆盖导入
  41. self::$tags = array_merge(self::$tags,$data);
  42. }else{ // 合并导入
  43. foreach ($data as $tag=>$val){
  44. if(!isset(self::$tags[$tag]))
  45. self::$tags[$tag] = array();
  46. if(!empty($val['_overlay'])){
  47. // 可以针对某个标签指定覆盖模式
  48. unset($val['_overlay']);
  49. self::$tags[$tag] = $val;
  50. }else{
  51. // 合并模式
  52. self::$tags[$tag] = array_merge(self::$tags[$tag],$val);
  53. }
  54. }
  55. }
  56. }
  57. /**
  58. * 获取插件信息
  59. * @param string $tag 插件位置 留空获取全部
  60. * @return array
  61. */
  62. static public function get($tag='') {
  63. if(empty($tag)){
  64. // 获取全部的插件信息
  65. return self::$tags;
  66. }else{
  67. return self::$tags[$tag];
  68. }
  69. }
  70. /**
  71. * 监听标签的插件
  72. * @param string $tag 标签名称
  73. * @param mixed $params 传入参数
  74. * @return void
  75. */
  76. static public function listen($tag, &$params=NULL) {
  77. if(isset(self::$tags[$tag])) {
  78. if(APP_DEBUG) {
  79. G($tag.'Start');
  80. trace('[ '.$tag.' ] --START--','','INFO');
  81. }
  82. foreach (self::$tags[$tag] as $name) {
  83. APP_DEBUG && G($name.'_start');
  84. $result = self::exec($name, $tag,$params);
  85. if(APP_DEBUG){
  86. G($name.'_end');
  87. trace('Run '.$name.' [ RunTime:'.G($name.'_start',$name.'_end',6).'s ]','','INFO');
  88. }
  89. if(false === $result) {
  90. // 如果返回false 则中断插件执行
  91. return ;
  92. }
  93. }
  94. if(APP_DEBUG) { // 记录行为的执行日志
  95. trace('[ '.$tag.' ] --END-- [ RunTime:'.G($tag.'Start',$tag.'End',6).'s ]','','INFO');
  96. }
  97. }
  98. return;
  99. }
  100. /**
  101. * 执行某个插件
  102. * @param string $name 插件名称
  103. * @param string $tag 方法名(标签名)
  104. * @param Mixed $params 传入的参数
  105. * @return void
  106. */
  107. static public function exec($name, $tag,&$params=NULL) {
  108. if('Behavior' == substr($name,-8) ){
  109. // 行为扩展必须用run入口方法
  110. $tag = 'run';
  111. }
  112. $addon = new $name();
  113. return $addon->$tag($params);
  114. }
  115. }