modulemanager: Allow setting priority of stanza handlers
[prosody.git] / core / modulemanager.lua
index b166682b485090d5ee03b77781d87695ff35cf47..6d857d5945ab48a20f1097a355f05c4c82569bd8 100644 (file)
@@ -49,6 +49,7 @@ local modulehelpers = setmetatable({}, { __index = _G });
 local features_table = multitable_new();
 local handler_table = multitable_new();
 local hooked = multitable_new();
+local hooks = multitable_new();
 local event_hooks = multitable_new();
 
 local NULL = {};
@@ -69,11 +70,16 @@ function load_modules_for_host(host)
                                disabled_set[module] = true;
                        end
                end
-               for _, module in ipairs(modules_enabled) do
+               for _, module in ipairs({"presence", "message", "iq"}) do
                        if not disabled_set[module] then
                                load(host, module);
                        end
                end
+               for _, module in ipairs(modules_enabled) do
+                       if not disabled_set[module] and not is_loaded(host, module) then
+                               load(host, module);
+                       end
+               end
        end
 
        -- Load modules from just this host
@@ -165,6 +171,13 @@ function unload(host, name, ...)
                end
        end
        event_hooks:remove(host, name);
+       -- unhook event handlers hooked by module:hook
+       for event, handlers in pairs(hooks:get(host, name) or NULL) do
+               for handler in pairs(handlers or NULL) do
+                       (hosts[host] or prosody).events.remove_handler(event, handler);
+               end
+       end
+       hooks:remove(host, name);
        return true;
 end
 
@@ -352,13 +365,23 @@ function api:add_event_hook(name, handler)
 end
 
 function api:fire_event(...)
-       local r = (hosts[self.host] or prosody).events.fire_event(...);
-       if r ~= nil then return r; end
-       return eventmanager.fire_event(...);
+       return (hosts[self.host] or prosody).events.fire_event(...);
 end
 
-function api:hook(event, handler)
-       (hosts[self.host] or prosody).events.add_handler(event, handler);
+function api:hook(event, handler, priority)
+       hooks:set(self.host, self.name, event, handler, true);
+       (hosts[self.host] or prosody).events.add_handler(event, handler, priority);
+end
+
+function api:hook_stanza(xmlns, name, handler, priority)
+       if not handler and type(name) == "function" then
+               -- If only 2 options then they specified no xmlns
+               xmlns, name, handler, priority = nil, xmlns, name, handler;
+       elseif not (handler and name and xmlns) then
+               module:log("warn", "Error: Insufficient parameters to module:hook_stanza()");
+               return;
+       end
+       return api.hook(self, "stanza/"..(xmlns and (xmlns..":") or "")..name, function (data) return handler(data.origin, data.stanza, data); end, priority);
 end
 
 --------------------------------------------------------------------