ColdFusion Application.cfc & cfinvoke & THIS scope

822 views Asked by At

In using the CF application.cfc - there is a need to create some vars to begin with (in the THIS scope) - such as this.name and this.applicationtimeout() etc.

I ran across something I consider an odd behavior - and hope someone can explain why this happens and a possible workaround.

There are quite a few "THIS" vars accepted that can work to set application specific variables (of course you have to check "allow application specific vars" in the CFADMIN - which I did)

One of these is THIS.mappings - which is an array of mappings - MINE looks something like this:

this.path = GetDirectoryFromPath( GetCurrentTemplatePath() );
this.mappings = {
     '/files' = '#this.path#_my_files\'
     ,'/functions' = '#this.path#_my_functions\'
     ,'/logs' = '#this.path#_my_logs\'
};

it works fine - when it is set inside a cfscript block at the top of the application.cfc it works fine - if I put that script block in it's own file and cfinclude it in the application.cfc

however - In an attempt to segment my code - I wanted to put ALL of my application setting in a settings.cfc... (the thought here was IF some setting had to be changed - I wouldn't have to worry about 'where' to look, I don't really want to split the THIS stuff on my app.cfc and other application or session settings in the settings.cfc

SO I created a method in the settings.cfc called getTHIS, and I put the script block there... then used

<cfinvoke component="settings"
          method="getTHIS" 
      returnvariable="THIS" 
    />

Which WORKS - except (it seems) on the mappings...

The this.name etc, all seem to work and get set - as a matter of fact the this.mappings gets set fine too (so it appears) if i do a

<cfdump var="#THIS#" label="THIS" />

The dump is identical to the dump of THIS when I set it 'literally' on the app.cfc page..

HOWEVER - any attempt to call a template thru the mapping - results in a standard "if you want to use absolute paths you have to create a mapping blah blah..."

MY BIGGER goal was (on application start) to scan a directory for sub-directories, and create mappings based on certain sub-directories.. but if I can't abstract that functionality out into it's own function - I'll be forced to write it directly in the app.cfc (which wouldn't KILL me, but again, I was trying to segment my code logically... There seems to be a limitation of when and where these mappings can be set... true?

So I guess the big question is - can I SET this.mappings thru an outside method?? I guess I could bring back the 'settings I want' using the cfc call, and then just do the 'set this.whatever = return form cfc' - (this may be my answer...)

Thanks

2

There are 2 answers

2
Scott Stroz On

Mappings can only be set in the 'pseudo-constructor' and not inside any of the methods inside Application.cfc - http://adobe.ly/QN2oX1

You could try setting this.mappings to the result of a CFC call (I cannot think of why this would not work), but if it depends on a mapping to do so, it will likely not work.

2
Sharondio On

I haven't tested this, but I'm pretty sure it would work if your application.cfc extends your settings.cfc.

component {
    public any function getMappings() {
        var mappings = {};
        //code to get your directories etc.
        return mappings;
    }
}

component extends="settings" {
    this.name = "xxxx";
    this.mappings = getMappings();
    ...
}