Migrating MVC Apps
For 0.2.0 major improvements have been made across the framework, but none are more evident than in the MVC and CLI systems. When migrating from the previous versions to 0.2.0 you will likely encounter several issues. This article will attempt to highlight them and offer advice on how to handle updating.
Migrating MVC Apps
The migration of CLI apps should be relatively straight forward. Most of the interfaces are still the same with few changes to the structure of the controllers and views. There are several points to note though:
Starting with 0.2.0, mvcRequest::getInstance is being avoided in all controllers, models and views. Access in the view is via the controller so instead of directly calling the mvcRequest, it should be accessed by calling: getController()->getRequest(). This should help make writing test cases much easier.
mvcRequest has inherited some of the methods that were originally in the distributor. These were moved here as they form part of the request and are not dependent on the dispatcher. This was the file type system that determines the output format for the current request.
mvcDistributorBase and the base/index.php launcher in the websites folder have seen many changes and refactorings. The biggest of these is the removal of much of the initialisation logic into plugins that can be fired during initialisation (e.g. session management, log setup, locale and device detection), pre-dispatch and post-dispatch. These plugins can be manually assigned to the distributor by instantiating and attaching them directly, or by using the distributorPlugins config section in the website config.xml file. Examples are available in the base/config.xml and baseAdminSite/config.xml.
Plugins are started by giving the full name of the plugin class and setting the value to "true". It is important to realise that plugins "stack" i.e. if they are defined in the base/config.xml they will be inherited through the site path. With that said, the current site always has priority, so any active plugin can be disabled on a site by site basis. Simply set the value to 0. Please note that ONLY 0 (the number zero) will disable a plugin.
These mvcDistributorPlugins can be added to by extending the base plugin and placing the necessary logic in the appropriate method. To load the plugin, add the class name and file location to the autoload classes section, again in the site config.xml file.
Several plugins are included with the framework, replicating the previous functionality that was hard-coded into the primary dispatch() method of the distributorDispatcher class. These plugins are:
|Plugin Class Name||Description|
Creates log files based on the site name and sets individual log levels for each site.
|mvcDistributorPluginSession||Creates and maintains sessions for the MVC system|
|mvcDistributorPluginLocale||Provides locale support for the MVC system|
|mvcDistributorPluginDetectDevice||Handles mobile device detection and content-negotiation (requires session and the WURFL system be configured and a current WURFL file parsed and ready for usage)|
All of these plugins can be loaded by simply setting the name in the distributorPlugins section of the config file.
Moving to the plugin system allows only those plugins that you need to be used. Note that there can (are) dependencies between plugins.
The final change in the distributor is that the mvcRequest is passed during instantiation - it is NOT created internally.
What do these changes mean for usage? If you have overridden, or implemented your own Distributor you should check the default in /base/index.php for the base implementation and then either update or use this. If you have added specific code to support your site, either try to re-implement it as a plugin or if not possible, again extend the mvcDistributorBase and add custom methods that contain only your changes. You are strongly urged to use the plugin system as a future version will move mvcDistributorBase into a concrete class.
mvcSessionBase has been extended to include pre and postInitialise methods to allow for easier overriding of functionality.
mvcControllerBase has seen a few changes the most prominent the addition of get/set Request for passing the mvcRequest around instead of needing to use the static mvcRequest::getInstance. There is still one call to this static method though, in the constructor. It was decided not to remove it just yet as this caused issues downstream in many controllers that used the constructor to setup various options.
The prefered method is to use the initialise() method to do this setup and this is what should be done as in a future release the constructor may be marked as "final" to prevent this from happening. However you can still overload it, but you must rememeber to call parent::__construct() BEFORE applying any logic.
The MVC autoloader has picked up a caching system to help improve performance. This caches the FULL path to the various classes that make up the site. By default this is enabled and set to auto-save on shutdown. This can improve performance quite substantially so understanding the changes is important. In particular you must pay attention to the fact that the ENTIRE filepath is stored in the cache file. Therefore when creating static caches (i.e. you disable autoload-class files and auto-save) you must pre-generate the cache file with the files in the exact same locations as they are on the production system. This means that you cannot create cache files on Windows and deploy to Linux (or vice versa). A command has been added to the scorpio CLI tool to automatically build the cache for any registered site. When deploying to production, you should re-run this after any updates.
Additionally: as the full path is stored you must re-build or delete the cache if you move any files, or create a new override - otherwise the already cached location will be used which will either error, cause inconsistent behaviour or hard to track errors.
The cache system can be completely disabled be setting autoloadCacheEnabled to 0 HOWEVER you MUST enable alwaysPreloadSiteClasses otherwise required files will not be loaded and your application will fail to start.
This work is licenced under a Creative Commons Licence.