Verification
Verify the existence and type of variables before allowing for a given controller action to run.
Verification, through the verifies() function, is just a special type of filter that runs before actions. With verifications defined in your controller, you can eliminate the need for wrapping your entire actions in
<cfif>
blocks checking for the existence and types of variables. You also can limit your actions' scopes to specific request types like post, get
, and AJAX requests.Let's say that you want to make sure that all requests coming to a page that handles form submissions are
post
requests. While you can do this with a filter and the isPost() function, it is more convenient and DRY to do it with the verifies() function.All that you need to do is add this line to your controller's
config()
function:// In the controller
function config(){
verifies(only="create,update", post=true);
}
The code above will ensure that all requests coming to the
create
and update
actions are from form submissions. All other requests will be aborted.There are also boolean arguments for
get
and ajax
request types.You can also specify different behavior for when the verification fails in a special
handler
function registered with the handler argument.In this example, we register the
incorrectRequestType()
function as the handler:// In the controller
function config(){
verifies(
only="create,update",
post=true,
handler="incorrectRequestType";
}
function incorrectRequestType(){
redirectTo(action="accessDenied");
}
Note that you have to either do a redirectTo() call or abort the request completely after you've done what you wanted to do inside your handler function. If you don't do anything at all and just let the function exit on its own, Wheels will redirect the user back to the page they came from. In other words, you cannot render any content from inside this function but you can let another function handle that part by redirecting to it.
A very convenient and common use of verifies() is when you want to make sure that a variables exists and is of a certain type; otherwise, you would like for your controller to redirect the user to a different page.
Step back in time for a moment and remember how you used to code websites before Wheels. (Yes I know those were dark days, but stay with me.)
On your
edit.cfm
page, what you probably did was write some code at the top of that looked like this:<cfif !StructKeyExists(form, "userId") OR !IsValid("guid", form.userId)>
<cflocation url="index.cfm" addToken="false">
</cfif>
With this snippet of code, you could ensure that any request to the
edit.cfm
had to have the userId
in the form scope and that userId
had to be of type guid
. If these conditions weren't met, the request was redirected to the index.cfm
page. This was a very tedious but necessary task.// In the controller
function config(){
verifies(
only="edit",
post=true,
params="userId",
paramsTypes="guid",
action="index",
error="Invalid user ID."
);
}
With that one line of code, Wheels will perform the following checks when a request is made to the controller's
edit
action:- Make sure that the request is a
post
request. - Make sure that the
userId
variable exists in theparams
struct. - Make sure that the
params.userId
is of typeguid
. - If any of those checks fail, redirect the request to the
index
action and place an error key in the Flash containing the message "Invalid user ID."
All that functionality in only one line of code!
What if you wanted do this for two or more variables? The
params
and paramsTypes
each accept a list so you can include as many variables to check against as you want.The only thing you need to make sure of is that the number of variables in the
params
list matches the number types to check against in the paramsTypes
list. This also goes for the session/sessionTypes
and cookie/cookieTypes
arguments, which check for existence and type in the session
and cookie
scopes, respectively.verifies() exists solely to validate controller and environment level variables and is not a substitute for Object Validationin your model.
A basic example of this is to validate params passed through to your controller from routes. Suppose we have the following route in our application:
.post(name="usersAddressesSave",
pattern="admin/users/[userid]/addresses/save",
to="UserAddresses##save")
In this example, we will want to verify that the
userId
integer and address
struct are both present in the params
struct and also that userId
is of a certain type:verifies(
only="save",
post=true,
params="userId,address",
paramsTypes="integer,struct"
)>
However, verifies() should not be used to make sure that values within the address struct themselves are valid (such as making sure that
address.zipCode
is correct). Because the address
struct will be passed in to the model, the validation will be performed there.