ColdFusion cffeed/cfoutput - coldfusion

I'm currently using a combination of cffeed and cfoutput to generate an XLM/RSS feed, but am getting some curious output, which manifest differently with different browser settings(I think).
The ColdFusion code that produces the XML is
<cfset RssDetails= StructNew()>
<cfset RssDetails.version = "rss_2.0">
<cfset RssDetails.title = #someTitle#>
<cfset RssDetails.link = "someLink#">
<cfset RssDetails.description = #someDetails#>
<cfset RssDetails.pubDate = now()>
<cfset RssDetails.item = ArrayNew(1)>
<cfloop query="queryResults">
<cfset RssDetails.item[currentRow] = structNew()>
<cfset RssDetails.item[currentRow].title = #someResultTitle#>
<cfset RssDetails.item[currentRow].description = structNew()>
<cfset RssDetails.item[currentRow].description.value = #someResultData#>
<cfset RssDetails.item[currentRow].link = "someResultLink#">
</cfloop>
<cffeed action="create" name="#RssDetails#" overwrite="true" xmlVar="someXML">
<cfoutput>#someXML#</cfoutput>
The basic output looks fine in a browser window, but if I then 'View Source' then there's several lines of 'whitespace' that are before and after the main body of XML. The format of the 'whitespace' when observed in 'View Source' is:
As mentioned above, the erroneous/additional output seems to vary with browser settings, although I've not worked out which ones yet, but ultimately, I'd like to remove the whitespace from the CF-generated XML, rather than rely on browser settings.
I've tried a couple of additional options in the cffeed command, but can't seem to hit a successful outcome...grateful for any thoughts or questions,
Phil

Related

Invalid Component Definition

I'm having an issue in the logs I cannot replicate on the browser. I'm getting hundreds of these per day
invalid component definition, can't find component [cfc.udf]
The cfc are stored in a cfc folder one level above the app. This is so that many apps can use the same cfc.
Folder structure:
---- cfc
--------- udf.cfc
---- myApp
--------- application.cfc
In the application.cfc, I'm using application-specific mappings because this is set on a lot of different load-balanced-servers in production as well as a QA environment and local testing environment and keeping them all synced would be difficult.
At onRequestStart, I have a function that restarts the application every 5 minutes. It was supplied by a consultant. I suspect that this is the culprit because the logs show these errors coming in at exactly 5 minute intervals
<cfcomponent>
<cfset This.name = "myApp">
<cfset This.Sessionmanagement=true>
<cfset This.Sessiontimeout="#createtimespan(0,0,30,0)#">
<cfset this.mappings['/cfc'] = ExpandPath('../cfc')>
<cffunction name="onApplicationStart">
<cfset Application.udf = createObject("component", "cfc.udf").init()>
</cffunction>
<cffunction name="onRequestStart">
<cfset appRefreshMinutes = 5>
<cfif Not IsDefined("Application.refreshTime")>
<cfset currentMinute = Minute(Now())>
<cfset Application.refreshTime = DateAdd("n", -(currentMinute MOD appRefreshMinutes)+appRefreshMinutes, Now())>
<cfset Application.refreshTime = DateAdd("s", -(Second(Application.refreshTime)), Application.refreshTime)>
</cfif>
<cfif Now() GTE Application.refreshTime Or IsDefined("URL.reload")>
<cflock name="ApplicationInit" type="exclusive" timeout="5" throwontimeout="false">
<cfif Now() GTE Application.refreshTime Or IsDefined("URL.reload")>
<cfset OnApplicationStart()>
<cfset Application.refreshTime = DateAdd("n", appRefreshMinutes, Application.refreshTime)>
</cfif>
</cflock>
</cfif>
</cffunction>
</cfcomponent>
Promoted from the comments
Have you tried using a mapping name other than /cfc? Like:
<cfset this.mappings['/somethingelse'] = ExpandPath('../cfc')>
so that you can then call it like:
<cfset Application.udf = createObject("component", "somethingelse.udf").init()>
Maybe it just looks odd to me or maybe that is causing your issue (cfc being a reserved word or somehow getting special treatment in this case).

