Chapter 13: Helper Scripts in PHP

The following exercises are supplements to Chapter 13 of Customing Library Vendor Tools for Better UX.

Trinity College Bookmarklet

Back in Chapter 5 we looked at the JavaScript to make a bookmarklet for Trinity College Library. The bookmarklet added an <img> tag to the page that sent data to an external script through the URL. Here is the JavaScript bookmarklet that you can run on the Trinity College Library catalog:

javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://gvsulib.com/temp/OPAC-Vote/opacvote.js';})();

You can install it by dragging the following link to your bookmarks bar: Add Vote Button

Here is the code for the helper script on the server.

<?php
header('Access-Control-Allow-Origin: *');
header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==');

// Set variables
$recordNo = $_GET['record'];
$time = date('m/d/Y', time());

// Create array
$data = array($time, $recordNo);

// Append to .csv file
if (!$DataFile = fopen("opacvote.csv", "a")) {
    echo "Failure: cannot open file"; die;
};
if (!fputcsv($DataFile, $data)) {
    echo "Failure: cannot write to file"; die;
};
fclose($DataFile);
?>

You can see what gets recorded by loking at the text file on my server at http://gvsulib.com/temp/OPAC-Vote/opacvote.csv.

Search Query Statistics

The following JavaScript captures the contents of a search box and sends it to a PHP script to be saved (below). It uses a numeric index to track which search tool it came from, so you can have a single database with search queries from all of your tools. (You can look at the MySQL file to see how the database was created.)

// Discovery Layer script with AJAX
var search_query = $('input[type="text"]').val();   

$.ajax({
  method: 'GET',
  url: '//mylibrary.org/searches.php',
  data: {tool: '1', search: search_query},
  success: function() {
    console.log('Search query recorded.');
  }
});

// OPAC Script with AJAX
var search_query('input[type="text"]).val();

$('body').append('<img src="//mylibrary.org/searches.php?tool=2&search=' + encodeURIComponent(search_query) + '" style="display: none;" />’);

Here is the PHP script that parses the data:

<?php
header("Access-Control-Allow-Origin: *");
header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==');

// Connect to the database
$db = new mysqli("localhost", "username", "password", "searches");

// Save the data from the request
if(is_numeric($_GET['tool'])) {
  $tool = $_GET['tool'];
  echo $tool;
} else {
	echo 'Not numeric';
  die;
}

$search = urldecode($_GET['search']);
$search = $db->real_escape_string($search);

// Save data to the database
$result = $db->query("INSERT INTO search_queries SET search_tool ='$tool', search_query='$search'");

?>

Let's say that a user did a search in your OPAC (search_tool ID of 2) for "batman" at 4:14pm on June 15th, 2016. If there are 190 other rows before this one, the JavaScript will insert a new row into your MySQL database, so now you'll have the following record:

query_id timestamp search_tool search_query
191 2016-06-15 16:14:05 2 batman

We might make this script a bit more sophisticated by using our PHP script to echo back to our search tool some information about other useful searches. Here is a jQuery script and a PHP script that send the search results and then suggest other tools where the same search has been done. (Here is the new MySQL file so you can see how that database was created.)

Here's the markup for our OPAC where it shows how many results are returned for a search:

<div class="browseSearchtoolMessage">       
    <i>116 results found.</i>
    Sorted by  <strong>relevance</strong>  | 
    <a href="/search~S19/X?batman&SORT=DX">date</a>  | 
    <a href="/search~S19/X?batman&SORT=AX">title</a>.
</div>

Here is our AJAX function, a pure AJAX call that parses the data returned by our PHP script, below:

// OPAC Results
var search_query = $('input[type="text"]').val();
var allResults = $('div.browseSearchtoolMessage').find('i').text().split(' ');
var catalogTotal = allResults[0];

$.ajax({
  method: 'POST',
  url: '//mylibrary.org/searches.php',
  data: {tool: '2', search: search_query, results: catalogTotal},
  success: function() {
    console.log('Search query recorded.');
    $('#opac_results').prepend(data);
  }
});

And here is our PHP script, complete with a sophisticated MySQL query to pull the other tools that have had similar searches more than 5 times, and return the results to our search tool where the results will be added to the page to help our users diversify their searches.

<?php
header("Access-Control-Allow-Origin: *");

// Connect to the database
$db = new mysqli("localhost", "username", "password", "searches");

// Save the data from the request
if(is_numeric($_GET['tool'])) {
  $tool = $_GET['tool'];
  echo $tool;
} else {
	echo 'Not numeric';
  die;
}

$search = urldecode($_GET['search']);
$search = $db->real_escape_string($search);
$no_results = $db->real_escape_string($_GET['results']);


// Save data to the database
$result = $db->query("INSERT INTO search_queries SET search_tool ='$tool', search_query='$search', no_of_results='$no_results'");


$suggestions = $db->query("SELECT COUNT(query_id) as count,
search_queries.no_of_results,
search_tools.search_tool,
search_tools.search_url
FROM search_queries,
search_tools
WHERE search_queries.search_query = '$search' 
AND search_queries.search_tool != '$tool'
AND search_queries.search_tool = search_tools.tool_id
GROUP BY search_tools.tool_id 
HAVING count > 5");


$suggestions = $db->query($query);

if($suggestions) { // true- it worked!
    $number_of_tools = $suggestions->num_rows;

	// Only add items when there is more than one tool recommended
	if($number_of_tools > 0) {
       echo '<div id="suggested-tools"><h4>Others have searched for this in:</h4></br />';
	   // Grab each row as an object and select the relevant properties
       while($other_tools = $suggestions->fetch_array()) {
	        echo '<p><a href="' . $other_tools['search_url'] . urlencode($search) . '">' . $other_tools['search_tool'] . '</a>: ' . $other_tools['no_of_results'] . ' results</p>';
    	}
    
    	echo '</div>'; // Close the container

	}

}  else { // false
    // An error happened
}
?>

Here is what the results of this query might look like:

count no_of_results search_tool search_url
40 1207 Catalog //library.catalog.gvsu.edu/search/?searchtype=X&searcharg=
25 2469 LibGuides //libguides.gvsu.edu/srch.php?q=

Of course, this script is a proof of concept. You can see a live version running at chapter13_test.html on this site. It doesn't account for the variances in search for a term with no filters and searchng for a term with many filters. In its current state it uses the value of the last recorded instance of the term for each tool to generate the number of results. But, as an example, I think it's kind of fun!