Stripping Out the File Name in the URL - coldfusion-8

I'm working on my final version of a script I've been working on for a week or so. I got everything working to my liking except the last one variable which is finalScriptPath which maps to my table columnscriptPath, which is to strip the page name out of the URL path so that a path like "www.example.com/products/2015/example.cfm will render just the "products\2015" folder structure. See included snip. Here is my code so far:
!---Function named EndRequestFunc for testing safely on CF Server--->
<!---Rename function to OnRequestStart and place in Application.cfm file before running live--->
<cffunction name="EndRequestFunc" access="public" returnType="string">
<!---Variable declared and set to empty--->
<cfset referer_path_and_file = "">
<cfset referer_path = "">
<cfset referer_file_name = "">
<cfset script_path_and_file = "">
<cfset script_path = "">
<cfset script_file_name = "">
<cfif cgi.HTTP_REFERER neq ''>
<!--- all of this will fail if there is no referer, for instance, if they bookmark the page --->
<!--- cgi.HTTP_REFERER may contain URL parameters, so let's strip those --->
<cfset referer_path_and_file = ListFirst(CGI.HTTP_REFERER, "?")>
<!--- now let's get just the path, stripping out the web server info --->
<cfset referer_path = ListDeleteAt(CGI.HTTP_REFERER, ListLen(CGI.HTTP_REFERER, "/"), "/")>
<cfset referer_path = ReplaceNoCase(referer_path, "https", "", "All")>
<cfset referer_path = ReplaceNoCase(referer_path, "http", "", "All")>
<cfset referer_path = ReplaceNoCase(referer_path, "://machine1.fss.com", "", "All")>
<cfset referer_path = ReplaceNoCase(referer_path, "://www_dev.fss.com", "", "All")>
<cfset referer_path = ReplaceNoCase(referer_path, "://www.fss.com", "", "All")>
<cfset referer_path = ReplaceNoCase(referer_path, "://10.11.2.60/", "", "All")>
<cfset referer_path = referer_path & "/">
<cfset referer_path = ReplaceNoCase(referer_path, "/", "\", "All")>
<!--- now let's remove everything but the file name --->
<cfset referer_file_name = ListLast(referer_path_and_file, "/")>
<!--- and that leaves us with these variables set --->
<!--- referer_path_and_file = "#referer_path_and_file#"<br />
referer_path = "#referer_path#"<br />
referer_file_name = "#referer_file_name#"<br />
<br />--->
</cfif>
<!--- cgi.SCRIPT_NAME does not include URL parameters --->
<cfset script_path_and_file = ListFirst(CGI.SCRIPT_NAME, "\")>
<!--- now let's get just the path, stripping out the web server info --->
<cfset script_path = GetDirectoryFromPath(GetCurrentTemplatePath())>
<cfset script_path = ReplaceNoCase(script_path, "C:\inetpub\wwwroot\Clients\fss.com\www_dev", "", "All")>
<cfset script_path = ReplaceNoCase(script_path, "C:\inetpub\wwwroot\Clients\fss.com\www", "", "All")>
<!--- now let's remove everything but the file name --->
<cfset script_file_name = ListLast(script_path_and_file, "/")>
<!--- and that leaves us with these variables set--->
<!---script_path_and_file = "#script_path_and_file#"<br />
script_path = "#script_path#"<br />
script_file_name = "#script_file_name#"<br />--->
<!---<!---CFC Test Query--->
<cfquery name="qryTest" datasource="Fss_Dev" >
INSERT INTO tblCFMPageRequest(pageName)
VALUES
('MyPage.cfm')
</cfquery>--->
<!---Directory Stripping And Modifier Block Goes Here--->
<!---Set CGI System Variables--->
<cfset currentHeader = CGI.HTTP_REFERER >
<cfset currentScriptPage = CGI.SCRIPT_NAME >
<!---Set currentScriptPage as command line directory string and delcare new variable "reverseScriptPage"--->
<cfset reverseScriptPage = ReReplace(#currentScriptPage#, "/", "\","ALL")>
<!---Set reverseScriptPage value as newly format command line directory structure--->
<cfset newScriptPage = ListSetAt(#reverseScriptPage#, 1, "#reverseScriptPage#") >
<cfset lastScriptPage = ListFirst(#newScriptPage#, "/") > <!---Added this 5/11/2015--->
<cfset finalScriptPage = ListSetAt(#lastScriptPage#, 1, "#lastScriptPage#") >
<cfset finalScriptPath = ReReplace(#finalScriptPage#, "/", "\","ALL") >
<!---CGI.HTTP_HEADER Formatting Block--->
<!---This block retrieves the http header value, then strips http formatting--->
<!---currentHeader variable truncated by ListLast then assigned to variable headerFileName--->
<cfset headerFileName = ListLast(#currentHeader#,"/")>
<!---currentHeader URL string has "/" replaced with "\" characters then set as variable reverseHeaderURL--->
<cfset reverseHeaderURL = ReReplace(#currentHeader#, "/", "\","ALL")>
<!---reverseHeaderURL is stripped of all known http type formattings and IP formattings--->
<cfif cgi.HTTP_REFERER neq ''>
<cfset reverseHeaderURL = ListDeleteAt(cgi.HTTP_REFERER, ListLen(cgi.HTTP_REFERER, "/"), "/")>
<cfset reverseHeaderURL = ReplaceNoCase(reverseHeaderURL, "https", "", "All")>
<cfset reverseHeaderURL = ReplaceNoCase(reverseHeaderURL, "http", "", "All")>
<cfset reverseHeaderURL = ReplaceNoCase(reverseHeaderURL, "://machine1.fss.com", "", "All")>
<cfset reverseHeaderURL = ReplaceNoCase(reverseHeaderURL, "://www_dev.fss.com", "", "All")>
<cfset reverseHeaderURL = ReplaceNoCase(reverseHeaderURL, "://www.fss.com", "", "All") >
<cfset reverseHeaderURL = ReplaceNoCase(reverseHeaderURL, "://machine1.fss.com", "", "All")>
<cfset reverseHeaderURL = ReplaceNoCase(reverseHeaderURL, "://10.11.2.60/", "", "All")>
<cfset reverseHeaderURL = ReplaceNoCase(reverseHeaderURL, ":\\dev.fss.com\", "", "All")> <!---Added this line 5/11/2015--->
<!---The end result is then formatted to C:\\ command line format and stored in new variable newHeaderURL--->
<cfset newHeaderURL = ListSetAt(#reverseHeaderURL#, 1, "#reverseHeaderURL#") >
<cfset finalHeaderURL = ReReplace(#newHeaderURL#, "/", "\","ALL")>
</cfif>
<!---Queries Table To Get Requested Record--->
<cfquery name="qryGetPageRecord" datasource="Fss_Dev" dbname="Fss_Dev">
SELECT referrerPage
FROM tblCFMPageRequest
WHERE referrerPage = '#referer_file_name#' AND scriptName = '#script_file_name#'
</cfquery>
<!---Conditional Check for record count equal to 0--->
<cfif qryGetPageRecord.recordCount eq 0>
<!---<cfset httpReferer = ListLast('http://www.fss.com/index.cfm?uid=testValue',"/")>
<cfset ListFirst(httpReferer,"?")>--->
<!---variable declared as scriptName and set equal to CGI.SCRIPT_NAME --->
<!---Value truncated to actual file name through function ListLast() --->
<cfquery name="setNewRecord" datasource="Fss_Dev" dbname="Fss_Dev">
INSERT INTO tblCFMPageRequest (referrerPage, referrerPath, scriptName, scriptPath)
VALUES (<cfqueryparam cfsqltype="cf_sql_varchar" value="#referer_file_name#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#finalHeaderURL#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#script_file_name#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#finalScriptPath#">)
</cfquery>
</cfif>
</cffunction>

Found my solution after some trial and error working with a code block in particular. Below is the solution that worked to strip out the file name, leaving only the path.
<cfif cgi.PATH_INFO neq ''>
<cfset script_path_and_file = ListFirst(CGI.PATH_INFO, "?")>
<cfset script_path = ListDeleteAt(CGI.PATH_INFO, ListLen(CGI.PATH_INFO, "/"), "/")>
<cfset script_path = ReplaceNoCase(script_path, "https", "", "All")>
<cfset script_path = ReplaceNoCase(script_path, "http", "", "All")>
<cfset script_path = ReplaceNoCase(script_path, "://machine1.fss.com", "", "All")>
<cfset script_path = ReplaceNoCase(script_path, "://www_dev.fss.com", "", "All")>
<cfset script_path = ReplaceNoCase(script_path, "://www.fss.com", "", "All")>
<cfset script_path = ReplaceNoCase(script_path, "://10.11.2.60/", "", "All")>
<cfset script_path = script_path & "/">
<cfset script_path = ReplaceNoCase(script_path, "/", "\", "All")>
<cfset script_file_name = ListLast(script_path_and_file, "/") >
</cfif>
<cfset script_path = GetDirectoryFromPath(GetCurrentTemplatePath())>
<cfset script_path = ReplaceNoCase(script_path, "C:\inetpub\wwwroot\Clients\fss.com\www_dev", "", "All")>
<cfset script_path = ReplaceNoCase(script_path, "C:\inetpub\wwwroot\Clients\fss.com\www", "", "All")>
<cfset script_path = ReplaceNoCase(script_path, "C:\inetpub\wwwroot\", "", "All")>
<cfset script_file_name = ListLast(script_path_and_file, "/")>
<cfquery name="setNewRecord" datasource="Fss_Main_Dev" dbname="Fss_Dev">
INSERT INTO tblCFMPageRequest (referrerPage, referrerPath, scriptName, scriptPath)
VALUES (<cfqueryparam cfsqltype="cf_sql_varchar" value="#referer_file_name#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#finalHeaderURL#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#script_file_name#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#script_path#">)
</cfquery>
</cffunction>

Related

Why is coldfusion outputting these values as floating point decimals?

I'm experiencing difficulties with a jwt token, turns out it's because coldfusion is converting an int to a float. I'm not sure where the problem is or how to fix it.
Token timestamp and expiration:
<cfset TimeStamp = '#VAL( int( getTickCount() / 1000 ) )#' >
<cfset Exp = '#VAL( int( (getTickCount() / 1000)+43200 ) )#' >
<cfscript>
Variables.payload = StructNew();
Variables.payload[ "nbf" ] = "#TimeStamp#";
Variables.payload[ "exp" ] = "#Exp#";
Variables.result = JWT.encode( payload, Variables.secretKey);
</cfscript>
The JWT.Encode call looks like this:
<cffunction name="encode" access="public" returntype="String">
<!--- ****************** Arguments ************************ --->
<cfargument name="payload" type="any" required="true">
<cfargument name="key" type="string" required="true">
<cfargument name="algo" type="string" required="false" default="HS256">
<!--- ****************** /Arguments *********************** --->
<!--- define our variables here --->
<cfset var currentTime = getCurrentUtcTime()>
<cfset var header = createObject("java", "java.util.LinkedHashMap").init() /> <!--- StructNew doesnt work because coldfusion 8 orders the keys --->
<cfset var claims = createObject("java", "java.util.LinkedHashMap").init() /> <!--- StructNew doesnt work because coldfusion 8 orders the keys --->
<cfset var segments = ArrayNew(1)>
<!---
creation of first segment of our JWT: the header
--->
<cfset header[ "typ" ] = "JWT">
<cfset header[ "alg" ] = "HS256">
<!--- add header an json with base64 encoding to segment array --->
<cfset arrayAppend( segments, replace( toBase64( serializeJSON( header ) ), "=", "", "all" ) )>
<!---
creation of the middle segment: the claims set
--->
<cfset claims = Arguments.payload>
<!---
escape forward slashes in generated JSON
--->
<cfset claimsJson = replace( serializeJSON( claims ), "/", "\/", "all" )>
<!--- add header and json with base64 encoding (with padding REMOVED!) to segment array --->
<cfset arrayAppend( segments, replace( toBase64( claimsJson ), "=", "", "all" ) )>
<!---
create the last segment: the signature
--->
<cfset signingInput = ArrayToList( segments, "." )>
<cfset signature = sign( signingInput, Arguments.key, Arguments.algo )>
<!---
add signature as last the element to our string
--->
<cfreturn ListAppend( signingInput, signature, ".")>
</cffunction>
Run through a base64 decoder, I get something like exp":1.498696809E9,"nbf":1.498653609E9
Get Nathan Mische's JSONUtil.cfc. Then replace the line
<cfset claimsJson = replace( serializeJSON( claims ), "/", "\/", "all" )>
with
<cfset jsonTool = createobject("component","jsonutil")>
<cfset claimsJson = replace(jsonTool.serializeJSON(claims,false,true), "/", "\/", "all" )>

Adding Colored Events to the Calendar

I have the following working Calendar page (lqCalendar.cfm) that places events from MySQL to the calendar.
<html>
<head>
<link rel="stylesheet" href="../fullcalendar-3.1.0/fullcalendar.min.css" />
<script src="../fullcalendar-3.1.0/lib/jquery.min.js"></script>
<script src="../fullcalendar-3.1.0/lib/moment.min.js"></script>
<script src="../fullcalendar-3.1.0/fullcalendar.min.js"></script>
<script>
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var calendar = $('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
selectable: true,
selectHelper: true,
select: function(start, end, allDay) {
var title = prompt('Event Title:');
if (title) {
calendar.fullCalendar('renderEvent',
{
title: title,
start: start,
end: end,
allDay: allDay
},
true // make the event "stick"
);
}
calendar.fullCalendar('unselect');
},
editable: true,
events: "getLeaveRequests.cfc?method=getMyData",
eventDrop: function(event, delta) {
alert(event.title + ' was moved ' + delta + ' days\n' +
'(should probably update your database)');
}
});
});
</script>
</head>
<body>
<div id='calendar'>
</div>
</body>
</html>
Here is my working CFC (getLeaveRequests.cfc) which queries the data:
<!--- Don't forget to VAR scope all local variables. --->
<cfset var getEvents = "">
<cfset var row = "">
<cfset var result = "">
<cfquery name="getEvents" datasource="care">
SELECT lqID AS id,
lqStartDate AS myStart,
lqEndDate AS myEnd,
CONCAT(lqUser, " (",lqTotalHours,") ", (COALESCE(lqDescription,'')),"") AS title
FROM tblleaverequest
</cfquery>
<cfset result = []>
<cfloop query="getEvents">
<!--- start new structure. must use array notation to preserve case of structure keys--->
<cfset row = {}>
<cfset eventurl ="leave_request_a01z.cfm?id=" & "id">
<cfset row["id"] = id>
<cfset row["title"] = title>
<cfset row["start"] = myStart>
<cfset row["end"] = myEnd>
<!--- append to results --->
<cfset arrayAppend(result, row)>
</cfloop>
<!--- convert to json --->
<cfreturn serializeJSON(result)>
<!---
<cfreturn getEvents>
--->
</cffunction>
</cfcomponent>
What is the best way to "color" the calendar items based on the value of "lqUser"?
- The colors can be dynamically assigned, or if needed, I can add a color field to the User table for each user, but how do I assign it to the FullCalendar?
Here is my updated CFC trying to get colors to work: (using code from "dwayne anderson" post on Raymond Camden site)
- I added a field to my User table called "category_id", then assigned values 1 thru 9 for colors.
The page gives me no errors, just a blank calendar?
<!--- Component to get all of the Leave Request Dates and place on FullCalendar page--->
<cfcomponent>
<cfsetting showDebugOutput='No'>
<cffunction name="getMyData" output="false" access="remote" returntype="any" returnformat="JSON">
<cfargument name="filter" type="string" required="no" default="">
<cfquery name="getallevents" datasource="care">
SELECT lqID AS id,
lqStartDate AS event_start_datetime,
lqEndDate AS event_end_datetime,
IF(category_id IS NULL, '1', category_id) AS color_id,
CONCAT(lqUser, " (",lqTotalHours,") ", (COALESCE(lqDescription,'')),"") AS title
FROM tblusers RIGHT OUTER JOIN tblleaverequest ON tblusers.username = tblleaverequest.lqUser
</cfquery>
<cfquery name="getallcolors" dbtype="query">
Select distinct color_id
from getallevents
</cfquery>
<cfset colorlist="red,green,blue,yellow,black,brown,aqua,orange,darkred">
<cfset colorpos=1>
<cfset colors = []>
<cfloop query = "getallcolors">
<cfset thecolor='#listgetat(colorlist,colorpos)#'>
<cfif colorpos eq listlen(colorlist)>
<cfset colorpos=0>
</cfif>
<cfset colorpos=colorpos+1>
<cfset colors[#color_id#] = thecolor>
</cfloop>
<cfset url.returnformat="json">
<cfset results = []>
<cfloop query = "getallevents">
<cfset eventurl ="eventdetails.cfm?id=" & "id">
<cfset eventcolor ="#colors[color_id]#">
<cfset s = structnew()>
<cfset s["id"] = id>
<cfset s["title"] = title>
<cfset s["start"] = getEpochTime(event_start_datetime)>
<cfset s["end"] = getEpochTime(event_end_datetime)>
<cfset s["url"] = eventurl>
<cfset s["color"] = eventcolor>
<cfset s["allDay"] = false>
<cfset arrayappend(results, s)>
</cfloop>
<cfreturn results>
</cffunction>
<cffunction access="private" name="getEpochTime" returntype="date">
<cfargument name="thedatetime" type="date"/>
<cfif (ArrayLen(Arguments) is 0)>
<cfset thedatetime = Now() />
<cfelseif IsDate(Arguments[1])>
<cfset thedatetime=Arguments[1] />
<cfelse>
return NULL;
</cfif>
<cfreturn DateDiff("s", DateConvert("utc2Local", "January 1 1970 00:00"), thedatetime) />
</cffunction>
</cfcomponent>
What is the best way to "color" the calendar items based on the value of "lqUser"?
You have two options if I am understanding this correctly.
You could set the color for the user in the query itself so its easier to manage at query level via case statments or any other logic
You could do div with classes for specific user or type of user.
HTH.
Got it working! Here is the final & working CFC that includes coloring the calendar events. Thanks for the help.
<!--- Component to get all of the Leave Request Dates and place on FullCalendar page--->
<cfcomponent>
<cfsetting showDebugOutput='No'>
<cffunction name="getMyData" output="false" access="remote" returntype="any" returnformat="JSON">
<cfargument name="filter" type="string" required="no" default="">
<!--- Don't forget to VAR scope all local variables. --->
<cfset var getEvents = "">
<cfset var row = "">
<cfset var result = "">
<cfset var getallcolors = "">
<!--- Query the Leave Requests table and get data for all employees --->
<cfquery name="getEvents" datasource="care">
SELECT lqID AS id,
lqStartDate AS myStart,
lqEndDate AS myEnd,
IF(category_id IS NULL, "", category_id) AS color_id,
CONCAT(lqUser, " (",lqTotalHours,") ", (COALESCE(lqDescription,'')),"") AS title
FROM tblusers RIGHT OUTER JOIN tblleaverequest ON tblusers.username = tblleaverequest.lqUser
</cfquery>
<!--- Do a Query of Queries to get all of the users color values --->
<cfquery name="getallcolors" dbtype="query">
Select distinct color_id
FROM getEvents
</cfquery>
<cfset result = []>
<!--- Assign colors to be used by the FullCalendar variable --->
<cfset colorlist="red,green,blue,black,gray,brown,orange,darkred,darkgreen,darkblue,darkgrey,purple,darkorange,">
<cfset colorpos=1>
<cfset colors = []>
<cfloop query = "getallcolors">
<cfset thecolor='#listgetat(colorlist,colorpos)#'>
<cfif colorpos eq listlen(colorlist)>
<cfset colorpos=0>
</cfif>
<cfset colorpos=colorpos+1>
<cfset colors[#color_id#] = thecolor>
</cfloop>
<cfloop query="getEvents">
<!--- start new structure. must use array notation to preserve case of structure keys--->
<cfset row = {}>
<cfset eventcolor ="#colors[color_id]#">
<cfset eventurl ="leave_request_a01z.cfm?id=" & "id">
<cfset row["id"] = id>
<cfset row["title"] = title>
<cfset row["start"] = myStart>
<cfset row["end"] = myEnd>
<cfset row["color"] = eventcolor>
<!--- append to results --->
<cfset arrayAppend(result, row)>
</cfloop>
<!--- convert to json --->
<cfreturn serializeJSON(result)>
<!---
<cfreturn getEvents>
--->
</cffunction>
</cfcomponent>

Cffile action="write" adding empty lines into my txt

Using ColdFusion I am updating the top line of my txt file, however once I do this it adds an empty line after each line in my txt file and I have no idea why.
A breakdown of my code is as follows:
<!---CSV FILE--->
<cffile action="read" file="C:/ColdFusion10/cfusion/wwwroot/kelly2/debitorders.csv" variable="csvfile">
<cfoutput>
<!---LOOP THROUGH CSV FILE--->
<cfloop index="index" list="#csvfile#" delimiters="#chr(10)##chr(13)#">
<!---SET VALUES--->
<!---TRIM VALUES--->
<!---SET STRING LENGTH FOR EACH--->
<!---SET TOTAL STRING--->
<!---IF FILE FOR BANK EXISTS--->
<cfif FileExists(ExpandPath("#listgetAt('#index#',5)#.txt"))>
<!---READ EXISTING FILE HEADER--->
<cffile action="read" file="C:/ColdFusion10/cfusion/wwwroot/kelly2/#bankname#.txt" variable="bankheader">
<!---SPLIT UP THE HEADER TO ADD NEW VALUES ONTO IT--->
<cfset numericvalue = listfirst(bankheader,chr(13))>
<cfset numericvalue = #Right(numericvalue, 13)#>
<cfset RecordCountvalue = #Left(numericvalue, 3)#>
<cfset RecordCountvalue = #RecordCountvalue# + 1>
<cfset RecordCountvalue = #NumberFormat(RecordCountvalue,"000")#>
<cfset RecordCountvalue = #Left(RecordCountvalue, 3)#>
<cfset RecordCountvalue = #RJustify(RecordCountvalue, 3)#>
<cfset TotalRecordvalue = #Right(numericvalue, 10)#>
<cfset TotalRecordvalue = (#TotalRecordvalue# + #amount#) * 100000>
<cfset TotalRecordvalue = #NumberFormat(TotalRecordvalue,"0000000000")#>
<cfset TotalRecordvalue = #Left(TotalRecordvalue, 10)#>
<cfset TotalRecordvalue = #RJustify(TotalRecordvalue, 10)#>
<!---SET HEADER FOR FILE--->
<cfset fileheader_bank = "#UCase(bankname)#">
<cfset fileheader_bank = "#Left(fileheader_bank, 15)#">
<cfset fileheader_bank = "#LJustify(fileheader_bank, 16)#">
<cfset newfile_header = "#fileheader_bank##RecordCountvalue##TotalRecordvalue#">
<!---APPEND FILE AND ADD UPDATED HEADER--->
<cfset bankheader = listSetAt(bankheader,1,"#newfile_header#","#chr(13)#")>
<cffile action="write" file="#getDirectoryFromPath(getTemplatePath())#/#listgetAt('#index#',5)#.txt" output="#bankheader#">
<!---APPEND FILE AND ADD NEW ENTRY--->
<cffile action = "append"
file = "C:/ColdFusion10/cfusion/wwwroot/kelly2/#listgetAt('#index#',5)#.txt"
output = "#total_string#">
</cfif>
</cfloop>
</cfoutput>
I am pretty sure the problem is in one of these cffile tags.
<!---APPEND FILE AND ADD UPDATED HEADER--->
<cfset bankheader = listSetAt(bankheader,1,"#newfile_header#","#chr(13)#")>
<cffile action="write" file="#getDirectoryFromPath(getTemplatePath())#/#listgetAt('#index#',5)#.txt" output="#bankheader#">
<!---APPEND FILE AND ADD NEW ENTRY--->
<cffile action = "append"
file = "C:/ColdFusion10/cfusion/wwwroot/kelly2/#listgetAt('#index#',5)#.txt"
output = "#total_string#">
I have removed a lot of the unnecessary but if you need any of it please let me know.
If you used CFScript you would not have the issue. Because your using ColdFusion Tags returns and spaces affect document layout. Try minifiying your code to remove any floating returns / spaces. I have run into this issue with creating PDF files in CF

ColdFusion 8 - Application.cfc interference

I've just had a strange issue with a client's website, my live domain was using my development domains Application settings. I've not had this issue before, and removing cflock around the Application.dsn (amongst other settings) resolved the issue.
As mentioned I have a live site *www.* and development site *dev.*, my development site is in a subfolder of the live site /dev/ and has it's own Application.cfc.
My first question is, if I have variables in my Application scope in the dev folder will this overwrite the Application scope variables in the folder above? Will it consider it the same scope? If so, then this might explain what the issue and if not then I am stumped.
My second question is, how should I correct cflock application scope variables in my application.cfc? Should I be doing this at all?
Here is my Application.cfc, advice would be greatly appreciated:
<cfcomponent output="true">
<cfimport taglib="taglib" prefix="func">
<!---
Check staging directory exists
--->
<cfset THIS.env = "staging">
<!---
Set application vars
--->
<cfset THIS.applicationTimeout = createTimeSpan(0,0,0,0)>
<cfset THIS.sessionManagement="Yes">
<cfset THIS.clientManagement = true>
<cfset THIS.clientStorage = "cookie">
<cfset THIS.loginStorage = "cookie">
<cfset THIS.setDomainCookies = false>
<cfset THIS.setClientCookies = true>
<cfset THIS.scriptProtect = true>
<cfset THIS.secureJSON = true> <!--- Added 12.06.13 --->
<!---
Check environment
Set application name
--->
<cfif THIS.env EQ "staging">
<cfset THIS.applicationName = "devenv">
<cfset THIS.dsn = "devenv">
<cfelse>
<cfset THIS.applicationName = "liveenv">
<cfset THIS.dsn = "liveenv">
</cfif>
<cfif #cgi.HTTP_HOST# NEQ "localhost">
<cfset THIS.dirpath = "http://#cgi.http_host#">
<cfset THIS.componentPath = "cfcs.">
<cfelse>
<cfset urlString = #mid(cgi.PATH_INFO, 2, 200)#>
<cfset THIS.localhostFolderName = #spanexcluding(urlString, "/")#>
<cfset THIS.dirpath = "http://localhost/#THIS.localhostFolderName#">
<cfset THIS.componentPath = "#THIS.localhostFolderName#.cfcs.">
</cfif>
<cfset THIS.name = THIS.applicationName>
<cfset THIS.sessiontimeout = createtimespan(0,0,20,0)>
<cfset THIS.setClientCookies = true>
<cfset THIS.visitor = true>
<cffunction name="onApplicationStart" returntype="void">
<cfset APPLICATION.name = THIS.applicationName>
<cfset APPLICATION.dsn = THIS.dsn>
<cfset APPLICATION.DSN = THIS.dsn>
<cfset APPLICATION.dirpath = THIS.dirpath>
<cfset APPLICATION.componentPath = THIS.componentPath>
<cfif #cgi.HTTP_HOST# EQ "localhost">
<cfset APPLICATION.localhostFolderName = THIS.localhostFolderName>
</cfif>
<!--- USED FOR PATHS AND URLS --->
<!--- Property image upload paths ---->
<cfset APPLICATION.paths = StructNew()>
<!---
Check environment
Set local root
--->
<cfif THIS.env EQ "staging">
<cfset APPLICATION.paths.localRoot = "c:\websites\foobar.co.uk\dev\">
<cfelse>
<cfset APPLICATION.paths.localRoot = "c:\websites\foobar.co.uk\">
</cfif>
<cfset APPLICATION.paths.logs = APPLICATION.paths.localRoot & "logs\">
<cfset APPLICATION.paths.logFile = APPLICATION.paths.logs & "site_log.txt">
<cfset APPLICATION.paths.property = StructNew()>
<cfset APPLICATION.paths.property.image = APPLICATION.paths.localRoot & "images\property\">
<cfset APPLICATION.paths.property.large = APPLICATION.paths.property.image & "large\">
<cfset APPLICATION.paths.property.thumb = APPLICATION.paths.property.image & "thumbs\">
<cfset APPLICATION.paths.property.cmsThumb = APPLICATION.paths.property.image & "thumbs\cms\">
<cfset APPLICATION.paths.property.pdf = APPLICATION.paths.localRoot & "pdf\">
<cfset APPLICATION.paths.property.pdfGenerated = APPLICATION.paths.property.pdf & "generated\">
<cfset APPLICATION.newsUploadPath = APPLICATION.paths.localRoot & "images\news\">
<cfset APPLICATION.articlesUploadPath = APPLICATION.paths.localRoot & "images\articles\">
<cfset APPLICATION.articlesThumbsDir = "../images/articles/thumbs/">
<cfset APPLICATION.articlesContentDir = "../images/articles/assets/">
<cfset APPLICATION.articlesAssetsDir = "../articles/assets/">
<!--- Site URLS ---->
<cfset APPLICATION.urls = StructNew()>
<cfset APPLICATION.urls.root = "http://" & CGI.server_name & "/">
<cfset APPLICATION.urls.com = "com">
<cfset APPLICATION.urls.tagLib = APPLICATION.urls.root & "taglib/">
<cfset APPLICATION.urls.cms.tagLib = "http://" & CGI.server_name & ":" & CGI.server_port & "/admin/tagLib/">
<cfset APPLICATION.RowsPerPage = 10>
<!--- Property URLS --->
<cfset APPLICATION.urls.property.pdf = APPLICATION.urls.root & "pdf/">
<cfset APPLICATION.urls.property.image = APPLICATION.urls.root & "images/property/">
<cfset APPLICATION.urls.property.large = APPLICATION.urls.root & "images/property/large/">
<cfset APPLICATION.urls.property.thumb = APPLICATION.urls.root & "images/property/thumbs/">
<cfset APPLICATION.urls.property.cmsThumb = APPLICATION.urls.root & "images/property/thumbs/cms/">
<cfset APPLICATION.urls.news.image = APPLICATION.urls.root & "images/news/">
<cfset APPLICATION.urls.articles.image = APPLICATION.urls.root & "images/articles/">
<cflock scope="Application" timeout="5" type="Exclusive">
<cfscript>
/* Commonly used objects and queries */
// DAOs
APPLICATION.propertyDAO = CreateObject("component", "cfcs.dataobjects.propertyDAO").init(APPLICATION.dsn);
APPLICATION.propertyImageDAO = CreateObject("component", "cfcs.dataobjects.property_imageDAO").init(APPLICATION.dsn);
APPLICATION.propertyToPropertyImageDAO = CreateObject("component", "cfcs.dataobjects.property_to_property_imageDAO").init(APPLICATION.dsn);
APPLICATION.propertyToPropertyLocationDAO = CreateObject("component", "cfcs.dataobjects.property_to_property_locationDAO").init(APPLICATION.dsn);
APPLICATION.propertyToPropertyTypeDAO = CreateObject("component", "cfcs.dataobjects.property_to_property_typeDAO").init(APPLICATION.dsn);
APPLICATION.propertyToPropertyTenureDAO = CreateObject("component", "cfcs.dataobjects.property_to_property_tenureDAO").init(APPLICATION.dsn);
APPLICATION.propertyGroupDAO = CreateObject("component", "cfcs.dataobjects.property_groupDAO").init(APPLICATION.dsn);
// Gateways
APPLICATION.propertyGateway = CreateObject("component", "cfcs.dataobjects.propertyGateway").init(APPLICATION.dsn);
APPLICATION.propertyImageGateway = CreateObject("component", "cfcs.dataobjects.property_imageGateway").init(APPLICATION.dsn);
APPLICATION.propertyToPropertyImageGateway = CreateObject("component", "cfcs.dataobjects.property_to_property_imageGateway").init(APPLICATION.dsn);
APPLICATION.propertyLocationGateway = CreateObject("component", "cfcs.dataobjects.property_locationGateway").init(APPLICATION.dsn);
APPLICATION.propertyImageGateway = CreateObject("component", "cfcs.dataobjects.property_imageGateway").init(APPLICATION.dsn);
APPLICATION.propertyTypeGateway = CreateObject("component", "cfcs.dataobjects.property_typeGateway").init(APPLICATION.dsn);
APPLICATION.propertyToPropertyTypeGateway = CreateObject("component", "cfcs.dataobjects.property_typeGateway").init(APPLICATION.dsn);
APPLICATION.propertyTenureGateway = CreateObject("component", "cfcs.dataobjects.property_tenureGateway").init(APPLICATION.dsn);
APPLICATION.propertyToPropertyTenureGateway = CreateObject("component", "cfcs.dataobjects.property_to_property_tenureGateway").init(APPLICATION.dsn);
APPLICATION.partnerGateway = CreateObject("component", "cfcs.dataobjects.partnerGateway").init(APPLICATION.dsn);
// Business Objects
APPLICATION.propertyBO = CreateObject("component", "cfcs.businessobjects.propertyBO").init(APPLICATION.dsn);
// Common queries
APPLICATION.qPartners = APPLICATION.partnerGateway.getAllRecords();
APPLICATION.qPropertyTypes = APPLICATION.propertyTypeGateway.getAllRecords();
APPLICATION.qPropertyTenures = APPLICATION.propertyTenureGateway.getAllRecords();
APPLICATION.qPropertyMinMaxSize = APPLICATION.propertyGateway.getMinMaxSize();
APPLICATION.qPropertyLocations = APPLICATION.propertyLocationGateway.getAllRecords();
</cfscript>
</cflock>
</cffunction>
<cffunction name="onSessionStart" returntype="void">
<cflock scope="Session" timeout="5" type="Exclusive">
<cfscript>
SESSION.propertySearchCriteria = CreateObject("component", "cfcs.beans.property_search_criteria").init();
SESSION.propertySearch = CreateObject("component", "cfcs.beans.property_search").init(SESSION.propertySearchCriteria);
</cfscript>
</cflock>
</cffunction>
Why do you change your application name based on the environment it's in? That makes no sense. The application is still the same app, irrespective of whether it's in prod, or you're staging it, or developing it.
Equally, same with the source code. You've got your dev site within your live website? How does this make any sense?
I dunno what's going on with your application variables, but they're bound to the application name (this.name), not where the Application.cfc is in the directory structure.
I suspect your zero applicationTimeout is not helping matters much here. This basically means your application never actually persists... it'll be timing out every request. This makes no sense either.
You do not need to <cflock> that code in onApplicationStart(). ColdFusion will only allow one request to run onApplicationStart(): all other requests will be queued until it's completed, by which time the application has started, so the queued requests won't even attempt to run it.
I think your problem is most likely causes by your poor application framework design, and this weird thing you're doing having dev and prod in the same source code tree (which defies all logic).
Sort your source code out, and the problem won't arise.
You can use conditional logic to set your application name.
if ( YouAreHappy and YouKnowIt ) {
This.name = "ClapYourHands";
}
else {
This.name = "StompYourFeet";
}
In real life, your if condition would be something that differented the live and test environments. cgi.http_host is a good candidate.

CFRETURN to .CFM page

Trying to display structExcelResult["strUrl"] created by the function on my .cfm page.
<cffunction name="getBuyerReport" output="false" access="public" returntype="struct">
<cfargument name="intRegionId" required="yes">
<cfargument name="intBuyerId" required="yes">
<cfargument name="intStage" required="yes">
<cfargument name="strSortField" required="yes">
<cfargument name="strSortDirection" required="yes">
<cfset var structExcelResult = StructNew()>
<cfset var qRead="" />
<cfquery name="qRead" datasource="#variables.dsn#">
SELECT CONVERT(varchar,t.RECEIVED_DATE,101) AS [Received Date]
, t.REQUISITION_NO AS [Requisition Number]
, t.REQUISITION_TITLE AS [Requisition Title]
, t.TECHNICAL_AUTHORITY_NAME AS [Technical Authority]
, bm.BID_START_DATE AS [Solicitation Date]
, bm.BID_END_DATE AS [Closing Date]
, CAST(t.REQ_AMOUNT AS MONEY) AS [Requisition Value]
, CAST(t.APPROVAL_AMOUNT AS MONEY) AS [Approval Value]
, t.CURRENT_STAGE AS [Current Stage]
, CONVERT(varchar,t.ESTIMATED_AWARD_DATE,101) AS [Estimated Award Date]
, replace(replace(n.NOTE,CHAR(13),''),CHAR(10),'') as [Comments]
, DATEDIFF(day, t.RECEIVED_DATE, getdate()) AS [Age of Requisition (days)]
, cb.USER_NAME as [Buyer Name]
, o.OFFICE_LOCATION_NAME as [Office Location]
FROM VW__TOMBSTONES__CLIENT_CODES t
LEFT OUTER JOIN TB__OFFICE_LOCATIONS o
ON o.ID = t.OFFICE__ID
LEFT OUTER JOIN TB__USERS cb
ON t.CURRENT_BUYER__ID = cb.ID
LEFT OUTER JOIN TB__BID_MANAGEMENTS bm
ON bm.TB__TOMBSTONES__ID = t.ID
LEFT OUTER JOIN TB__REQUISITIONS r
ON r.TOMBSTONES__ID = t.ID
LEFT OUTER JOIN TB__NOTES n
ON n.REQUISITION__ID = r.ID
AND t.CURRENT_STAGE = n.NOTE_TYPE
WHERE t.CURRENT_STAGE <= 4
AND n.NOTE_TYPE BETWEEN 1 AND 4
AND t.REGION__ID = #arguments.intRegionId#
</cfquery>
<!--- Create new spreadsheet --->
<cfset sObj = SpreadsheetNew()>
<!--- Excel Functions --->
<cfset countFormula="COUNTA(A8:A20000)">
<cfset sumFormula="SUM(G2:G2000)">
<!--- Create header row --->
<cfset SpreadsheetMergeCells(sObj,1,1,1,2)>
<cfset SpreadsheetSetCellValue(sObj, "BUYER REGISTER REPORT",1,1)>
<cfset SpreadsheetFormatRow(sObj, {bold=TRUE, alignment="center"}, 1)>
<cfset SpreadsheetSetCellValue(sObj, "Report Generated Date:",3,1)>
<cfset SpreadsheetFormatCell(sObj, {bold=TRUE, alignment="right"}, 3,1)>
<cfset SpreadsheetSetCellValue(sObj, "#ToString(DateFormat(now(), "mmmm d yyyy"))#",3,2 )>
<cfset SpreadsheetFormatCell(sObj, {bold=TRUE, alignment="left"}, 3,2)>
<cfset SpreadsheetSetCellValue(sObj, "Number of Requisitions:",4,1)>
<cfset SpreadsheetFormatCell(sObj, {bold=TRUE, alignment="right"}, 4,1)>
<cfset SpreadsheetSetCellFormula(sObj,countFormula, 4, 2)>
<cfset SpreadsheetFormatCell(sObj, {bold=TRUE, alignment="left"}, 4,2)>
<cfset SpreadsheetSetCellValue(sObj, "Value of Requisitions:",5,1 )>
<cfset SpreadsheetFormatCell(sObj, {bold=TRUE, alignment="right"}, 5,1)>
<cfset SpreadsheetSetCellFormula(sObj,sumFormula, 5, 2)>
<cfset SpreadsheetFormatCell(sObj, {bold=TRUE, alignment="left"}, 5,2)>
<cfset SpreadsheetFormatCell(sObj, {dataformat="$##,##0.00"}, 5,2)>
<cfset SpreadsheetAddRow(sObj, "" )>
<cfset SpreadsheetAddRow(sObj, "RECEIVED DATE,REQUISITION NUMBER,REQUISITION TITLE,TECHNICAL AUTHORITY,SOLICITATION DATE,CLOSING DATE,REQUISITION VALUE,APPROVAL VALUE,CURRENT STAGE,ESTIMATED AWARD DATE,COMMENTS,AGE OF REQUISITION (DAYS),BUYER NAME,OFFICE LOCATION")>
<cfset SpreadsheetFormatRow(sObj, {bold=TRUE}, 7)>
<!--- Add orders from query --->
<cfset SpreadsheetAddRows(sObj, qRead)>
<cfset SpreadsheetFormatColumns(sObj, {dataformat="$##,##0.00"}, "7-8")>
<cfset SpreadsheetFormatColumns(sObj, {alignment="center"}, "9-10")>
<cfset SpreadsheetFormatColumns(sObj, {alignment="center"}, "12-15")>
<!--- Excel document naming and storing location --->
<cfset strDir=GetDirectoryFromPath(GetCurrentTemplatePath())&"/../assets/generatedXLS/">
<cfset strFilePrepend = "-BuyerReport-" />
<cfset strFileNameStamp = "Galileo" & "#strFilePrepend#" & "#ToString(DateFormat(now(), "yy-mm-dd"))#" & "-#ToString(TimeFormat(now(), "HHmmss"))#" & ".xls"/>
<cfspreadsheet action="write"
filename="#strDir##strFileNameStamp#"
name="sObj"
overwrite="true"
sheetname="Active (Stages 1-4)">
<cfset structExcelResult["strURL"] = "/web_apps/app/assets/generatedXLS/" & #strFileNameStamp# />
<cfset structExcelResult["strNoRecordsFoundMsg"] = "" />
<cfreturn structExcelResult>
How do I fetch that data (structExcelResult["strURL"]) and display it on my .cfm page?
I'm new at this and going through Ben Forta books... Thanks!
Since you have a cfreturn in your code, I'll assume that was meant to have been wrapped in cffunction.
You can call a cffunction a couple of different ways. It could be on the same .cfm page that you're on:
<cffunction name="sayHello" output="false">
<cfargument name="username" type="string" required="false" default="Anonymous" />
<cfreturn "Hello, " & username />
</cffunction>
<cfoutput>#sayHello( 'Charlie' )#</cfoutput>
However, it's more likely that your function is part of a ColdFusion Component (CFC). To call a function that's part of a CFC, you first have to instantiate the CFC:
<cfset myCFC = createObject( 'component', 'path.to.my.cfc' ) />
Now you can call any method that resides in the CFC via:
<cfoutput>#myCFC.myFunction( 'foo' )#</cfoutput>
Going back to my first (very simple) example, let's say the sayHello() function resided in the Greeting.cfc file that was at /com/Greeting.cfc.
<cfset greeting = createObject( 'component', 'com.greeting' ) />
<cfoutput>#greeting.sayHello( 'Charlie' )#</cfoutput>
You can use anything you'd like for the name. It doesn't have to be myCFC or greeting. It's just a variable that represents a hook into your component.
Hope that helps.