• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Turning queries into session variables

Participant ,
Mar 11, 2009 Mar 11, 2009

Copy link to clipboard

Copied

Hello;
I am trying to learn about session variables for more stability in an application I am writting. I am still not sure of how this works and was hoping someone can show me so I can get the idea.

I want to make the part of my application that updates info into sessions. I want the sessions to control the usage of the section. So if user a is logged in, no one else can make changes to the area until they log out. Somethign like that, or they can log in, but can't make changes if another user is.

I realize some of this is controled by islogged in and the session started by the logged in user. How do I make my application into a session managed app?

Here is some code, just some of the code in my app, I will show you what I am doing, I don't think it is right.

this is the start page:

<cfset preappendURL = "../">
<cfset pageType = "admin">
<cfquery name="catMan" datasource="#APPLICATION.dataSource#">
SELECT Categories.Name AS ViewField1, Categories.CategoryID
FROM Categories
</cfquery>
<cfset rowsPerPage = 6>
<cfparam name="URL.startRow" default="1" type="numeric">
<cfset totalRows = catMan.recordCount>
<cfset endRow = min(URL.startRow + rowsPerPage - 1, totalRows)>
<cfset startRowNext = endRow + 1>
<cfset startRowBack = URL.startRow - rowsPerPage>
<head>
</head>
<body>
<cfoutput>
Displaying <b>#URL.startRow#</b> to <b>#endRow#</b> of <b>#totalRows#</b> Records.
<cfif startRowBack GT 0><a href="#CGI.script_name#?startRow=#startRowBack#" class="nav">&lt; Previous Records</a></cfif>

<cfif startRowNext lte totalRows><a href="#CGI.script_name#?startRow=#startRowNext#" class="nav">Next Records &gt; </a>
</cfif>
</cfoutput>'

<cfloop query="catMan" startRow="#URL.startRow#" endrow="#endRow#">
<cfset class = iif(catMan.currentRow mod 2 eq 0, " 'DataA' ", " 'DataB' ")>
<cfoutput>
#ViewField1#
<a href="project-manager.cfm?CategoryID=#CategoryID#" class="nav">Edit Projects</a>
<a href="projectCat-edit.cfm?CategoryID=#CategoryID#" class="nav">Edit Category</a>
<form action="ProjectCat-Action.cfm" method="post">
<input type="hidden" name="ID" value="#CategoryID#">
<input type="submit" name="cat_Delete" class="formButtons" onClick="return confirmDelete('ID','#ViewField1#')" value="Delete"></form>
</cfoutput></cfloop>

<cfoutput>
<cfset thisPage = 1>
<cfloop from="1" to="#totalRows#" step="#rowsPerPage#" index="pageRow">
<cfset isCurrentPage = (pageRow gte URL.startRow) and (pageRow lte endRow)>
<cfif isCurrentPage>
<cfoutput><font size="2" face="Verdana, Arial, Helvetica, sans-serif"><b>#thisPage#</b></font></cfoutput><cfelse><cfoutput>
<a href="#CGI.script_name#?startRow=#pageRow#" class="nav">#thisPage#</a></cfoutput></cfif>
<cfset thisPage = thisPage + 1>
</cfloop>

<cfif startRowBack GT 0><a href="#CGI.script_name#?startRow=#startRowBack#" class="nav">&lt; Previous Records</a></cfif>

<cfif startRowNext lte totalRows><a href="#CGI.script_name#?startRow=#startRowNext#" class="nav">Next Records &gt; </a>
</cfif>
</cfoutput>
</body>

There is another page that goes with this. It is the edit page. But I don't know if we can start here to create this part into sessions.

Here is page 2:

<cfset preappendURL = "../">
<cfset pageType = "admin">
<cfparam name="url.id" type="integer" default="0">
<cfparam name="variables.CategoryID" type="integer" default="#url.id#">
<cfparam name="variables.Name" default="">
<cfparam name="variables.Description" default="">
<cfparam name="variables.MYFile" default="">


<cfif url.id GT 0>
<cfquery name="categRec" dataSource="#APPLICATION.dataSource#">
SELECT Name, Description, MYFile, CategoryID
FROM Categories
WHERE CategoryID = <cfqueryparam value="#URL.ID#" cfsqltype="cf_sql_integer">
ORDER BY Name
</cfquery>

<!--- if the record was found, store the values --->
<cfif categRec.RecordCount EQ 1>
<cfset variables.CategoryID = categRec.CategoryID>
<cfset variables.Name = categRec.Name>
<cfset variables.Description = categRec.Description>
<cfset variables.MYFile = categRec.MYFile>
</cfif>
</cfif>
<head>
</head>
<body>
<cfoutput>
<form action="ProjectCat-Action.cfm" method="post" name="content" id="content"
enctype="multipart/form-data">
<input type="hidden" name="ID" value="#variables.CategoryID#">
<input type="hidden" name="oldimage" value="#variables.MYFile#">

