How to rename the primary key field in CFWHEELS? - coldfusion

This is what I've tried... but for some reason "model("user").primaryKey() is still returning the old "User_Id" column...
<cfset table("user_table")>
<cfset property(name="id", column="User_Id") />
<cfset setPrimaryKey(property="id") />
UPDATE
The problem lies within the "Scaffold" plugin.
It's using the "COLUMNLIST" instead of the "PROPERTYLIST"
I've repaired this and it seems to be generating properly now.

Originally the question did not state that it was a problem with the Scaffold plugin.
However, the solution is to just specify
<cfset property(name="id", column="User_Id") />
(as stated in the CFWHEELS documentation)
The bug itself, lies within the Scaffold plugin which uses "COLUMNLIST" to generate the HTML.
The HTML is then referencing "#users.user_id#" which doesn't exist since it's now called "id".
I changed the Scaffold plugin to use "PROPERTYLIST" and now it's fine.
Very sorry for confusion!

Try to put only
<cfset setPrimaryKey("id") />
inside User model. After all add &reload=true to your URL. This will rebuild the application and refresh the settings.

Related

Referencing code-created datasources in Lucee

I have created a number of datasources in Lucee using code. This is for a legacy ColdFusion application that we are migrating to Azure, and per the powers-that-be, they want the DSNs created in code so we can store the DSN passwords in a keystore. I have that part already working.
The datasources look something like this: this.datasources["myDSN"]
If, in the code (Application.cfm), I do this:
<cfset myDSN = this.datasources["myDSN"]>
This will then fail:
<cfquery name="whatever" datasource="#myDSN#">
It fails with "datasource myDSN not found."
BUT, if I do this instead:
<cfquery name="whatever" datasource="#this.datasources['myDSN']#">
... it works fine.
Is there a workaround for this? At last check in this one application alone, there are 368 occurrences of datasource= in 115 files. I'd rather not have to do a bulk search/replace. It makes no sense to me that the variable "myDSN" would fail.
As there are multiple datasources being used, I can't just set the default datasource and remove the datasource= attribute entirely; even then, it'd still require a mass search/replace.
I must be missing something. I've read the Lucee docs on datasources but it hasn't helped. Thanks!
Turns out that Scott Stroz was correct. I switched over to Application.cfc and now it works fine.

Adding page numbers to PDF with Lucee cfpdf

Everything I have found about CFPDF says that the way to add page numbers to a PDF is like this
<cfpdf action="addFooter" source="#finalFile#" name="mypdf"
text="Page _PAGENUMBER of _LASTPAGENUMBER" />
The problem is every reference I have found is for coldFusion 9 and before and I am wondering if maybe the Lucee guys didn't include this functionality because I get an error that says
Attribute text is not allowed for tag cfpdf
Is this a syntax issue or an oversight by Lucee/Railo not to put this in.
I am merging a group of PDFs using CFPDFs merge feature that this is working correctly but I now need to put page numbers on the PDF and that is were I am hitting a wall.
Here is the a more complete picture of what I am trying to do. The only part that isn't working is the addFooter line
<cfpdf action = "merge" destination="#finalFile#" overwrite="yes">
<cfloop array="#arrayOfPdfs#" index="k">
<cfpdfparam source="#k#">
</cfloop>
</cfpdf>
<cfpdf action="addFooter" source="#finalFile#" name="mypdf"
text="Page _PAGENUMBER of _LASTPAGENUMBER" />
<cfloop array="#arrayOfPdfs#" index="k">
<cffile action="delete" file="#k#">
</cfloop>
I did a little searching and here is what I found. Remember that Lucee was previously Railo. I found your exact issue reported as a bug in Railo back in August 2011 - cfpdf addfooter not supported It looks like that bug was never addressed.
The Lucee docs mention the ability to add a header/footer using cfpdf in the lead-in paragraph but not in the tags attributes - Lucee documentation for cfpdf
Create PDF portfolios - Add and remove header/footer from PDF documents - Optimize PDF documents
(my emphasis) But there is no mention of addheader or addfooter beyond that.
This just mirrors the original Railo documentation - Railo documentation for cfpdf
I am guessing that this bug was never resolved and now exists (still exists) in Lucee. I would create a new issue for the Lucee group to revisit this - https://luceeserver.atlassian.net/secure/Dashboard.jspa
It is interesting that it seems to accept the addfooter action just not the text attribute. That makes it seem like a bug.
UPDATE 11/18/2021
From Andy's comment below "It looks like a fix is coming from the PULL requests at github.com/lucee/extension-pdf/pulls specifically github.com/lucee/extension-pdf/pull/31" it appears that a fix may finally be coming for this issue. Thanks for the update Andy!

How do I locate a custom tag instantiation in a coldFusion App

I am migrating a very old app (currently running in CF8) to Lucee. But I am running into a problem with what appears to be a custom tag of some sort.
I have tried to make sure that all the virtual directories are the same in IIS for both the old and the new installs. And made sure the mapping and custom tag paths in both the CFIDE and the Lucee Admin are the same.
But I am getting this error. And can't figure out how this cflink is being instantiated.
I have found the location of the erroring code on line 300 the utils.cfc file
I haven't used custom tags in a long time but thought they were generally called with an underscore and the code should like more like <cf_link pageid="#LinkPageID#" Init="start"> if this was being called as a custom tag.
If I go the the current CF server that is running this app I can find that a cfclass files HAS been created
From a file called cflink.cfm in a directory called "tags" even though there seems to be no mapping for the "tags" directory nor is is listed under "custom tags paths" in the administrator.
This App was start in 2003 and as you can imagine has grown into a mis-match of spaghetti code and no one from the beginning is around to ask how this tag is instantiated.
Does anyone with experience in legacy code has any other ideas where I should be looking to try to get this to work? The currently has only a production environment and if I can get it to work on Lucee it will not only be a dev environment that hasn't existed here in 10 years but will be a great way for me to be able to continue showcasing Lucee as a great CFML engine
Adding addition info
Leigh had asked if the init might be a jar reference but in the cflink.cfm file I see this code:
<cfif Attributes.Init IS "start">
<cfset Request.PageID = Attributes.PageID>
<cfset Request.Page_Width = Variables.qParentInfo.Page_Width>
<cfset Request.Page_Height = Variables.qParentInfo.Page_Height>
<cfset Request.Page_TypeID = Variables.qParentInfo.Page_TypeID>
<cfset Request.AddPath = "">
<cfif IsDefined("Attributes.Anchor")>
<cfset Request.Anchor = Attributes.Anchor>
<cfelse>
<cfset Request.Anchor = "">
</cfif>
<cfset Request.IsInternalLink = false>
<cfexit method="EXITTAG">
</cfif>
There are also references to cflink in the code inside tags\cflink.cfm
<cfif Len(Variables.qParentInfo.ParentID) GT 0>
<!--- Add the page title to the end of the path --->
<cfset Request.AddPath = ReplaceNoCase(Variables.qParentInfo.Nav_Title," ","_","ALL") & "/" & Request.AddPath>
<cflink init="working" pageid="#Variables.qParentInfo.ParentID#" popcode="#Attributes.popcode#">
<cfelse> ......</cfif>
Although this may be recursion given it was written in 2004 I kind of doubt it
Adding screen shots of searches
If anyone else runs into this. In CF8, and presuming earlier versions, you could put a cfm file into the ColdFusion8\wwwroot\WEB-INF\cftags Directory and that file in this case ColdFusion8\wwwroot\WEB-INF\cftags\link.cfm Then acts as any other cftag.
I was able to find the person who originally build this app in 2004 and he told me that they did it this way to avoid typing the underscore that they would have typed if they'd done it as a custom tag.
I kind of get it since this tag is used everywhere in the app, literally hundreds of times. Bit boy with a bitch to find.
Now all I have to do is figure out how to move it to the Lucee world in a similar fashion. So it instanciates the same way.
Thanks #Leigh for all your help, you are always amazing!
Adding more information
if there are files in the WEB-INF\lucee\library\tag the corresponding Lucee directory is WEB-INF\lucee\library\tag. These files are read on load and then able to be used as any other cf tag.
For example if you have file WEB-INF\lucee\library\tag\link.cfm it can be called by `cflink'.
Seems like a cool idea but a bit of a bitch for someone to find 10 years after the fact

Can we pass a whole Structure over an URL?

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.

Custom Tags and cfimport

Do Custom Tags work with mappings?
I'm trying not to have to address the CustomTags folder as a relative address.
I've tried:
<cfset this.mappings["/CT"] = Expandpath("/myProjects/Project1/CustomTags")>
inside of Application.cfc and then
<cfimport prefix="tag" taglib="/CT">
inside of my page, but it doesn't.
It says:
Cannot import the tag library specified by /CT.
The following error was encountered: C:\Inetpub\wwwroot\CT. Ensure that you have specified a valid tag library.
Contrary to what Jayson reported - I have CFIMPORT working just fine w/ a per application mapping vs one globally set in CFAdmin. CFIMPORT is pretty cranky about mappings (for instance you cannot use variable for relativepath, nor use expandpath) - but you should be able to do what you are requesting w/o issue.
Do you have "Enable Per App Settings" checked in CFAdmin | Settings to allow you the use of this.mappings? What version of CF are you running? I'm using CF8 with this code and have no issues:
Application CFC (outside a function but w/in component):
this.rootPath = getDirectoryFromPath(getCurrentTemplatePath()); // this assures path of application.cfc is used to determine path, likely equivalent to expandPath("/")
structInsert(this.mappings, '/vp', this.rootPath);
In CFC (outside a function but w/in component):
<cfimport prefix="loader" taglib="/vp/view/_loader/">
I can then use in the CFC and it works as expected.
The docs says it works with a directory specified in the Administrator ColdFusion mappings page. Have you tried setting the mapping in the ColdFusion administrator to see if that works first? If that works, but the this.mappings set per application in the application.cfc doesn't work, then possibly it is a bug?!?
EDIT:
I tested Adam's suggestion to use the expandPath() function, but this also does not work because the taglib attribute must contain a constant value. It cannot contain a variable or function. It simply doesn't work unless you use a mapping set in the ColdFusion Administrator. I tried the following tests using this application.cfc.
<cfcomponent>
<cfset this.name = "TestApp" />
<cfset this.loginStorage = "session" />
<cfset this.sessionManagement = true />
<cfset this.setClientCookies = true />
<cfset this.setDomainCookies = false />
<cfset this.sessionTimeOut = CreateTimeSpan(0,12,0,0) />
<cfset this.applicationTimeOut = CreateTimeSpan(1,0,0,0) />
<cfset this.mappings['/CT'] = "C:\apache\htdocs\myProjects\Project1\CustomTags"/>
</cfcomponent>
And this in a ColdFusion template:
<cfimport prefix="tag" taglib="#expandpath('/CT')#">
Throws the error:
This expression must have a constant
value.
<cfset CT = expandpath('/CT')/>
<cfimport prefix="tag" taglib="#CT#">
Throws the error:
This expression must have a constant
value.
I'm pretty sure you can't do anything fancy with the cfimport tag. I think you have to use relative paths, and you have to include it manually on every page. (vs. putting it in the application.cfc file somewhere or whatever)
I'm pretty sure that expandPath respects CF mappings. Have you tried something like this?
<cfset this.mappings["/CT"] = Expandpath("/myProjects/Project1/CustomTags")>
<cfimport prefix="tag" taglib="#expandPath('/CT')#">
I've confirmed it... you cannot use mappings that are created via the "this.mappings" structure in the application.cfc.
From Adobe's documentation (Coldfusion 9):
The path must be relative to the web
root (and start with /), the current
page location, or a directory
specified in the Administrator
ColdFusion mappings page.
CFImport Documentation for CF 9
Not sure why application.cfc mappings work for just about everything else but this. Kind of disappointing, since I've loved the idea of defining as little as possible in the Administrator. I like just zipping up an application and deploying it anywhere.