Can we pass a whole Structure over an URL? - coldfusion

I am opening a new popup window on click of an URL in my page.
My question over here is Can i pass whole structure to the new page ?
If thats not possible is there any simple method to do that ?

Is the page being opened in the URL part of the same application?
If so a better way would be to save the structure in the user's session and pull in the information in that way. Cleaner URLs, code and more secure.
Cheers,
James

Expanding on James Buckingham's answer...
(This assumes you have session management set to true.)
In the calling page, simply copy your structure to a session variable:
<cfset session.myTempStruct=variables.myTempStruct />
Then, in the popup, copy the structure back to the local scope for that request:
<cfset variables.myTempStruct=session.myTempStruct />
If you don't want that structure to hang around in the session, you can have the request for the popup remove it from the session right after copying it to the local scope.
<cfset structDelete(session, "myTempStruct") />

Although HIGHLY NOT recommended, you could do this:
<cfset tmp = {} />
<cfset tmp.name="Marcos" />
<cfset tmp.lname="Placona" />
<cfwddx action="cfml2wddx" input="#tmp" output="tmpWDDX">
link
If you decide to take this approach, I'd suggest sending the information via form as opposed to URL.
You always have the option to store the data in a persistent object such as a bean, or a more simple approach such as a session.
Hope this helps you

You can add your data points as parameters to the end of the URI, but I do not suggest using the method you see as it would be highly subject to injection.

Serializing Struct (with serializeJSON() or something) and puttin git in URL seems reasonable in case struct is not too big (read: less than 3-4k characters in total).
Other solution would be to put this in some shared scope: session, application etc.
Third, would be to call cfm with POST request which can handle larger structs then GET.

Related

Counting the number of hits in a life cycle method using ColdFusion

