Passing a variable into a cfcomponent initialization method - coldfusion-10

If I'm doing the following :
<cfobject name="EmployeePermissions" component="CFCs.Permissions" >
<cfoutput>
Username: #EmployeePermissions.UserName#<br>
</cfoutput>
Using component:
<cfcomponent>
<cfset This.UserName = '' >
<cffunction name="init" access="public" output="no" returntype="Permissions">
<cfargument name="UserName" type="string" required="yes">
<cfset variables.UserName = arguments.UserName >
<cfreturn this>
</cffunction>
</cfcomponent>
The initialization method doesn't seem to be called. Further, the object can be used without ever specifying a username. How do I require the username and ensure the init method is called?

Hope, the below answer will clear your doubts.
<cfobject name="EmployeePermissions" component="CFCs.Permissions" >
<cfset getUser = EmployeePermissions.init(UserName = "jawa")>
<cfoutput>
#getUser#
</cfoutput>

Related

ColdFusion dateformat wrong format

I have an input text where I get the date:
<input type="text" name="myDate" />
After submitting the form, I save this date into the database doing a dateformat:
#DateFormat(myDate, "yyyy-mm-dd")#
If the user enters: 02/19/1948, it saves correct: 1948-02-19.
But if the user enters: 02191948, it saves: 7901-05-07. Why? Does anyone know how I can fix it?
Thanks
ColdFusion's DateFormat() expects a valid date representation. ColdFusion is very sloppy when it comes to what type of input is considered valid. Safe date inputs are ODBC literals and most of ISO 8601. Beware of format pitfalls like mm/dd and dd.mm and avoid them altogether, if possible.
What you want to use is LSParseDateTime(). It allows you to specify the locale and format you expect and make ColdFusion parse a date object based on the input. It's not fail-safe though, meaning you have to try-catch it in case the input doesn't match at all. There is a fail-safe LSIsDate(), which tells you if the input is considered valid in the specified locale. But either way, it's a game of format detection. Having fixed <select> tags for month, day and year is the easiest way to avoid issues.
Loose demo for localized date input:
<cfset myLocale = "en_US">
<cfset myDateFormat = "yyyy-mm-dd">
<cfset dateByInput = "">
<cfset errorReason = "">
<cfif structKeyExists(FORM, "myDate")>
<cfif lsIsDate(FORM["myDate"], myLocale)>
<cftry>
<cfset dateByInput = lsParseDateTime(FORM["myDate"], myLocale, myDateFormat)>
<cfcatch>
<cfset errorReason = ("Your input is invalid. Please enter in the following format: " & myDateFormat)>
</cfcatch>
</cftry>
<cfelse>
<cfset errorReason = ("Your input is invalid. Please enter in the following format: " & myDateFormat)>
</cfif>
</cfif>
<cfset dateByInputIsValid = isDate(dateByInput)> <!--- note: it's sufficient to use the unlocalized date check here, since dateByInput is either not valid at all or a (universal) date object --->
<cfif dateByInputIsValid>
<!--- store date input in database --->
<cftry>
<cfset myDatasource = "exampleDS">
<cfquery datasource="#myDatasource#">
INSERT INTO `myDatabase`.`myTable` ( `myDateColumn` ) VALUES (
<cfqueryparam value="#dateByInput#" cfSqlType="CF_SQL_TIMESTAMP">
)
</cfquery>
<cfcatch>
<cfset errorReason = "Oh noes, something went wrong attempting to save your input.">
</cfcatch>
</cftry>
</cfif>
<cfoutput>
<cfif dateByInputIsValid>
<p>Date input valid: #lsDateFormat(dateByInput, myDateFormat, myLocale)#</p>
<cfif len(errorReason)>
<p>#errorReason#</p>
<cfelse>
<p>Input successfully stored in database.</p>
</cfif>
<cfelse>
<cfif len(errorReason)>
<p>#errorReason#</p>
</cfif>
<form method="post">
<input type="text" name="myDate" />
<button type="submit">send</button>
</form>
</cfif>
</cfoutput>

