Money-Code

Coding For Online Success

Capture search data on your site

| 0 comments

In early September, ShoeMoney posed this question “Are You Selling Your Search Data For Pennies”. This was a very interesting post talking about using AdSense for search (
) to search your site and possibly generate revenue. This can be a great revenue tool for some, but as ShoeMoney mentions, that you are possibly throwing away incredibly useful data.

On one of my sites (eBay niche site using RSS feeds to populate the store), I thought it would be a great opportunity to see what my visitors might be interested to see on the site. I recently included the eBay API to pull in ‘featured’ auctions, but what featured auctions would be successful for me?

In my application, the search criteria is fed directly to my eBay API to pull real time auction results based off of their search. Before sending the search query to eBay, I wanted to track this data, so I can reference it and showcase those high searched items on the home page. I’ll be talking about the eBay API in another post, but first I’ll discuss how I capture search data.

First, we need to create the database table:

CREATE TABLE `tblSearch` (
  `SearchID` int(11) NOT NULL auto_increment,
  `Criteria` varchar(250) NOT NULL,
  `MonthYear` varchar(4) NOT NULL,
  `Count` int(11) NOT NULL,
  PRIMARY KEY  (`SearchID`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
 

Now we need to make our search box. I like to work in a templated system using MVC (Model View Controller) architecture called Fusebox. This example will just assume that you’re passing from page to page, so any architecture (if any) will work just fine.

<div id="head-ebay"><h3>Search</h3></div>
<div id="box">
        <script language="javascript">
                function validateSearch(frm){
                        if(frm.Criteria.value.length < 5){
                                alert("Search Criteria is too short");
                                frm.Criteria.select();
                                return false;
                        }
                }
        </script>
        Please enter your search criteria.<br><br>
        <form action="searchResults.php" method="post" name="SearchForm" onSubmit="return validateSearch(SearchForm);">
                <table cellpadding=0 cellspacing=5 border=0 valign="top">
                <tr>
                        <td><strong>Search:</strong></td>
                        <td><input type="text" name="Criteria" value="" class="text" size=15></td>
                        <td><input type="submit" value="Search" class="text"></td>
                </tr>
                </table>
        </form>
</div>
 

This form posts to searchResults.php, but we’re doing some client-side validation with javascript. I can’t stress the importance of controlling input and paying attention to security. This will be discussed in many posts in the future. This client-side validate is checking to see that the search word is longer than 5 characters.

On the processing page (searchResults.php), we need to follow up our client-side validation with server-side validation. The client-side validation is primary set up as a convenience to the user, the server-side is set up to protect our application and ensure that the input we’re expecting is correct.

if(!isset($_POST["Criteria"]) || strlen(trim($_POST["Criteria"])) == 0){
        header("Location:search.php");
        exit();
}
if(strlen(trim($_POST["Criteria"])) < 5){
        echo "Search Criteria is too short";
        exit();
}
$_POST["Criteria"] = trim(htmlspecialchars(strip_tags(addslashes($_POST["Criteria"]))));
if(strlen(trim($_POST["Criteria"])) == 0){
        header("Location:search.php");
        exit();
}
$monthYear      = date(‘my’);
$sql            = "UPDATE tblSearch
                                SET Count = Count + 1
                                WHERE Criteria = ‘"
.safeSQL($_POST["Criteria"],2,200)."’
                                AND MonthYear = ‘"
.$monthYear."’";
if(!mysql_query($sql,$connect)){
        trigger_error(sprintf("SQL Error: %d: %s\n" , mysql_errno(), mysql_error()), E_USER_ERROR);
}
if(!mysql_affected_rows()){
        $sql    = "INSERT INTO tblSearch(Criteria, MonthYear, Count)
                                VALUES(‘"
.safeSQL($_POST["Criteria"],2,200)."’,
                                ‘"
.$monthYear."’,1)";
        if(!mysql_query($sql,$connect)){
                trigger_error(sprintf("SQL Error: %d: %s\n" , mysql_errno(), mysql_error()), E_USER_ERROR);
        }
}
 

Our PHP code is checking to see if the field ‘Criteria’ is available and contains a length. If that fails it will redirect the user to the first search form. Next it checks to see if the length is greater than 5 characters. If it’s not, it’ll output a message and stop page execution.

Next, we’re sanitizing the post. We’re stripping tags, and making sure the value has no potentially hazardous values (ie: scripting, etc).

Finally, we’re going to update the search count if the same search criteria has been posted before. Basically, this will increment a counter for that search word. If no rows were affected with the update, that means it’s not in the database, and we need to insert this new search item. I’m trying to group these by month/year. I plan on doing weekly reports on the search criteria and sorting by count. This will give me a nice top 10 of popular searches.

You might notice the trigger_error(). I provide custom error handling, if you’re not doing custom error handling, you can do die() or some other handling to manage the MySQL error. I don’t recommend ever displaying error messages to the public.

I’ll follow this post up with part 2, which will include the eBay API query.

Leave a Reply

Required fields are marked *.


CommentLuv badge