<input type="text" name="Name" class="textInputs"
value="#variables.Name#" maxLength="510">

<cfif len(trim(variables.MYFile)) GT 0>
<b>Image in use:</b>#variables.MYFile#</cfif>

<input name="MYFile" type="file" id="MYFile">

<input name="Description" type="text" class="textInputs"
value="#variables.Description#" size="50" maxLength="510">
</cfoutput>
<input type="submit" class="formButtons" name="cat_OK" onclick=";DisableButton(this);" value=" OK ">
<input type="submit" class="formButtons" name="cat_Cancel" value="Cancel">
</form>

How would I make this into session managed variables? That is where I am confused. I have session variables enabled in my application.cfc file. Now I want to manage them better.

Can anyone help show me how to do this? Or point me to a web site that explains what I am trying to do?

Thank you.

CFmonger
TOPICS
Advanced techniques

Views

1.8K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 11, 2009 Mar 11, 2009

Copy link to clipboard

Copied

First of all, to make a query a session variable - just put it there.

<cfquery name="session.contentMAN"...>
...
</cfquery>

<cfoutput query="session.contentMAN">
...
</cfoutput>

Now I need to tell you this will not help you in your stated
requirement. Putting data into the session scope will not make your
application 'session' aware. Data in the session scope is global only
to one, individual user. No other user can see what is in any other
user's session scope. [Unless you do some strange stuff with
undocumentated and unsupported ColdFusion java objects]

To do that you need a scope that is global to all users of the
application and that is the 'application' scope. Luckily this is just
as easy to use.

<cfquery name="application.contentMAN"...>
...
</cfquery>

<cfoutput query="application.contentMAN">
...
</cfoutput>

I'll leave it to you to figure out all the logic for what data gets
stored in what scopes and what decisions your code makes based on this data.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Mar 11, 2009 Mar 11, 2009

Copy link to clipboard

Copied

ok, that makes sense. so if I put my query into the application scope, I will be able to manage my users easier? Correct?

So once the query is in the application scope, I put the rest in the same scope? or not?

Like this:

<cfparam name="url.id" type="integer" default="0">
<cfparam name="application.CategoryID" type="integer" default="#url.id#">
<cfparam name="application.Name" default="">
<cfparam name="application.Description" default="">
<cfparam name="application.MYFile" default="">

<!--- if the record was found, store the values --->
<cfif application.categRec.RecordCount EQ 1>
<cfset application.CategoryID = categRec.CategoryID>
<cfset application.Name = categRec.Name>
<cfset application.Description = categRec.Description>
<cfset application.MYFile = categRec.MYFile>
</cfif>
</cfif>

and then this?


<cfoutput>
<form action="ProjectCat-Action.cfm" method="post" name="content" id="content"
enctype="multipart/form-data">
<input type="hidden" name="ID" value="#application.CategoryID#">
<input type="hidden" name="oldimage" value="#application.MYFile#">

and so on with the rest of this page.

But for the action part, do I make all those into the application variables as well?

<cfquery datasource="#APPLICATION.dataSource#">
UPDATE Categories
SET
<cfif fileuploaded is true>
Categories.MYFile=<cfqueryparam cfsqltype="cf_sql_varchar"
value="#application.uploadedfile#">,
</cfif>
Categories.Name=<cfqueryparam cfsqltype="cf_sql_varchar"
value="#form.application.Name#">,
Categories.Description=<cfqueryparam cfsqltype="cf_sql_longvarchar"
value="#form.application.Description#">
WHERE CategoryID = <cfqueryparam value="#form.application.ID#" cfsqlType="CF_SQL_INTEGER">
</cfquery>

Is that how it is done?
and thank you. I had an idea, but I am trying to decide my best way to approach this.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 11, 2009 Mar 11, 2009

Copy link to clipboard

Copied

CFmonger wrote:
> ok, that makes sense. so if I put my query into the application scope, I will
> be able to manage my users easier? Correct?
>
> So once the query is in the application scope, I put the rest in the same
> scope? or not?
>

That is a much bigger question and rather difficult to answer
specifically in a quick fire method such as these forums.

But in general, yes. You would put data into the application scope that
you need to be accessible in any template run by any user of this
application. Your code can then access this data when necessary and
make appropriate decisions base on what the data is.

