Into The Box Notes: Migrating Legacy Applications to ColdBox MVC - Scott Coldwell

May 17, 2015

ColdBox Implicit View Dispatch
-- Wraps Around your App in ColdBox

In ColdBox, if a view file exists it can be called without a handler
the handler/event are implicitly created
the view doesn't need to know anything about ColdBox
you can write an entire app in the /view folder if you NEED to, not that it's recommended

(will still NEED to make some tweaks to the code though.)

REQUIRED TASKS ("MUST DO" tasks) ---

make urls compatible (index.cfm vs all the other pages)

deal w/ application.cfc content

"routes" can be an issue

cfinclude, createObject(), etc
any time you have a path, you'll need to adjust that.
path isn't situated from ROOT, it's situated from "views" folder

primary concern: index.cfm in ColdBox urls
ColdBox has URLs like this out of the box:
site.com/index.cfm/user/account

but your app is probably
site/user/account.cfm

the .cfm extension is no longer necessary but IS permitted
to fix: enable SES URL setting, maybe use web server rewrite rules (IIS rewrite, etc) to mask the index.cfm

Application.cfc --
ColdBox is now the application
settings, environment var's, etc. needs a new home
ColdBox settings and environment system

datasources/mappings, etc can be moved up a level to the ColdBox application.cfc

routes --
ColdBox auto-generates (implicitly dispatches) handler and routes for most cases

need to create custom routes for 2+deep level directories
use a CLI to find the entire list in your app
-- something you'll need to process thru to make sure all the app URLs are still working

prepend all <cfinclude> template values with /views/
cfinclude template=/widgets/top_nav.cfm
should now be
cfinclude template=/views/widgets/top_nav.cfm

createObject( "cfc.myObject" )
createObject( "views.cfc.myObject" );

RECOMMENDED TASKS ( "SHOULD DO" tasks) -----

use getModel() in WireBox to reference CFC invocation
or getInstance() -- they do the same thing now in CB4

move settings and env settings to ColdBox.cfc

Utilize Layouts
-- assign layouts to views in ColdBox.cfc
-- empty layout

getModel() instead of CreateObject()
easy search/replace

use WireBox inside of model objects
<cfproperty name=myOldCFC inject=model:myOldFCF">
<cfset foo = createObject( "component", "myOldCFC" ).doSomething()>
-- easy way to "wrap" a legacy object that references another legacy object, this makes things go more smoothly

Consider how to handle the init() call if applicable
can maybe use WireBox to handle some of these dependencies

ColdBox has great settings management and environment management -- use them
search / replace "application.mySpecialSetting" with getSetting("mySpecialSetting")
regEx is your friend

could also use Interceptors to catch the "old variables" and use them as well.

just depends how much you want to 'wrap' the app vs how much are you willing to tweak/change the application.

Layouts --
see if they make sense for your app
control multiple layouts via coldbox.cfc
when you apply a layout, it applies EVERYWHERe
but legacy app may have included it only in certain places
can make a blank layout for ajax responses
maybe a "popup" layout for simple popup windows.

COULD DO'S --

(to make the app more fully MVC)
move static assets to the /includes folder
just a CB convention
search/replace your code to change this

move CFCs to /models
created /models/legacy folder for older CFCs and they can eventually be ported to /models as they're upgraded and made into CB

Security
Utilize Security Interceptor

Configure WireBox for models
can go as crazy as you want. the more you do now, the better.

Use RC scope instead of form/url

GoingForward --
new dev can be ColdBox-esque

even just having the little benefits from these first steps will be helpful, even with a terrible old legacy app
because new dev can be done with ColdBox, proper views, models, etc.

Refactor legacy code to be MVC when possible.

Final notes --
the process is subjective
but you want to do as much as you can to make it MVC
but also need to get the app out the door
lay as much groundwork as you can, but get it out the door
if it lingers forever, these won't happen. have to get it done quickly.

search/replace is your friend
learn regex!

use a build process, not just source control
need more than just a "merge" in source control
make a branch, move these files, do a search/replace, validate these things, etc.
how long is it going to take to complete? may have to repeat these steps many times over a few months while you refactor

don't try to do too much at once. port the app, THEN refactor
if you try to take on too much you won't get it there
keep the scope manageable

can use routes to mask the way old things were vs how they are in the new app

any tricks to "mask" how you get from point A to point B will help.

automated testing tools can help
code analyzers -- look for repeated blocks of code that could be turned into a function, etc.

gotchas--
forms that look at CGI.script_name
in ColdBox, that is ALWAYS index.cfm
getEventHandler() to determine what that url SHOULD be so they don't all become index.cfm and break.