<?php
//
// class.cafepressbox.php
// version 1.2.0 - 22nd November, 2003
//
// Description
//
// This class will display a random product from your CafePress store.
// You can supply a simple template to control style, and have the
// output link directly to the shown product or simply to your main
// account. You can cache the results so you don't have to connect to
// the CafePress website all the time. Images can be cached and work
// on the same time length as the product list caching. Images can
// also be resized as desired before saved into the cache.
//
// This has only been tested with the free accounts from CafePress,
// and requires PHP 4.1.0+
//
// CafePress.com is � Copyright 1999-2003 CafePress.com.
//
// Author
//
// Andrew Collington, 2003
// php@amnuts.com, http://php.amnuts.com/
//
// Feedback
//
// There is message board at the following address:
//
// http://php.amnuts.com/forums/index.php
//
// Please use that to post up any comments, questions, bug reports, etc. You
// can also use the board to show off your use of the script.
//
// Support
//
// If you like this script, or any of my others, then please take a moment
// to consider giving a donation. This will encourage me to make updates and
// create new scripts which I would make available to you. If you would like
// to donate anything, then there is a link from my website to PayPal.
//
// Example of use
//
// $cp = new cafePressBox('collingtons');
// $cp->setCacheDir('./cache');
// $cp->setCacheTime(86400);
// $cp->setCacheImages(true);
// $cp->displayItem(true);
//
// With a REALLY simple template
//
// $cp = new cafePressBox('amnuts');
// $cp->setTemplate('<div align="center">[IMG]<br>[TXT]</div>');
// $cp->displayItem(false);
//
// [IMG] is where the product image will be displayed
// [TXT] is where the product text will be displayed
//
// Example with using a category with a paid-for account
//
// $cp = new cafePressBox('amnuts', '123456');
// $cp->displayItem(true);
//
class cafePressBox {
var $storeID;
var $categoryID;
var $products;
var $template;
var $cacheTime;
var $cacheDir;
var $cacheImages;
var $cpPattern;
var $resizeImage;
//
// Constructor
//
/**
* @return cafePressBox
* @param bool $id
* @param bool $category
* @desc The main class constructor
*/
function cafePressBox($id = false, $category = false)
{
$this->setStore($id, $category);
$this->products = array();
$this->setCacheTime();
$this->setCacheDir();
$this->setTemplate();
$this->setCacheImages();
$this->setResizeCachedImages();
}
//
// Public Methods - User called functions
//
/**
* @return void
* @param string $id
* @param mixed $category
* @desc Even though you can pass the store id in the constructor, you can use this function to change the store id.
*/
function setStore($id, $category = false)
{
$this->storeID = $id;
$this->categoryID = $category;
$this->setPattern();
$this->products = array();
}
/**
* @return void
* @param int $len
* @desc Set the time out for the cache file. If you do not with the results to be cached, then set this to 0.
* Time length is in seconds.
*/
function setCacheTime($len = 0)
{
$this->cacheTime = $len;
}
/**
* @return void
* @param string $dir Path of directory
* @desc Assign the directory to where the cache file will be saved
*/
function setCacheDir($dir = '.')
{
$this->cacheDir = $dir . ($dir[strlen($dir)-1] != '/' ? '/' : '');
}
/**
* @return void
* @param bool $okay
* @desc Sets whether or not we should store images locally. Image caching is based on cache time.
*/
function setCacheImages($okay = false)
{
$this->cacheImages = ($okay === true) ? true : false;
}
/**
* @return void
* @param int $size
* @desc To resize cached images, set the width size with this function
*/
function setResizeCachedImages($size = 0)
{
$this->resizeImage = ($size > 0) ? $size : false;
}
/**
* @return void
* @param string $pattern
* @desc The pattern string to find the products. This is likely to change if/when CafePress update their output.
*/
function setPattern($pattern = '')
{
if ($pattern == '')
{
$this->cpPattern = "<td align="center" valign="top"><p><a href="\/{$this->storeID}\.(\d+)">" .
"<img class="imageborder" border="0" height="150"" .
" alt="(.*?)" src="http:\/\/storetn\.cafepress\.com\/(\d)\/(.*?)\.jpg">" .
"<\/a><br><br><a href="\/{$this->storeID}\.(\d+)">(.*?)<\/a><br>\$(d+)\.(\d+)<\/td>";
}
else
{
$this->cpPattern = $pattern;
}
}
/**
* @return void
* @param string $template
* @desc You can pass a string which has some special place holders.
* These place holders will then be replaced with the output from the displayItem function.
* The place holders are:
* [IMG] = the image
* [TXT] = the text
*/
function setTemplate($template = '')
{
static $default = '<table border="0" cellpadding="5" cellspacing="0" width="150" style="border:1px dashed black;"><tr><td align="center" style="font-family : Verdana, Arial, sans-serif; font-size : 11px; text-decoration : none;">[IMG]<br>[TXT]</td></tr></table>';
if ($template == '' || (!strstr($template, '[IMG]') || !strstr($template, '[TXT]')))
{
$this->template = $default;
}
else
{
$this->template = $template;
}
}
/**
* @return void
* @param bool $link_to_product If true then add link directly to product information.
* @param int $id Use this to display a particular product. If the product is not listed then a random one will be chosen.
* @desc Display a random image from those in your inventory.
*/
function displayItem($link_to_product = false, $id = false)
{
$got = false;
$out = $txt = $img = '';
// get products
if (empty($this->products))
{
$got = $this->getProducts();
}
// if no products now, we couldn't get any
if (empty($this->products))
{
if (!$got)
{
$txt .= 'could not connect';
}
else
{
$txt .= 'no products found';
}
}
else
{
if (!$id || !array_key_exists($id, $this->products))
{
$id = array_rand($this->products);
}
$img .= '<a target="_blank" href="http://www.cafeshops.com/' . $this->storeID . ($link_to_product ? ".$id" : '/') . '">';
if ($this->cacheImages && @file_exists("{$this->cacheDir}{$this->products[$id]['image']}.jpg"))
{
$sizes = getimagesize("{$this->cacheDir}{$this->products[$id]['image']}.jpg");
$img .= '<img src="' . $this->cacheDir . $this->products[$id]['image'] . '.jpg" ' . $sizes[3] . ' border="0" title="' . $this->products[$id]['description'] . '">';
}
else
{
$img .= '<img src="' . $this->products[$id]['image_url'] . '" height="150" width="150" border="0" title="' . $this->products[$id]['description'] . '">';
}
$img .= "</a>n";
if ($link_to_product)
{
$product = '<a target="_blank" href="http://www.cafeshops.com/' . $this->storeID . ".$id">" . strtolower($this->products[$id]['description']) . '</a>';
}
else
{
$product = strtolower($this->products[$id]['description']);
}
$txt .= "n<p>Check out our $product and other great products at <a target="_blank" href="http://www.cafeshops.com/{$this->storeID}/">Cafe Press</a></p>n";
}
$out = str_replace('[IMG]', $img, $this->template);
$out = str_replace('[TXT]', $txt, $out);
echo $out;
}
//
// Private Methods - not called directly by user
//
/**
* @return bool
* @desc Saves parsed results to a cache file
*/
function saveCache()
{
$cache_file = $this->cacheDir . 'cache.' . $this->storeID;
if ($this->categoryID)
{
$cache_file .= '-' . $this->categoryID;
}
$fp = @fopen($cache_file, 'w');
if ($fp)
{
fwrite($fp, serialize($this->products));
fclose($fp);
return true;
}
else
{
return false;
}
}
/**
* @return bool
* @param string $name file name of image
* @param string $data image data
* @desc Saves image to a file
*/
function saveImage($name, $data)
{
$fp = @fopen("{$this->cacheDir}{$name}.jpg", 'w');
if ($fp)
{
fwrite($fp, $data);
fclose($fp);
if ($this->resizeImage)
{
$this->doImageResize("{$this->cacheDir}{$name}.jpg");
}
return true;
}
else
{
return false;
}
}
/**
* @return void
* @param string $filename
* @desc Resize an image based on class variable resizeImage
*/
function doImageResize($filename)
{
$version = $this->getGDVersion();
if (!empty($version))
{
$sizes = array();
$sizes = @getimagesize($filename);
if ($sizes[0] != $this->resizeImage)
{
$imIn = imagecreatefromjpeg($filename);
$height = $sizes[1] / ($sizes[0] / $this->resizeImage);
if ($version[0] == 1)
{
$imOut = @ImageCreate($this->resizeImage, $height);
@ImageCopy($imOut, $imIn, 0, 0, 0, 0, $this->resizeImage, $height, $sizes[0], $sizes[1]);
}
else if ($version[0] == 2)
{
$imOut = @ImageCreateTrueColor($this->resizeImage, $height);
@ImageCopyResampled($imOut, $imIn, 0, 0, 0, 0, $this->resizeImage, $height, $sizes[0], $sizes[1]);
}
imagejpeg($imOut, $filename, 100);
imagedestroy($imIn);
imagedestroy($imOut);
}
}
}
/**
* @return mixed
* @desc Get the version of GD being used
*/
function getGDVersion()
{
static $version = array();
if (empty($version))
{
ob_start();
phpinfo();
$buffer = ob_get_contents();
ob_end_clean();
if (preg_match("|<B>GD Version</B></td><TD ALIGN="left">([^<]*)</td>|i", $buffer, $matches))
{
$version = explode('.', $matches[1]);
}
else if (preg_match("|GD Version </td><td class="v">bundled (([^ ]*)|i", $buffer, $matches))
{
$version = explode('.', $matches[1]);
}
else if (preg_match("|GD Version </td><td class="v">([^ ]*)|i", $buffer, $matches))
{
$version = explode('.', $matches[1]);
}
}
return $version;
}
/**
* @return bool Success of getting product list
* @desc Get the product information either from cache file or from CafePress website.
*/
function getProducts()
{
$this->products = array();
$cache_file = $this->cacheDir . 'cache.' . $this->storeID;
if ($this->categoryID)
{
$cache_file .= '-' . $this->categoryID;
}
if ($this->cacheTime && ((time() - @filemtime($cache_file)) < $this->cacheTime))
{
$this->products = @unserialize(@join('', @file($cache_file)));
}
else
{
// connect to the website
if ($this->categoryID === false)
{
$reqheader = "GET /cp/store.aspx?s={$this->storeID} HTTP/1.0rnHost: www.cafeshops.comrnUser-Agent: RandomProductrnrn";
}
else
{
$reqheader = "GET /cp/store.aspx?s={$this->storeID}.{$this->categoryID} HTTP/1.0rnHost: www.cafeshops.comrnUser-Agent: RandomProductrnrn";
}
$socket = @fsockopen("www.cafeshops.com", 80, $errno, $errstr, 60);
// we have the socket open
if ($socket)
{
fputs($socket, $reqheader);
while (!feof($socket))
{
$line = fgets($socket, 4096);
$matches = array();
if (preg_match("/{$this->cpPattern}/i", $line, $matches))
{
// item # :: item desc :: directory :: image name :: item # :: item desc :: price dollar :: price cents
// e.g.
// 5956381 :: White T-Shirt :: 1 :: 5956381_F_store :: 5956381 :: White T-Shirt :: 14 :: 99
$this->products[$matches[1]]['description'] = trim($matches[2]);
$this->products[$matches[1]]['image'] = trim($matches[4]);
$this->products[$matches[1]]['image_url'] = "http://storetn.cafepress.com/{$matches[3]}/" . trim($matches[4]) . '.jpg';
$this->products[$matches[1]]['price'] = "{$matches[7]}.{$matches[8]}";
}
}
fclose($socket);
if ($this->cacheTime)
{
$this->saveCache();
}
if ($this->cacheImages && $this->cacheTime)
{
// as we're caching, grab the files too
foreach($this->products as $product)
{
set_time_limit(120);
$data = '';
$fp = @fopen($product['image_url'], 'r');
if ($fp)
{
while(!feof($fp))
{
$data .= fgets($fp, 4096);
}
fclose($fp);
$this->saveImage($product['image'], $data);
}
}
}
}
// there was a problem
else
{
return false;
}
}
return true;
}
}
?>
|
|