Coldfusion: specific action after selecting an option in select

I have following code:
<cfif session.language is ("DE")>
<cfset bl=ValueList(getContent.G,",")>
<cfelseif session.language is ("FR")>
<cfset bl=ValueList(getContent.H,",")>
<cfelseif session.language is ("EN")>
<cfset bl=ValueList(getContent.I,",")>
</cfif>
<cfset tags = sizes />
<cfset bltags = bl />
<cfset tagArray = arrayNew(1) />
<cfset tagArrayDATA = arrayNew(1) />
<cfloop list="#tags#" index="tag" delimiters=",">
<cfif not ArrayFindNoCase(tagArray,tag)>
<cfset arrayAppend(tagArray, tag) />
</cfif>
</cfloop>
<cfloop list="#bltags#" index="tag" delimiters=",">
<cfif not ArrayFindNoCase(tagArrayDATA,tag)>
<cfset arrayAppend(tagArrayDATA, tag) />
</cfif>
</cfloop>
<cfoutput>
<cfif isdefined("tagArray") AND arraylen(tagArray) GT 1>
<form name="frmsize" id="frmsize" action="/index.cfm?showusage" method="post">
<cfif isdefined("tagArray") AND arraylen(tagArray) GT 1>
<div>
<select name="valuesize">
<option value="">Choose your option</option>
<cfloop from="1" to="#arraylen(tagArray)#" index="i">
<option value="#tagArray[i]#">#tagArray[i]#
<cftry>
#tagArrayDATA[i]#
<cfcatch>
</cfcatch>
</cftry>
</option>
</cfloop>
</select>
</div>
</cfif>
</form>
</cfif>
</cfoutput>
My goal is to send a value from tagArrayDATA[i] via link.
It should look like that:
<form name="frmsize" id="frmsize" action="/index.cfm?showusage&valueArrayData="#tagArrayDATA[i]#" method="post">
I don't know how to manage that because the cfloop is below the action attribute of the form.
You can't really do what you are trying to do with server side code alone as far as I can tell. But you have a couple of options. One easy one is to just Javascript to update the action when the select is changed.
The other option is to put both values in the select and parse on the end.
<cfloop from="1" to="#arraylen(tagArray)#" index="i">
<option value="#tagArray[i]#-#tagArrayDATA[i]#">
#tagArray[i]# #tagArrayDATA[i]#
</option>
</cfloop>
Then when you are parsing the data just do:
<cfset data = listToArray(FORM.valuesize,'-') />
<!-- data[1] will be the selected value of #tagArray[i]# -->
<!-- data[2] will be the selected value of #tagArrayData[i]# -->
<!-- This assumes the - will never be actually in the data, you could use a different separator -->
My guess is they are both strings and this should work, though I have no idea why you have a try/catch in the select part of your code, probably look at a better way of doing that. If you really need that, I would clean it up as.
<cfloop from="1" to="#arraylen(tagArray)#" index="i">
<cfset data = '' />
<cftry>
<cfset data = tagArrayData[i] />
<cfcatch></cfcatch>
</cftry>
<option value="#tagArray[i]#-#data#">
#tagArray[i]# #data#
</option>
</cfloop>
Though if you are processing the data on the other end, I would make sure all the data is either in the FORM or the URL scopes but not mix. I would be pissed to have to parse some form data in the FORM scope and other data in the URL scope.

Email field validation in Coldfusion