I am needing to display some analytics regarding how many times a "OnRequestStart" function is called, or rather the number of hits per hour on our internal API that’s contained in a .cfc file. Preferably through the life cycle method; however the counter must continue outside of the life cycle. I know this can be done easily in other languages, but I am new to ColdFusion and have been trying to read through the documentation to see if there is some form of life cycle method I can use in order to achieve this. If there are any sort of documentation I am missing (I've tried learn cf in a week, cfdocs, adobe documentation), but there's not really much out there. This probably isn’t 100% clear, but if there is any clarification needed I’ll be happy to help.
Edit: I figured it would be best to set an application variable in onApplicationStart and incrementally add 1 to the counter variable within the onRequest start. Here is my example code:
Application.cfc:
<CFFUNCTION NAME="OnApplicationStart" ACCESS="PUBLIC" RETURNTYPE="BOOLEAN">
<cfset Application.timer EQ 0/>
<cfset Application.counter EQ 0/>
</CFFUNCTION>
somepage.cfm
<tr>
<cfoutput> #Application.counter#</cfoutput>
</tr>
I thought this would work, but I get an error saying Element COUNTER is undefined in APPLICATION. Is there something I am missing? I tried to restart the CF server service and web server, but no luck.
Thank you everyone for your help
Write it to the application scope, in onRequestStart(), include the following code:
lock scope="application" type="exclusive" timeout=1 throwontimeout=false {
if (!application.keyExists("reqCount") {
application.reqCount= 0;
}
application.reqCount++;
}
Then you can use it whereever you need it.
Turns out, the simplest way to do this is to simply create a variable either outside of the lifecycle or within onApplicationStart then increment the variable with each onRequestStart. You can then do whatever is needed after that. One thing I did stupidly was put <cfset Application.timer EQ 0/> <cfset Application.counter EQ 0/> after a <cfreturn> tag. Lesson learned, don't assume anything, research everything haha.
Thank you everyone

Cfdocument being served by server despite being in cfsavecontent

It seems that when I use the <cfsavecontent> tag, the output of that is being served by the server (without the variable being outputted), which, to me, kind of defeats the purpose of <cfsavecontent>.
If this is important: my application uses ColdSpring, ModelGlue and Transfer ORM.
Here's my example code in a function:
<cfsavecontent variable="testvar">
<cfinclude template="test.cfm" />
</cfsavecontent>
<cfreturn testvar>
And the template:
<cfdocument format="PDF" pagetype="A4" orientation="portrait" unit="cm">
<cfoutput>
<!--- PDF content here --->
</cfoutput>
</cfdocument>
The PDF content is being parsed by my browser (Google Chrome), while the view hasn't even been loaded in. How can I best prevent this from happening?
Just to clarify: I am not outputting the #testvar# variable yet in this code, though it seems it loads the template in the browser anyways.
To achieve what you're trying to do, should you not simply be using the name attribute of <cfdocument> to put the PDF data into a variable, instead of trying to <cfsavecontent> it?
Disclosure: I've never used <cfdocument> for anything other than proof-of-concept code and testing, but that's what I'm inferring from the docs.
As I also needed to make multiple PDF documents merge, I ended up doing the following. Many thanks to Adam Cameron for providing the solution to my initial issue.
In the template file, I use the <cfdocument> tag with the name attribute to save the PDF in a variable (thanks to Adam Cameron for this)
Then, I store all the PDF documents in an array in their binary format
In my view, I merge the PDF documents together by using <cfpdf>'s merge action, and using a cfloop, to loop over the array, inside it.
Finally, I display the content by using <cfcontent> and using the variable attribute with toBinary(myPdf)
This got me to where I am.
cfinclude will process the test.cfm page, and the way you configured cfdocument will cause "opening" of pdf document in your browser.
You can prevent openning of this file by saving file on the disc:
<cfdocument format="PDF" pagetype="A4" orientation="portrait" unit="cm" filename ="test.pdf" overwrite ="yes">
But this will not prevent execution of cfinclude in the cfcontent tag, it will just prevent opening in the browser.
You can observe cfinclude as request to the server, it will always be executed.
The solution would be to invoke request on test.cfm file which contains cfdocument in the moment that you actually want to generate pdf.
Example: Use javascript on client to invoke report service which will generate and pop out the screen with pdf report.
Hope this helps.

ColdFusion include

I'm currently learning ColdFusion. I have a background in PHP and I am a bit confused by this.
I have a select menu and I want the options to be saved in a different file. (For example options.cfm) When I call the file I want to include the options inside the select menu.
Now I realize I could probably do it with something like this:
<select>
<cfinclude template="options.cfm">
</select>
Although what I really want to do is a bit more complicated. I want to have the cfinclude saved inside a variable. I realize this won't work but it is basically what I want to accomplish:
<cfset options=<cfinclude template="options.cfm">>
Is there anyway to do that? Or at least a better way to accomplish what I am doing.
Take a look at the cfsavecontent tag, It allows you to capture what would otherwise have been output to the response :
<cfsavecontent variable="options">
<cfinclude template="options.cfm">
</cfsavecontent>
UPDATE: Instead of using cfsavecontent every time you need those options saved to a variable, you could instead do it once inside of the options.cfm file. Then, anytime you include the file, it will create the variable.
<!--- Inside options.cfm --->
<cfsavecontent variable="options">
<option value="val1">Value 1</option>
<option value="val2">Value 2</option>
<option value="val3">Value 3</option>
</cfsavecontent>
Then where ever you needed that variable to exist you would simply need to cfinclude that file.
<cfinclude template="options.cfm">
i know this is a bit late but one issue i see is if this is site wide or just per client.
if site wide then great but if it is different on each client it could cause some issues.
my solution as i don't use cookies or sessions is to create a temp table and write the variables to it. each page that loads and needs that data queries and/or writes to the table.
a client id variable is created when the client visits the site and the table is named it.
just a thought.

Session variable not refreshing with new cfimage

Here's an odd one, for me at least. I'm reading an image into a cf image variable and saving it as a session variable:
<cfimage action="read" source="myPath/image.jpg" name="myImage" />
<cfset session.image = #myImage# />
I plan to be manipulating that image at some point, which is why I'm saving it to a variable. Anyway, then I stream it with cfcontent:
<img id="photoPlaceholder" src="/#application.root_name#/administration/PhotoManagement/displayPhoto.cfm" width="500px" />
from template displayPhoto.cfm:
<cfcontent variable="#imageGetBlob(session.image)#" />
Here's the problem. After the first call, the first retrieved image is displayed no matter which new image is passed to it. I've tried destroying the session variable before the cfimage tag, and I've verified that I'm passing the correct image variable each time. The only way a new image is shown is if I refresh the page.
It seems to me that cfimage is somehow caching the image, and each new call to it doesn't refresh the variable myImage. CF documentation says nothing about this, and google brought up nothing.
Thoughts?
Your problem is probably client-side. Since the URL in your img tag doesn't change (...displayPhoto.cfm), your browser doesn't see that you are in fact pointing to a new image, so it keeps serving up the image already in cache.
You might try adding a randomized fake parameter to the end of your src attribute, something like this pseudo code:
<img id="photoPlaceholder" src="/#application.root_name#/administration/PhotoManagement/displayPhoto.cfm?somevar=#aUniqueValue#" width="500px" />
You could create the aUniqueValue variable from a random number generator or timestamp generator.
You could also set the HTTP headers up in displayPhoto.cfm to tell the browser not to cache the content form that URL. In theory, this may be better, as otherwise the browser will keep in cache the image from each time it is given a slightly different URL. that's probably not a real-world concern on a desktop where the cache is large and not segmented by site, but a mobile client with limited cache may purge other content which you'd like cached.
If the image is large or the same version is likely to get loaded a lot, look at the HTTP headers, otherwise the approach above is fine (we use both in the app I work on)

store data in array

I have used cfhttp to read a .cfm file, but I want to store the data in one variable or array and pass this variable to a cfchart to display it in chart format. How can I do this?
Use XMLParse and then pull the information you need out of the XML Object and put it into an array or struct or what ever format you need.
As an aside you need to take a look at the online references I've been giving you before asking a question and you also need to mark the previous questions you've asked as answered.
The answer to this will depend on what the .cfm page is returning. If the returned value is XML, then #stephen is pretty much dead on. XMLParse will convert well-formed XML into nested structures and arrays. You can dump them to view the structure, and loop over them to insert it into the array you need.
If the .cfm page returns a list, you can use listToArray() to convert that directly into an array.
If you get name-value pairs, you'll have to do a little work to assign the data correctly, but there are several approaches.
If you edit your question to include more info about the data being returned, and maybe a sample of both the data and what you need it transformed into, we could probably give more specific advice.
Depending on just exactly what your accessing on the .cfm page you're loading via cfhttp, you could try something like:
<cfhttp method="Get"
url="somepage.cfm"
result="myResult">
<cfset PageLoad = ArrayNew(1) />
<cfset PageLoad = #ArrayAppend(PageLoad, myResult.FileContent)# />
I use a variation of that code to return and store a call/response to my custom url shortener...
Hope it helps!