Evaluating Coldfusion directory path for file existence

I've been working on a script for a couple of weeks tweaking it as need be to track CGI.script_PATH and CGI.REFERER on an older coldfusion install which has over 500 .cfc and .cfm pages. I just hit a snag in my code. It doesn't capture a page name in the CGI.Referer variable when the referer is a folder. I'm sure it has something to do with Coldfusion automatically looking for an index.cfm even when the path doesn't include an actual file name.
How can I write an addition to my script where if there is no .cfm in the CGI.Referer, it can search the directory and capture the default file set to load or at least search for an occurrence of index.cfm or default.cfm?
Here is a block of code handling the referer element:
<!---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>
<!---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#") >
The code just strips the CGI script and referer variables of their http web references and then strips the directory structure portion and inserts the .cfm file name and original directory structure into the DB table, but not before reversing the / characters to \ because they want to be able to setup a script which will loop through the table and see something like "\admin\controls\" and auto create those directories, then copy the example.cfm page into that directory. The aim is to 1.) determine which of the 500 cfc/cfm files are still used in the application, then copy them and their directory structure to a new location, and redesign those files in a new technology that isn't Coldfusion.
Update: I'm running into an issue with my code. When I test it, it works well, truncating the http domain portion. However once its operating live under the web server, it doesn't truncate the url despite there being a ReplaceNoCase method to do so:
Under the web root in the wwwroot root, it works well giving this output:
refererPage: testFiles.cfm refererPath = testCodes\MVC
Under the live site I get this:
refererPage: client_display refererPath: **:\dev.fss.com\admin_area**
despite having this line in my code:
Any idea why?
If your cgi.http_referrer variable does not not contain .cfm, you can use the DirectoryExists function on your referer_path variable. If it returns true, you can use the DirectoryList function or cfdirectory tag to search for an occurrence of index.cfm or default.cfm.
they may have this going through a framework (like a model view controller). Without knowing more about the URL structures and the naming conventions.
And without knowing more I would say you are dealing with dynamic content (especially if it is going through index.cfm). Even in an engine with 500 pages, there is a unique identifier and that should be your target not a file. So we may assume there are no files at all and we are just calling parts and pieces from here and there to make a page based on your URL querystring, local variables and/or form variables.
So tables are your friends. Examine your URL structure, try to break down the parameters, search the code base for those parameters and once you have located the area that builds the pages then somewhere there set your tracking tools (a bit higher up stream in the page request stream).
Maybe with some code snippets we could give you a more precise answer but for now this should at least get you looking at your code base for clues.

ColdFusion HELP Pages not Updating: My CF pages are still pointing to the original folder of my application