I'm a very new to Coldfusion scripting. I need to validate an Email field on a form, so that the Email field accepts "...#waldorf.edu" email address from prospective applicants ONLY. All other email addresses should be an error. I have this code right now, but it doesn't validate the domain unfortunately.
<tr bgcolor="##ffffff">
<td valign="top" class="style13"><strong>Email</strong><br />
<font size="2">(Must be Waldorf faculty member. <strong>Use "waldorf.edu" email address only.)</strong></font></td>
<td valign="top"><font color="##FF0000">*</font>
<cfinput type="text" Name="email" Message="Please input a valid Waldorf Email Address, ex.: you#waldorf.edu." validate="email" required="yes" value="#appinfo.email#" size="40"> </td>
</tr>
Thank you for your help!
Controller:
<cfcomponent name="fellowsapp" output="false">
<cfscript>
function init(fw) { variables.fw = fw; }
</cfscript>
<cffunction name="validate" access="public" returntype="array" output="false">
<cfargument name="rc" type="struct" />
<cfargument name="form" type="struct" />
<cfset var errors = arrayNew(1) />
<cfset var thisError = structNew() />
<!--- Email --->
<cfif form.Email eq ''>
<cfset thisError.field = "Email" />
<cfset thisError.type = "error" />
<cfset thisError.message = "Email is required" />
<cfset arrayAppend(errors,duplicate(thisError)) />
</cfif>
If the requirement is to only allow #waldorf.edu email addresses, simply take away the option for the user to enter that part of the address. Make it obvious to the user. Something like this:
<cfinput name="email"
required="yes"
message = "Please enter an email address"
>#waldorf.edu
If you want to enhance this on the form page, you can add some javascript that strips away the #character and everything after it.
In your controller, use a regular expression to ensure that the submitted value contains only characters that are valid for #waldorf.edu email addresses.

ColdFusion form: how to refer to a selection from a binding?

I am not sure if I am thinking about this correctly. I am still new to ColdFusion. I am creating a form which uses binding for the user to select a category and then a specific service. The code for the binding works great. The problem is that now I need to pull some additional information from the service to refer to another field. For example, if the service selected has a "Y" under additional info needed. A field will show that additional information is needed (this field is not changeable)
Originally I thought I could do something like regenerate the same query I did to pull the list of services and just refer to the service type that is selected. Yet I keep getting an error that the field is not defined. Here is the code that I am trying to make it work.
UPDATED: I got it to work I changed the code below the only problem is that I can not get the "Y" to display I get [object Object] instead. Any advice on how to display the text with use of cfinput?
CFC:
<!--- Get array of Catagory Description types --->
<cffunction name="cat_description" access="remote" returnType="array">
<!--- Define variables --->
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>
<!--- Get data --->
<cfquery name="getServiceCat" datasource="Some Database">
select distinct 2 AS SortBy, CATG_NAME
from some table
UNION
select 1 AS SortBy, '' AS CATG_NAME
from Some table
order by SortBy
</cfquery>
<!--- Convert results to array--->
<cfloop index="i" from="1" to="#getServiceCat.recordcount#">
<cfset result[i][1]=getServiceCat.CATG_NAME[i]>
<cfset result[i][2]=getServiceCat.CATG_NAME[i]>
</cfloop>
<!--- And return it --->
<cfreturn result>
</cffunction>
<!--- Get Service Type by Cat description type --->
<cffunction name="getServiceType2" access="remote" returnType="array">
<cfargument name="CATG_NAME" type="string" required="true">
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>
<cfquery name="getServiceType2" datasource="Some Database">
select 1 AS SortBy, '' AS SRTY_BNR, '' AS SRTY_NAME
from Some table
UNION
select distinct 2 AS SortBy, SRTY_NBR, SRTY_NAME
from Some Table
where CATG_NAME = <cfqueryparam value="#ARGUMENTS.CATG_NAME#"
cfsqltype="cf_sql_varchar">
order by SortBy
</cfquery>
<cfloop index="i" from="1" to="#getServiceType2.recordcount#">
<cfset result[i][1]=getServiceType2.SRTY_NAME[i]>
<cfset result[i][2]=getServiceType2.SRTY_NAME[i]>
</cfloop>
<cfreturn result>
</cffunction>
<!---Updated below table into CFC to pull information depending on what is pulled
from category and service type--->
<cffunction name="getLR" access="remote" returnType="query">
<cfargument name="SRTY_NAME" type="string" required="true">
<cfset var data="">
<!---Query to get "Y"--->
<cfquery name="lr_required" datasource="Some Datebase">
select distinct LAB_REL_NTFN_FLAG
from some table
where SRTY_NAME = <cfqueryparam value="#ARGUMENTS.SRTY_NAME#"
cfsqltype="cf_sql_varchar">
</cfquery>
<cfreturn lr_required>
</cffunction>
Here is the code within the form:
<TR id="serv_ty" style="display: inline;">
<td align="left" nowrap><label>Service Type:</label></td>
<td>Select Category:
<cfselect name="catdesc"
bind="cfc:servicetype2.cat_description()"
bindonload="true"/><br />
</td>
</TR>
<tr id="serv_ty2" style="display: inline;">
<td></td>
<td>Select Service:
<cfselect name="service_type"
bind="cfc:servicetype2.getServiceType2({catdesc})"
bindonload="false"/>
</td>
</tr>
This is the form code to use the bind which works but will not display the DATA:
<tr id="lr_verify" style="display: inline;">
<td></td>
<td>Additional Info Reuired:
<cfinput
name="lr_needed"
bind="cfc:servicetype2.getLR({service_type})"
bindonload="no"
disabled="disabled"
display="LAB_REL_NTFN_FLAG"/></td>
</tr>
Any advice on how to get it to display or if I should use a different CF statement with the bind to get the correct display. Thanks in advnace for your help on this.

