Copy link to clipboard
Copied
Sorry for this total newb question that's probably been covered a bazillion times, but I'm having some trouble getting things to work. I should know all this stuff, as I've taken the CF9 advanced training, but when you have 60,000 pages worth of content back at the office waiting to be converted to a new design, there isn't much time to practice what you learned in class.
A lot of my office's website is leftover from when we were running CF 6.1, so everything uses Application.cfm files. Now that we're running CF8 (and may soon move to something even newer), I'd like to get everything modernized, including getting my Application.cfm stuff into an Application.cfc file. One of the reasons I want to do this is because I have a few apps that I want to use OnRequestStart() methods for.
My problem stems from the fact that our Application.cfm file does a lot of things like setting global variables, doing queries, and other things that I can't seem to get to work inside an Application.cfc file. Particularly odd is the fact that I recently set up a CF10 site for my wife's business's websites and was able to get Application.cfc working without much trouble, leading me to suspect a setup problem with my office.
I tried following the guide on Hostek's forum, but to no avail. I can't seem to include the contents of our old Application.cfm file in the new cfc.
Any tips?
...
BreakawayPaul wrote:
<cfset rights = userdata.admin>
<cffile action="read" file="D:\inetpub\fhwaroot_test\includes\hep\acronyms.xml" variable="myxml" />
<cfset variables.acrXML = XmlParse(myxml) />
<cfset variables.acrList = acrXML.acronyms.XmlChildren />
<cfset variables.acrListSize = ArrayLen(acrList) />
<cfset variables.acrQuery = QueryNew("id, name, old, new") />
<cfset variables.acrTemp = QueryAddRow(acrQuery, #acrListSize#) />
<cfloop index="i" from="1" to="#acrListSize#">
<cfset variables.acrTemp
Copy link to clipboard
Copied
Yep, first tip: show us the code that isn't working, and explain in what way it's not working, ie: what you expect it to do, and what it's doing instead.
Other than that, your question is too nebulous to be able to answer properly beyond "yeah, it should all work".
--
Adam
Copy link to clipboard
Copied
Well as far as code goes I basically just copied an Application.cfc example template from a website and edited it.
What I have now is basically this:
<cfcomponent>
<cfscript>
this.name = "hepcms";
this.sessionManagement = "Yes";
this.sessionTimeout = CreateTimeSpan(0,1,0,0);
this.setClientCookies = "Yes";
</cfscript>
<cffunction name="onRequestStart">
<cfargument name="requestname" required=true />
<cfinclude template="application.cfm">
</cffunction>
</cfcomponent>
Thing is, I'm not sure I even need an application name, since this is just the CMS for the website.
@Dan
The reason I'd like to do this change is because I want to use the OnRequestStart feature in Application.cfc. Our CMS used to have a cflogin, and I would record who logged in and at what time/date. Now we've been forced to switch to a central type of authentication that works similar to password protected directories.
Once we log in to access the CMS folder, credentials are contained in GetAuthUser(). I want to still be able to see who logged in and when, but I can't use the old method.
Also, with my wife's website, I was able to use Application.cfc to add common headers and footers to each page without having the includes directly on the pages. This is something else I'd like to implement.
Copy link to clipboard
Copied
You do need an application name.
Get rid of the <cfinclude template="application.cfm"> tag.
Copy link to clipboard
Copied
Dan Bracuk wrote:
You do need an application name.
There is an application name. Unless you wish to emphasize the point.
Get rid of the <cfinclude template="application.cfm"> tag.
No need to get rid of it. As long as the file name begins with small-letter 'a' and the file contains appropriate code.
Copy link to clipboard
Copied
I have the application name in there because there was one in the sample.
However, the include doesn't work. Any variables set in that include are undefined. Perhaps I need to go around and reference them all as #variables.variable_name# for them to work?
EDIT: It turns out that the variables aren't all that's missing. Any results from queries done in application.cfm are also not available on the pages.
Copy link to clipboard
Copied
What does the included code look like?
Copy link to clipboard
Copied
BreakawayPaul wrote:
However, the include doesn't work. Any variables set in that include are undefined.
Did you save the file as Application.cfc, with capital A.
Copy link to clipboard
Copied
Everything's lowercase. It's a Windows machine, so not case sensitive.
This is what's in the included file:
<cfquery name="userdata" datasource="hepoffice">
SELECT usernm, user_email, admin
FROM users
WHERE usernm = '#listlast(GetAuthUser(),"\")#'
</cfquery>
<cfif userdata.recordcount eq 0>
<cflocation url="noaccess.html">
</cfif>
<cfset rights = userdata.admin>
<cffile action="read" file="D:\inetpub\fhwaroot_test\includes\hep\acronyms.xml" variable="myxml" />
<cfset variables.acrXML = XmlParse(myxml) />
<cfset variables.acrList = acrXML.acronyms.XmlChildren />
<cfset variables.acrListSize = ArrayLen(acrList) />
<cfset variables.acrQuery = QueryNew("id, name, old, new") />
<cfset variables.acrTemp = QueryAddRow(acrQuery, #acrListSize#) />
<cfloop index="i" from="1" to="#acrListSize#">
<cfset variables.acrTemp = QuerySetCell(acrQuery, "id", #i#, #i#) />
<cfset variables.acrTemp = QuerySetCell(acrQuery, "name", #acrXML.acronyms.acronym.name.XmlText#, #i#) />
<cfset variables.acrTemp = QuerySetCell(acrQuery, "old", #acrXML.acronyms.acronym.old.XmlText#, #i#) />
<cfset variables.acrTemp = QuerySetCell(acrQuery, "new", #acrXML.acronyms.acronym.new.XmlText#, #i#) />
</cfloop>
Copy link to clipboard
Copied
BreakawayPaul wrote:
Everything's lowercase. It's a Windows machine, so not case sensitive.
Use the file name Application.cfc, even on Windows.
Copy link to clipboard
Copied
BreakawayPaul wrote:
<cfset rights = userdata.admin>
<cffile action="read" file="D:\inetpub\fhwaroot_test\includes\hep\acronyms.xml" variable="myxml" />
<cfset variables.acrXML = XmlParse(myxml) />
<cfset variables.acrList = acrXML.acronyms.XmlChildren />
<cfset variables.acrListSize = ArrayLen(acrList) />
<cfset variables.acrQuery = QueryNew("id, name, old, new") />
<cfset variables.acrTemp = QueryAddRow(acrQuery, #acrListSize#) />
<cfloop index="i" from="1" to="#acrListSize#">
<cfset variables.acrTemp = QuerySetCell(acrQuery, "id", #i#, #i#) />
<cfset variables.acrTemp = QuerySetCell(acrQuery, "name", #acrXML.acronyms.acronym.name.XmlText#, #i#) />
<cfset variables.acrTemp = QuerySetCell(acrQuery, "old", #acrXML.acronyms.acronym.old.XmlText#, #i#) />
<cfset variables.acrTemp = QuerySetCell(acrQuery, "new", #acrXML.acronyms.acronym.new.XmlText#, #i#) />
</cfloop>
If you wish these variables (included in Application.cfc) to be available to every requested page, then you should store them in the request scope instead.
Copy link to clipboard
Copied
Wow, that was a pain. I had to find EVERY variable and scope it. But at least it works! Thanks.
Copy link to clipboard
Copied
BKBK wrote:
BreakawayPaul wrote:
<cfset rights = userdata.admin>
<cffile action="read" file="D:\inetpub\fhwaroot_test\includes\hep\acronyms.xml" variable="myxml" />
[...]
If you wish these variables (included in Application.cfc) to be available to every requested page, then you should store them in the request scope instead.
Or, use the onRequest() interceptor to include the requested template, then it will get executed in the same memory space as Application.cfc, so its variables scope will be shared throughout the request. IE: the request will use Application.cfc's variables scope.
--
Adam
Copy link to clipboard
Copied
Adam Cameron. wrote:
Or, use the onRequest() interceptor to include the requested template, then it will get executed in the same memory space as Application.cfc, so its variables scope will be shared throughout the request. IE: the request will use Application.cfc's variables scope.
I should probably figure out how to do that, because I just noticed that any queries done in the included application.cfm (which I'll likely rename) are not accessible on any of the pages in the application.
Copy link to clipboard
Copied
BreakawayPaul wrote:
I should probably figure out how to do that, because I just noticed that any queries done in the included application.cfm (which I'll likely rename) are not accessible on any of the pages in the application.
You needed <cfquery name="request.userdata" datasource="hepoffice">
Copy link to clipboard
Copied
I love it! Got the updated CMS working now.
In the old CMS, I used to keep the name of the last logged-in user in the database, and that would display on the front page when the next person logged in. That way if something weird got changed, you knew who to ask about it.
With no cflogin, I'm hoping I can use something like OnSessionStart() (or End()) to do this same thing, but my trial and error hasn't been going well.
Should I be using OnSession or OnApplication? And how does the Session timeout affect things? If no one requests a page before the session timeout occurs, does the session end? Not that it matters, because the way we're authenticating, it would just renew the credentials.
Copy link to clipboard
Copied
BreakawayPaul wrote:
In the old CMS, I used to keep the name of the last logged-in user in the database, and that would display on the front page when the next person logged in. That way if something weird got changed, you knew who to ask about it.With no cflogin, I'm hoping I can use something like OnSessionStart() (or End()) to do this same thing, but my trial and error hasn't been going well.
They way you describe it, userLastLoggedIn is user-dependent, hence a session variable. For example, when I log in, my value of session.userLastLoggedIn is the user who last logged in before me. If you're the next to log in after me, your value of session.userLastLoggedIn will be me.
The variable has to be available thoughout my session. So the best place to set it is in onSessionStart.
And how does the Session timeout affect things? If no one requests a page before the session timeout occurs, does the session end? Not that it matters, because the way we're authenticating, it would just renew the credentials.
You have set the sessiontimeout value at 1 hour. It means that a user's session will end if the user doesn't make any requests to the server in a period of 1 hour. Users don't share sessions. The server gives each user his own. Therefore, if after logging in you go away for an hour, the server will time your session out. That there are a thousand other users active on the server has no effect on your session.
Copy link to clipboard
Copied
Thanks. I'll play with getting the last logged in user thing to work tomorrow. Today it told me that the last user (me) logged in back in December of 1899. Either the webserver has a time setting problem or something else is wrong. Besides, I only look like I was around in 1899.
The session timeout is pretty irrelevant for us. They've set up some sort of password-protected directory where if you visit the CMS (which is on an intranet server) in IE, your network credentials are retained, and you're let right in. I control access with a database query - if you're in the database, you get in. If you're not, you get sent to an HTML page telling you that you don't have access to the system.
Since the credentials are always "there" from IE, nothing seems to ever time out, even if I make the session time 10 seconds. Firefox users get a login box, but their session never seems to timeout either. I guess I'll leave the session timeout at an hour, since it won't hurt anything.
Copy link to clipboard
Copied
Totally works now!
I had to work around a weird Access (probably) thing. I was entering the last logged in time/date as #Now()# and then querying it. I used timeformat() to get the time out of that, then dateformat() to get the date. But doing that kept giving me the correct time but December 1899 for the date.
To fix this I had to use two separate fields, and update them differently. After trying it probably two dozen different ways, this is the only thing I could get to work:
lastlogintime = <cfqueryparam value="#Now()#" cfsqltype="cf_sql_time">
, lastlogindate = <cfqueryparam value="#dateformat(Now(),"mm-dd-yyyy")#" cfsqltype="cf_sql_date">
In Access both field types are Date/Time.
Hopefully once we get MSSQL working properly, things like that will stop being an issue.
Copy link to clipboard
Copied
Sounds more like you doing something wrong than it does a wierd access thing. Breaking a timestamp into two fields makes sense in some situations, but not yours. But if you are going to do it, you may as well do it properly and send a date to your date field, not a string.
Copy link to clipboard
Copied
@Dan
My first attempt was to just stick #Now()# onto a date/time field with no formatting. Somehow that got me the 1899 thing. I tried many iterations until finally stumbling across the above solution. I don't get why a plain #Now()# can't be used for both time and date, unless the date/time data type of Access is screwy.
I didn't try storing it as text. Maybe I should have just to see what happened.
Copy link to clipboard
Copied
If you insert now() into a table, select the field with a cf query, and cfdump that query, do you get the proper date and time?
Copy link to clipboard
Copied
I get this:
2012-12-20 15:27:04.0
Which seems right.
Copy link to clipboard
Copied
So when you saw something else earlier, it wasn't necessarily bad data.
Copy link to clipboard
Copied
Yes and no. When I queried the database column I was having trouble with before, it started with 1899-12.
I fiddled around some and determined that it was somehow the way the update was being done. I took the <cfqueryparam> off of the #Now()# in the query, and now I get the results I expect. BUT I didn't get it right away. I had to close the browser completely and log back in before it showed up the right way. Maybe it was a session or a caching thing.
Anyway, I FINALLY have one database field for the timestamp!