[aur-dev] [PATCH 2/2] Added simple hook framework in preperation to solve FS#30109. Signed-off-by: Mario (xenji) Mueller <mario at xenji.com>
mario at xenji.com
mario at xenji.com
Mon Sep 17 08:11:43 EDT 2012
From: "Mario (xenji) Mueller" <mario at xenji.com>
Signed-off-by: Mario (xenji) Mueller <mario at xenji.com>
---
web/lib/acctfuncs.inc.php | 5 ++
web/lib/aur.inc.php | 4 ++
web/lib/hookdef.php | 113 ++++++++++++++++++++++++++++++++++++++++++++++
web/lib/hooks/account.php | 4 ++
4 files changed, 126 insertions(+)
create mode 100644 web/lib/hookdef.php
create mode 100644 web/lib/hooks/account.php
diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php
index 6f7c98a..0ccd235 100644
--- a/web/lib/acctfuncs.inc.php
+++ b/web/lib/acctfuncs.inc.php
@@ -188,6 +188,11 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
} else {
# account created/modified, tell them so.
#
+
+ // trigger hook and pass the fully escaped array to it.
+ // see lib/hookdef.php for details.
+ trigger_hook('newAccount', $escaped);
+
print __("The account, %s%s%s, has been successfully created.",
"<b>", htmlspecialchars($U,ENT_QUOTES), "</b>");
print "<p>\n";
diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php
index 6dcbb34..50c4bce 100644
--- a/web/lib/aur.inc.php
+++ b/web/lib/aur.inc.php
@@ -11,6 +11,10 @@ include_once('translator.inc.php');
set_lang();
include_once("config.inc.php");
+
+include_once("hookdef.php");
+include_once("hooks/account.php");
+
include_once("routing.inc.php");
include_once("version.inc.php");
include_once("acctfuncs.inc.php");
diff --git a/web/lib/hookdef.php b/web/lib/hookdef.php
new file mode 100644
index 0000000..19d93d5
--- /dev/null
+++ b/web/lib/hookdef.php
@@ -0,0 +1,113 @@
+<?php
+/*
+ * This hook system is similar to the ones in wordpress or durpal.
+ *
+ * It is meant to be simple and effective, whithout any overengineered stuff.
+ * If you think about making it "better" by creating a OOP version with
+ * interfaces, please take a look at the rest of the system and ask yourself
+ * if this really fits in here.
+ */
+
+// LIST OF EXISTING HOOKS
+/*
+ * USE THIS PATTERN:
+ *
+ * filename.php hookname (payload1, payload2, ...)
+ *
+ * acctfuncs.inc.php newAccount (array($U, $E, $P, $salt, $R, $L, $I, $K))
+ */
+
+/**
+ * Triggers the hook by it's name and passes the given payload to the hook.
+ *
+ * The trigger does not return anything as they must be used in a fire-and-
+ * forget manner.
+ *
+ * The functions for the hooks must follow a naming convention to be triggered
+ * by this function. Keep in mind that the weight goes from 1 (lowest) to
+ * PHP_INT_MAX (highest). The higher the number the earlier it will be executed.
+ *
+ * The pattern is:
+ *
+ * <code>hook_$hookname_$weight_uniqueId</code>
+ *
+ * @example <code>
+ * function hook_registerUser_15_SendmailOnReg($sUsername) { do something }
+ * // or
+ * function hook_updatePackage_1_SendmailOnUpdt($sPkgName, $sUsername) {
+ * do something
+ * }
+ * </code>
+ *
+ * @param string $sHookName The hook name to be triggered
+ * @param mixed $mPayload A nullable payload to pass to the hook.
+ *
+ * @return void
+ * @author xenji <mario at xenji.com>
+ * @since 2012-09-17
+ */
+function trigger_hook($sHookName, $mPayload)
+{
+ error_log('Started ' . __FUNCTION__);
+ $aUserDefFunctions = get_defined_functions()['user'];
+ error_log('Got defined fncs: ' . implode(', ', $aUserDefFunctions));
+
+ // We just want to process the relevant hooks, no other hooks or fnc.
+ $oFilter = new \CallbackFilterIterator(
+ new \ArrayIterator($aUserDefFunctions),
+ function ($mCurr, $iKey, $oIter) use ($sHookName)
+ {
+ // keep this with three eq. signs, it is needed!
+ if (
+ strpos($mCurr, 'hook_') !== false
+ && strpos(strtolower($mCurr), strtolower($sHookName)) !== false
+ )
+ {
+ error_log('Hookname OK: '. $sHookName . ' in ' . $mCurr);
+ return true;
+ }
+ return false;
+ });
+
+
+ $oHookQueue = new \HookQueue();
+
+ foreach ($oFilter as $sFunction)
+ {
+ // $_ => unused declaration, borrowed from scala's convention
+ list($_, $_, $iWeight, $_) = explode('_', $sFunction);
+ error_log("Inserting $sFunction into Queue with weight $iWeight");
+ $oHookQueue->insert($sFunction, (int)$iWeight);
+ }
+
+ // We just want to have the function name, not the prio
+ $oHookQueue->setExtractFlags(\SplPriorityQueue::EXTR_DATA);
+ if ($oHookQueue->count() > 0)
+ {
+ $oHookQueue->top();
+
+ foreach ($oHookQueue as $sFunction)
+ {
+ call_user_func($sFunction, $mPayload);
+ }
+ }
+}
+
+/**
+ * This is an implementation of the prio queue, which fits perfectly for our
+ * need to sort the hooks in relation to their weight.
+ *
+ * Taken from the example on php.net, because I was too lazy to type the text.
+ *
+ * @see http://php.net/manual/de/class.splpriorityqueue.php
+ * @author xenji <mario at xenji.com>
+ * @since 2012-09-17
+ */
+class HookQueue extends SplPriorityQueue
+{
+ public function compare($priority1, $priority2)
+ {
+ if ($priority1 === $priority2) return 0;
+ return $priority1 < $priority2 ? -1 : 1;
+ }
+}
diff --git a/web/lib/hooks/account.php b/web/lib/hooks/account.php
new file mode 100644
index 0000000..aea57b5
--- /dev/null
+++ b/web/lib/hooks/account.php
@@ -0,0 +1,4 @@
+<?php
+function hook_newAccount_1_SendMailForNewAccount($aAccountData) {
+ // send a mail if you want to...
+}
\ No newline at end of file
--
1.7.12
More information about the aur-dev
mailing list