RFC - Hooks for Module Developers
Initial Author: Akitson (Ashley Kitson)
Date: 06/06/2007
Analysing By: Nekro Complements By: GibaPhp
Objective
This functional requirement is for the Xoops CMS
and is aimed at providing hooks into the Xoops core where module
developers can extend the functionality of the core.
The primary aim is to avoid end users having to
hack core files in order to make certain modules work.
Classic examples of this are:
Peak's Protector - requires mainfile.php to be
hacked in order to provide site security.
XBS's Metatags - requires footer.php to be hacked
to provide MetaTag Keyword optimisation.
Myreferrer (Solo) - Required interference
in....
XT-Monitor (Claudia/GibaPhp) - Required adjust in
/class/logger.php , no final da function addQuery(...)
RWbanner (TheRpLima) - Necessary adjust in
fhooter.php
Statistic - required mainfile adjust or
fhooter.php
And others modules not mencioned here.
There are others.
Limitations
Xoops is not event driven.
If it were then module developers could hook into
events to provide this functionality. Xoops is (currently) mainly
procedural and this puts a limitation on how this functionality can
be added to it. Any technical design that is a result of this
requirement should bear in mind what is likely to happen in the
future and should be written to take advantage of the core objects
within Xoops so that any future changes in Xoops core processing
strategy can take this functionality with it. As a result of this
limitation, some thought needs to be put into where hook points are
placed in the xoops core files.
Design proposal
1/ A new class (inherited from XoopsObject) is
defined: XoopsHook()
XoopsHook() has an underlying data table to store
non transitory information.
All processing of hooks is done via
XoopsHook().
2/ xoops_version.php for modules is extended to
allow $modversion[] to carry new data for module installation
i.e.
$modversion['hook'][$n]['file_to_run'] =
"example.php";
$modversion['hook'][$n]['file_where_run'] =
"mainfile.php";
$modversion['hook'][$n]['stage_where_run'] =
1;
A new subdirectory for modules is defined called
'hooks' where hook files are located, e.g. in this example for a
module called 'mymodule', the hook is in
XOOPS_ROOT_PATH/modules/mymodule/hooks/example.php.
Module installation processes this new
$modversion information and stores it in the hooks data table,
e.g.
Table xoops_hooks
id : 1
modid : 23
file_where_run: mainfile.php
stage_where_run: 1
file_to_run: example.com
run_order: 0
3/ Deinstallation of the module clears any hook
data. Any module update must be handled to cater for changed
hooks.
4/ A new administration screen is provided that
allows the administrator to;
a - change the run order of multiple hooks vying
for the same file and stage spot
b - deactivate/activate a hook (deinstallation of
a hook occurs when the module is deinstalled)
5/ A singleton xoops_hook() object is
instantiated on Xoops Core startup that reads in the data for the
hook table and stores in memory.
6/ At strategic points in mainfile.php,
footer.php and header.php (as a starting point - we need to canvas
module developers here,) a call is made to xoops_hook() object
i.e.
xoops_hook-
>run($current_file_name,$stageId);
This call quickly sees if any code is 'hooked' in
and if required, runs it.
7/ Documentation is provided for developers to
allow them to create hooks
- and as importantly, rules and parameters are
set within which such hooks
must run.
Caveat
There may be better ways of doing this.