-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBetterRedirects.cfc
186 lines (142 loc) · 6.49 KB
/
BetterRedirects.cfc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
<!---
Based on Better Redirects in Rails:
http://ethilien.net/archives/better-redirects-in-rails/
--->
<cfcomponent output="false">
<cffunction name="init">
<cfset this.version = "1.0,1.01,1.1.8">
<cfreturn this>
</cffunction>
<cffunction name="redirectToIndex"
hint="RedirectToIndex(flashMessage) Set flash and redirect to index."
description="This method is useful when you the user has just edited an object, and you now want to display a message
in the flash like 'User updated successfully', and then redirect them back to the index action.">
<cfargument name="flashMessage" default="" required="false">
<cfif StructKeyExists(arguments,"flashMessage")>
<cfset flashInsert(notice=arguments.flashMessage)>
</cfif>
<cfset redirectTo(action="index")>
</cffunction>
<cffunction name="flashRedirect"
hint="FlashRedirect(flashMessage) Set flash and redirect to index."
description="This method is useful when you want to display a message in the flash and then send them to another controller.
FlashRedirect accepts both a message to be put in the flash, along with the params for redirectTo, so that you can
flash a message and then send the user anywhere you please.">
<cfif StructKeyExists(arguments,"flashMessage")>
<cfset flashInsert(notice=arguments.flashMessage)>
<cfset StructDelete(arguments, "flashMessage")>
</cfif>
<cfset redirectTo(argumentCollection=arguments)>
</cffunction>
<cffunction name="redirectAway"
hint="RedirectAway(params) Saves URL, then does redirect."
description="Store the original url in the session, and then redirect to the other action">
<cfset var return_url = $getCurrentURL()>
<cfset setSessionRedirectParams()>
<!--- add the returnUrl param --->
<cfif return_url neq "">
<cfif IsDefined("arguments.params") AND (arguments.params neq "")>
<cfset arguments.params = arguments.params & "&">
<cfelse>
<cfset arguments.params = "">
</cfif>
<cfset arguments.params = arguments.params &
"returnUrl=" & return_url>
</cfif>
<cfreturn redirectTo(argumentcollection: arguments)>
</cffunction>
<cffunction name="redirectBack"
hint="RedirectBack(params) returns to the saved URL."
description="Returns the person to either the original url from a redirect_away or to a default url.">
<cfset var backUrl = "">
<cfset var redirect_args = "">
<cfset var pattern_args = "">
<cfif IsDefined("params") AND IsStruct(params) AND StructKeyExists(params, "returnUrl")>
<cfset backUrl = URLDecode(params.returnUrl)>
</cfif>
<cfif Len(backURL) GT 0>
<cftry>
<!--- find the matches route --->
<cfset route = application.wheels.dispatch.$findMatchingRoute(backUrl)>
<!--- for unit testing purposes, we need to add the "delay" param --->
<cfset redirect_args = {
route = route.name,
delay = true
}>
<!--- must pass the variables as well --->
<cfset pattern_args = $parseRoutePattern(pattern: route.pattern,
backUrl: backUrl)>
<cfset StructAppend(redirect_args, pattern_args, true)>
<cfreturn redirectTo(argumentcollection: redirect_args)>
<cfcatch type="any">
<!--- fallback to cflocation if we can't find any matching route --->
<cflocation url="#backURL#" addtoken="false">
</cfcatch>
</cftry>
<cfelse>
<cfset redirectTo(argumentCollection: arguments)>
</cfif>
</cffunction>
<cffunction name="setSessionRedirectParams" access="public" returntype="void" output="false" hint="Store the params variable in the session.">
<cfargument name="excludes" type="string" required="false" default="" hint="List of params to be excluded in the session.">
<cfset var session_name = "">
<cfset var key = "">
<cfif IsDefined("params")>
<cfset session_name = $getSessionRedirectParamsName()>
<cfset session[session_name] = Duplicate(params)>
<cfloop index="key" list="#arguments.excludes#" delimiters=",">
<cfset StructDelete(session[session_name], key)>
</cfloop>
</cfif>
</cffunction>
<cffunction name="getSessionRedirectParams" access="public" returntype="struct" output="false" hint="Get the params that are stored in the session.">
<cfargument name="clearAfterGet" type="boolean" required="false" default="true" hint="Clear the params in the session variable after finished?">
<cfset var session_params = StructNew()>
<cfset var key_name = $getSessionRedirectParamsName()>
<cfif StructKeyExists(session, key_name)>
<cfset session_params = Duplicate(session[key_name])>
<!--- clear the session params --->
<cfif arguments.clearAfterGet>
<cfset StructDelete(session, key_name)>
</cfif>
</cfif>
<cfreturn session_params>
</cffunction>
<cffunction name="clearSessionRedirectParams" access="public" returntype="void" output="false" hint="Clear the params in session.">
<cfset StructDelete(session, $getSessionRedirectParamsName)>
</cffunction>
<cffunction name="$getCurrentURL" access="public" output="false">
<cfset var current_url = "">
<!--- retreive the current url --->
<cfset current_url = application.wheels.dispatch.$getPathFromRequest(CGI.path_info, CGI.script_name)>
<!--- make sure that it always starts with "/" --->
<cfif (current_url neq "") AND (Left(current_url, 1) neq "/")>
<cfset current_url = "/" & current_url>
</cfif>
<cfreturn current_url>
</cffunction>
<cffunction name="$parseRoutePattern" access="public" returntype="struct" output="false" hint="Parse the url using the route's pattern.">
<cfargument name="pattern" type="string" required="true" hint="The route pattern.">
<cfargument name="backUrl" type="string" required="true" hint="The return url.">
<cfset var regex_pattern = "">
<cfset var find_pos = "">
<cfset var matches_count = 0>
<cfset var key = "">
<cfset var value = "">
<cfset var struct_out = {}>
<cfset regex_pattern = "^" & REReplace(arguments.pattern, "\[.*?\]", "(.*)", "all") & "$">
<cfset find_pos = REFindNoCase(regex_pattern, arguments.backUrl, 1, true)>
<cfset matches_count = ArrayLen(find_pos.pos) - 1>
<cfif matches_count gt 0>
<cfloop index="i" from="1" to="#matches_count#">
<cfset key = ListGetAt(route.variables, i, ",")>
<cfset value = Mid(arguments.backUrl, find_pos.pos[i + 1], find_pos.len[i + 1])>
<cfset struct_out[key] = value>
</cfloop>
</cfif>
<cfreturn struct_out>
</cffunction>
<cffunction name="$getSessionRedirectParamsName" access="public" returntype="string" output="false" hint="Get the params name in session.">
<cfreturn "betterRedirectsParams">
</cffunction>
</cfcomponent>