[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/Extension/ -> Event.php (source)

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