DRY: Applied to your setup

20 November, 2007

Show comments

As pointed out in a recent comment, when changing your cake version you may find that some of your hand written config files are nolonger compatible with the version of cake you have selected. However by making use of a a custom production setup there is a way to configure your application defensively and in less lines of code.

Every time I use copy, paste & edit, I'm thinking how to avoid doing so. So whenever I started a new application and moved the files around inline with what I described in the Production Setup article, it annoyed me to have to keep redefining the same variables/constants in slightly different ways with the risk of missing one of them or defining them not-quite-right. After setting up a few projects, I had one of those moments of truth that are normally accompanied by the sound of a penny hitting the floor: By not editing directly the app folder that comes with cake, it would always be available to be referred to in it's pristine, checked out state.


Before going on to show a bit of code, here's what you need to know or at least be aware of. Using the production setup outlined previously:

  • Application and cake folders are kept completely seperate
  • By defining CAKE_CORE_INCLUDE_PATH in the index, you can configure which version of cake a specific application will use
  • If your config files don't match the expectations of your selected version of cake, the app won't work

If any of the above is not clear please review the folder structure outlined in the production setup revisited post (and maybe also production setup).

Tackle the index

Take a look at the complete index.php file which is shown in the production setup revisited post. It should look familiar :). Now compare with the following:

define('ROOT', dirname(dirname(__FILE__)) . DS . '_website_files'. DS . 'apps');
define('APP_DIR', basename(dirname(__FILE__)));
define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(__FILE__)) . DS . '_website_files' . DS . 'cakes'. DS . '1_2_branch');
include(CAKE_CORE_INCLUDE_PATH . DS . 'app' . DS . 'webroot' . DS .  basename(__FILE__));

Because the cake index file first checks if a constant is defined before defining it; it's possible to define the constants of interest and just include the standard index file. What's the benefit of that? If the index file changes between versions (or when you svn update your 1.2 branch code etc.), you immediately inherit those changes.

Tackle the core

Who of you have already guessed :)? basename(__FILE__) tells you the name of the file you are in, and unless you want to change something you want to include the equivalent file from the app folder in the version of cake you are using. Or in other words you want your core.php file to look like this:

include(CAKE_CORE_INCLUDE_PATH . DS . 'app' . DS . 'config' . DS .  basename(__FILE__));
Configure::write('debug', 0);
Configure::write('Routing.admin', 'admin');
Configure::write('Security.salt', 'sha1 of a random quote');

By including the default core.php file and then overriding the configure settings you want to change, you have a core file that is easier to edit and (with a notable exception, covered below) will not break and allow you freedom to change cake versions and not find your app doesn't work for wont of a configure definition.

Other Files

What other files could you use this principle for? Well in truth there is only the core.php file and possibly the inflections file that are likely to be of interest. Bootstrap is an empty file and applying the same principle to your routes file could mean you don't get what you want.

When will this not work?

Somewhere before revision 5700, core.php was full of defines, by 5886 most of the defines have gone and are replaced by Configure::write statements. What I've outlined here could be interpreted as a means of keeping on top of the branch 1.2 code, as if you go too far back you may find that, for example, the Configure class is unavailable and/or your calls to Configure are having no effect (as the previous define is being used).

Wrapping Up

Using the concept outlined here, you can update or switch your version of cake (within reason!) and avoid needing to change or add to your core.php file to get your app working. Cross-version conflicts can be reduced and time spent coding (or testing) increased.

Bake on!