Hook.class.php 5.5 KB

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