I expect to improve this in 2.0beta in a few ways:
1.) Zend Framework 2 operates using modules. The framework can load multiple modules and merge their configurations together. Each module has its own namespace, and its configuration tells the framework where to find the controllers for various routes. All the VuFind-specific code will be in the VuFind module. Users can plug in a module that loads after the VuFind module and overrides some of its settings. This means that they can point specific routes to their own custom controllers. Because of the namespacing, their controllers can extend the core VuFind controllers and only override or add very targeted behavior. No need to copy-and-paste large amounts of code.
2.) VuFind already has a lot of different plug-in areas: ILS drivers, record drivers, recommendation modules, session handlers, authentication handlers, link resolver drivers. 2.0alpha also adds related record modules for the record view. I also expect to add plug-ins for controlling record tabs (
). In 2.0beta, I plan to extend the configuration for all of these options to recognize fully-qualified, namespaced class names. That way, custom plug-ins can be built either inside or outside the core VuFind module, depending on user preferences. (By default, plug-ins are loaded using a specific namespace within the VuFind core).
3.) I will try to increase the use of dependency injection in VuFind so that deeper behavior can be more easily modified by extending record drivers and/or controllers, injecting modified dependencies, and then calling parent functionality. I can't guarantee that every single aspect of VuFind will be customizable in this fashion, but I hope this will improve over time as code gets refactored. If there are particular areas in need of special customization, feel free to suggest areas of concern.
I hope this will address the vast majority of plug-in use cases. For extreme situations where it is impractical to modify VuFind from the outside, I hope that the transition to Git for version control will make management of custom VuFind instances somewhat easier.
I also realize that this requires different techniques for different types of modifications, and some of these techniques are harder to master than others. However, I think it is probably better to have clear, straightforward APIs for the most common tasks rather than trying to come up with a single, unified API for absolutely everything -- I can't really envision a universal plug-in API that would be easily comprehensible. Also, documentation will play an important role here -- if the wiki includes good tutorials on customizing different aspects of VuFind, that will make a big difference... and I certainly plan to document everything once the design is more stable (which is getting significantly closer now that the move to ZF2 is underway).
Of course, I'm open to suggestions and criticism if anyone sees a better way forward or notices flaws in my current working plan.