1
0

OC_Hook.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. use Psr\Log\LoggerInterface;
  8. class OC_Hook {
  9. public static $thrownExceptions = [];
  10. private static $registered = [];
  11. /**
  12. * connects a function to a hook
  13. *
  14. * @param string $signalClass class name of emitter
  15. * @param string $signalName name of signal
  16. * @param string|object $slotClass class name of slot
  17. * @param string $slotName name of slot
  18. * @return bool
  19. *
  20. * This function makes it very easy to connect to use hooks.
  21. *
  22. * TODO: write example
  23. */
  24. public static function connect($signalClass, $signalName, $slotClass, $slotName) {
  25. // If we're trying to connect to an emitting class that isn't
  26. // yet registered, register it
  27. if (!array_key_exists($signalClass, self::$registered)) {
  28. self::$registered[$signalClass] = [];
  29. }
  30. // If we're trying to connect to an emitting method that isn't
  31. // yet registered, register it with the emitting class
  32. if (!array_key_exists($signalName, self::$registered[$signalClass])) {
  33. self::$registered[$signalClass][$signalName] = [];
  34. }
  35. // don't connect hooks twice
  36. foreach (self::$registered[$signalClass][$signalName] as $hook) {
  37. if ($hook['class'] === $slotClass and $hook['name'] === $slotName) {
  38. return false;
  39. }
  40. }
  41. // Connect the hook handler to the requested emitter
  42. self::$registered[$signalClass][$signalName][] = [
  43. 'class' => $slotClass,
  44. 'name' => $slotName
  45. ];
  46. // No chance for failure ;-)
  47. return true;
  48. }
  49. /**
  50. * emits a signal
  51. *
  52. * @param string $signalClass class name of emitter
  53. * @param string $signalName name of signal
  54. * @param mixed $params default: array() array with additional data
  55. * @return bool true if slots exists or false if not
  56. * @throws \OCP\HintException
  57. * @throws \OC\ServerNotAvailableException Emits a signal. To get data from the slot use references!
  58. *
  59. * TODO: write example
  60. */
  61. public static function emit($signalClass, $signalName, $params = []) {
  62. // Return false if no hook handlers are listening to this
  63. // emitting class
  64. if (!array_key_exists($signalClass, self::$registered)) {
  65. return false;
  66. }
  67. // Return false if no hook handlers are listening to this
  68. // emitting method
  69. if (!array_key_exists($signalName, self::$registered[$signalClass])) {
  70. return false;
  71. }
  72. // Call all slots
  73. foreach (self::$registered[$signalClass][$signalName] as $i) {
  74. try {
  75. call_user_func([ $i['class'], $i['name'] ], $params);
  76. } catch (Exception $e) {
  77. self::$thrownExceptions[] = $e;
  78. \OCP\Server::get(LoggerInterface::class)->error($e->getMessage(), ['exception' => $e]);
  79. if ($e instanceof \OCP\HintException) {
  80. throw $e;
  81. }
  82. if ($e instanceof \OC\ServerNotAvailableException) {
  83. throw $e;
  84. }
  85. }
  86. }
  87. return true;
  88. }
  89. /**
  90. * clear hooks
  91. * @param string $signalClass
  92. * @param string $signalName
  93. */
  94. public static function clear($signalClass = '', $signalName = '') {
  95. if ($signalClass) {
  96. if ($signalName) {
  97. self::$registered[$signalClass][$signalName] = [];
  98. } else {
  99. self::$registered[$signalClass] = [];
  100. }
  101. } else {
  102. self::$registered = [];
  103. }
  104. }
  105. /**
  106. * DO NOT USE!
  107. * For unit tests ONLY!
  108. */
  109. public static function getHooks() {
  110. return self::$registered;
  111. }
  112. }