Creating Combinations using CF List Loops - coldfusion

I'm working on a Coldfusion project and I seem to be stuck. I am a newbie so I hope I don't get too much slack. The purpose of my project is to create a password list by using nested loops. I am to design a template that combines all words in the list "cold, fusion, dynamic" with all words on the list "bert, ernie, oscar" to produce a bulleted list of vaild passwords. This template should process two URL prarameters named List1 and List2. I must use two list loops nested within each other to produce all possible combinations of words. (For example "coldbert", "coldernie", "coldoscar", "fusionbert" and so on..)
This is what I have so far:
<cfinclude template="header.cfm">
<body>
<h2>Loop List</h2>
<cfhttp url="looplist.cfm?List1=cold,fusion,dynamic&List2=bert,ernie,oscar" method="get">
<CFLOOP LIST="#URL.List1#"
INDEX="List1">
<UL><CFOUTPUT>#List1#</CFOUTPUT></UL><br>
</CFLOOP>
<cfinclude template="footer.cfm">
I want to ensure that I'm going in the right direction here. Thanks guys for any assistance.

Unless you're calling a page that doesn't exist on your site, I do not see a need to do a http call. You could just create a function in the template (although I'd prefer it to be in a separate cfc) and call that to get your password combos. Something like ...
<cffunction name="getPasswordCombos" returntype="string">
<cfargument name="list1" type="string" required="true" />
<cfargument name="list2" type="string" required="true" />
<cfset var passwordCombos = "" />
<cfset var i = "" />
<cfset var j = "" />
<!--- your combo generation logic might look something like --->
<cfloop list="#arguments.list1#" index="i">
<cfloop list="#arguments.list2#" index="j">
.....
<!--- set passwordCombos logic here --->
.....
</cfloop>
</cfloop>
<cfreturn passwordCombos />
</cffunction>
Then,
<cfset passwordCombos = getPasswordCombos("cold,fusion,dynamic", "bert,ernie,oscar") />
Then loop over the "passwordCombos"
<ul>
<cfloop list="#passwordCombos#" index="i">
<li>#i#</li>
</cfloop>
</ul>
Also, if you HAVE to user CFHTTP, use cfhttpparam to pass in arguments. It's much cleaner.
<cfhttp result="result" url="looplist.cfm" method="GET">
<cfhttpparam name="list1" type="url" value="cold,fusion,dynamic">
<cfhttpparam name="list2" type="url" value="bert,ernie,oscar">
</cfhttp>

Related

using autocomplete with commas in a field

I'm trying to use autocomplete with a field with commas in it. When I type the comma it will ignore it, and won't return anything. So far I have this:
index.cfm
<!--- A simple form for auto suggest --->
<cfform action="autosuggest.cfm" method="post">
Artist:
<cfinput type="text" name="artist" size="50" autosuggest="cfc:autosuggest.findartist({cfautosuggestvalue})" autosuggestminlength="4" maxresultsdisplayed="5" /><br /><br />
</cfform>
autosuggest.cfc
<cfcomponent output="false">
<!--- Lookup used for auto suggest --->
<cffunction name="findartist" access="remote" returntype="string">
<cfargument name="search" type="any" required="false" default="">
<!--- Define variables --->
<cfset var local = {} />
<!--- Query Location Table --->
<cfquery name="local.query" datasource="#application.datasource#" >
select DISTINCT artist
from items
where artist like <cfqueryparam cfsqltype="cf_sql_varchar" value="#ucase(arguments.search)#%" />
order by artist
</cfquery>
<!--- And return it as a List --->
<cfreturn valueList(local.query.artist)>
</cffunction>
</cfcomponent>
When I try to search for example Brown,James it doesn't return anything. What do I need to put in it to return results with commas.
Thanks
One option is to have your function return an array, instead of a string. Then delimiters are not an issue.
<cffunction name="findartist" access="remote" returntype="array">
...
<cfreturn listToArray(valueList(local.query.artist, chr(30)), chr(30))>
</cffunction>
Update:
As Raymond pointed out, the only sure-fire way to avoid delimiter issues on the CF side is not to use them. Instead loop through the query to build the array, ie:
<cffunction name="findartist" access="remote" returntype="array">
...
<cfset local.arr = []>
<cfloop query="local.query">
<cfset arrayAppend(local.arr, local.query.artist)>
</cfloop>
<cfreturn local.arr>
</cffunction>

Newbie, very basic CRUD via Application.cfc

So I've been using in-line (correct term?) ColdFusion code to run all my pages and have gotten to a point where I think I have a decent understanding of the basics, and want to take the next step. After a lot of cross-referencing, research, and trial and error, I've come up with the following 4 pages of which the intent is to be able to enter a username and password in the form page (crud.cfm), then, after submission, redirect the user to a page which displays the newly entered data, as well as any past entries.
I can do all of this with simple in-line code and an Application.CFM but I want to migrate toward a more OOP/Modular approach going forward, as presently I find myself rewriting/copy-pasting scads of code across several different pages. The error that I get when I submit from 'crud.cfm' is:
"The component attribute in cfinvoke tag has invalid value."
I have tried it without hashes and without the uppercase "A" to no avail. Here is my non-working code:
Application.cfc
<cfcomponent output="false">
<cffunction name="insertrecord" access="public" output="false">
<cfargument name="data" type="struct" required="true">
<cfquery name="create" datasource="test">
INSERT INTO logins(
username,
password)
VALUES(
'trim(form.username)',
'trim(form.password)')
</cfquery>
</cffunction>
</cfcomponent>
crud.cfm
<h3> Enter new user/password </h3>
<cfform name="thisform" method="post" action="procpage.cfm">
Username:<cfinput type="text" name="username" value="">
Password:<cfinput type="password" name="password" value="">
<input type="submit" value="submit">
</cfform>
procpage.cfm
<cfif !StructIsEmpty(form)>
<cfinvoke component="#Application#" method="insertrecord">
<cfinvokeargument name="data" value="#form#">
</cfinvoke>
</cfif>
<cflocation url="resultpage.cfm" addtoken="no">
resultpage.cfm
<cfquery name="read" datasource="test">
SELECT * FROM logins
</cfquery>
<table>
<tr>
<th>LOGIN</th>
<th>USERNAME</th>
<th>PASSWORD</th>
</tr>
<cfloop query="read">
<tr>
<td>#read.login#</td>
<td>#read.username#</td>
<td>#read.password#</td>
</tr>
</cfloop>
</table>
ColdFusion version 8, MSSQL 2005 database.
Thank you all in advance for your help, looking forward to your responses!
Application.cfc is a special file in ColdFusion.
http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=AppEvents_01.html
You'll need to name your component something else. Application.cfc is where you put Application events, setup code, etc.
In answer to your question to Miguel, Yes. The application.cfc is called each time a cfm is called. So when you hit the crud.cfm, application.cfc runs. When you hit procpage.cfm application.cfc runs etc..
so you want your procpage.cfm to look more like
<cfif !StructIsEmpty(form)>
<cfinvoke component="functions" method="insertrecord">
<cfinvokeargument name="data" value="#form#">
</cfinvoke>
</cfif>
and your functions.cfc looks more like
<cfcomponent output="false">
<cffunction name="insertrecord" access="public" output="false" returntype="void">
<cfargument name="data" type="struct" required="true">
<cfquery name="create" datasource="test">
INSERT INTO logins(
username,
password)
VALUES(
<cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.username)#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.password)#">
)
</cfquery>
</cffunction>
<cffunction name="readRecord" access="public" returntype="query">
<cfargument name="loginID" type="numeric" required="false" default="0">
<cfquery name="read" datasource="test">
SELECT * FROM logins
where loginID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.loginID#">
</cfquery>
<cfreturn read/>
</cffunction>
</cfcomponent>
resultsPage.cfm
<cfscript>
f = createObject('component','functions');
r= f.readRecord(theIdToPass);
</cfscript>
<table>
<tr>
<th>LOGIN</th>
<th>USERNAME</th>
<th>PASSWORD</th>
</tr>
<cfloop query="r">
<tr>
<td>#r.login#</td>
<td>#r.username#</td>
<td>#r.password#</td>
</tr>
</cfloop>
</table>
You will find that cfqueryparam not only has a small performance boost but will protect you from sql attacks and such, USE IT!! Always.
You also might think about doing arguments for each one expect instead of using struct variables, since writting error trapping for a struct without know what you are expecting to be passed can be pretty frustrating.
Hopefully this can get you off to a positive start with CF!

