This patch is an attempt to provide a clean way of overriding drupal node hooks, nodeapi hook, as well as submit & validate hooks.
I faced a situation where I needed to override a module's nodeapi hook on op = submit & prepare to handle doing some processing on an uploaded file before the module saved it. Furthermore, this change was related to code in a custom module I created, so submitting a patch was out. Only way I had was to either change the module itself, which I knew would be calling for trouble, or in somehow implementing an override for nodeapi externally, thus this patch.
This patch will allow inheritance like capabilities in drupal's node hooks, nodeapi hook & submit/validate hooks. I'm not too well acquainted with core modules and files so feel free to update the code if it needs any changes or fails to account for anything. By mainly adding a function called
override_<target_module>_<target_hook>(<params>)
As an example
override_video_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL)
The override function which can be implemented in an external module will be called instead of the module's own. As with object oriented approach, the overridden function can call its parent by issuing a module_invoke. Thus in nodeapi, for example, you can do a module_invoke on all relevant ops except prepare and submit which your new module will override.
| Comment | File | Size | Author |
|---|---|---|---|
| allow_overrides.patch | 2.24 KB | Ashraf Amayreh |
Comments
Comment #1
RobRoy commentedCode style issues, see http://drupal.org/node/318. What if there is a module called "override"? What if two modules want to override something?
I think we need to put more effort towards chx's before/after hook ordering patch and then allow another module to pull a hook out of that lst once it has been calculated. If nodeapi hooks for modules foo, bar, baz are going to be called, to a invoke_all('hook_alter', 'nodeapi') or something so other modules could pull bar_nodeapi out of that list. Something like that seems more The Drupal Way.
Comment #2
Ashraf Amayreh commentedThe point is only one override function is allowed. There's no logic in having two modules implementing overrides, which override will "win"? If two modules implement an override, then they're most likely doing conflicting things and only one should be enabled. This feature is not implemented to be liberally used but only when a code change inside a module hook can't be avoided for cleaner implementation.
Name conflicts are as likely as name conflicts with the current hooks which must be avoided by convention. Same case applies here, override functions should be avoided by convention. I looked at the coding standards but didn't notice anything wrong (actually I just skimmed over it heh)
I'm not really aware of chx's patch, could you point me to that?
Comment #3
Ashraf Amayreh commentedahhh, a module called override. ok, that's different.
Comment #4
Ashraf Amayreh commentedumm... I still can't see where a naming conflict could occur even if there's a module called override, but if a conflict could actually occur, could you provide a sample? Override was really an arbitrary name, so anything else should do.
RobRoy, could you advise on some other naming scheme here?
Comment #5
nedjoThis is pretty much a duplicate of http://drupal.org/node/29428, which was, correctly, marked won't fix after due discussion. I think the same reasoning applies here.
Comment #6
killes@www.drop.org commentedack
Comment #7
wmostrey commentedWith both issues not being fixed, what manner is offered to override functions? Are we to use the mutli-site trick?
Comment #8
Ashraf Amayreh commentedI've given an example of a case where an override is a must, if there's an alternative implementation please share it here. Either that or hacking the module itself which is definitely wrong.
Only one override is allowed, so it's not really a feature that should be used by contributed modules at all, but by custom modules that are not contributed. NOT IMPLEMENTING it could even be a requirement for contributed modules. Without this, we would promote hacking contributed modules on live sites when an override can do. When the required functionality can only be achieved by an override, then better implement it separately than hack the module itself even if it's a non contributed module. In the least, this would ease porting of real live sites that use custom modules to later drupal versions.
I'm open for different implementation suggestions or naming conventions, but as I see it, this feature is a must to prevent the -currently unavoidable- massive module hacking that's hindering many sites from porting to new drupal versions.
Comment #9
nedjoIMO this is a duplicate of the other issue I pointed to, http://drupal.org/node/29428 (slightly different, yes, but substantively the same). The needed review is in that issue, and the outcome of 'won't fix' was correct. Please don't comment further in this issue.
Reopening debates that have been satisfactorily concluded is not a service unless you can bring something substantively new.
Since presumably you weren't aware of the previous discussion, it was perfectly appropriate to bring it up and suggest a solution. No one is trying to discourage you from contributing--far from it. Keep in mind I'm saying this as the one who posted the original patch in the other issue and would still like a solution to the issue you raised :)
You could consider reopening the other issue, but that would only make sense if you could demonstrably show that you had addressed the compelling arguments made against the approach. You haven't made that case yet.
Comment #10
nedjoUnless we consider that overriding hooks is different enough from overriding functions. In which case, this should be switched back to 'won't fix'.
Comment #11
Ashraf Amayreh commentedI just stumbled on yet another case where hook overriding is needed. A contributed module, let's call it abc implements nodeapi op "rss item" and returns an array with additional RSS fields. In my custom site, I don't want this module to add these fields. How can I prevent it from doing that without modifying the module itself?
If hook overriding is allowed, then all I have to do is implement a custom module that contains something like this :
I really haven't tested this specific case, but I'm simply trying to show that hook overriding can indeed be useful and would avoid hacking the module itself. This simply isolates all overrides in one module and greatly eases the operation of updating to next drupal versions. Compare this to what needs to be done if modules were hacked to add the functionality that would otherwise be impossible to implement!
Comment #12
RobRoy commentedI think this is useful, but again would say that better hook ordering could accomplish most of this. Your module could say it wants its nodeapi hook to go after 'abc_nodeapi' and then should be able to alter the current rss item additions. In the case of 'rss item' we'd need another patch so we could modify it by reference like hook_form_alter() so we could just unset that (but that is another patch).
Or, we could follow suit of more 'alter' hooks. So one round is to find all rss item additions, then invoke all on 'rss item alter' to allow modules to modify those additions. This is more overhead though.
chx's before/after stuff is in his sandbox. IIRC no issue yet.
Comment #13
moshe weitzman commentedsometimes hacking modules is the *right solution*. this usually happens when drupal chooses not to support certain configurations/features because of the complexity they bring to developers or to the UI. IMO this is an example.
Comment #14
pwolanin commentedAt first review, I also don't see why this could not be accomplished with hook ordering (as proposed) or the current mechanism of module weighting.
Comment #15
Ashraf Amayreh commentedThe workaround using nodeapi and weight manipulation above would work on the condition that another patch be submitted that would change how nodeapi handles the "rss item" op. Even if it were to be created, it is clearly going to be more complex and add a considerable overhead compared to overriding.
Moreover, this may work with op='rss item', but let's assume (from what I actually saw firsthand) that a module implements a number of permissions but you need more granular control in your custom site. You could create a module with your own granular permissions, but then you'd need to hack the module's code to check for these new permissions. If overriding is allowed, then you can override the implementation in an external module like so:
Another scenario would be a module that adds a file upload field to another node's form, then saves that file in nodeapi's submit op. If you need a reference to the newly created file from a custom module you can't get it. But if you override the submit op you'll have full control.
I'm not proposing that this feature be widely used or allowed to be used at all in contributed modules, but having it will prevent a whole lot of module hacking in custom drupal sites that can't upgrade because there are hundreds of hacks distributed over a large number of modules. This would make upgrading to new drupal versions a whole lot easier. Also, hook overriding is an emulation of a sound OO approach called inheritance, we can't simply keep complicating things to avoid using a very legitimate OO approach when it is genuinely needed.
Comment #16
Scott Reynolds commentedWhat about this?
Introduce to Drupal a way to register and unregister hooks. Then provide an UI for the admin of the site to unregister hooks.
Comment #17
Scott Reynolds commented@ #15 hooking has little to nothing to do with OO.
Comment #18
RobRoy commentedI'd suggest we continue with some feedback at http://drupal.org/node/116165.
Comment #19
Ashraf Amayreh commentedThe ability to override some functionality to provide custom ones while being able to utilize the original functionality is inheritance. I'm not saying this *makes* drupal an OO system, I'm only saying this capability is very useful in an OO environment or any other.
Comment #20
chx commentedDrupal does not cater to fulfill every single possible scenario -- does not and of course can not. You got killes , nedjo and moshe stating that this won't happen, what more do you need? Me? OK, then I also say it won't happen. Discussion is closed. Let's focus on the registry patch that RobRoy is linked -- which already has Dries' semi-approval unlike this issue which has basically every high profile developer's disapproval.
Comment #21
Ashraf Amayreh commentedwhatever
Comment #22
RobRoy commented@mistknight: I hope you don't take these comments too hard. Some of my first issues got ripped apart and I took offense, but definitely no offense is intended in these reviews. Just keep 'em coming and you'll nail one! :D
Comment #23
manimaran commentedi need to override core module function.
ie--->
node.module
in this node module i need to over ride "FUNCTION NODE_SHOW()",in which place i have to write the override function?
help me...