PayPal ExpressCheckout Missing Total column

Why am I missing the total on the checkout page?
Apologies.
As my code is working, because it actually got to PayPal and does have all the field correct.
I didn't think it was necessary to post the code.
I thought it could be answered simply, "you're missing the XXXX variable in your post to PayPal."
But, seeing as this is StackOverflow, code is required.
This is COLDFUSION (yes caps because people think this is a dead/dying language).
<cffunction name="expressCheckout" access="remote" returnformat="JSON" output="false" description="Processes PayPal Subscription">
<cfargument name="L_BILLINGAGREEMENTDESCRIPTION0" type="string" required="yes" />
<cfargument name="L_BILLINGTYPE0" type="string" required="yes" />
<cfargument name="AMT" type="numeric" required="yes" />
<cfset var username = "wpp_1306278086_biz_api1.blahblah.com">
<cfset var password = "1306278555">
<cfset var signature = "someSig">
<cfset var serverURL = "https://api-3t.sandbox.paypal.com/nvp">
<cfset var version = "65.1">
<cfset requestData = StructNew()>
<cfset requestData.USER = "#USERNAME#">
<cfset requestData.PWD = "#PASSWORD#">
<cfset requestData.SIGNATURE = "#SIGNATURE#">
<cfset requestData.SUBJECT = "">
<cfset requestData.VERSION = "#version#">
<cfset requestData.METHOD = "SetExpressCheckout">
<cfset requestData.AMT = "#arguments.AMT#">
<cfset requestData.DESC = "#arguments.L_BILLINGAGREEMENTDESCRIPTION0#">
<cfset requestData.CUSTOM = "#session.rfcid#">
<cfset requestData.returnURL = "http://localhost:8500/rfc2-1/membership/payPalConfirm.cfm">
<cfset requestData.cancelURL = "http://localhost:8500/rfc2-1/membership/creditcardform.cfm">
<cfset payPalReturn = doHttppost(requestData, serverURL, "no")>
<cfset payPalReturn = getNVPResponse(#URLDecode(payPalReturn)#)>
<cfif payPalReturn.ACK EQ "Failure">
<!--- return the error message --->
<cfset payPalReturn.ERRORMESSAGE = #payPalReturn.L_LONGMESSAGE0#>
</cfif>
<cfreturn payPalReturn>
</cffunction>
This retuns a json object to the browser.
The browser then sends me to:
https://sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=SomeToken
All fine when I get to PayPal. Just missing the total in the left hand box (as diagrammed)
Try appending &useraction=commit to the PayPal redirection URL (https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-xxxxxx&useraction=commit).
Not sure of this works for billing agreements, but worth a shot. It'll work for regular payments anyway.
edit:
Actually, on second thought; since it's a billing agreement, which is not for a fixed price (otherwise you wouldn't need a billing agreement in the first place); this would be intended. Since there is no specific price to display.