ClickTale Support Forums

All times are UTC - 6 hours



Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Wed Jan 28, 2009 3:51 pm 
Offline

Joined: Fri Jan 23, 2009 12:43 pm
Posts: 1
The integration of Clicktale with pages that rely on POST data can be tricky. In a scenario with 2 pages, with page A being a form that sends data to page B using the form method="post", you will usually want to validate user input on the server side, before outputting anything on page B (or writing it to a database, etc.). Ideally, this server-side validation is a fallback security measure that you have added to any client-side (JavaScript) validation of the form on page A.

By the way: NEVER trust user input, ALWAYS validate on both ends.

So, how to integrate such a functionality with Clicktale?

Fortunately, Arik already provided a great explanation about recording POST pages in ASP. I have applied the techniques he mentions to a recent project, coded in PHP - but while working on it, I stumbled over a couple of things. With Arik's help though (thanks Arik), I have been able to wrap my head around how exactly Clicktale works, and what is needed to make it work.

This tutorial may help some to clarify a few issues I have run into. I will try to make it as simple and thorough as possible. This tutorial also applies when using PHP_SELF, by the way - I am using two pages in this example though.

Scenario
Image
The above is a simple visualization of our site structure.

* We have page A to the left which sends the data user entered into the form to page B using the POST method.
* On page B, all fields are being validated even before the page loads. If validation fails, then the PHP code redirects back to page A without loading the page. If validation passes, then it will continue to load the page.

What server-side validation is taking place in the above structure?

Step 1: Validation Function for Form Fields
To make things simple, let's say we have 1 form field that we need to validate. Usually, you will have more fields, but that's irrelevant to this tutorial because we will validate each field in its own PHP function. You'll see where I'm getting at in a minute.

We will be validating an age field (where user has to enter how old they are).

Code:
//set $valid to true before anything else
$valid = true;

//run the validation function, which will change $valid to FALSE if validation fails
chk_age();

//check for $valid and redirect back to page A if FALSE
if(!$valid)
   header('location: pageA.php');

//else, do nothing, but let page B load as usual


The above code will simply redirect the user back to page A if $valid happens to be false.
Now for the $chk_age() function, which does the actual validation of the field. Ideally, you will want to create a separate file (e.g. functions.php) for all functions, and include that file before the above code.

Code:
function chk_age() {
   global $valid, $age;
   
   //the minumum and maximum age required to pass validation
   $min = 18;
   $max = 99;
   
   //five checks:
   if(      isset($_POST['age'])      //is the field passed at all?
      && !empty($_POST['age'])   //is the field empty?   
      && is_numeric($_POST['age'])   //is the passed value a number?
      && ($_POST['age'] >= $min)   //is it larger than the minimum value?
      && ($_POST['age'] <= $max)   //is it below the maximum value?
   ) {
      //if all of the above passes as true, proceed by writing the passed value to a variable
      $age = $_POST['age'];
      
      //now do something with the variable, e.g. write it to a cookie
      setcookie('age', $age, time()+60*60*24);
      
   } else {
      //if any one of the 5 checks returns FALSE, we set the global $valid variable to false
      //and we dont do anything with the passed value either
      $valid = false;
   }
   
   return $valid;
}


What this does is run a passed form textfield with name="age" through a series of checks. If all checks pass as true, then $valid is not touched. If any one of the checks doesn't pass, $valid is set to false. Remember we set $valid to true BEFORE we ran this function (in the first code above). By declaring $valid as a global variable within chk_age(), the function already starts off with $value=true.

We wrote a function for this so that we can add validation for additional form fields to the fist code. For each form field we want to validate, we write a separate validation function. We then only need to call the functions for more fields one after another in the first code, before we check if $valid is true or false.

Step 2: Understanding the Problem
Now we want to make Clicktale work with this thing. The single most important fact we need to understand for this is the following:

Quote:
Treat Clicktale like a separate user who is allowed to bypass any validation.


This might be old news to you, but it took me a while to get this. Clicktale doesn't simply record page for page, but it records a user's interaction with the whole site. It also doesn't simply sit on user's shoulder and follows his path through validation, but it is like a 2nd user standing next to the actual user, and it needs extra treatment.

In short, we need to enable Clicktale to override all validation and to be able to access all pages at all times.

Step 3: Creating the Solution
As Arik pointed out in his post, we will let Clicktale pass a query through the URL. We will then add an extra validation function with the following attributes:

* the function is called AFTER all other validation functions
* the function checks for Clicktale's query parameter in the URL
* if it finds the parameter, it will override all other validation functions and let the page load as usual.

Image

The blue GET represents the query parameter in the URl, e.g. pageB.php?clicktale=yes. You can name this whatever you like (e.g. "pass=true" or "x=1").

Step 4: Add Code to Page A
We will add the ClickTaleFetchFrom variable to the Clicktale JavaScript code at the bottom of the page, as pointed out in the API reference:

Code:
<div id="ClickTaleDiv" style="display: none;"></div>
<script src="http://s.clicktale.net/WRb.js" type="text/javascript"></script>
<script type="text/javascript">
          ClickTaleFetchFrom=http://mydomain.com/pageA.php?clicktale=yes
if(typeof ClickTale=='function') ClickTale(00000,1);
</script>


* add the indented line after running WRb.js and before calling the ClickTale function, as above
* replace mydomain.com/pageA.php with the CURRENT URL of the page you are on
* add your custom parameter (?clicktale=yes) to this URL, which we will check for in the next step.

I used ClickTale(00000,1); in the funciton call on the last line, this will obviously be your own number for your account.

Step 5: Validation Function on Page B

In functions.php, we add a very simple function:
Code:
function chk_clicktale() {
   global $valid;
   if(isset($_GET['clicktale']) && ($_GET['clicktale'] == 'yes'))
      $valid = true;
   
   return $valid;
}


* if the URL parameter clicktale is set and has the value yes, then we set $valid to true.

Now we only need to run this function after we run all other validation functions. So we add it to the first piece of code in this tutorial:

Code:
$valid = true;

chk_age();
chk_clicktale();

if(!$valid)
   header('location: pageA.php');


In essence, page B checks if clicktale=yes exists in the URL, and if so, it allows access, regardless of the form on the previous page not having validated.

And we're done! Clicktale should now be able to record POST pages which rely on validation to load. I hope this example will be of help!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group