Can't get my reCaptcha to work on my ColdFusion form

I signed up for reCaptcha, got my private/public keys, made my recaptcha.cfm and put the code in my form. The form renders perfectly when you go to the URL but it submits even when the person doesn't put anything in the captcha. This is the code for my recaptcha.cfm and I have the relevant code for the form page commented out in recaptcha.cfm under "Sample." Any help would be greatly appreciated. Thank you.
<cfsetting enablecfoutputonly="true">
<!---
Use the reCAPTCHA API to verify human input.
reCAPTCHA improves the process of digitizing books by sending words that
cannot be read by computers to the Web in the form of CAPTCHAs for
humans to decipher. More specifically, each word that cannot be read
correctly by OCR is placed on an image and used as a CAPTCHA. This is
possible because most OCR programs alert you when a word cannot be read
correctly.
You will need a key pair from http://recaptcha.net/api/getkey to use this tag.
Sample
--------------------------------
<html>
<body>
<cfform>
<cf_recaptcha
privateKey="6LepjdQSAAAAAMspsO04gZUXltxddkiI0ZgSF02h"
publicKey="6LepjdQSAAAAADoLvfvgkwacBAI_GbL-nTy2zvS6">
<cfinput type="submit" name="submit">
</cfform>
<cfif isDefined("form.submit")>
<cfoutput>recaptcha says #form.recaptcha#</cfoutput>
</cfif>
</body>
</html>
--->
<cfscript>
CHALLENGE_URL = "http://api.recaptcha.net";
SSL_CHALLENGE_URL = "https://api-secure.recaptcha.net";
VERIFY_URL = "http://api-verify.recaptcha.net/verify";
</cfscript>
<cfif not structKeyExists(attributes, "publicKey")>
<cfthrow type="RECAPTCHA_ATTRIBUTE"
message="recaptcha: required attribute 'publicKey' is missing">
</cfif>
<cfif not structKeyExists(attributes, "privateKey")>
<cfthrow type="RECAPTCHA_ATTRIBUTE"
message="recaptcha: required attribute 'privateKey' is missing">
</cfif>
<cftry>
<cfparam name="attributes.action" default="render">
<cfif not listContains("render,check", attributes.action)>
<cfset sInvalidAttr="action not render|check">
<cfthrow>
</cfif>
<cfset sInvalidAttr="ssl not true|false">
<cfparam name="attributes.ssl" type="boolean" default="false">
<cfparam name="attributes.theme" type="regex" pattern="(red|white|blackglass)" default="red">
<cfif not listContains("red,white,blackglass", attributes.theme)>
<cfset sInvalidAttr="theme not red|white|blackglass">
<cfthrow>
</cfif>
<cfset sInvalidAttr="tabIndex not numeric">
<cfparam name="attributes.tabIndex" type="numeric" default="0">
<cfcatch type="any">
<cfthrow type="RECAPTCHA_ATTRIBUTE"
message="recaptcha: attribute #sInvalidAttr#">
</cfcatch>
</cftry>
<cfif isDefined("form.recaptcha_challenge_field") and isDefined("form.recaptcha_response_field")>
<cftry>
<cfhttp url="#VERIFY_URL#" method="post" timeout="5" throwonerror="true">
<cfhttpparam type="formfield" name="privatekey" value="#attributes.privateKey#">
<cfhttpparam type="formfield" name="remoteip" value="#cgi.REMOTE_ADDR#">
<cfhttpparam type="formfield" name="challenge" value="#form.recaptcha_challenge_field#">
<cfhttpparam type="formfield" name="response" value="#form.recaptcha_response_field#">
</cfhttp>
<cfcatch>
<cfthrow type="RECAPTCHA_NO_SERVICE"
message="recaptcha: unable to contact recaptcha verification service on url '#VERIFY_URL#'">
</cfcatch>
</cftry>
<cfset aResponse = listToArray(cfhttp.fileContent, chr(10))>
<cfset form.recaptcha = aResponse[1]>
<cfset structDelete(form, "recaptcha_challenge_field")>
<cfset structDelete(form, "recaptcha_response_field")>
<cfif aResponse[1] eq "false" and aResponse[2] neq "incorrect-captcha-sol">
<cfthrow type="RECAPTCHA_VERIFICATION_FAILURE"
message="recaptcha: the verification service responded with error '#aResponse[2]#'. See http://recaptcha.net/apidocs/captcha/ for error meanings.">
</cfif>
<cfelse>
<cfset form.recaptcha = false>
</cfif>
<cfif attributes.action eq "render">
<cfif attributes.ssl>
<cfset challengeURL = SSL_CHALLENGE_URL>
<cfelse>
<cfset challengeURL = CHALLENGE_URL>
</cfif>
<cfoutput>
<script type="text/javascript">
<!--
var RecaptchaOptions = {
theme : '#attributes.theme#',
tabindex : #attributes.tabIndex#
};
//-->
</script>
<script type="text/javascript"
src="#challengeURL#/challenge?k=#attributes.publicKey#">
</script>
<noscript>
<iframe src="#challengeURL#/noscript?k=#attributes.publicKey#"
height="300" width="500" frameborder="0"></iframe><br>
<textarea name="recaptcha_challenge_field" rows="3" cols="40">
</textarea>
<input type="hidden" name="recaptcha_response_field"
value="manual_challenge">
</noscript>
</cfoutput>
</cfif>
<cfsetting enablecfoutputonly="false">
That custom tag is badly out of date. You need to update the URLs because Google changed them. Change them to this:
CHALLENGE_URL = "http://www.google.com/recaptcha/api";
SSL_CHALLENGE_URL = "https://www.google.com/recaptcha/api";
VERIFY_URL = "http://www.google.com/recaptcha/api/verify";
I have posted an updated version of this custom tag as a Gist here: https://gist.github.com/2210356

