KXStudio Website https://kx.studio/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
6.1KB

  1. <?php
  2. /**
  3. * Class: Trigger
  4. * Controls and keeps track of all of the Triggers and events.
  5. */
  6. class Trigger {
  7. # Array: $priorities
  8. # Custom prioritized callbacks.
  9. public $priorities = array();
  10. # Array: $called
  11. # Keeps track of called Triggers.
  12. private $called = array();
  13. # Array: $exists
  14. # Caches trigger exist states.
  15. private $exists = array();
  16. /**
  17. * Function: cmp
  18. * Sorts actions by priority when used with usort.
  19. */
  20. private function cmp($a, $b) {
  21. if (empty($a) or empty($b)) return 0;
  22. return ($a["priority"] < $b["priority"]) ? -1 : 1 ;
  23. }
  24. /**
  25. * Function: call
  26. * Calls a trigger, passing any additional arguments to it.
  27. *
  28. * Parameters:
  29. * $name - The name of the trigger, or an array of triggers to call.
  30. */
  31. public function call($name) {
  32. if (is_array($name)) {
  33. $return = null;
  34. foreach ($name as $index => $call) {
  35. $args = func_get_args();
  36. $args[0] = $call;
  37. if ($index + 1 == count($name))
  38. return $this->exists($call) ? call_user_func_array(array($this, "call"), $args) : $return ;
  39. else
  40. $return = $this->exists($call) ? call_user_func_array(array($this, "call"), $args) : $return ;
  41. }
  42. }
  43. if (!$this->exists($name))
  44. return false;
  45. $arguments = func_get_args();
  46. array_shift($arguments);
  47. $return = null;
  48. $this->called[$name] = array();
  49. if (isset($this->priorities[$name])) { # Predefined priorities?
  50. usort($this->priorities[$name], array($this, "cmp"));
  51. foreach ($this->priorities[$name] as $action) {
  52. $return = call_user_func_array($action["function"], $arguments);
  53. $this->called[$name][] = $action["function"];
  54. }
  55. }
  56. foreach (Modules::$instances as $module)
  57. if (!in_array(array($module, $name), $this->called[$name]) and is_callable(array($module, $name)))
  58. $return = call_user_func_array(array($module, $name), $arguments);
  59. return $return;
  60. }
  61. /**
  62. * Function: filter
  63. * Filters a variable through a trigger's actions. Similar to <call>, except this is stackable and is intended to
  64. * modify something instead of inject code.
  65. *
  66. * Any additional arguments passed to this function are passed to the function being called.
  67. *
  68. * Parameters:
  69. * &$target - The variable to filter.
  70. * $name - The name of the trigger.
  71. *
  72. * Returns:
  73. * $target, filtered through any/all actions for the trigger $name.
  74. */
  75. public function filter(&$target, $name) {
  76. if (is_array($name))
  77. foreach ($name as $index => $filter) {
  78. $args = func_get_args();
  79. $args[0] =& $target;
  80. $args[1] = $filter;
  81. if ($index + 1 == count($name))
  82. return $target = call_user_func_array(array($this, "filter"), $args);
  83. else
  84. $target = call_user_func_array(array($this, "filter"), $args);
  85. }
  86. if (!$this->exists($name))
  87. return $target;
  88. $arguments = func_get_args();
  89. array_shift($arguments);
  90. array_shift($arguments);
  91. $this->called[$name] = array();
  92. if (isset($this->priorities[$name]) and usort($this->priorities[$name], array($this, "cmp")))
  93. foreach ($this->priorities[$name] as $action) {
  94. $call = call_user_func_array($this->called[$name][] = $action["function"],
  95. array_merge(array(&$target), $arguments));
  96. $target = fallback($call, $target);
  97. }
  98. foreach (Modules::$instances as $module)
  99. if (!in_array(array($module, $name), $this->called[$name]) and is_callable(array($module, $name))) {
  100. $call = call_user_func_array(array($module, $name),
  101. array_merge(array(&$target), $arguments));
  102. $target = fallback($call, $target);
  103. }
  104. return $target;
  105. }
  106. /**
  107. * Function: remove
  108. * Unregisters a given $action from a $trigger.
  109. *
  110. * Parameters:
  111. * $trigger - The trigger to unregister from.
  112. * $action - The action name.
  113. */
  114. public function remove($trigger, $action) {
  115. foreach ($this->actions[$trigger] as $index => $func) {
  116. if ($func == $action) {
  117. unset($this->actions[$trigger][$key]);
  118. return;
  119. }
  120. }
  121. $this->actions[$trigger]["disabled"][] = $action;
  122. }
  123. /**
  124. * Function: exists
  125. * Checks if there are any actions for a given $trigger.
  126. *
  127. * Parameters:
  128. * $trigger - The trigger name.
  129. *
  130. * Returns:
  131. * @true@ or @false@
  132. */
  133. public function exists($name) {
  134. if (isset($this->exists[$name]))
  135. return $this->exists[$name];
  136. foreach (Modules::$instances as $module)
  137. if (is_callable(array($module, $name)))
  138. return $this->exists[$name] = true;
  139. if (isset($this->priorities[$name]))
  140. return $this->exists[$name] = true;
  141. return $this->exists[$name] = false;
  142. }
  143. /**
  144. * Function: current
  145. * Returns a singleton reference to the current class.
  146. */
  147. public static function & current() {
  148. static $instance = null;
  149. return $instance = (empty($instance)) ? new self() : $instance ;
  150. }
  151. }