Cgi.http_referer ++?

Hi all. I was wondering is there something like cgi.http_referer + or a referer of a referer

I’m working on a website where members have certain privileges over none members, like adding properties to a wish/enquiry list. When someone add a property to their list, an action page first check if the member is logged in and if this turns out to be true the property is added to the appropriate table and the member is redirected to his/her personal properties page. If the member is not logged he or she is redirected to a login page and this is the point where my question comes in.

A member added a property to his list but was not logged in, and redirected to the login page. After entering the login information this information is checked (Application.cfm). When the information is right and I would use a normal cgi.http_referer the member would be redirected back to the login page, but I would like the member be redirected to the properties page where in the first place they added the property to their list or even better to the action page so that the property will be processed after all.

“… my form since the validation taks place in Application.cfm.”

Sounds messy! Why have you got login validation going on in Application.cfm? Really that should be only used for setting up global settings.

Good for you ;), but yeah expect a steep learning curve if you’re not used to frameworks. Once you get past the initial pain barrier though you won’t look back ;).

First thing to focus on is the MVC concept as you’ll find ColdBox, and the majority of main frameworks, follow that approach.

In terms of tutorials best place I can suggest is have a look at some of the presentations here - http://www.carehart.org/ugtv/index.cfm?search=ColdBox&sort1=vdateposted&sort1order=desc&strt=1&show=10

The ColdBox team are very active on the documentation side of things so if you have any issues then the best place is to start there on the main site OR buy the book. Only thing I’d say on that side though is the book is version 2.6.3, 3.0 is about to come out and the training they offer is based on that version now.

They tend to offer in-house training, actually booked in for it in a few weeks myself, rather than online tutorials though… it’s their commercial arm of the business ;). Google should be your friend though as there are a few blogs out there that have articles on people’s experience with it.

If all that fails to answer your question(s) then I’d say your best hitting the ColdBox Google Group. They’re a helpful bunch so you should get a decent answer there.

Good luck with it, let us know how you get on :wink:

Cheers,
James

Aha. That’s my problem. I use cgi.http_script in my form since the validation taks place in Application.cfm. Gonna play alittle further with it and let you know

Hi James,

I didn’t read your mail till now. Thank you for your reply. Both options are valuable. And before I read your mail, after trying and trying, I came up with the second option myself :). But the first option Is maybe a better option. I’m for sure going to try it in a test environment. Which option did you choose?

Cheers

If you start looking at ColdBox, or any framework, you’re looking at a rewrite of the application pretty much.

The resourceBundle theory it uses you could copy over to other applications though and it sounds like it could save you a load of headache if you can spend the time on this.

What you’d essentially be doing is this…

  1. Create the resourceBundles (basic text files) for each language and in there you’d put your site labels. So for your login you’d have something like this maybe…

login.title = Login
login.username = username
login.password = password
login.submit = login

  1. Write some code, would have to be a CFC or global function (UDF) to do this across the whole site, which will read these resources and pull out the appropriate text based on the passed in value.

So syntax wise I’d say you’d make a function called getResourceBundle and would use it as - getResourceBundle(‘login.title’).

That call should return the word “Login” from the example above.

  1. Change all your template content to use this new functionality so for where you had things like username, password etc. written into the page like before you’d now have getResourceBundle(‘login.username’) and getResourceBundle(‘login.password’). Again those returning the words username and password.

  2. Now the clever bit would be that you’d need to know what site the user has come into. So if they hit the English site you’d load the English resourcebundle. If they hit the Greek site you’d load in the Greek bundle.

Know which bundle to load in would need to go either in the user’s session OR you’d need some kind of check off the address they’re currently on so the decision can be made on how to display things.


The good thing about this way is if your client decides you want another 50+ languages on the site :slight_smile: you just need to take a copy of a resourceBundle, change the labelling to suit the new language and you’re pretty much up and running… no ColdFusion / HTML changes needed to do it.

But yeah we’ve all got deadline of “yesterday” to met and have all made decisions at the time we’re now happy about ;).

It’s coming up with clever ways like this and doing a bit of upfront planning that allow you to cut your time down later down the line :wink:

:slight_smile: It’s not only messy. It’s dodgy as well. I know you’re right, but I was struggling with the entire login section. I’m working on a site with multiple languages. (was 2 has now grown to 5). I have the main language in the root and the other four in seperate folders. I’ve read your suggestion in another post about Coldbox and had a look at it. It is very interesting indeed, but there was not that much budget left for the three extra languages plus the fact that I’m on a timeframe as well(everything always has to be ready yesterday), so I couldn’t bother to get myself familiar with Coldbox for this project, but will definitely try to use it in feature projects. So I indeed cut corners somehow :(. I tried to keep the login part centralized and couldn’t think of another way of doing it (specially with the referer part) :confused:.

Cheers Donald

Hi James, All,

Things are a bit more complicated than I thought It would. My problem is the following. I not only have my members login page, where people are forced, when they added a property to their wish list without being logged in, I have a regular login form on every page as well. For these pages I use the regular cgi.http_referer in my Application script (visitors will at all time return to the page where they logged in) and that works great. So somehow I have to work with a CFIF block but that is where thing are not working. This is what I have in the page that add the property to the member_properties table:


<cfif structKeyExists( session, 'member' )>

    <cfquery name="verifyProperty" datasource="#Request.dsn#">
        SELECT property_id 
        FROM member_properties
        WHERE property_id IN ( <cfqueryparam cfsqltype="cf_sql_integer" value="#Val( Url.property )#" /> )
    </cfquery>
    
    <cfif verifyProperty.recordCount>
    <!--- I use this in case the property is already in the members list and I don't want double entries in the database I use cgi.http_referer because there are two places where they can add a property --->
        <cflocation url="#cgi.http_referer#" addtoken="no">
    <cfelse>
        <cfquery datasource="#Request.dsn#">
            INSERT INTO
            member_properties
            (
             property_id
            ,member_id                  
            )
            VALUES
	(
	<cfqueryparam cfsqltype="cf_sql_integer" value="#Val(  Url.property )#" />
					)
        </cfquery>
        <!--- If exist delete the temporary session set when a member was not logged in while adding a property (see below) --->
        <cfif structKeyExists( session, 'refererProperty' )>
            <cfset structDelete ( session, 'refererProperty' )>
        </cfif>
        <cflocation url="favorite_properties.cfm" addtoken="no">
    </cfif>        
        
<cfelse>

<!--- Set temporary session in order to redirect the member back to this page so the property can be added to the database after the member has successfully logged in --->
     <cfset session.refererProperty = Url.property />
    <cflocation url="members_signin.cfm" addtoken="no">
    
</cfif>    
                                       

After verifying the member I have the following cfif block within Application.cfm to decide to where the member should be redirected:


<cfif verifyMember.recordCount>
    <cfset session.member = verifyMember.member_id>
    <!--- This is the temp session which I have set on the add property action page --->        
    <cfif structKeyExists( session, 'refererProperty' )>
        <cflocation url="add_favorite.cfm?property=#session.refererProperty#" addtoken="no">
    <cfelse>
        <cflocation url="#cgi.http_referer#" addtoken="no">            
    </cfif>        
<cfelse>
    <cflocation url="members_signin.cfm" addtoken="no">
</cfif>

But somehow

<cfif structKeyExists( session, 'refererProperty' )>
        	<cflocation url="add_favorite.cfm?property=#session.refererProperty#" addtoken="no">

is completely ignored, and

<cflocation url="#cgi.http_referer#" addtoken="no">

is executed all the time. I know this because, this is the scenario where a property was added while the member was not logged in so the member was forced to the members login page.

As a test I added the following cfif block to the members login page to see if my suspicion that cgi.http_referer is executed all the time was right:

<cfif structKeyExists( session, 'refererProperty' ) AND structKeyExists ( session, 'member' )><cfoutput>#session.refererProperty#</cfoutput></cfif> 

I cleared all sessions and added a property to my whish list without being logged in. I was indeed forced to the members login page. The session refererProperty didn’t show since the session member didn’t exists as yet. I logged in and ended up on the members login page again, this time with the refererProperty showing.

So I knew that my suspision that <cflocation url=“#cgi.http_referer#” addtoken=“no”> was the one that is executed all the time was right, because I ended up on the members login page again after login in. I also knew that session. refererProperty exist because it shows up after I logged in. I furthermore know that the session.member exist not only because of the other session showing after login in, but also if it does, the main menu should change( an extra menu item my account is added) and it does change indeed. So all evidence indicates that this approach should work but it doesn’t unless I’m overseeing something.

Do you or anyone else have any idea why this isn’t working?

Thank you in advance

I just skimmed all that but glad you got it sorted :lol:

Hi James. Thank you again for all your input. I get your point and have decided to put in some extra time and try to reproduce the site i’m working on using Coldbox, but I have to admit that this is all completely new to me so one question I have left for you. Is there a good beginners tutorial you suggest I should start with?

Thank you in advance

Are you passing that variable as part of your form submission? You’ll need to do that for the processing page and as part of your redirect code.

Not tested but you’d do something like …


<cfparam name="url.redirect" default="" type="string" />

<form action="act_login.cfm#iif(len(url.redirect,DE("?redirect=#url.redirect#"),DE(""))#" method="post>
<!--- YOUR LOGIN FORM IN HERE --->
</form>

then act_login.cfm - Assuming they’ve logged in successfully…



.... your validation checks going on here.

<!--- If successfully logged in and a redirect variable exists in the URL then redirect to that page --->
<cfif structKeyExists(url,'redirect')>
[INDENT][/INDENT]<cflocation url="#url.redirect#" addToken=false />
</cfif>


One last question James :slight_smile: Yesterday I was playing arround a bit with your first solution

http://www.mydomain.com/login.cfm?redirectURL=/processList.cfm

but in my case I never got further then the members login page, it somehow never passed tha page. How would that scenario be in my case.

Thank you

Problem solved. Hi all. The problem is solved. It all had to do with in what order things took place on the add_property page. So I changed

<cfif structKeyExists( session, 'member' )>

    <cfquery name="verifyProperty" datasource="#Request.dsn#">
        SELECT property_id 
        FROM member_properties
        WHERE property_id IN ( <cfqueryparam cfsqltype="cf_sql_integer" value="#Val( Url.property )#" /> )
    </cfquery>
    
    <cfif verifyProperty.recordCount>
    <!--- I use this in case the property is already in the members list and I don't want double entries in the database I use cgi.http_referer because there are two places where they can add a property --->
        <cflocation url="#cgi.http_referer#" addtoken="no">
    <cfelse>
        <cfquery datasource="#Request.dsn#">
            INSERT INTO
            member_properties
            (
             property_id
            ,member_id                  
            )
            VALUES
	(
	<cfqueryparam cfsqltype="cf_sql_integer" value="#Val(  Url.property )#" />
					)
        </cfquery>
        <!--- If exist delete the temporary session set when a member was not logged in while adding a property (see below) --->
        <cfif structKeyExists( session, 'refererProperty' )>
            <cfset structDelete ( session, 'refererProperty' )>
        </cfif>
        <cflocation url="favorite_properties.cfm" addtoken="no">
    </cfif>        
        
<cfelse>

<!--- Set temporary session in order to redirect the member back to this page so the property can be added to the database after the member has successfully logged in --->
     <cfset session.refererProperty = Url.property />
    <cflocation url="members_signin.cfm" addtoken="no">
    
</cfif>

into

<cfif structKeyExists( session, 'member' )>

	<cfquery name="verifyProperty" datasource="#Request.dsn#">
    	SELECT property_id 
        FROM member_properties
        WHERE property_id IN ( <cfqueryparam cfsqltype="cf_sql_integer" value="#Val( Url.property )#" /> )
    </cfquery>
    
    <cfif Not verifyProperty.recordCount>

		<cfquery datasource="#Request.dsn#">
			INSERT INTO
			member_properties
			(
		 	property_id
			,member_id                  
			)
			VALUES
			(
	 	 	<cfqueryparam cfsqltype="cf_sql_integer" value="#Val(  Url.property )#" />
			,<cfqueryparam cfsqltype="cf_sql_integer" value="#Val( session.member )#" />
			)
		</cfquery>
        <cfif structKeyExists( session, 'refererProperty' )>
			<cfset structDelete ( session, 'refererProperty' )>
		</cfif>
        <cflocation url="favorite_properties.cfm" addtoken="no">    
    
    <cfelse>
		<cflocation url="#cgi.http_referer#" addtoken="no">
	</cfif>        
        
<cfelse>
	<cfset session.refererProperty = Url.property />
    <cflocation url="members_signin.cfm" addtoken="no">
    
</cfif> 

So basically I switched the <cfif verifyProperty.recordCount> and the <cfif Not verifyProperty.recordCount> arround and now everything works great.

I’m actually working on something similar myself at the moment :slight_smile:

A couple of ideas for you, both would stem from the decision to redirect to the login and processing after they’ve successfully logged in.

Rather than use the cgi.http_referrer directly you could either… .

a) Send them back to the login screen with a variable tagged to the end of the address with the redirectURL … i.e.

http://www.mydomain.com/login.cfm?redirectURL=/processList.cfm

So when they login there is a check for that variable. If it exists, and the page is valid, redirect.

b) Before you redirect to the login screen grab the page details and save it in their session. <cfset session.redirectURL = xxxxxxx />

Again once they login check for the existence of that variable and redirect if it exists.

Option b probably has a few advantages in that you’re shielding the processing from the user, so no one can play around with the address etc., and looks a bit cleaner.

However option b probably needs a bit more work because you’'ll need to clear the session after redirect (just to make sure everything is nice and clean).

Cheers,
James