Unwanted Facebook button at first time use of my FB application in coldfusion

I am playing around with facebook application, making them in iframe using coldfusion.
Following is the url of my app http://apps.facebook.com/firstones/
Instead of going directly going to the permissions page, it goes to the page shown below in picture.
And after clicking on that big 'Facebook' button it goes to ask for applications permission. And once permissions are granted it takes to my website, where I have hosted the application, instead of opening it in Facebook only.
Following is the code of my canvas url [http://www.dkyadav.com/firstOnes/auth/]
index.cfm
<cfparam name="client_id" default="1234"> <!---same as app_id --->
<cfparam name="redirect_uri" default="http://www.dkyadav.com/firstOnes/auth/">
<cfparam name="redirect_uri_final" default="http://www.dkyadav.com/firstOnes/">
<cfparam name="scope" default="user_education_history,user_hometown,friends_education_history ">
<cfparam name="client_secret" default="56789"> <!---- App_secret key ---->
<cfif not isdefined('url.code')>
<Cflocation url="https://www.facebook.com/dialog/oauth?client_id=#client_id#&redirect_uri=#redirect_uri#&scope=#scope#" >
<Cfelse>
<Cfif isdefined('url.error')>
<Cfoutput>
#url.error#<br />
Access denied.
</Cfoutput>
<cfelse>
<cfoutput>#url.code#<br />
<cfhttp url="https://graph.facebook.com/oauth/access_token" result="token">
<cfhttpparam name="client_id" value="#client_id#" encoded="no" type="url">
<cfhttpparam name="redirect_uri" value="#redirect_uri#" encoded="no" type="url">
<cfhttpparam name="client_secret" value="#client_secret#" encoded="no" type="url">
<cfhttpparam name="code" value="#url.code#" encoded="no" type="url">
</cfhttp>
<cflocation url="#redirect_uri_final#?#token.filecontent#" addtoken="no">
</cfoutput>
</Cfif>
</cfif>
And in http://www.dkyadav.com/firstOnes/index.cfm I look for access_token and have rest of my application.
I does the above said things only for the first time it run. Once its permission get approved, it works normally as expected.
You can try out this app running yourself http://apps.facebook.com/firstones/
Please help and let me know what I am actually missing. Thanks!!
I think the problem you have is that your initial display page on Facebook is actually bursting out of the iframe.
You can see the Javascript doing that on http://www.dkyadav.com/firstOnes/index.cfm in the fbLogin() function:
top.location.href = "https://graph.facebook.com/oauth/authorize?...
top refers to the window at the top of your window hierarchy which in your case will mean the actual Facebook home page with the iframe in it.
Hope that helps!
I think I dont need access_token, I just need oauth_token that I get by Decoding the result I got from submitting my client_id to 'https://www.facebook.com/dialog/oauth....'
Below is the code that I am using:
<cfif isdefined('signed_request')>
<cfoutput>
<cfset b64 = signed_request>
<!--- Split the param by the . --->
<cfset raw_str = ListGetAt(b64, 2, ".")>
<cfset res = Len(raw_str) % 4>
<cfif res eq 2>
<cfset raw_str &= "==">
<cfelseif res eq 3>
<cfset raw_str &= "=">
</cfif>
<!--- Base 64 Decode --->
<cfset result = ToString(BinaryDecode(raw_str, "Base64"))>
<!--- String to JSON --->
<cfset json = DeserializeJSON(result)>
<cfif StructKeyExists(json,'oauth_token')>
<Cfset at = json.oauth_token>
<cfhttp url="https://graph.facebook.com/me/friends?access_token=#at#" result="newsFeed" />
<cfif IsJSON(newsFeed.filecontent)>
<cfset cfData=DeserializeJSON(newsFeed.filecontent)>
<cfdump var = #cfData#>
<cfelse>
filecontent not in json format
</cfif>
<cfelse>
<script>
top.location.href='https://www.facebook.com/dialog/oauth?client_id=12345XXX&redirect_uri=http://apps.facebook.com/test_app/&scope=read_stream,email'
</script>
</cfif>
</cfoutput>
</cfif>

ColdFusion Class definition error

I have the following Applicaton.cfc
<cffunction name="onApplicationStart" access="public" returntype="Object">
<cfset application.dsn = "myDB" />
<cfset application.userGateway = createObject("component","cfc.UserGateway").init(dsn = application.dsn) />
<cfreturn this />
</cffunction>
This is my component UserGateway.cfc
<cfcomponent name="UserGateway" hint="Data Access Object" output="false">
<cffunction name="init" access="public" hint="constructor" output="false" returntype="UserGateway">
<cfargument name="dsn" type="string" required="true" hint="datasource" />
<cfset variables.dsn = arguments.dsn />
<cfreturn this />
</cffunction>
<cffunction name="getUsers" access="public" output="false" returntype="query">
<cfargument name="id" type="String" default="" />
<cfargument name="name" type="String" default="" />
<cfargument name="district" type="String" default="" />
<cfset var qQuery = "" />
<cfquery name="qQuery" datasource="#variables.dsn#">
SELECT *
FROM A INNER JOIN B
ON A.X = B.Y
WHERE 0=0
<cfif "#arguments.id#" neq "">
AND B.X LIKE '%#arguments.id#%'
</cfif>
<cfif "#arguments.name#" neq "">
AND (A.I LIKE '#arguments.name#%'
OR A.J LIKE '#arguments.name#%')
</cfif>
<cfif "#arguments.district#" neq "">
AND A.O LIKE '%#arguments.district#%'
</cfif>
</cfquery>
<cfreturn qQuery />
</cffunction>
</cfcomponent>
And this is my same.cfm
<cfform action="same.cfm" method="post" preservedata="true">
<p>ID: <cfinput type="text" name="id" size="20" maxlength="4" /></p>
<p>Name: <cfinput type="text" name="name" size="20" maxlength="64" /></p>
<p>District: <cfinput type="text" name="district" size="20" maxlength="3" /></p>
<p><cfinput class="button" type="submit" name="submit" value="OK" /></p>
</cfform>
<cfif IsDefined("form.submit")>
<table>
<cfset qQuery = application.userGateway.getUsers(id = form.id, name = form.name, district = form.district) />
<cfoutput query="qQuery">
<tr>
<td>#qQuery.currentRow#.</a></td>
<td>#qQuery.I#</a></td>
<td>#qQuery.M#, #qQuery.N#</a></td>
<td>#qQuery.D#</a></td>
</tr>
</cfoutput>
</table>
</cfif>
I get the following error:
Element USERGATEWAY is undefined in a Java object of type class [Ljava.lang.String;.
The error occurred in same.cfm: line 10
What am i missing?
-------------------------------------------
-------------------------------------------
When i do it this way it works. it must be something trivial that i as a beginner do not get.
Application.cfc
<cffunction name="onRequestStart" access="public" returntype="String">
<cfset request.dsn="myDB" />
</cffunction>
same.cfm
<cfset userGateway = createObject("component","cfc.UserGateway").init(dsn = request.dsn) />
<cfset qGetUser = userGateway.getUsers(id = form.personid, name = form.name, district = form.district) />
<cfoutput query="qQuery">
<tr>
<td>#qQuery.currentRow#.</a></td>
<td>#qQuery.I#</a></td>
<td>#qQuery.M#, #qQuery.N#</a></td>
<td>#qQuery.D#</a></td>
</tr>
</cfoutput>
There are two things I see wrong here:
First, To my understanding, using the 'this' scope in application.cfc doesn't work the way you're trying to do it. By setting your userGateway object to an application scoped value, it becomes globally available and really makes returning it in onApplicationStart unnecessary. In your application.cfc, change your returntype to boolean and just return true; that should fix your problem.
Second, if in your query, your arguments and conditionals are not proxies of what you actually have, you're referencing an argument 'personid' which does not exist in your function. When calling that query through an object call in the application scope, I've seen the java string error returned as an error before as opposed to the CF Friendly 'variable doesn't exist' error.
In same.cfm, run this:
<cfset OnApplicationStart()>
Then refresh the page again. Does it now work?
<cffunction name="init" access="public" hint="constructor" output="false" returntype="UserGateway">
should be:
<cffunction name="init" access="public" hint="constructor" output="false" returntype="Any">
The following line is incorrect:
<cfset application.userGateway = createObject("component","cfc.UserGateway").init(dsn = application.dsn) />
It should read with out "cfc." at the beginning of the component name you want:
<cfset application.userGateway = createObject("component","UserGateway").init(dsn = application.dsn) />
Also, double check the rest of the application.cfc for correctness because something isn't running right, as you should have seen this error that it couldn't find component cfc.UserGateway.
EDIT:
I also forgot to mention that onApplicationStart does not need to return anything. The return type should be void and no <return this/> needs to be present.
Could it be this:
http://kathylynnward.wordpress.com/2008/04/14/lyra-captcha-error-element-captcha-is-undefined-in-a-java-object-of-type-class-ljavalangstring/
(I'll elaborate the post if this is the problem)
restart your CF service might help.