Skip to content

[3.0] Shows which mod added each integration hook - #9700

Open
albertlast wants to merge 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/hooks-show-owning-mod
Open

albertlast wants to merge 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/hooks-show-owning-mod

Conversation

@albertlast

Copy link
Copy Markdown
Collaborator

Description

Admin → Maintenance → Hooks lists every function attached to every hook, with its file and its status. What it never says is which mod put it there.

That is the question an admin actually has. Something on the forum misbehaves, the list shows forty entries across a dozen hooks, and finding out which mod owns the one that looks suspicious means opening mod files, or uninstalling mods one at a time. The information exists — every package says what it hooks in its package-info.xml — it just isn't shown anywhere.

This adds an "Added By" column naming the package that registered each entry, sortable, so the hooks belonging to one mod can be grouped together:

Hook Name Function Name File Name Added By Status
integrate_load_theme my_mod_load_theme ./Sources/MyMod.php My Mod
integrate_menu_buttons other_mod_buttons ./Sources/OtherMod.php Other Mod
integrate_pre_load some_leftover_function Not from a package

How it works: PackageUtils::getHookOwners() walks the installed packages, reads the hooks each one registers in its package-info.xml, and builds the entry exactly as IntegrationHook::add() stores it, so the two can be matched. A hook a mod registered from its own code, and SMF's own hooks, have no owner and are shown as "Not from a package" rather than being blamed on anything.

Notes on the decisions in it:

  • No new column and no migration. Ownership is derived from the packages themselves, so it works for mods that are already installed rather than only for ones installed after an upgrade.
  • Every install and upgrade block is read, whatever version it is for. Filtering blocks by SMF version was the first attempt and it was wrong: on this branch SMF_VERSION is 3.0 Alpha 5-dev, which does not match a package's for="3.0 - 3.0.99", so the hooks of a perfectly normal mod went unattributed. Entries from a block that never ran match no stored hook, so keeping them costs nothing.
  • Reverse hooks are left out, since those remove a hook rather than adding one.
  • Cost. The page reads the installed packages' package-info.xml. That is much less work than what the page already does, which is to scan every file in Sources/ and parse out the functions each one defines.

Related: #8808 adds an id_package column to a dedicated hooks table and carries it into this list's data, but does not display it. This is the admin-facing half, it works on release-3.0 as it stands today, and if that PR lands the lookup here can be replaced by reading that column.

Testing

tests/Unit/PackageUtilsTest.php covers the reading of the hooks out of a package-info.xml: the entry built for a plain function, for a file plus function, for an instantiated class, hooks added by an upgrade block, blocks for other SMF versions, and reverse hooks.

Verified in the Docker environment as well, with a package installed that registers three hooks, one of them disabled and one an object. All three are attributed to the mod, a hook belonging to no package shows "Not from a package", sorting by the new column groups them, and nothing new appears in log_errors.

Issues References (Fixes|Related|Closes)

Related: #8808, #9695

🤖 Generated with Claude Code

The hooks list tells an admin that a function is attached to a hook, but
not where it came from, so working out which mod is responsible for one
means reading mod files. Each installed package is asked which hooks its
package-info.xml registers, and the list gains a column naming the
package that added each entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Mathias Albert <mathiaspapealbert@hotmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant