How do I access the system environment variables in CFML? It is required to read out the CloudFoundry database connectivity settings.
The variable required is "VCAP_SERVICES".
Is there a function for that?
Thanks,
Yvan
Following solution seems to work very-very partially on my Ubuntu (it gets far from all variables listed by env -- bit this may be fine because JVM just does not get most of these), but it may somehow work for you:
<cfset properties = createObject("java", "java.lang.System").properties />
<cfdump var="#properties#">
Variable you are looking for can be prefixed with user.
Related
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.
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
I need to check if my server is on the live or development mode. Currently I am doing it like this:
<cfset isLive = FindNoCase("www.mydomain.com",CGI.SERVER_NAME) NEQ 0>
But the above does not seem foolproof. If the user tries
http://mydomain.com or
https:///mydomian.com or
http://www.mydomain.com
.. it will not work properly. Can anyone tell me how to accomplish this with a regex?
Turn it around and check for the dev mode instead of live. That will give you less options to struggle with. This solution is not foolproof either.
I would recommend:
Define the environment in a settings file. Make it accessible to your application.
Set your version management system to ignore it on commits and updates.
Read the environment settings from the settings file and use it in the application.
<cfset isLive = ReFindNoCase("^(www\.)?mydomain\.com$",CGI.SERVER_NAME) NEQ 0>
The good news is that CGI.SERVER_NAME only includes the domain name used to access the site - not the protocol information (even on HTTPS), so you don't have to worry about that.
I'm guessing from your examples that if the site is accessed using "www" prefix or no prefix that it should be the live site and all other prefixes - or any other domain name - will indicate the dev site.
This would mean that if you ever need another domain prefix on the live site for any reason that this would return false.
Here is how to change it if you needed the "bob" prefix on the live site:
<cfset isLive = ReFindNoCase("^(((www)|(bob))\.)?mydomain\.com$",CGI.SERVER_NAME) NEQ 0>
You could also go the other way and look for something like "test" or "dev" anywhere in the domain name to establish that it is a test site:
<cfset isTest = ReFindNoCase("\b((test)|(dev))\b",CGI.SERVER_NAME) NEQ 0>
i am using the latest version of railo, and am trying to get the per-application mappings to work. this is what i am doing:
<cfcomponent name="MyApp">
<cfset THIS.Name = "MyApp">
<cfset THIS.Mappings["/myapp"] = ExpandPath(".")>
</cfcomponent>
so, i am trying to be able to access components within this application folder through a myapp.* mappings rather than having to to rootapp.myapp.* (from what i understand, this component setup should then work.
however, my components cannot be accessed by this mapping, and when i do a cfdump on the application variable in my code, it will show that the "applicationname" is set to "MyApp", but nothing shows for the mappings.
does railo not support these mappings, or am i doing something wrong?
EDIT:
this is the exact error that i am getting:
invalid component definition, can't find myapp.data.MyObject
the myapp mapping should have been made, and the MyObject does exist. here is my structure:
/rootfolder/myapp/Application.cfc
/rootfolder/myapp/data/MyObject.cfc
/rootfolder/myapp/pages/MyPage.cfm
in short, "MyPage.cfm" relies on the mapping to easily access the "MyObject" component. the Application.cfc should be loaded as the cfml processor should start moving up directories until it finds one.
Your syntax is OK, I've just did the same for application deep in directories tree and it works fine.
however, my components cannot be accessed by this mapping,
What is exact error? "invalid component definition, can't find myapp.xyz"?
Are your cfm and cfc in the same directory? (this is basically what you are trying to do)
and when i do a cfdump on the application variable in my code, it will show that the "applicationname" is set to "MyApp", but nothing shows for the mappings.
You wont see this info by dumping the application scope. Only option is to use Application.cfc as usual cfc.
<cfset app = CreateObject("component", "application") />
<cfdump var="#app#">
EDIT. You have two solutions here.
Define mapping like this, so path will be calculated for Application.cfc:
<cfset this.mappings["/myapp2"] = getDirectoryFromPath(getCurrentTemplatePath())>
Or change component path like this:
<cfset MyObject = CreateObject("component", "myapp.data.MyObject") />
Problem is in differences between paths returned by ExpandPath and getCurrentTemplatePath().
Update: As Sergii pointed out, the syntax is valid, but the net effect is the same.
Try using this syntax
<cfcomponent>
<cfset THIS.Name = "MyApp">
<cfset THIS.mappings = { "/myapp" = ExpandPath(".") } >
</cfcomponent>
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.