I have this working great on my dev server.
Features
Why do we want this, what does it offer? With the override system:
- Contribs never touch core files since they are in their own "override" folder
- Core upgrades never overwrite the contrib files they are in their own "override" folder
- Code always has the corefile fallback
- Contribs are dynamic. If you remove or add a file, it will automatically revert to the core or use the contrib respectively
- Contrib code doesn't change, only the folder structure move to the override subfolder
And the goals that are achieved with this are:
- Upgrades do not break contribs (unless there is a major code change in the new version, but it would still be minimal (per-file))
- Contribs can be plug-n-play, and easily unplugged without hours of manual coding
- Admin can disable use of "override" globally with a single configuration option. Returning the store to the default core install
- Paves the way for a package (zip) installer by setting up a framework now that promotes the non-touching of core files
Simple.
Each existing folder gets an override subfolder. For the example we will use the catalog/controller/product.php file:
Now, the core file is in: catalog/controller/product.php
The person making a contrib that modifies the product.php file would create it inside an override folder, that is one subfolder down.
So the new file would go in: catalog/controller/override/product.php
How major is the code change?
The only code change is in the library file for controller loading, which is found at:/library/application/controller.php
Simply do a file_exist check on the override location. If it doesn't exists, fallback to the core version:
Change:
[php]$file = $this->directory . basename($action['class']) . '.php';[/php]
To:
[php]$file = $this->directory . 'override/'. basename($action['class']) . '.php';
if (!file_exists($file)) {
$file = $this->directory . basename($action['class']) . '.php';
}[/php]
Simple!
Do the same for the other loader files: language, template, and a few others. And we have a viable, yet simple override system in place for contributions.
Admin Control
Also, by adding an option to the admin area, and a slight adjustment to the conditional above, we can globally disable all contribs based on a single admin setting. This is good when you found a contrib that breaks something but you aren't sure which one it is yet and you just want to get your store working again, so you can revert back to the default store with no contribs.
Only One Potential Limitation
There is still one limitation. Which is that if I make a contrib that modifies product.php and someone else makes a contrib that modifies product.php, then there will be a conflict. But think about it:
- That is currently how it is now, plus you have to worry about the core file changing, so that is 3 files to maintain & merge.
- If 2 contribs modify the same file, it is likely that they are conflicting features anyway, so you'd likely not be using them together
- This is pretty rare already from the contribs I've seen. Most developers keep their files self-contained whenever possible (thank you:))
So the long list of pros outweigh the single unlikely con.
Kohana?
I know we've talked about Kohana before when thinking about overrides, but after looking into it, that image that keeps getting flashed around doesn't do what it looks like it does. That just shows how MVC framework works with the controller and all the controller files loading, which is what OC already does. So I don't think that is what we want. But I'm not sure.
This override method, on the other hand is simple, and usable now. But it needs to be widely accepted as it will govern the way contribs are packaged for the future.
Thoughts?