If you are an extension developer, you may have come across a scenario where you need to change core behavior but there isn't an available hook or other means to go about achieving it. It's tempting to override the core file by copying it into your extension and then making your changes. Avoid it if you can.
An extension that overrides a core file has two giant strikes against it. First off, any changes to the file in core, whether security fixes or new features or whatever, will not be seen until you incorporate those same changes into your override. Secondly, an extension containing a core override is automatically incompatible with every other extension that overrides the same file.
Before committing to a core override, please do your due diligence. Make sure none of the existing hooks can be used. Ask in chat. Maybe post an issue in GitLab suggesting a new hook be added to core, etc. You might spend a little more time upfront, but avoiding the hassle of maintaining your override will be worth the effort.
Once you're certain the override is required, you can avoid the first strike mentioned above by subclassing the core class. Depending on your needs, this may or may not be possible, e.g. if you need to change behavior in the middle of an existing method then subclassing wouldn't really work. This method doesn't get past the second strike because it is still technically an override.
I recently created an extension, https://lab.civicrm.org/extensions/btrmsgtpl, where I wanted to capture the data being sent to a message template. There is a hook I could use for this, hook_civicrm_alterMailParams()
, but it needed to be the last extension called. Before I realized I could use EventDispatcher
to make sure that happened, I tried the technique shown in MessageTemplate.php
and it worked without issues.
The gist of it:
- override the file in the extension, but don't start with a copy from core.
- read in the original core class.
- do some string replacing.
- evalutate it.
- subclass it.
As far as "do some string replacing", you might be able to just blanket search/replace on the class name and on self::
and be fine, I didn't try that. I wanted to be very specific in what I replaced. Depending on the class you want to override, you may have to do some adjusting, i.e. YMMV.