I have an existing ColdFusion application in my server. What I needed is a duplicate of that application. What I did was copy the entire folder of the original application and put it into another folder.
I already edited the Application.cfm and the links across all the pages in my copy. However, .../indexc.cfm?page=a_app_checklist - in this case, the a_app_checklist is not being updated even if I changed everything on my server /Copy/pages/app/a_app_checklist.cfm
I tried to upload the updated a_app_checklist.cfm on the original application and from there, it was updated. What should I do because I want my copy of the application to be a stand-alone from the original application.
Here is a part of my Application.cfm code:
<cfapplication name="Applicationv2" sessionmanagement="yes" setclientcookies="yes" sessiontimeout="#CreateTimeSpan(00,00,30,00)#"
applicationtimeout="#CreateTimeSpan(00,01,00,00)#" clientstorage="cookie" loginstorage="session">
<cfparam name="Url.page" default="a_main_index">
<cfparam name="Url.formpage" default="">
<cfparam name="Url.resetAppCache" default="">
<!--- Set the Application variables if they aren't defined. --->
<cfset app_is_initialized = False>
<cflock scope="application" type="readonly" timeout="5">
<cfset app_is_initialized = IsDefined("Application.initialized")>
</cflock>
<cfif not app_is_initialized>
<cflock scope="application" type="exclusive" timeout=10>
<cfif not IsDefined("Application.initialized")>
<!--- Do initializations --->
<cfset Application.StudentDB = "DB">
<cfset Application.Url = "/CopyOfApplication/">
<cfset Application.NSUrl = "/CopyOfApplication/">
<cfset Application.EmailLocation = "/CopyOfApplication/pages/email/">
<cfset Application.userfilespath = "/web_assets/UserFiles/">
<cfset Application.UnauthorizedFileExtentions = "ade,adp,asx,bas,chm,cmd,cpl,crt,dbx,exe,hlp,com,hta,inf,ins,isp,jse,lnk,mda,mde,mdz,mht,msc,msi,msp,mst,nch,pcd,prf,reg,scf,scr,sct,shb,shs,url,tmp,pif,dll,vb,vbs">
<cfset Application.ReportPage = "report.cfm">
<cfset Application.PrintPage = "print.cfm">
<!---Puts an instance of the user.cfc and system.cfc in the application scope. All pages can use it. --->
<cfobject type="component" name="Application.System" component="application.system">
<cfset Application.initialized = "yes">
</cfif>
</cflock>
<cfscript>
Application.System.LogActivity("Name","IP","Application scope variables initialized.");
</cfscript>
</cfif>
Like I said, the "page" part in the URL are the only ones that are not being updated. Does it mean I have problems with my URL.Page initialization?
Please let me know if you need additional code. I appreciate any input about this question. Thank you in advance! I am still learning ColdFusion and I will appreciate it if you will help me understand what I need to know!

ColdFusion 10 Error occurring only in IE9

My customer is encountering the error The 2 parameter of the Left function, which is now -1, must be a positive integer after migrating from ColdFusion 8 to ColdFusion 10. The page performs as expected in Firefox 31 and Chrome 36 on Windows 7. However, this error occurs in IE9 but not IE7. Are there different security settings in IE9 that prohibit the processing of the code?
The snippet of code in question is:
<!--- Populate the UserInfo struct --->
<cfloop INDEX="item" LIST="#COOKIE.MYELVIS_USERINFO#" DELIMITERS="&">
<cfset delim = #FindOneOf("=",item)#>
<cfif (len(item)-delim)>
<cfset UserInfo[UCase(left(item,delim-1))] = right(item,len(item)-delim)>
<cfelse>
<cfset UserInfo[UCase(left(item,delim-1))] = "">
</cfif>
</cfloop>
I'm torn to say it's a code error when it works in other browsers, just not IE9. Any thoughts? Thank you.
Perhaps have him clear cookies, he might have a holdover from cf 8 and perhaps the two versions encode differently. It looks like, if this is possible, one of the values doesn't contain a =.
Upon reviewing your code, I think this is what you need.
<cfloop INDEX="item" LIST="#COOKIE.MYELVIS_USERINFO#" DELIMITERS="&">
<cfset delim = #FindOneOf("=",item)#>
<cfif (delim) and (len(item)-delim)>
<cfset UserInfo[UCase(left(item,delim-1))] = right(item,len(item)-delim)>
<cfelse>
<cfset UserInfo[UCase(item)] = "">
</cfif>
</cfloop>

How to extract slide notes from a PowerPoint file with ColdFusion