What this data is and how it is used is up to you as the developer to
decide. But I don't think it needs to be much more then something that
says userA is engaged.

Then the working code can make the decision that since userA is engage,
other uses can not access the code to the restricted functionality until
userA disengages. Be aware that with the nature of HTTP web requests, a
browser never goes backs and tells a server that the user has left. All
the server can do, is wait for a specified time for a new request, and
if one never arrives, assume the user has left.

Once you have the mechanism to know a user is accessing this feature and
to shut out others, then the actual work of editing and updating the
data can be done in the local scope. You do not need to put all the
data into the application scope. Just enough of it to be able to make
the appropriate decisions in your code.

So this type of application will make a use of various variable scopes
including the application scope for information available to all users,
the session scope for information available to all requests by that user
and the local scope for data needed just for this request.

P.S. If you need a even more global scope there is the server scope
where you can put data so it is available to all requests of all users
of all applications running on the ColdFusion server.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 11, 2009 Mar 11, 2009

Copy link to clipboard

Copied

I forgot to add that this type of application can usual make good use of
the newish Application.cfc and its event functions. These functions
fire on the start and end of various events.

onApplicationStart - when an Applicaiton first starts a good place to
initialize application scope data.

onSessionStart - when a user first access an application for a new
session a good place to initialize session data and|or update
application data about this user.

onRequestStart - when a new request is started. A good place to
initialize request variables. Note can not initialize local variables
unless the onRequest function is also defined which has serious pros and
cons. Also can update session and or application data about the start
of this request.

onRequestEnd - when the request is done. A good place to do something
when each request finishes.

onSessionEnd when the session times out. A good place to do something
when a user session ends.

onApplicationEnd when the application times out. A good place to do
something when an application ends if it has not been used in a certain
period of time.

The documentation has lots of great information about this feature.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Mar 11, 2009 Mar 11, 2009

Copy link to clipboard

Copied

I do use the application.cfc I agree I like it so much better then the appication.cfm far better control of variables.

this is my on app start tag.

<cffunction name="onApplicationStart" returntype="boolean" output="false">
<cfset APPLICATION.appStarted = now()>
<cfset APPLICATION.dataSource = "myDB">
<cfset APPLICATION.companyName = "My company">
<cfreturn true>
</cffunction>

Do I need to add anything else to this so I can run the "back end" in the application scope?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 11, 2009 Mar 11, 2009

Copy link to clipboard

Copied

CFmonger wrote:
>
> Do I need to add anything else to this so I can run the "back end" in the
> application scope?
>

Possibly, depending on how you want to structure your application.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Mar 11, 2009 Mar 11, 2009

Copy link to clipboard

Copied

how do you mean?
I have the public side, and a directory I lock people out of, you need to log in. This is the area I am going to set it up with the sessions for modifying content.

My application.cfc is in the main directory, I don't have ownership of my server, so I had to use a proxyapplication.cfc to lock out the back end. All variables are running fine from teh application.cfc in the main directory to the one in the private folder.

Is that the structure I need? How would I write that in this area if I am right?

CFmonger

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 16, 2009 Mar 16, 2009

Copy link to clipboard

Copied

LATEST
CFmonger wrote:
> how do you mean?
> I have the public side, and a directory I lock people out of, you need to log
> in. This is the area I am going to set it up with the sessions for modifying
> content.
>
> My application.cfc is in the main directory, I don't have ownership of my
> server, so I had to use a proxyapplication.cfc to lock out the back end. All
> variables are running fine from teh application.cfc in the main directory to
> the one in the private folder.
>
> Is that the structure I need? How would I write that in this area if I am
> right?
>
> CFmonger
>

First of all I do not understand your reference to proxyApplication.cfc
and you not having ownership of your server? Why do you need to use
proxyApplicaiton.cfc? Are you not able to upload files to your web
server web root directories?

I *CAN NOT* tell you what structure you need. The answer to that
depends on what exactly *YOUR* requirements are for *YOUR* application.
If you care to write these requirements into a reasonably detailed
document and pay somebody somewhere between $50 and $150(US) an hour the
y would be happy to work out exactly what you need.

You could also attempt to post such a document to a list such as this,
but I would not hold out much hope of it generating many free responses.

The solution to your requirement might be as simple as putting a new
Applicaiton.cfc file in the sub directory that will contain the code of
this administration function. It might be a great deal more intricate
and complicated then that. I don't know, I don't know what your
application needs to do. Quick fire forums like this are not well
suited for such lengthy and detailed discussions.

We are most happy to offer specific answers to specific issues vexing
our fellow developers. But some work on your end needs to be apparent.

P.S.
Why do I have this strange feeling of channeling Adam?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation