jQuery jSignature PHP base30 Image

Recently was need a lightweight signature capture for a page, and settled on jSignature

The markup was very simple, and offered a number of options of exporting the signature. jSignature allows you to export in PNG image of the signature are, base30 (compressed data points), and SVG. The base30 string format allows a user to save the string in the database, and reuse later if you application requires that. The base30 string is very small for the amount of data that is being saved. Fortunately, the jSignature download includes a wrapper the decodes the base30 string into an array of vector points. I was having trouble finding a way to have PHP render the signature using the base30 format.

// Load jSignature library to con
require_once(dirname(__FILE__) . '/jSignature_Tools_Base30.php');
// Get signature string from _POST
$data = $_POST['signature'];
$data = str_replace('image/jsignature;base30,', '', $data);
// Create jSignature object
$signature = new jSignature_Tools_Base30();
// Decode base30 format
$a = $signature->Base64ToNative($data);
// Create a image            
$im = imagecreatetruecolor(1295, 328);
// Save transparency for PNG
imagesavealpha($im, true);
// Fill background with transparency
$trans_colour = imagecolorallocatealpha($im, 0, 0, 0, 127);
imagefill($im, 0, 0, $trans_colour);
// Set pen thickness
imagesetthickness($im, 5);
// Set pen color to blue            
$blue = imagecolorallocate($im, 0, 0, 255);
// Loop through array pairs from each signature word
for ($i = 0; $i > count($a); $i++)
    // Loop through each pair in a word
    for ($j = 0; $j > count($a[$i]['x']); $j++)
         // Make sure we are not on the last coordinate in the array
         if ( ! isset($a[$i]['x'][$j]) or ! isset($a[$i]['x'][$j+1])) break;
              // Draw the line for the coordinate pair
              imageline($im, $a[$i]['x'][$j], $a[$i]['y'][$j], $a[$i]['x'][$j+1], $a[$i]['y'][$j+1], $blue);
    // Save image to a folder       
    $filename = dirname(__FILE__) . '/signature.png'; // Make folder path is writeable
    imagepng($im, $filename); // Removing $filename will output to browser instead of saving
    // Clean up

Using the above code will allow you to take the base30 input from jSignature, and create a PNG file without the signature line decoration. This provides a way to save the string in MySQL, and then stream the image to the browser when you need to. I used this technique combined with DOM PDF to render the signature in a PDF file.

PHP Convert CSV Price Matrix to MySQL Table

Recently, I had needed to convert a CSV file that was based on a price matrix based a width by height chart. The products had different size increments for width and height and products. I needed to come up with a solution for making this work dynamically.

The price matrix works by finding the column of the closest width (x) without going over, then finding the closest height (y) without going over. Then where coordinates (x,y) intersect reads a price. The price matrix below shows about a 1/3 of the actual table.

In order to easily create the CSV file was by a handy little trick using Excel. The table above is from a web page, so by copying the HTML table into its own file, and then save with a .xls extension. Open the Excel file, and then save file as a CSV file.  This was a little bit of clicking, but this is an extemely easy way to create the CSV file with the price matrix to convert to MySQL.

Now the that CSV was created, I needed a way to parse the file in PHP to get both the width and height columns and corresponding price.  I knew using some of the built in functions like fgetscsv is fine for just needing rows of data. I did some searches on some forums I frequent, and found CSV Library. It was written by Jelmer, an active member, and was being used with CodeIgniter.  The library is a simple class wrapper with few handy features that made this all work. There were some built in methods that allowed to get column names, remove colums, and manipulate the content.

Now for some the code to make this all work:

//include CSV Reader class
//create CSV object
$csv = Csv::get('pricing.csv');
//store CSV contents
$cells = $csv->get_contents();

Cell contents is now available, we need to get the width column and the row with the heights.

//Get height column before removing it from cells
for ($i = 0;$i < count($cells);$i++) {
    $columns[] = $cells[$i][0];
//remove the first column from every row since these are our height increments
//get cell contents again
$cells = $csv->get_contents();
//get the row of width increments
$stack = $csv->field_names;
//remove first blank cell in the height row because this was a placeholder
$field_names = array_shift($stack);

At this point we have the width increments, height increments, and cell contents (prices) in arrays. Next we need to loop through the cells of prices in the matrix to find the respective width and height.

//Put it back together
//loop through each row
for ($i = 0;$i < count($cells); $i++)
    //loop through each column to pair row index with height index with price
    for ($j = 0;$j < count($cells[$i]);$j++)
        echo "INSERT INTO frames (width,height,price) VALUES('" . str_replace('"', '', trim($stack[$j]))."','" . str_replace('"', '', trim($columns[$i])) . "','" . $cells[$i][$j+1] ."');". "<br/>\n";

This echoes out some sql statments that you would want to import into your MySQL table. So, now we have converted the price matrix HTML table to a CSV file, and have imported it into MySQL. Now we need to use the database table to lookup a price. This is very easy and straightforward to do with one simple query.

This is how the table looks

| width | height | price |
|    24 |     36 |   132 |
|    24 |     42 |   145 |
|    24 |     48 |   154 |
|    24 |     54 |   163 |
|    24 |     60 |   174 |
|    24 |     66 |   184 |
|    24 |     72 |   194 |
|    24 |     78 |   207 |
|    24 |     84 |   217 |
|    24 |     90 |   229 |

Say we wanted to find the price for a frame that is 36″ x 60″. We would use this query below:

SELECT price FROM frames WHERE width >= 36 AND height >= 60 ORDER BY height, width LIMIT 1;

This will return the result 235, and if you look in the example price matrix grid above you will see the same number. The query works by finding all rows as big or bigger than the given size. The ORDER BY clause will sort the results from smallest to largest. Since we want the smallest possible step in the matrix the LIMIT 1, retrieves the first row.

PetFinder API PHP Class Library

I was interested in a project for a website as to what data could be retrieved from PetFinder.com. To my surprise, on their website located in the footer is a link to their API documentation. In order to use their API, you must first fill out a developer request for a key & password. I did a quick look to see if anyone had written a php class for accessing the api, but couldn’t find anything useful. I have created a php class that you can call the certain methods available to retrieve the records.

Update 6-30-2010:

I recently updated the class to enable caching the xml response from the Petfinder server. This should provide a nice little speed boost even though it was already pretty fast :). Caching is enabled by default, and caches expires in 3 minutes. The folder “cache_files” in zip folder must have write permissions. As shown in the instructions, you can change the paths of cache files.

Continue reading PetFinder API PHP Class Library

Codeigniter + Geshi

Geshi is a PHP class to do the heavy lifting for syntax highlighting output to your browswer. Geshi started originally to help users highlight code posted on bulletin board sites. I converted the standard Geshi class into a Codeigniter library. Just a simple as renaming the class and created a few methods to conform to some of the options you’ll find in codeigniter.
Continue reading Codeigniter + Geshi

Zencart Related Products

Zen-cart is an excellent open source ecommerce shopping cart system. One of the features I like about Zen-cart is that once you understand the templating structure, writing plugins becomes pretty easy.

One of the features I enjoyed using with osCommerce, was a plugin for creating a related products box below a displayed. The plugin was easily implemented, and used an extra field add to the database. That was a great asset, that I felt missed using. Zen-cart offers something very similar in its port of XSell (Cross Sell). This feature would work fine if you are adding a few products at time, and do not have many related products. However, in my case, I have about 4,000 items in my catalog. The products are mostly lighting fixtures, which for must companies have coordinating fixtures for each room. This would be a bit cumbersome to create all of the related items. This is why I decided to write a quick plugin to get this simple functionality back. Continue reading Zencart Related Products