Event.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <?php
  2. // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
  3. namespace dokuwiki\Extension;
  4. use dokuwiki\Logger;
  5. /**
  6. * The Action plugin event
  7. */
  8. class Event
  9. {
  10. /** @var string READONLY event name, objects must register against this name to see the event */
  11. public $name = '';
  12. /** @var mixed|null READWRITE data relevant to the event, no standardised format, refer to event docs */
  13. public $data = null;
  14. /**
  15. * @var mixed|null READWRITE the results of the event action, only relevant in "_AFTER" advise
  16. * event handlers may modify this if they are preventing the default action
  17. * to provide the after event handlers with event results
  18. */
  19. public $result = null;
  20. /** @var bool READONLY if true, event handlers can prevent the events default action */
  21. public $canPreventDefault = true;
  22. /** @var bool whether or not to carry out the default action associated with the event */
  23. protected $runDefault = true;
  24. /** @var bool whether or not to continue propagating the event to other handlers */
  25. protected $mayContinue = true;
  26. /**
  27. * event constructor
  28. *
  29. * @param string $name
  30. * @param mixed $data
  31. */
  32. public function __construct($name, &$data)
  33. {
  34. $this->name = $name;
  35. $this->data =& $data;
  36. }
  37. /**
  38. * @return string
  39. */
  40. public function __toString()
  41. {
  42. return $this->name;
  43. }
  44. /**
  45. * advise all registered BEFORE handlers of this event
  46. *
  47. * if these methods are used by functions outside of this object, they must
  48. * properly handle correct processing of any default action and issue an
  49. * advise_after() signal. e.g.
  50. * $evt = new dokuwiki\Plugin\Doku_Event(name, data);
  51. * if ($evt->advise_before(canPreventDefault) {
  52. * // default action code block
  53. * }
  54. * $evt->advise_after();
  55. * unset($evt);
  56. *
  57. * @param bool $enablePreventDefault
  58. * @return bool results of processing the event, usually $this->runDefault
  59. */
  60. public function advise_before($enablePreventDefault = true)
  61. {
  62. global $EVENT_HANDLER;
  63. $this->canPreventDefault = $enablePreventDefault;
  64. if ($EVENT_HANDLER !== null) {
  65. $EVENT_HANDLER->process_event($this, 'BEFORE');
  66. } else {
  67. Logger::getInstance(Logger::LOG_DEBUG)
  68. ->log($this->name . ':BEFORE event triggered before event system was initialized');
  69. }
  70. return (!$enablePreventDefault || $this->runDefault);
  71. }
  72. /**
  73. * advise all registered AFTER handlers of this event
  74. *
  75. * @param bool $enablePreventDefault
  76. * @see advise_before() for details
  77. */
  78. public function advise_after()
  79. {
  80. global $EVENT_HANDLER;
  81. $this->mayContinue = true;
  82. if ($EVENT_HANDLER !== null) {
  83. $EVENT_HANDLER->process_event($this, 'AFTER');
  84. } else {
  85. Logger::getInstance(Logger::LOG_DEBUG)->
  86. log($this->name . ':AFTER event triggered before event system was initialized');
  87. }
  88. }
  89. /**
  90. * trigger
  91. *
  92. * - advise all registered (<event>_BEFORE) handlers that this event is about to take place
  93. * - carry out the default action using $this->data based on $enablePrevent and
  94. * $this->_default, all of which may have been modified by the event handlers.
  95. * - advise all registered (<event>_AFTER) handlers that the event has taken place
  96. *
  97. * @param null|callable $action
  98. * @param bool $enablePrevent
  99. * @return mixed $event->results
  100. * the value set by any <event>_before or <event> handlers if the default action is prevented
  101. * or the results of the default action (as modified by <event>_after handlers)
  102. * or NULL no action took place and no handler modified the value
  103. */
  104. public function trigger($action = null, $enablePrevent = true)
  105. {
  106. if (!is_callable($action)) {
  107. $enablePrevent = false;
  108. if ($action !== null) {
  109. trigger_error(
  110. 'The default action of ' . $this .
  111. ' is not null but also not callable. Maybe the method is not public?',
  112. E_USER_WARNING
  113. );
  114. }
  115. }
  116. if ($this->advise_before($enablePrevent) && is_callable($action)) {
  117. $this->result = call_user_func_array($action, [&$this->data]);
  118. }
  119. $this->advise_after();
  120. return $this->result;
  121. }
  122. /**
  123. * stopPropagation
  124. *
  125. * stop any further processing of the event by event handlers
  126. * this function does not prevent the default action taking place
  127. */
  128. public function stopPropagation()
  129. {
  130. $this->mayContinue = false;
  131. }
  132. /**
  133. * may the event propagate to the next handler?
  134. *
  135. * @return bool
  136. */
  137. public function mayPropagate()
  138. {
  139. return $this->mayContinue;
  140. }
  141. /**
  142. * preventDefault
  143. *
  144. * prevent the default action taking place
  145. */
  146. public function preventDefault()
  147. {
  148. $this->runDefault = false;
  149. }
  150. /**
  151. * should the default action be executed?
  152. *
  153. * @return bool
  154. */
  155. public function mayRunDefault()
  156. {
  157. return $this->runDefault;
  158. }
  159. /**
  160. * Convenience method to trigger an event
  161. *
  162. * Creates, triggers and destroys an event in one go
  163. *
  164. * @param string $name name for the event
  165. * @param mixed $data event data
  166. * @param callable $action (optional, default=NULL) default action, a php callback function
  167. * @param bool $canPreventDefault (optional, default=true) can hooks prevent the default action
  168. *
  169. * @return mixed the event results value after all event processing is complete
  170. * by default this is the return value of the default action however
  171. * it can be set or modified by event handler hooks
  172. */
  173. static public function createAndTrigger($name, &$data, $action = null, $canPreventDefault = true)
  174. {
  175. $evt = new Event($name, $data);
  176. return $evt->trigger($action, $canPreventDefault);
  177. }
  178. }