Skip to main content
Inspiring
March 5, 2007
Answered

setting variables in a CFC

  • March 5, 2007
  • 10 replies
  • 1329 views
Is it possible to set application or session variables from within a CFC. I know this is not typical programming, but I have a situation where I would like to have a CFC function set a session or application variable to be used within the rest of the application. Is this possible? I'm asking because I cannot get it to work.
    This topic has been closed for replies.
    Correct answer Newsgroup_User
    > You are absolutely right, your proof of concept does work. The problem is that
    > the application scope is lost within the FCKeditor itself. The cfc that is
    > called can see the application scope, but the subsequent pages of the FCKeditor
    > cannot.

    How are those "subsequent pages" accessed from with FCKEditor? Are they
    browsed to, included, invoked as CFC instances? I suspect browsed to, as
    the others would not cause the problem.


    > That has always been the problem

    Right. So your first post and all the subsequent discussion about it
    having something to do with the CFC was actually... well... ballocks.

    [furrowed brow]

    If, as I suspect, you have separate requests going through directly to
    files in the FCKEditor dir, as opposed to everything being initiated from
    your site dir, then the treatment is different but dead easy.

    Go back to my previous example file structure:

    webroot/
    --site1/
    ----Application.cfm
    ----caller.cfm
    --app/
    ----c.cfc
    ====Application.cfm
    ====someOtherFile.cfm

    (note the other two files I've added)

    First, create a web server virtual directory which maps

    /site/app to the /app dir

    (NB: set your FCKConfig.BasePath to point to that virtual dir, in your
    case)

    Next have this sort of thing in the new Application.cfm:

    <cfset sSiteDir = listGetAt(cgi.script_name, listLen(cgi.script_name, "/")
    - 2, "/")>
    <cfset sAppInclude = "../#sSiteDir#/Application.cfm">
    <cfset sAppFile = expandPath(sAppInclude)>

    <cfif fileExists(sAppFile)>
    <cfinclude template="#sAppInclude#">
    </cfif>

    someOtherFile.cfm
    (stick any old crap in this; it's just something to browse to)

    Browse to /site/app/someOtherFile.cfm, and the Application.cfm for the site
    should get executed.

    Check for any other Application.cfm files in the app and make similar
    adjustments if need be.

    --
    Adam

    10 replies

    fillaeAuthor
    Inspiring
    March 16, 2007
    quote:

    Right. So your first post and all the subsequent discussion about it
    having something to do with the CFC was actually... well... ballocks.

    Not at all. I started down a path to that I thought would be a reasonable solution. That doesn't mean what I posted was the original problem. It was a problem with the solution I was currently working on. I apologize if I misled you. It certainly wasn't intentional.

    With that said, I finally got a few moments to try your solution. I made a couple small changes, but for the most part your solution worked like a champ! Thank you very much. This is a very slick solution!
    Newsgroup_UserCorrect answer
    Inspiring
    March 8, 2007
    > You are absolutely right, your proof of concept does work. The problem is that
    > the application scope is lost within the FCKeditor itself. The cfc that is
    > called can see the application scope, but the subsequent pages of the FCKeditor
    > cannot.

    How are those "subsequent pages" accessed from with FCKEditor? Are they
    browsed to, included, invoked as CFC instances? I suspect browsed to, as
    the others would not cause the problem.


    > That has always been the problem

    Right. So your first post and all the subsequent discussion about it
    having something to do with the CFC was actually... well... ballocks.

    [furrowed brow]

    If, as I suspect, you have separate requests going through directly to
    files in the FCKEditor dir, as opposed to everything being initiated from
    your site dir, then the treatment is different but dead easy.

    Go back to my previous example file structure:

    webroot/
    --site1/
    ----Application.cfm
    ----caller.cfm
    --app/
    ----c.cfc
    ====Application.cfm
    ====someOtherFile.cfm

    (note the other two files I've added)

    First, create a web server virtual directory which maps

    /site/app to the /app dir

    (NB: set your FCKConfig.BasePath to point to that virtual dir, in your
    case)

    Next have this sort of thing in the new Application.cfm:

    <cfset sSiteDir = listGetAt(cgi.script_name, listLen(cgi.script_name, "/")
    - 2, "/")>
    <cfset sAppInclude = "../#sSiteDir#/Application.cfm">
    <cfset sAppFile = expandPath(sAppInclude)>

    <cfif fileExists(sAppFile)>
    <cfinclude template="#sAppInclude#">
    </cfif>

    someOtherFile.cfm
    (stick any old crap in this; it's just something to browse to)

    Browse to /site/app/someOtherFile.cfm, and the Application.cfm for the site
    should get executed.

    Check for any other Application.cfm files in the app and make similar
    adjustments if need be.

    --
    Adam
    fillaeAuthor
    Inspiring
    March 8, 2007
    You are absolutely right, your proof of concept does work. The problem is that the application scope is lost within the FCKeditor itself. The cfc that is called can see the application scope, but the subsequent pages of the FCKeditor cannot. If I try to access an application variable I get the " The requested scope application has not been enabled." error. The scope is lost because the FCKeditor itself calls files internally, so it has no idea of the application space. I could edit all the internal urls and get it to work, but no thanks. That has always been the problem and is why I attempted to establish a separate application space for the FCKeditor. That led to my very first post. I was attempting to pass the needed parameters to the cfc and then let the cfc create the needed application variables in its own application space.

    The FCKeditor is open source with a GNU license ( http://www.fckeditor.net), so if your really bored you can download it and try it in your example above.
    BKBK
    Community Expert
    Community Expert
    March 7, 2007
    The CFC is isolated because I want to share it across multiple websites.
    I find this a contradiction. I would have thought the lesson to learn from your problem is that isolation makes sharing dificult.

    Another basic point of application design is not duplicating code.
    Agreed. In fact, the approach you and Adam have adopted will avoid duplication. But there's something I don't quite understand. What do you mean by "use the variable within the CFC itself, but not subsequent pages of the FCKeditor. " What are subsequent pages of a CFC?

    fillaeAuthor
    Inspiring
    March 7, 2007
    quote:

    What are subsequent pages of a CFC?

    As I sort of described, the CFC creates the html/javascript that is used to display the editor. Subsequent pages would be when a toolbar item is selected and a popup window is displayed. That code is imbeded in the fckeditor. The CFC is only used to create the instance of the editor. There are other methods to do this as well. There is a purely javascript class provided. The CFC is provided for CF users. The fckeditor also supports asp, php, lasso, among others.
    BKBK
    Community Expert
    Community Expert
    March 6, 2007
    the CFC exits in a separate directory with it's own application.cfm

    Isolating a CFC like that is almost never necessary. The basic point of application design is to get the objects to communicate with each other. Sharing the same application scope makes that communication better.

    Participating Frequently
    March 6, 2007
    As I understand it the fck component is just a generic object that doesn't need its own application scope, it just needs to be instantiated by a site with an application scope. The mistake I think you're making is trying to set an application scoped variable inside the cfc instead of creating the an instance of the cfc in the application scope for each site (a facade).

    Instead of this:

    fckEditor = createObject("component", "/fckeditor/fckeditor");

    do this

    application.fckEditor = createObject("component","/fckeditor/fckeditor").create(application_level_variables)

    and inside the component use the variables scope instead of application scope:
    <cfargument name="FCKstruct" type="struct" />
    <cfset variables.UserFilesPath = arguments.FCKstruct.UserFilesPath />

    That way each site will have it's own instance of the FCKEditor which is what I think you're after?

    Of course that's not thread safe and you'll want to properly lock the fck instance when creating.
    fillaeAuthor
    Inspiring
    March 6, 2007
    quote:

    Originally posted by: maxell
    As I understand it the fck component is just a generic object that doesn't need its own application scope, it just needs to be instantiated by a site with an application scope. The mistake I think you're making is trying to set an application scoped variable inside the cfc instead of creating the an instance of the cfc in the application scope for each site (a facade).

    Instead of this:

    fckEditor = createObject("component", "/fckeditor/fckeditor");

    do this

    application.fckEditor = createObject("component","/fckeditor/fckeditor").create(application_level_variables)

    and inside the component use the variables scope instead of application scope:
    <cfargument name="FCKstruct" type="struct" />
    <cfset variables.UserFilesPath = arguments.FCKstruct.UserFilesPath />

    That way each site will have it's own instance of the FCKEditor which is what I think you're after?

    Of course that's not thread safe and you'll want to properly lock the fck instance when creating.


    That is the approach I was taking, but the FCKeditor expects the UserFilesPath to be scoped as application, server or request. I can do that and use the variable within the CFC itself, but not subsequent pages of the FCKeditor. The cfc basically generates the html/javascript code for the editor. There is a toolbar on the editor that launches html popup windows to do things like insert hyperlinks, images, change fonts, etc. It is in the popup windows where the variables are not available (they are cfm pages, not pure html).
    Inspiring
    March 6, 2007
    Have you considered a udf that is not in a cfc?
    Inspiring
    March 5, 2007
    > What I am trying to do is a little more complicated. The CFC actually exists
    > under it's own application scope.

    Well you cannot set a variable in another application then (or a session
    within that application).

    Your subssequent description as to why the CFC is in its own application
    space does not make sense to me, to be honest.

    You also seem to have some confusion as to how Application.cfm relates to
    "the application scope", in that you think there IS some relationship
    between the two, and in fact there isn't.

    Application.cfm is executed before any other template, for a given request.
    it would better be called "onRequestStart.cfm", as it has NOTHING to do
    with "applications" in the CF sense of that notion.

    The application space is set via either a <cfapplication
    name="nameOfAppHere"> tag, or the equivalent variable setting in
    Application.cfc.

    I think you should post the relevant bits of your code, so we can work
    through this.

    --
    Adam
    fillaeAuthor
    Inspiring
    March 5, 2007
    quote:

    Originally posted by: Newsgroup User
    Your subssequent description as to why the CFC is in its own application
    space does not make sense to me, to be honest.



    The reason for this is because the CFC is shared across multiple websites (applications).

    quote:

    Originally posted by: Newsgroup User
    You also seem to have some confusion as to how Application.cfm relates to
    "the application scope", in that you think there IS some relationship
    between the two, and in fact there isn't.



    No confusion. You cannot have an application scope without an application.cfm. By scope I meant the application scope of the main application is not the same as the application scope for the CFC. Two separate apps, two separate application scopes. Since I have multiple websites (applications) sharing the CFC, I cannot share their application.cfm, thus they do not share application scopes.

    quote:

    Originally posted by: Newsgroup User
    I think you should post the relevant bits of your code, so we can work
    through this.



    I was hoping there would be someone familiar with the FCKEditor because there is a fair bit of code involved. I will try to clarify what the issue is.

    I have a website directory, say C:\Inetpub\wwwroot. I then have multiple websites beneath that:

    C:\Inetpub\wwwroot\Site1
    C:\Inetpub\wwwroot\Site2

    And also the FCKeditor

    C:\Inetpub\wwwroot\FCKeditor

    From within Site1 I create an FCKEditor object like this:

    <cfscript>
    fckEditor = createObject("component", "/fckeditor/fckeditor");
    fckEditor.instanceName = "editor";
    fckEditor.value = '';
    fckEditor.basePath = "/fckeditor/";
    fckEditor.width = "100%";
    fckEditor.height = 400;
    fckEditor.create(#request.FCKeditor#); // create the editor.
    </cfscript>

    The request.FCKeditor is a structure I have created and am passing to the CFC. Now, in the CFC create function I try to do the following:

    <cffunction
    name="create"
    access="public"
    output="true"
    returntype="void"
    hint="Initialize the FCKeditor instance."
    >

    <cfargument name="FCKstruct" type="struct" />

    <cflock scope="application" type="exclusive" timeout="5">
    <cfset application.UserFilesPath = arguments.FCKstruct.UserFilesPath />
    </cflock>


    I can spit out the value of application.UserFilesPath at this point and all is fine. The problem is that the variable is not present when using a plugin of the FCKeditor (essentially a popup window that allows the user to edit some text and save it back to the browser).

    I have never tried to create another application via a CFC, so I don't know if this is even possible. It doesn't seem like it is because the variables are being lost. I can hardcode an application variable in the application.cfm (located in the /FCKEditor/ directory), but that doesn't solve my problem.

    I can always copy the FCKeditor code into each website, but that causes maintenance nightmares and I really don't want to do that.
    fillaeAuthor
    Inspiring
    March 5, 2007
    What I am trying to do is a little more complicated. The CFC actually exists under it's own application scope. It essentially is responsible for creating and displaying an html editor (FCKEditor). I can set an application variable in the application.cfm of the app containing the CFC, but I cannot set it in the CFC itself. It exists in the scope of the CFC, but not in the subsequent objects the CFC creates. I'm trying to set the application variable based on argument passed to the CFC (like in the example BKBK provided, except the CFC exits in a separate directory with it's own application.cfm)

    My description is probably a bit confusing, but I'm a bit confused myself. I can find no reason this should not work, but it doesn't. If anyone is familiar with the FCKEditor, I would love to hear from you!
    BKBK
    Community Expert
    Community Expert
    March 5, 2007
    Is it possible to set application or session variables from within a CFC

    Yes