[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

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

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