I have a .PPT (PowerPoint, transferrable to ODP or PPTX) file with speaker notes on every slide. I want to extract the entire presentation into something dynamic so I can create a speaker cheat sheet for running on a phone or table while I talk (thumbnail of the slide with speaker notes). I do this just often enough to HATE doing it by hand.
This is almost easy enough with <cfpresentation format="html" showNotes="yes"> which splits the PPT up into HTML pages and creates an image for every slide. cfpresentation, however, does not transfer the speaker notes, they are lost in translation.
I have also tried <cfdocument> which has no options for preserving slide notes once it converts to PDF.
Is there a way to get the notes out of the PowerPoint file from within ColdFusion?
The simplest solution:
Convert the PowerPoint presentation to OpenOffice ODP format. That's a ZIP file. CFML can unzip it and inside there's a content.xml file which contains the slides and the notes, so CFML can extract the notes from that format.
Given the CFDOCUMENT functionality, perhaps ColdFusion can even convert the PPT to ODP for you?
There's no way to do this directly in CF. You can do this by dropping to the underlying Java. I stand corrected. Using the showNotes attribute on the <cfpresentation> tag, should add the notes to the HTML.
As an alternative, or if that doesn't work for some reason, you should be able to use Apache POI to do this, although you may need to use a more recent version of poi than shipped with your version of coldfusion, which may require some additional work.
public static LinkedList<String> getNotes(String filePath) {
LinkedList<String> results = new LinkedList<String>();
// read the powerpoint
FileInputStream fis = new FileInputStream(filePath);
SlideShow slideShow = new SlideShow(is);
fis.close();
// get the slides
Slide[] slides = ppt.getSlides();
// loop over the slides
for (Slide slide : slides) {
// get the notes for this slide.
Notes notes = slide.getNotesSheet();
// get the "text runs" that are part of this slide.
TextRun[] textRuns = notes.getTextRuns();
// build a string with the text from all the runs in the slide.
StringBuilder sb = new StringBuilder();
for (TextRun textRun : textRuns) {
sb.append(textRun.getRawText());
}
// add the resulting string to the results.
results.add(sb.toString());
}
return results;
}
Carrying over complex formatting may be a challenge (bulleted lists, bold, italics, links, colors, etc.), as you'll have to dig much deeper into TextRuns, and the related API's and figure how to generate HTML.
CFPRESENTATION (at least as of version 9) does have a showNotes attribute, but you'd still have to parse the output. Depending on the markup of the output, jQuery would make short work of grabbing what you want.
Felt bad that my above answer didn't work out so I dug a little bit. It's a little dated, but it works. PPTUtils, which is based on the apache library that #Antony suggested. I updated this one function to do what you want. You may have to tweak it a bit to do exactly what you want, but I like the fact that this utility returns the data to you in data format rather than in HTML which you'd have to parse.
And just in case, here is the POI API reference I used to find the "getNotes()" function.
<cffunction name="extractText" access="public" returntype="array" output="true" hint="i extract text from a PPT by means of an array of structs containing an array element for each slide in the PowerPoint">
<cfargument name="pathToPPT" required="true" hint="the full path to the powerpoint to convert" />
<cfset var hslf = instance.loader.create("org.apache.poi.hslf.HSLFSlideShow").init(arguments.pathToPPT) />
<cfset var slideshow = instance.loader.create("org.apache.poi.hslf.usermodel.SlideShow").init(hslf) />
<cfset var slides = slideshow.getSlides() />
<cfset var notes = slideshow.getNotes() />
<cfset var retArr = arrayNew(1) />
<cfset var slide = structNew() />
<cfset var i = "" />
<cfset var j = "" />
<cfset var k = "" />
<cfset var thisSlide = "" />
<cfset var thisSlideText = "" />
<cfset var thisSlideRichText = "" />
<cfset var rawText = "" />
<cfset var slideText = "" />
<cfloop from="1" to="#arrayLen(slides)#" index="i">
<cfset slide.slideText = structNew() />
<cfif arrayLen(notes)>
<cfset slide.notes = notes[i].getTextRuns()[1].getRawText() />
<cfelse>
<cfset slide.notes = "" />
</cfif>
<cfset thisSlide = slides[i] />
<cfset slide.slideTitle = thisSlide.getTitle() />
<cfset thisSlideText = thisSlide.getTextRuns() />
<cfset slideText = "" />
<cfloop from="1" to="#arrayLen(thisSlideText)#" index="j">
<cfset thisSlideRichText = thisSlideText[j].getRichTextRuns() />
<cfloop from="1" to="#arrayLen(thisSlideRichText)#" index="k">
<cfset rawText = thisSlideRichText[k].getText() />
<cfset slideText = slideText & rawText />
</cfloop>
</cfloop>
<cfset slide.slideText = duplicate(slideText) />
<cfset arrayAppend(retArr, duplicate(slide)) />
</cfloop>
<cfreturn retArr />
</cffunction>