Code:
<?php
/**
* download header_php.php
*
* @package page
* @copyright Copyright 2003-2011 Zen Cart Development Team
* @copyright Portions Copyright 2003 osCommerce
* @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
* @version $Id: header_php.php 18964 2011-06-22 19:58:38Z drbyte $
*/
// This should be first line of the script:
$zco_notifier->notify('NOTIFY_HEADER_START_DOWNLOAD');
define('SYMLINK_GARBAGE_COLLECTION_THRESHOLD', 1*60*60); // 1 hour default
require(DIR_WS_MODULES . zen_get_module_directory('require_languages.php'));
// if the customer is not logged on, redirect them to the time out page
if (!$_SESSION['customer_id']) {
zen_redirect(zen_href_link(FILENAME_TIME_OUT));
}
// Check download.php was called with proper GET parameters
if ((isset($_GET['order']) && !is_numeric($_GET['order'])) || (isset($_GET['id']) && !is_numeric($_GET['id'])) ) {
// if the paramaters are wrong, redirect them to the time out page
zen_redirect(zen_href_link(FILENAME_TIME_OUT));
}
// Check that order_id, customer_id and filename match
$sql = "SELECT date_format(o.date_purchased, '%Y-%m-%d')
AS date_purchased_day, opd.download_maxdays, opd.download_count, opd.download_maxdays, opd.orders_products_filename, o.customers_email_address
FROM " . TABLE_ORDERS . " o, " . TABLE_ORDERS_PRODUCTS . " op, " . TABLE_ORDERS_PRODUCTS_DOWNLOAD . " opd
WHERE o.customers_id = customersID
AND o.orders_id = ordersID
AND o.orders_id = op.orders_id
AND op.orders_products_id = opd.orders_products_id
AND opd.orders_products_download_id = downloadID
AND opd.orders_products_filename != ''";
$sql = $db->bindVars($sql, 'customersID', $_SESSION['customer_id'], 'integer');
$sql = $db->bindVars($sql, 'downloadID', $_GET['id'], 'integer');
$sql = $db->bindVars($sql, 'ordersID', $_GET['order'], 'integer');
$downloads = $db->Execute($sql);
if ($downloads->RecordCount() <= 0 ) die;
$zco_notifier->notify('NOTIFY_CHECK_DOWNLOAD_HANDLER', array($downloads));
// MySQL 3.22 does not have INTERVAL, so must calculate dates with PHP:
list($dt_year, $dt_month, $dt_day) = explode('-', $downloads->fields['date_purchased_day']);
$download_timestamp = mktime(23, 59, 59, $dt_month, $dt_day + $downloads->fields['download_maxdays'], $dt_year);
// Die if time expired (maxdays = 0 means no time limit)
if (($downloads->fields['download_maxdays'] != 0) && ($download_timestamp <= time())) {
zen_redirect(zen_href_link(FILENAME_DOWNLOAD_TIME_OUT));
}
// Die if remaining count is <=0 (maxdays = 0 means no time limit)
if ($downloads->fields['download_count'] <= 0 and $downloads->fields['download_maxdays'] != 0) {
zen_redirect(zen_href_link(FILENAME_DOWNLOAD_TIME_OUT));
}
$zco_notifier->notify('NOTIFY_DOWNLOAD_DAYS_COUNT_OK');
// FIX HERE AND GIVE ERROR PAGE FOR MISSING FILE
// Die if file is not there
if (!file_exists(DIR_FS_DOWNLOAD . $downloads->fields['orders_products_filename'])) die('Sorry. File not found. Please contact the webmaster to report this error.<br />c/f: ' . $downloads->fields['orders_products_filename']);
$zco_notifier->notify('NOTIFY_DOWNLOAD_FILE_OK');
// Now decrement counter (probably should skip this if download_maxdays = 0, ie: unlimited) -- move it up to lines 48-54?
$sql = "UPDATE " . TABLE_ORDERS_PRODUCTS_DOWNLOAD . "
SET download_count = download_count-1
WHERE orders_products_download_id = :downloadID";
$sql = $db->bindVars($sql, ':downloadID', $_GET['id'], 'integer');
$db->Execute($sql);
// Returns a random name, 16 to 20 characters long
// There are more than 10^28 combinations
// The directory is "hidden", i.e. starts with '.'
function zen_random_name()
{
$letters = 'abcdefghijklmnopqrstuvwxyz';
$dirname = '.';
$length = floor(zen_rand(16,20));
for ($i = 1; $i <= $length; $i++) {
$q = floor(zen_rand(1,26));
$dirname .= $letters[$q];
}
return $dirname;
}
// Unlinks all subdirectories and files in $dir
// Works only on one subdir level, will not recurse
function zen_unlink_temp_dir($dir)
{
$h1 = opendir($dir);
while ($subdir = readdir($h1)) {
// Ignore non directories
if (!is_dir($dir . $subdir)) continue;
// Ignore . and .. and .svn
if ($subdir == '.' || $subdir == '..' || $subdir == '.svn') continue;
// Loop and unlink files in subdirectory
$h2 = opendir($dir . $subdir);
list($fn, $exptime) = explode('-', $subdir);
if ($exptime + SYMLINK_GARBAGE_COLLECTION_THRESHOLD > time()) continue;
while ($file = readdir($h2)) {
if ($file == '.' || $file == '..') continue;
@unlink($dir . $subdir . '/' . $file);
}
closedir($h2);
@rmdir($dir . $subdir);
}
closedir($h1);
}
// disable gzip output buffering if active:
@ob_end_clean();
if (@ini_get('zlib.output_compression')) @ini_set('zlib.output_compression', 'Off');
// determine filename for download
$origin_filename = $downloads->fields['orders_products_filename'];
$browser_filename = str_replace(' ', '_', $origin_filename);
if (strstr($browser_filename, '/')) $browser_filename = substr($browser_filename, strrpos($browser_filename, '/')+1);
if (strstr($browser_filename, '\\')) $browser_filename = substr($browser_filename, strrpos($browser_filename, '\\')+1);
if (substr(DIR_FS_DOWNLOAD, -1) != '/') $origin_filename = '/' . $origin_filename;
if (!file_exists(DIR_FS_DOWNLOAD . $origin_filename)) {
$msg = 'DOWNLOAD PROBLEM: Problems detected with download for ' . DIR_FS_DOWNLOAD . $origin_filename . ' because the file could not be found on the server. If the file exists, then its permissions are too low for PHP to access it. Contact your hosting company for specific help in determining correct permissions to make the file readable by PHP.';
zen_mail('', STORE_OWNER_EMAIL_ADDRESS, ERROR_CUSTOMER_DOWNLOAD_FAILURE, $msg, STORE_NAME, EMAIL_FROM);
}
$downloadFilesize = @filesize(DIR_FS_DOWNLOAD . $origin_filename);
if (!isset($downloadFilesize) || ($downloadFilesize < 1)) {
$msg = 'DOWNLOAD PROBLEM: Problem detected with download for ' . DIR_FS_DOWNLOAD . $origin_filename . ' because the server is preventing PHP from reading the file size attributes, or the file is actually 0 bytes in size (which suggests the uploaded file is damaged or incomplete). Perhaps its permissions are too low for PHP to access it? Contact your hosting company for specific help in determining correct permissions to allow PHP to stat the file using the filesize() function.';
zen_mail('', STORE_OWNER_EMAIL_ADDRESS, ERROR_CUSTOMER_DOWNLOAD_FAILURE, $msg, STORE_NAME, EMAIL_FROM);
}
/* ---- Start lat9 PDF Stamper ---
**
** Stamped file is of the format: originalname_ordernum_downloadcount.pdf
*/
$stamp_fn_out = basename($origin_filename, '.pdf') . '_' . $_GET['order'] . '_' . $downloads->fields['download_count'] . '.pdf';
$stamp_fn_out = str_replace(' ', '_', $stamp_fn_out);
$stamp_file_out = DIR_FS_DOWNLOAD_PUBLIC . $stamp_fn_out;
$stamp_file_in = DIR_FS_DOWNLOAD . $origin_filename;
/**
* set the includepath for SetaPDF APIs
* You have to point to the root directory "SetaPDF"
*/
set_include_path(get_include_path() . PATH_SEPARATOR . DIR_FS_SETAPDF);
$zco_notifier->notify('NOTIFY_DOWNLOAD_PATH', get_include_path());
// require the SetaPDF_Stamper-class
require_once("Stamper/SetaPDF_Stamper.php");
$zco_notifier->notify('NOTIFY_DOWNLOAD_STAMP_LOADED');
// Define the path, where the SetaPDF-Stamper will find the font-definition files
define('SetaPDF_STAMPER_FONTPATH', 'Stamper/font/');
// Create a new instance of SetaPDF_Stamper with output method "Download" w/buffering
$stamper =& SetaPDF_Stamper::factory('D', true);
$stamper->addFile(
array(
"in" => $stamp_file_in,
"out" => $stamp_file_out,
"compression" => true
)
);
// Let's create the text stamp
// require the SetaPDF_TextStamp-class
require_once("Stamper/SetaPDF_Stamp/SetaPDF_TextStamp.php");
// Initiate a new instance of text_stamp
$textstamp =& new SetaPDF_TextStamp();
// Set the text
$textstamp->setText("Licensed to:" . "\n" . $downloads->fields['customers_email_address']);
// Set font definitions
$textstamp->setFont("Arial", "B", 20, 20, "C");
// Set text color to red
$textstamp->SetFontColor(255, 0, 0);
// Set the charspacing
$textstamp->setCharSpacing(15);
// Set the rendering mode
$textstamp->setRenderingMode(2);
// Set the opacity
$textstamp->setAlpha(0.2);
/**
* Now we assign the text stamp to our stamper
* - we define the position on the center and middle of a page (CM)
* - the stamp should appear on "all" pages
* - no translation of the x-axis nor the y-axis will be done
* - we rotate the stamp about 60 degree
*/
$stamper->setStamp($textstamp,"CM", "all", 0, 0, 60);
// Let's stamp!
$stamper->stampit();
$stamper->cleanUp();
// This should be last line of the script:
$zco_notifier->notify('NOTIFY_HEADER_END_DOWNLOAD');
// finally, upon completion of the download, the script should end here and not attempt to display any template components etc.
zen_exit();